Fixed Controller unit tests and UnboundlocalError 53/34653/4
authorYing Ruoyu <ruoyu.ying@intel.com>
Thu, 8 Mar 2018 11:14:39 +0000 (19:14 +0800)
committerYing Ruoyu <ruoyu.ying@intel.com>
Tue, 13 Mar 2018 09:15:21 +0000 (17:15 +0800)
Fix parse_optimization function in translator.py
Defined and initialized variable function in the scope
Fix unit test for parse_optimization function
Add condition variable in function row_update in api.MockAPI

Change-Id: I2f08bcfc001e9ccb22a7315d243006a1995edc81
Issue-ID: OPTFRA-69
Signed-off-by: Ying Ruoyu <ruoyu.ying@intel.com>
conductor/conductor/controller/translator.py
conductor/conductor/tests/unit/controller/test_rpc.py
conductor/conductor/tests/unit/controller/test_translator.py
conductor/conductor/tests/unit/controller/test_translator_svc.py

index 45eab8d..00e650b 100644 (file)
@@ -712,6 +712,7 @@ class Translator(object):
             if operand.keys() == ['distance_between']:
                 # Value must be a list of length 2 with one
                 # location and one demand
+                function = 'distance_between'
                 args = get_distance_between_args(operand)
 
             elif operand.keys() == ['product']:
index 1039468..568aa75 100644 (file)
@@ -43,7 +43,6 @@ class TestRPCNoException(unittest.TestCase):
         cfg.CONF.set_override('timeout', 10, 'controller')
         cfg.CONF.set_override('limit', 1, 'controller')
         cfg.CONF.set_override('keyspace', 'conductor')
-        cfg.CONF.set_override('mock', True, 'music_api')
         conf = cfg.CONF
         plan_class = plan_prepare(conf)
         self.r = rpc(conf, plan_class)
index 2dbee00..26b1182 100644 (file)
@@ -46,7 +46,6 @@ class TestNoExceptionTranslator(unittest.TestCase):
         cfg.CONF.set_override('keyspace', 'conductor')
         cfg.CONF.set_override('keyspace', 'conductor_rpc', 'messaging_server')
         cfg.CONF.set_override('concurrent', True, 'controller')
-        cfg.CONF.set_override('mock', True, 'music_api')
         conf = cfg.CONF
         self.Translator = Translator(
             conf, 'some_template', str(uuid.uuid4()), get_template())
@@ -91,6 +90,15 @@ class TestNoExceptionTranslator(unittest.TestCase):
         self.Translator.validate_components()
         self.assertTrue(self.Translator._valid)
 
+    @patch('conductor.controller.translator.Translator._parse_parameters')
+    def test_parse_parameters(self, mock_parse):
+        self.Translator._locations = ''
+        self.Translator._demands = ''
+        self.Translator._constraints = ''
+        self.Translator._reservations = ''
+        self.Translator.parse_parameters()
+        mock_parse.assert_called()
+
     def test_parse_parameter(self):
         self.Translator.create_components()
         rtn = self.Translator._parse_parameters(
@@ -114,6 +122,46 @@ class TestNoExceptionTranslator(unittest.TestCase):
         self.assertRaises(TranslatorException,
                           self.Translator.parse_demands, demands)
 
+    @patch('conductor.common.music.messaging.component.RPCClient.call')
+    def test_parse_demands_with_candidate(self, mock_call):
+        demands = {
+            "vGMuxInfra": [{
+                "inventory_provider": "aai",
+                "inventory_type": "service",
+                "customer_id": "some_company",
+                "service_type": "5G",
+                "candidates": [{
+                    "candidate_id": []
+
+                }],
+                "required_candidates": [{
+                    "candidate_id": "1a9983b8-0o43-4e16-9947-c3f37234536d"
+                }]
+            }]
+        }
+        self.Translator._plan_id = ""
+        self.Translator._plan_name = ""
+        mock_call.return_value = {'resolved_demands': {"vGMuxInfra": [{
+            'inventory_provider': 'aai',
+            'inventory_type': 'service',
+            'customer_id': 'some_company',
+            'service_type': '5G',
+            "candidates": {
+                "candidate_id": []
+            }
+        }]
+        }}
+        rtn = {'vGMuxInfra': {'candidates': [{'candidate_id': [],
+                                              'cost': 0,
+                                              'inventory_provider': 'aai'},
+                                             {'candidates': {'candidate_id': []},
+                                              'customer_id': 'some_company',
+                                              'inventory_provider': 'aai',
+                                              'inventory_type': 'service',
+                                              'service_type': '5G'}]}}
+
+        self.assertEquals(self.Translator.parse_demands(demands), rtn)
+
     @patch('conductor.common.music.messaging.component.RPCClient.call')
     def test_parse_demands_without_candidate(self, mock_call):
         demands = {
@@ -164,6 +212,7 @@ class TestNoExceptionTranslator(unittest.TestCase):
             'demands': ['vG'],
             'properties': {'distance': '< 100 km',
                            'location': 'custom_loc'}}}
+
         rtn = {'constraint_loc_vG': {
             'demands': 'vG',
             'name': 'constraint_loc',
@@ -174,23 +223,33 @@ class TestNoExceptionTranslator(unittest.TestCase):
             'type': 'distance_to_location'}}
         self.assertEquals(self.Translator.parse_constraints(constraints), rtn)
 
-    # TODO(ruoyu)
     @patch('conductor.controller.translator.Translator.create_components')
