efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 1 | # ============LICENSE_START=================================================== |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 2 | # Copyright (C) 2019-2021 Nordix Foundation. |
efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 3 | # ============================================================================ |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. |
| 15 | # |
| 16 | # SPDX-License-Identifier: Apache-2.0 |
| 17 | # ============LICENSE_END===================================================== |
| 18 | import json |
| 19 | import os |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 20 | from unittest.mock import patch, MagicMock |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 21 | from http import HTTPStatus |
| 22 | |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 23 | from mod import aai_client |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 24 | from mod.api.controller import status, post_subscription, get_subscription_by_name,\ |
| 25 | get_subscriptions |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 26 | from tests.base_setup import BaseClassSetup |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 27 | from mod.api.db_models import SubscriptionModel, NfMeasureGroupRelationalModel |
| 28 | from mod.subscription import SubNfState |
| 29 | from mod.network_function import NetworkFunctionFilter |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 30 | from tests.base_setup import create_subscription_data, create_multiple_subscription_data |
efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 31 | |
| 32 | |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 33 | class ControllerTestCase(BaseClassSetup): |
efiacor | 80ff148 | 2020-06-09 19:20:22 +0100 | [diff] [blame] | 34 | |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 35 | @classmethod |
| 36 | def setUpClass(cls): |
| 37 | super().setUpClass() |
| 38 | |
| 39 | def setUp(self): |
| 40 | super().setUp() |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 41 | super().setUpAppConf() |
efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 42 | with open(os.path.join(os.path.dirname(__file__), 'data/aai_xnfs.json'), 'r') as data: |
| 43 | self.aai_response_data = data.read() |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 44 | with open(os.path.join(os.path.dirname(__file__), 'data/aai_model_info.json'), 'r') as data: |
| 45 | self.good_model_info = data.read() |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 46 | with open(os.path.join(os.path.dirname(__file__), |
| 47 | 'data/create_subscription_request.json'), 'r') as data: |
| 48 | self.subscription_request = data.read() |
efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 49 | |
| 50 | def tearDown(self): |
efiacor | 0080fa4 | 2020-09-08 16:26:50 +0100 | [diff] [blame] | 51 | super().tearDown() |
| 52 | |
| 53 | @classmethod |
| 54 | def tearDownClass(cls): |
| 55 | super().tearDownClass() |
efiacor | 5ed9b7d | 2020-05-20 15:18:41 +0100 | [diff] [blame] | 56 | |
| 57 | def test_status_response_healthy(self): |
| 58 | self.assertEqual(status()['status'], 'healthy') |
| 59 | |
SagarS | 70de6a2 | 2021-09-08 14:46:32 +0100 | [diff] [blame] | 60 | def create_test_subs(self, new_sub_name, new_msrmt_grp_name): |
| 61 | subscription = self.subscription_request.replace('ExtraPM-All-gNB-R2B', new_sub_name) |
| 62 | subscription = subscription.replace('msrmt_grp_name', new_msrmt_grp_name) |
| 63 | return subscription |
| 64 | |
| 65 | @patch('mod.api.services.subscription_service.save_nf_filter', MagicMock(return_value=None)) |
| 66 | @patch('mod.pmsh_config.AppConfig.publish_to_topic', MagicMock(return_value=None)) |
| 67 | @patch.object(aai_client, '_get_all_aai_nf_data') |
| 68 | @patch.object(aai_client, 'get_aai_model_data') |
| 69 | @patch.object(NetworkFunctionFilter, 'get_network_function_filter') |
| 70 | def test_post_subscription(self, mock_filter_call, mock_model_aai, mock_aai): |
| 71 | mock_aai.return_value = json.loads(self.aai_response_data) |
| 72 | mock_model_aai.return_value = json.loads(self.good_model_info) |
| 73 | subscription = self.create_test_subs('xtraPM-All-gNB-R2B-post', 'msrmt_grp_name-post') |
| 74 | subscription = json.loads(subscription) |
| 75 | mock_filter_call.return_value = NetworkFunctionFilter( |
| 76 | **subscription['subscription']["nfFilter"]) |
| 77 | sub_name = subscription['subscription']['subscriptionName'] |
| 78 | mes_grp = subscription['subscription']['measurementGroups'][0]['measurementGroup'] |
| 79 | mes_grp_name = mes_grp['measurementGroupName'] |
| 80 | response = post_subscription(subscription) |
| 81 | subscription = (SubscriptionModel.query.filter( |
| 82 | SubscriptionModel.subscription_name == sub_name).one_or_none()) |
| 83 | self.assertIsNotNone(subscription) |
| 84 | msr_grp_nf_rel = (NfMeasureGroupRelationalModel.query.filter( |
| 85 | NfMeasureGroupRelationalModel.measurement_grp_name == mes_grp_name)).all() |
| 86 | for published_event in msr_grp_nf_rel: |
| 87 | self.assertEqual(published_event.nf_measure_grp_status, |
| 88 | SubNfState.PENDING_CREATE.value) |
| 89 | self.assertEqual(response[1], 201) |
| 90 | |
| 91 | def test_post_subscription_duplicate_sub(self): |
| 92 | # Posting the same subscription request stored in previous test to get duplicate response |
| 93 | response = post_subscription(json.loads(self.subscription_request)) |
| 94 | self.assertEqual(response[1], 409) |
| 95 | self.assertEqual(response[0], 'subscription Name: ExtraPM-All-gNB-R2B already exists.') |
| 96 | |
| 97 | def test_post_subscription_invalid_filter(self): |
| 98 | subscription = self.create_test_subs('xtraPM-All-gNB-R2B-invalid', 'msrmt_grp_name-invalid') |
| 99 | subscription = json.loads(subscription) |
| 100 | subscription['subscription']['nfFilter']['nfNames'] = [] |
| 101 | subscription['subscription']['nfFilter']['modelInvariantIDs'] = [] |
| 102 | subscription['subscription']['nfFilter']['modelVersionIDs'] = [] |
| 103 | subscription['subscription']['nfFilter']['modelNames'] = [] |
| 104 | response = post_subscription(subscription) |
| 105 | self.assertEqual(response[1], 400) |
| 106 | self.assertEqual(response[0], 'At least one filter within nfFilter must not be empty') |
| 107 | |
| 108 | def test_post_subscription_missing(self): |
| 109 | subscription = json.loads(self.subscription_request) |
| 110 | subscription['subscription']['subscriptionName'] = '' |
| 111 | response = post_subscription(subscription) |
| 112 | self.assertEqual(response[1], 400) |
| 113 | self.assertEqual(response[0], 'No value provided in subscription name') |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 114 | |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 115 | @patch('mod.api.services.subscription_service.query_subscription_by_name', |
| 116 | MagicMock(return_value=create_subscription_data('sub_demo'))) |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 117 | def test_get_subscription_by_name_api(self): |
| 118 | sub, status_code = get_subscription_by_name('sub_demo') |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 119 | self.assertEqual(status_code, HTTPStatus.OK.value) |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 120 | self.assertEqual(sub['subscription']['subscriptionName'], 'sub_demo') |
| 121 | self.assertEqual(sub['subscription']['nfFilter']['nfNames'], |
| 122 | ['^pnf.*', '^vnf.*']) |
| 123 | self.assertEqual(sub['subscription']['controlLoopName'], |
| 124 | 'pmsh_control_loop_name') |
| 125 | self.assertEqual(len(sub['subscription']['measurementGroups']), 2) |
| 126 | self.assertEqual(sub['subscription']['operationalPolicyName'], |
| 127 | 'pmsh_operational_policy') |
| 128 | |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 129 | @patch('mod.api.services.subscription_service.query_subscription_by_name', |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 130 | MagicMock(return_value=None)) |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 131 | def test_get_subscription_by_name_api_none(self): |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 132 | sub, status_code = get_subscription_by_name('sub_demo') |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 133 | self.assertEqual(status_code, HTTPStatus.NOT_FOUND.value) |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 134 | self.assertEqual(sub['error'], |
| 135 | 'Subscription was not defined with the name : sub_demo') |
| 136 | |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 137 | @patch('mod.api.services.subscription_service.query_subscription_by_name', |
raviteja.karumuri | 86f4eb2 | 2021-11-09 17:30:03 +0000 | [diff] [blame] | 138 | MagicMock(side_effect=Exception('something failed'))) |
| 139 | def test_get_subscription_by_name_api_exception(self): |
| 140 | sub, status_code = get_subscription_by_name('sub_demo') |
raviteja.karumuri | 7e30421 | 2021-11-24 13:10:09 +0000 | [diff] [blame] | 141 | self.assertEqual(status_code, HTTPStatus.INTERNAL_SERVER_ERROR.value) |
| 142 | |
| 143 | @patch('mod.api.services.subscription_service.query_all_subscriptions', |
| 144 | MagicMock(return_value=create_multiple_subscription_data( |
| 145 | ['sub_demo_one', 'sub_demo_two']))) |
| 146 | def test_get_subscriptions_api(self): |
| 147 | subs, status_code = get_subscriptions() |
| 148 | self.assertEqual(status_code, HTTPStatus.OK.value) |
| 149 | self.assertEqual(subs[0]['subscription']['subscriptionName'], 'sub_demo_one') |
| 150 | self.assertEqual(subs[1]['subscription']['subscriptionName'], 'sub_demo_two') |
| 151 | self.assertEqual(subs[1]['subscription']['measurementGroups'][0]['measurementGroup'] |
| 152 | ['measurementGroupName'], 'MG1') |
| 153 | self.assertEqual(len(subs[1]['subscription']['measurementGroups']), 2) |
| 154 | self.assertEqual(len(subs), 2) |
| 155 | |
| 156 | @patch('mod.api.services.subscription_service.query_all_subscriptions', |
| 157 | MagicMock(return_value=None)) |
| 158 | def test_get_subscriptions_api_none(self): |
| 159 | subs, status_code = get_subscriptions() |
| 160 | self.assertEqual(status_code, HTTPStatus.OK.value) |
| 161 | self.assertEqual(subs, []) |
| 162 | |
| 163 | @patch('mod.api.services.subscription_service.query_all_subscriptions', |
| 164 | MagicMock(side_effect=Exception('something failed'))) |
| 165 | def test_get_subscriptions_api_exception(self): |
| 166 | subs, status_code = get_subscriptions() |
| 167 | self.assertEqual(status_code, HTTPStatus.INTERNAL_SERVER_ERROR.value) |