Merge "[DCAEGEN2] Enhance (KPI-MS) KpiComputation for SUM-RATIO operation."
[dcaegen2/services.git] / components / pm-subscription-handler / tests / test_pmsh_utils.py
1 # ============LICENSE_START===================================================
2 #  Copyright (C) 2019-2021 Nordix Foundation.
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 from test.support import EnvironmentVarGuard
19 from unittest.mock import patch, Mock
20
21 import responses
22 from jsonschema import ValidationError
23 from requests import Session
24 from tenacity import RetryError
25
26 from mod import get_db_connection_url
27 from mod.network_function import NetworkFunction
28 from tests.base_setup import BaseClassSetup
29 from tests.base_setup import get_pmsh_config
30
31
32 class PmshUtilsTestCase(BaseClassSetup):
33
34     @classmethod
35     def setUpClass(cls):
36         super().setUpClass()
37
38     def setUp(self):
39         super().setUp()
40         self.mock_app = Mock()
41
42     def tearDown(self):
43         super().tearDown()
44
45     @classmethod
46     def tearDownClass(cls):
47         super().tearDownClass()
48
49     def test_utils_get_mr_sub(self):
50         mr_policy_sub = self.app_conf.get_mr_sub('policy_pm_subscriber')
51         self.assertTrue(mr_policy_sub.aaf_id, 'dcae@dcae.onap.org')
52
53     def test_utils_get_mr_sub_fails_with_invalid_name(self):
54         with self.assertRaises(KeyError):
55             self.app_conf.get_mr_sub('invalid_sub')
56
57     def test_utils_get_mr_pub(self):
58         mr_policy_pub = self.app_conf.get_mr_pub('policy_pm_publisher')
59         self.assertTrue(mr_policy_pub.aaf_pass, 'demo123456!')
60
61     def test_utils_get_mr_pub_fails_with_invalid_name(self):
62         with self.assertRaises(KeyError):
63             self.app_conf.get_mr_pub('invalid_pub')
64
65     def test_utils_get_cert_data(self):
66         self.assertEqual(self.app_conf.cert_params, ('/opt/app/pmsh/etc/certs/cert.pem',
67                                                      '/opt/app/pmsh/etc/certs/key.pem'))
68
69     @patch.object(Session, 'post')
70     def test_mr_pub_publish_to_topic_success(self, mock_session):
71         mock_session.return_value.status_code = 200
72         mr_policy_pub = self.app_conf.get_mr_pub('policy_pm_publisher')
73         with patch('requests.Session.post') as session_post_call:
74             mr_policy_pub.publish_to_topic({"dummy_val": "43c4ee19-6b8d-4279-a80f-c507850aae47"})
75             session_post_call.assert_called_once()
76
77     @responses.activate
78     def test_mr_pub_publish_to_topic_fail(self):
79         responses.add(responses.POST,
80                       'https://message-router:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS',
81                       json={'error': 'Client Error'}, status=400)
82         mr_policy_pub = self.app_conf.get_mr_pub('policy_pm_publisher')
83         with self.assertRaises(Exception):
84             mr_policy_pub.publish_to_topic({"dummy_val": "43c4ee19-6b8d-4279-a80f-c507850aae47"})
85
86     def test_mr_pub_publish_sub_event_data_success(self):
87         mr_policy_pub = self.app_conf.get_mr_pub('policy_pm_publisher')
88         with patch('mod.pmsh_utils._MrPub.publish_to_topic') as pub_to_topic_call:
89             mr_policy_pub.publish_subscription_event_data(
90                 self.app_conf.subscription,
91                 NetworkFunction(nf_name='pnf_1',
92                                 model_invariant_id='some-id',
93                                 model_version_id='some-id'))
94             pub_to_topic_call.assert_called_once()
95
96     @responses.activate
97     def test_mr_sub_get_from_topic_success(self):
98         policy_mr_sub = self.app_conf.get_mr_sub('policy_pm_subscriber')
99         responses.add(responses.GET,
100                       'https://message-router:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS/'
101                       'dcae_pmsh_cg/1?timeout=1000',
102                       json={"dummy_val": "43c4ee19-6b8d-4279-a80f-c507850aae47"}, status=200)
103         mr_topic_data = policy_mr_sub.get_from_topic(1)
104         self.assertIsNotNone(mr_topic_data)
105
106     @responses.activate
107     def test_mr_sub_get_from_topic_fail(self):
108         policy_mr_sub = self.app_conf.get_mr_sub('policy_pm_subscriber')
109         responses.add(responses.GET,
110                       'https://message-router:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS/'
111                       'dcae_pmsh_cg/1?timeout=1000',
112                       json={"dummy_val": "43c4ee19-6b8d-4279-a80f-c507850aae47"}, status=400)
113         with self.assertRaises(Exception):
114             policy_mr_sub.get_from_topic(1)
115
116     def test_get_db_connection_url_success(self):
117         self.env = EnvironmentVarGuard()
118         self.env.set('PMSH_PG_URL', '1.2.3.4')
119         self.env.set('PMSH_PG_USERNAME', 'pmsh')
120         self.env.set('PMSH_PG_PASSWORD', 'pass')
121         db_url = get_db_connection_url()
122         self.assertEqual(db_url, 'postgresql+psycopg2://pmsh:pass@1.2.3.4:5432/pmsh')
123
124     def test_get_db_connection_url_fail(self):
125         self.env = EnvironmentVarGuard()
126         self.env.set('PMSH_PG_USERNAME', 'pmsh')
127         self.env.set('PMSH_PG_PASSWORD', 'pass')
128         with self.assertRaises(Exception):
129             get_db_connection_url()
130
131     @patch('mod.logger.info')
132     @patch('mod.pmsh_utils.get_all')
133     def test_refresh_config_success(self, mock_cbs_client_get_all, mock_logger):
134         mock_cbs_client_get_all.return_value = get_pmsh_config()
135         self.app_conf.refresh_config()
136         mock_logger.assert_called_with('AppConfig data has been refreshed')
137
138     @patch('mod.logger.error')
139     @patch('mod.pmsh_utils.get_all')
140     def test_refresh_config_fail(self, mock_cbs_client_get_all, mock_logger):
141         mock_cbs_client_get_all.side_effect = ValueError
142         with self.assertRaises(RetryError):
143             self.app_conf.refresh_config()
144         mock_logger.assert_called_with('Failed to refresh PMSH AppConfig')
145
146     @patch('mod.logger.debug')
147     def test_utils_validate_config_subscription(self, mock_logger):
148         self.app_conf.validate_sub_schema()
149         mock_logger.assert_called_with("Subscription schema is valid.")
150
151     @patch('mod.logger.debug')
152     def test_utils_validate_config_subscription_administrativeState_locked(self, mock_logger):
153         self.app_conf.subscription.administrativeState = "LOCKED"
154         self.app_conf.validate_sub_schema()
155         mock_logger.assert_called_with("Subscription schema is valid.")
156
157     def test_utils_validate_config_subscription_administrativeState_invalid_value(self):
158         self.app_conf.subscription.administrativeState = "FAILED"
159         with self.assertRaises(ValidationError):
160             self.app_conf.validate_sub_schema()
161
162     def test_utils_validate_config_subscription_nfFilter_failed(self):
163         self.app_conf.subscription.nfFilter = {}
164         with self.assertRaises(ValidationError):
165             self.app_conf.validate_sub_schema()
166
167     def test_utils_validate_config_subscription_nfFilter_not_empty(self):
168         self.app_conf.subscription.nfFilter = {
169             "nfNames": [
170
171             ],
172             "modelInvariantIDs": [
173
174             ],
175             "modelVersionIDs": [
176
177             ],
178             "modelNames": [
179
180             ]
181         }
182         with self.assertRaises(ValidationError):
183             self.app_conf.validate_sub_schema()
184
185     @patch('mod.logger.debug')
186     def test_utils_validate_config_subscription_nfFilter_with_empty_property(self, mock_logger):
187         self.app_conf.subscription.nfFilter = {
188             "nfNames": [
189                 "^pnf.*",
190                 "^vnf.*"
191             ],
192             "modelInvariantIDs": [
193                 "7129e420-d396-4efb-af02-6b83499b12f8"
194             ],
195             "modelVersionIDs": [
196
197             ],
198             "modelNames": [
199                 "pnf102"
200             ]
201         }
202         self.app_conf.validate_sub_schema()
203         mock_logger.assert_called_with("Subscription schema is valid.")
204
205     def test_utils_validate_config_subscription_where_measurementTypes_is_empty(self):
206         self.app_conf.subscription.measurementGroups = [{
207             "measurementGroup": {
208                 "measurementTypes": [
209                 ],
210                 "managedObjectDNsBasic": [
211                     {
212                         "DN": "dna"
213                     },
214                     {
215                         "DN": "dnb"
216                     }
217                 ]
218             }
219         }]
220         with self.assertRaises(ValidationError):
221             self.app_conf.validate_sub_schema()
222
223     def test_utils_validate_config_subscription_where_managedObjectDNsBasic_is_empty(self):
224         self.app_conf.subscription.measurementGroups = [{
225             "measurementGroup": {
226                 "measurementTypes": [
227                     {
228                         "measurementType": "countera"
229                     },
230                     {
231                         "measurementType": "counterb"
232                     }
233                 ],
234                 "managedObjectDNsBasic": [
235
236                 ]
237             }
238         }]
239         with self.assertRaises(ValidationError):
240             self.app_conf.validate_sub_schema()
241
242     def test_utils_validate_config_subscription_where_measurementGroups_is_empty(self):
243         self.app_conf.subscription.measurementGroups = []
244         with self.assertRaises(ValidationError):
245             self.app_conf.validate_sub_schema()