CORD-2237 modify synchronizer tests to work with nose2
cherry-picked from CORD-2237 commit e032324d5993741ef1975c9a74d891d9ffd0c58e

Change-Id: I5076155edbb3e5527b68c3834bd20af0d755d65e
diff --git a/xos/synchronizers/new_base/tests/steps/mock_modelaccessor.py b/xos/synchronizers/new_base/mock_modelaccessor.py
similarity index 100%
rename from xos/synchronizers/new_base/tests/steps/mock_modelaccessor.py
rename to xos/synchronizers/new_base/mock_modelaccessor.py
diff --git a/xos/synchronizers/new_base/modelaccessor.py b/xos/synchronizers/new_base/modelaccessor.py
index 7e4dcd4..0500f88 100644
--- a/xos/synchronizers/new_base/modelaccessor.py
+++ b/xos/synchronizers/new_base/modelaccessor.py
@@ -229,11 +229,28 @@
 
     reactor.run()
 
+def config_accessor_mock():
+    global model_accessor
+    from mock_modelaccessor import model_accessor as mock_model_accessor
+    model_accessor = mock_model_accessor
+
+    # mock_model_accessor doesn't have an all_model_classes field, so make one.
+    import mock_modelaccessor as mma
+    all_model_classes = {}
+    for k in dir(mma):
+        v = getattr(mma, k)
+        if hasattr(v, "leaf_model_name"):
+            all_model_classes[k] = v
+
+    model_accessor.all_model_classes = all_model_classes
+
+    import_models_to_globals()
+
 def config_accessor():
     accessor_kind = Config.get("accessor.kind")
 
     if accessor_kind == "testframework":
-        pass
+        config_accessor_mock()
     elif accessor_kind == "grpcapi":
         config_accessor_grpcapi()
     else:
diff --git a/xos/synchronizers/new_base/tests/test_controller_dependencies.py b/xos/synchronizers/new_base/tests/test_controller_dependencies.py
index 8b75579..2e65d23 100644
--- a/xos/synchronizers/new_base/tests/test_controller_dependencies.py
+++ b/xos/synchronizers/new_base/tests/test_controller_dependencies.py
@@ -23,24 +23,46 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import event_loop
-import backend
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 class TestControllerDependencies(unittest.TestCase):
     def setUp(self):
+        global mock_enumerator, event_loop
+
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+        from mock_modelaccessor import mock_enumerator
+        from modelaccessor import model_accessor
+
+        # import all class names to globals
+        for (k, v) in model_accessor.all_model_classes.items():
+            globals()[k] = v
+
         b = backend.Backend()
         steps_dir = Config.get("steps_dir")
         self.steps = b.load_sync_step_modules(steps_dir)
         self.synchronizer = event_loop.XOSObserver(self.steps)
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     def test_multi_controller_path(self):
         csl = ControllerSlice()
         csi = ControllerSite()
diff --git a/xos/synchronizers/new_base/tests/test_load.py b/xos/synchronizers/new_base/tests/test_load.py
index b33dd4f..165aca9 100644
--- a/xos/synchronizers/new_base/tests/test_load.py
+++ b/xos/synchronizers/new_base/tests/test_load.py
@@ -1,4 +1,3 @@
-
 # Copyright 2017-present Open Networking Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# TEST_FRAMEWORK: IGNORE
-
 import unittest
 from mock import patch
 import mock
@@ -23,19 +20,29 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import event_loop
-import backend
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 class TestScheduling(unittest.TestCase):
     def setUp(self):
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+
         # self.policy = TenantWithContainerPolicy()
         # self.user = User(email="testadmin@test.org")
         # self.tenant = Tenant(creator=self.user)
@@ -48,6 +55,10 @@
         self.steps = b.load_sync_step_modules(steps_dir)
         self.synchronizer = event_loop.XOSObserver(self.steps)
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     def test_load_steps(self):
         step_names = [s.__name__ for s in self.steps]
         self.assertIn('SyncControllerSlices', step_names)
