def setUp(self):
     # Note: All configurations are saved in memory
     self.mock_archive = ArchiverManager(None, None, MockArchiverWrapper())
     self.mock_file_manager = MockConfigurationFileManager()
     self.activech = ActiveConfigHolder(
         MACROS, self.mock_archive, MockVersionControl(), self.mock_file_manager, MockIocControl("")
     )
class TestActiveConfigHolderSequence(unittest.TestCase):
    def setUp(self):
        # Note: All configurations are saved in memory
        self.mock_archive = ArchiverManager(None, None, MockArchiverWrapper())
        self.mock_file_manager = MockConfigurationFileManager()
        self.activech = ActiveConfigHolder(
            MACROS, self.mock_archive, MockVersionControl(), self.mock_file_manager, MockIocControl("")
        )

    def tearDown(self):
        pass

    def create_ach(self):
        ch = ActiveConfigHolder(
            MACROS, self.mock_archive, MockVersionControl(), MockConfigurationFileManager(), MockIocControl("")
        )
        return ch

    def test_add_ioc(self):
        cs = self.activech
        iocs = cs.get_ioc_names()
        self.assertEqual(len(iocs), 0)
        cs._add_ioc("SIMPLE1")
        cs._add_ioc("SIMPLE2")
        iocs = cs.get_ioc_names()
        self.assertTrue("SIMPLE1" in iocs)
        self.assertTrue("SIMPLE2" in iocs)

    def test_save_config(self):
        cs = self.activech
        add_basic_blocks_and_iocs(cs)
        try:
            cs.save_active("TEST_CONFIG")
        except Exception:
            self.fail("test_save_config raised Exception unexpectedly!")

    def test_load_config(self):
        cs = self.activech
        add_basic_blocks_and_iocs(cs)
        cs.save_active("TEST_CONFIG")
        cs.clear_config()
        blocks = cs.get_blocknames()
        self.assertEquals(len(blocks), 0)
        iocs = cs.get_ioc_names()
        self.assertEqual(len(iocs), 0)
        cs.load_active("TEST_CONFIG")
        blocks = cs.get_blocknames()
        self.assertEquals(len(blocks), 4)
        self.assertTrue("TESTBLOCK1" in blocks)
        self.assertTrue("TESTBLOCK2" in blocks)
        self.assertTrue("TESTBLOCK3" in blocks)
        self.assertTrue("TESTBLOCK4" in blocks)
        iocs = cs.get_ioc_names()
        self.assertTrue("SIMPLE1" in iocs)
        self.assertTrue("SIMPLE2" in iocs)

    def test_load_notexistant_config(self):
        cs = self.activech
        self.assertRaises(IOError, lambda: cs.load_active("DOES_NOT_EXIST"))

    def test_save_as_component(self):
        cs = self.activech
        try:
            cs.save_active("TEST_CONFIG1", as_comp=True)
        except Exception:
            self.fail("test_save_as_component raised Exception unexpectedly!")

    def test_save_config_for_component(self):
        cs = self.activech
        cs.save_active("TEST_CONFIG1", as_comp=True)
        try:
            cs.save_active("TEST_CONFIG1")
        except Exception:
            self.fail("test_save_config_for_component raised Exception unexpectedly!")

    def test_load_component_fails(self):
        cs = self.activech
        add_basic_blocks_and_iocs(cs)
        cs.save_active("TEST_COMPONENT", as_comp=True)
        cs.clear_config()
        self.assertRaises(IOError, lambda: cs.load_active("TEST_COMPONENT"))

    def test_load_last_config(self):
        cs = self.activech
        add_basic_blocks_and_iocs(cs)
        cs.save_active("TEST_CONFIG")
        cs.clear_config()
        blocks = cs.get_blocknames()
        self.assertEqual(len(blocks), 0)
        iocs = cs.get_ioc_names()
        self.assertEqual(len(iocs), 0)
        cs.load_last_config()
        grps = cs.get_group_details()
        self.assertTrue(len(grps) == 3)
        blocks = cs.get_blocknames()
        self.assertEqual(len(blocks), 4)
        self.assertTrue("TESTBLOCK1" in blocks)
        self.assertTrue("TESTBLOCK2" in blocks)
        self.assertTrue("TESTBLOCK3" in blocks)
        self.assertTrue("TESTBLOCK4" in blocks)
        iocs = cs.get_ioc_names()
        self.assertTrue("SIMPLE1" in iocs)
        self.assertTrue("SIMPLE2" in iocs)

    def test_reloading_current_config_with_blank_name_does_nothing(self):
        # arrange
        config_name = self.activech.get_config_name()
        self.assertEquals(config_name, "")
        load_requests = self.mock_file_manager.get_load_config_history()
        self.assertEquals(len(load_requests), 0)

        # act
        self.activech.reload_current_config()

        # assert
        load_requests = self.mock_file_manager.get_load_config_history()
        self.assertEquals(len(load_requests), 0)

    def test_reloading_current_config_sends_load_request_correctly(self):
        # arrange
        cs = self.activech
        config_name = "TEST_CONFIG"
        add_basic_blocks_and_iocs(cs)
        cs.save_active(config_name)

        load_requests = self.mock_file_manager.get_load_config_history()
        self.assertEquals(len(load_requests), 0)

        # act
        cs.reload_current_config()

        # assert
        load_requests = self.mock_file_manager.get_load_config_history()
        self.assertEquals(load_requests.count(config_name), 1)

    def test_iocs_changed_no_changes(self):
        # Arrange
        ch = self.create_ach()
        details = ch.get_config_details()
        ch.set_config_details(details)
        # Assert
        start, restart = ch.iocs_changed()
        self.assertEqual(len(start), 0)
        self.assertEqual(len(restart), 0)

    def test_iocs_changed_ioc_added(self):
        # Arrange
        ch = self.create_ach()
        details = ch.get_config_details()
        # Act
        details["iocs"].append(MockIoc())
        ch.set_config_details(details)
        # Assert
        start, restart = ch.iocs_changed()
        self.assertEqual(len(start), 1)
        self.assertEqual(len(restart), 0)

    def test_iocs_changed_ioc_removed(self):
        # Arrange
        ch = self.create_ach()
        details = ch.get_config_details()
        details["iocs"].append(MockIoc())
        ch.set_config_details(details)
        # Act
        details["iocs"].pop(0)
        ch.set_config_details(details)
        # Assert
        start, restart = ch.iocs_changed()
        self.assertEqual(len(start), 0)
        self.assertEqual(len(restart), 0)

    def _test_attribute_changes(self, initial_attrs={}, final_attrs={}, has_changed=True):
        # Take a dict of initial attributes and final attributes and
        # check for the correct change response.

        # Arrange
        ch = self.create_ach()
        details = ch.get_config_details()

        initial_ioc = MockIoc()
        for key, value in initial_attrs.iteritems():
            setattr(initial_ioc, key, value)
        final_ioc = MockIoc()
        for key, value in final_attrs.iteritems():
            setattr(final_ioc, key, value)

        details["iocs"].append(initial_ioc)
        ch.set_config_details(details)
        # Act
        details["iocs"][0] = final_ioc
        ch.set_config_details(details)
        # Assert
        start, restart = ch.iocs_changed()
        self.assertEqual(len(start), 0)
        self.assertEqual(len(restart), 1 if has_changed else 0)

    def test_iocs_changed_macro_added(self):
        self._test_attribute_changes(final_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST"}]})

    def test_iocs_changed_macro_removed(self):
        self._test_attribute_changes(initial_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST"}]})

    def test_iocs_changed_macro_changed(self):
        self._test_attribute_changes(
            initial_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST"}]},
            final_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST_NEW"}]},
        )

    def test_iocs_changed_macro_not_changed(self):
        self._test_attribute_changes(
            initial_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST"}]},
            final_attrs={"macros": [{"name": "TESTMACRO1", "value": "TEST"}]},
            has_changed=False,
        )

    def test_iocs_changed_pvs_added(self):
        self._test_attribute_changes(final_attrs={"pvs": [{"name": "TESTPV1", "value": 123}]})

    def test_iocs_changed_pvs_removed(self):
        self._test_attribute_changes(initial_attrs={"pvs": [{"name": "TESTPV1", "value": 123}]})

    def test_iocs_changed_pvs_changed(self):
        self._test_attribute_changes(
            initial_attrs={"pvs": [{"name": "TESTPV1", "value": 123}]},
            final_attrs={"pvs": [{"name": "TESTPV1", "value": 456}]},
        )

    def test_iocs_not_changed_pvs_not_changed(self):
        self._test_attribute_changes(
            initial_attrs={"pvs": [{"name": "TESTPV1", "value": 123}]},
            final_attrs={"pvs": [{"name": "TESTPV1", "value": 123}]},
            has_changed=False,
        )

    def test_iocs_changed_pvsets_added(self):
        self._test_attribute_changes(final_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": True}]})

    def test_iocs_changed_pvsets_removed(self):
        self._test_attribute_changes(initial_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": True}]})

    def test_iocs_changed_pvsets_changed(self):
        self._test_attribute_changes(
            initial_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": True}]},
            final_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": False}]},
        )

    def test_iocs_not_changed_pvsets_not_changed(self):
        self._test_attribute_changes(
            initial_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": True}]},
            final_attrs={"pvsets": [{"name": "TESTPVSET1", "enabled": True}]},
            has_changed=False,
        )

    def test_iocs_changed_simlevel_added(self):
        self._test_attribute_changes(final_attrs={"simlevel": "recsim"})

    def test_iocs_changed_simlevel_removed(self):
        self._test_attribute_changes(initial_attrs={"simlevel": "recsim"})

    def test_iocs_changed_simlevel_changed(self):
        self._test_attribute_changes(initial_attrs={"simlevel": "recsim"}, final_attrs={"simlevel": "devsim"})

    def test_iocs_not_changed_simlevel_unchanged(self):
        self._test_attribute_changes(
            initial_attrs={"simlevel": "recsim"}, final_attrs={"simlevel": "recsim"}, has_changed=False
        )