-    def parse_optimization(self, mock_create):
-        args = ['customer_loc', 'vGMuxInfra']
-        func = 'distance_between'
-        expected_parse = {
-            "goal": "min",
-            "operation": "sum",
-            "operands": [{"operation": "product",
-                          "weight": 1.0,
-                          "function": func,
-                          "function_param": args}]
-        }
+    def test_parse_optimization(self, mock_create):
+        expected_parse = {'goal': 'min',
+                          'operands': [{'function': 'distance_between',
+                                        'function_param': ['customer_loc', 'vGMuxInfra'],
+                                        'operation': 'product',
+                                        'weight': 1.0},
+                                       {'function': 'distance_between',
+                                        'function_param': ['customer_loc', 'vG'],
+                                        'operation': 'product',
+                                        'weight': 1.0}],
+                          'operation': 'sum'
+                          }
+
         opt = {'minimize': {
-            'sum': [{
-                'distance_between': ['customer_loc', 'vGMuxInfra']}, {
-                'distance_between': ['customer_loc', 'vG']}]}}
+            'sum': [{'distance_between': ['customer_loc', 'vGMuxInfra']},
+                    {'product': [{'distance_between': ['customer_loc', 'vG']},
+                                 {'aic_version': ['']},
+                                 {'sum':
+                                      [{'product':
+                                            [{'distance_between':
+                                                  ['customer_loc', 'vG']}]
+                                        }]},
+                                 ]
+                     }
+
+                    ]}}
         self.Translator._demands = {'vG': '',
                                     'vGMuxInfra': '',
                                     'customer_loc': ''}
index 051e9d3..4b24001 100644 (file)
@@ -20,6 +20,8 @@
 
 import unittest
 import uuid
+import time
+import futurist
 
 from mock import patch
 from mock import PropertyMock
@@ -39,7 +41,10 @@ def plan_prepare(conf):
 
 
 class TestTranslatorServiceNoException(unittest.TestCase):
-    def setUp(self):
+    @patch('conductor.common.music.model.base.Base.table_create')
+    @patch('conductor.common.music.model.base.Base.insert')
+    @patch('conductor.controller.translator_svc.TranslatorService._reset_template_status')
+    def setUp(self, mock_reset, mock_insert, mock_table_create):
         cfg.CONF.set_override('polling_interval', 1, 'controller')
         cfg.CONF.set_override('keyspace', 'conductor')
         cfg.CONF.set_override('timeout', 10, 'controller')
@@ -47,7 +52,6 @@ class TestTranslatorServiceNoException(unittest.TestCase):
         cfg.CONF.set_override('concurrent', True, 'controller')
         cfg.CONF.set_override('keyspace',
                               'conductor_rpc', 'messaging_server')
-        cfg.CONF.set_override('mock', True, 'music_api')
         self.conf = cfg.CONF
         self.Plan = plan_prepare(self.conf)
         kwargs = self.Plan
@@ -62,7 +66,7 @@ class TestTranslatorServiceNoException(unittest.TestCase):
             worker_id=1, conf=self.conf, plan_class=kwargs)
         self.translator_svc.music.keyspace_create(keyspace=self.conf.keyspace)
 
-    #TODO(ruoyu)
+    # TODO(ruoyu)
     @patch('conductor.controller.translator.Translator.ok')
     def translate_complete(self, mock_ok_func):
         with patch('conductor.controller.translator.Translator.ok',
@@ -72,10 +76,11 @@ class TestTranslatorServiceNoException(unittest.TestCase):
         self.translator_svc.translate(self.mock_plan)
         self.assertEquals(self.mock_plan.status, 'translated')
 
-    # TODO(ruoyu)
+
     @patch('conductor.controller.translator.Translator.translate')
     @patch('conductor.controller.translator.Translator.error_message')
-    def translate_error(self, mock_error, mock_trns):
+    @patch('conductor.common.music.model.base.Base.update')
+    def test_translate_error(self, mock_row_update, mock_error, mock_trns):
         with patch('conductor.controller.translator.Translator.ok',
                    new_callable=PropertyMock) as mock_ok:
             mock_ok.return_value = False
@@ -83,6 +88,36 @@ class TestTranslatorServiceNoException(unittest.TestCase):
         self.translator_svc.translate(self.mock_plan)
         self.assertEquals(self.mock_plan.status, 'error')
 
+    def test_millisec_to_sec(self):
+        self.assertEquals(self.translator_svc.millisec_to_sec(1000), 1)
+
+    def test_current_time_seconds(self):
+        self.assertEquals(self.translator_svc.current_time_seconds(),
+                          int(round(time.time())))
+
+    @patch('conductor.common.music.model.base.Base.insert')
+    @patch('conductor.common.music.model.search.Query.all')
+    @patch('conductor.common.music.model.base.Base.update')
+    def test_reset_template_status(self, mock_call, mock_update, mock_insert):
+        mock_plan = self.Plan(str(uuid.uuid4()),
+                              self.conf.controller.timeout,
+                              self.conf.controller.limit, None,
+                              status=self.Plan.TRANSLATING)
+        mock_call.return_value = mock_plan
+        self.translator_svc._reset_template_status()
+        mock_update.assert_called_once()
+
+    @patch('conductor.controller.translator_svc.TranslatorService._gracefully_stop')
+    def test_terminate(self, mock_stop):
+        self.translator_svc.terminate()
+        mock_stop.assert_called_once()
+        self.assertFalse(self.translator_svc.running)
+
+    @patch('conductor.controller.translator_svc.TranslatorService._restart')
+    def test_reload(self, mock_restart):
+        self.translator_svc.reload()
+        mock_restart.assert_called_once()
+
     def tearDown(self):
         patch.stopall()