diff --git a/xos/synchronizers/new_base/tests/test_payload.py b/xos/synchronizers/new_base/tests/test_payload.py
index c130c50..953681a 100644
--- a/xos/synchronizers/new_base/tests/test_payload.py
+++ b/xos/synchronizers/new_base/tests/test_payload.py
@@ -15,6 +15,7 @@
 
 # TEST_FRAMEWORK: IGNORE
 
+import json
 import unittest
 from mock import patch
 import mock
@@ -23,24 +24,8 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import mock
-import event_loop
-import backend
-import json
-
-import steps.sync_instances
-import steps.sync_controller_slices
-from multistructlog import create_logger
-
-log = create_logger()
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 ANSIBLE_FILE='/tmp/payload_test'
 
@@ -54,11 +39,45 @@
 
 class TestPayload(unittest.TestCase):
     def setUp(self):
+        global log, steps
+
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+        import steps.sync_instances
+        import steps.sync_controller_slices
+        from modelaccessor import model_accessor
+
+        # import all class names to globals
+        for (k, v) in model_accessor.all_model_classes.items():
+            globals()[k] = v
+
+        from multistructlog import create_logger
+        log = create_logger()
+
         b = backend.Backend()
         steps_dir = Config.get("steps_dir")
         self.steps = b.load_sync_step_modules(steps_dir)
         self.synchronizer = event_loop.XOSObserver(self.steps)
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     @mock.patch("steps.sync_instances.syncstep.run_template",side_effect=run_fake_ansible_template)
     @mock.patch("event_loop.model_accessor")
     def test_delete_record(self, mock_run_template, mock_modelaccessor):
@@ -83,7 +102,7 @@
 
         a = get_ansible_output()
         self.assertDictContainsSubset({'delete':False, 'name':o.name}, a)
-        o.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register'])
+        o.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register', 'backend_code'])
 
     @mock.patch("steps.sync_instances.syncstep.run_template",side_effect=run_fake_ansible_template)
     @mock.patch("event_loop.model_accessor")
@@ -104,8 +123,8 @@
 
         a = get_ansible_output()
         self.assertDictContainsSubset({'delete':False, 'name':o.name}, a)
-        o.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register'])
-        cs.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register'])
+        o.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register', 'backend_code'])
+        cs.save.assert_called_with(update_fields=['enacted', 'backend_status', 'backend_register', 'backend_code'])
 
     @mock.patch("steps.sync_instances.syncstep.run_template",side_effect=run_fake_ansible_template)
     @mock.patch("event_loop.model_accessor")
@@ -124,7 +143,7 @@
         cs.synchronizer_step = steps.sync_controller_slices.SyncControllerSlices()
 
         self.synchronizer.sync_cohort(cohort, False)
-        o.save.assert_called_with(always_update_timestamp=True, update_fields=['backend_status', 'backend_register'])
+        o.save.assert_called_with(always_update_timestamp=True, update_fields=['backend_status', 'backend_code', 'backend_register'])
         self.assertEqual(cs.backend_code, 1)
 
         self.assertIn('Force', cs.backend_status)
@@ -147,7 +166,7 @@
         cs.synchronizer_step = steps.sync_controller_slices.SyncControllerSlices()
 
         self.synchronizer.sync_cohort(cohort, False)
-        o.save.assert_called_with(always_update_timestamp=True, update_fields=['backend_status', 'backend_register'])
+        o.save.assert_called_with(always_update_timestamp=True, update_fields=['backend_status', 'backend_code', 'backend_register'])
         self.assertIn('Force', cs.backend_status)
         self.assertIn('Failed due to', o.backend_status)
 
diff --git a/xos/synchronizers/new_base/tests/test_run.py b/xos/synchronizers/new_base/tests/test_run.py
index d8512d9..8b089a4 100644
--- a/xos/synchronizers/new_base/tests/test_run.py
+++ b/xos/synchronizers/new_base/tests/test_run.py
@@ -23,21 +23,8 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import mock
-import event_loop
-import backend
-import json
-
-import steps.sync_instances
-import steps.sync_controller_slices
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 ANSIBLE_FILE='/tmp/payload_test'
 
@@ -51,6 +38,24 @@
 
 class TestRun(unittest.TestCase):
     def setUp(self):
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+
         b = backend.Backend()
         steps_dir = Config.get("steps_dir")
         self.steps = b.load_sync_step_modules(steps_dir)
@@ -64,6 +69,10 @@
         except OSError:
             pass
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     @mock.patch("steps.sync_instances.syncstep.run_template",side_effect=run_fake_ansible_template)
     @mock.patch("event_loop.model_accessor")
     def test_run_once(self, mock_run_template, mock_accessor, *_other_accessors):
diff --git a/xos/synchronizers/new_base/tests/test_scheduler.py b/xos/synchronizers/new_base/tests/test_scheduler.py
index a2bfd96..5c6d6c5 100644
--- a/xos/synchronizers/new_base/tests/test_scheduler.py
+++ b/xos/synchronizers/new_base/tests/test_scheduler.py
@@ -23,19 +23,37 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import event_loop
-import backend
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 class TestScheduling(unittest.TestCase):
     def setUp(self):
+        global mock_enumerator, event_loop
+
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+        from mock_modelaccessor import mock_enumerator
+        from modelaccessor import model_accessor
+
+        # import all class names to globals
+        for (k, v) in model_accessor.all_model_classes.items():
+            globals()[k] = v
+
         # self.policy = TenantWithContainerPolicy()
         # self.user = User(email="testadmin@test.org")
         # self.tenant = Tenant(creator=self.user)
@@ -48,6 +66,10 @@
         self.steps = b.load_sync_step_modules(steps_dir)
         self.synchronizer = event_loop.XOSObserver(self.steps)
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     def test_same_object_trivial(self):
         s = Slice(pk=4)
         t = Slice(pk=4)
diff --git a/xos/synchronizers/new_base/tests/test_services.py b/xos/synchronizers/new_base/tests/test_services.py
index 20d52ea..7c92d9a 100644
--- a/xos/synchronizers/new_base/tests/test_services.py
+++ b/xos/synchronizers/new_base/tests/test_services.py
@@ -23,25 +23,43 @@
 
 import os, sys
 
-sys.path.append("../..")
-sys.path.append("../../new_base")
-
-config =  os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/test_config_onos.yaml")
-from xosconfig import Config
-Config.init(config, 'synchronizer-config-schema.yaml')
-
-import synchronizers.new_base.modelaccessor
-from steps.mock_modelaccessor import *
-import event_loop
-import backend
+test_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+xos_dir = os.path.join(test_path, '..', '..', '..')
 
 class TestServices(unittest.TestCase):
     def setUp(self):
+        self.sys_path_save = sys.path
+        self.cwd_save = os.getcwd()
+        sys.path.append(xos_dir)
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base'))
+        sys.path.append(os.path.join(xos_dir, 'synchronizers', 'new_base', 'tests', 'steps'))
+
+        config = os.path.join(test_path, "test_config.yaml")
+        from xosconfig import Config
+        Config.clear()
+        Config.init(config, 'synchronizer-config-schema.yaml')
+
+        os.chdir(os.path.join(test_path, '..'))  # config references tests/model-deps
+
+        import event_loop
+        reload(event_loop)
+        import backend
+        reload(backend)
+        from modelaccessor import model_accessor
+
+        # import all class names to globals
+        for (k, v) in model_accessor.all_model_classes.items():
+            globals()[k] = v
+
         b = backend.Backend()
         steps_dir = Config.get("steps_dir")
         self.steps = b.load_sync_step_modules(steps_dir)
         self.synchronizer = event_loop.XOSObserver(self.steps)
 
+    def tearDown(self):
+        sys.path = self.sys_path_save
+        os.chdir(self.cwd_save)
+
     def test_service_models(self):
         a = ONOSApp()
         s = ONOSService()