diff options
Diffstat (limited to 'tests/ga/test_extension.py')
-rw-r--r-- | tests/ga/test_extension.py | 177 |
1 files changed, 175 insertions, 2 deletions
diff --git a/tests/ga/test_extension.py b/tests/ga/test_extension.py index 71c219c..1df0a04 100644 --- a/tests/ga/test_extension.py +++ b/tests/ga/test_extension.py @@ -15,12 +15,141 @@ # Requires Python 2.4+ and Openssl 1.0+ # +import azurelinuxagent.common.utils.fileutil as fileutil + from tests.protocol.mockwiredata import * + from azurelinuxagent.common.exception import * from azurelinuxagent.common.protocol import get_protocol_util +from azurelinuxagent.common.protocol.restapi import ExtHandlerStatus, \ + ExtensionStatus, \ + ExtensionSubStatus, \ + Extension, \ + VMStatus, ExtHandler, \ + get_properties from azurelinuxagent.ga.exthandlers import * from azurelinuxagent.common.protocol.wire import WireProtocol +class TestHandlerStateMigration(AgentTestCase): + def setUp(self): + AgentTestCase.setUp(self) + + handler_name = "Not.A.Real.Extension" + handler_version = "1.2.3" + + self.ext_handler = ExtHandler(handler_name) + self.ext_handler.properties.version = handler_version + self.ext_handler_i = ExtHandlerInstance(self.ext_handler, "dummy protocol") + + self.handler_state = "Enabled" + self.handler_status = ExtHandlerStatus( + name=handler_name, + version=handler_version, + status="Ready", + message="Uninteresting message") + return + + def _prepare_handler_state(self): + handler_state_path = os.path.join( + self.tmp_dir, + "handler_state", + self.ext_handler_i.get_full_name()) + os.makedirs(handler_state_path) + fileutil.write_file( + os.path.join(handler_state_path, "state"), + self.handler_state) + fileutil.write_file( + os.path.join(handler_state_path, "status"), + json.dumps(get_properties(self.handler_status))) + return + + def _prepare_handler_config(self): + handler_config_path = os.path.join( + self.tmp_dir, + self.ext_handler_i.get_full_name(), + "config") + os.makedirs(handler_config_path) + return + + def test_migration_migrates(self): + self._prepare_handler_state() + self._prepare_handler_config() + + migrate_handler_state() + + self.assertEquals(self.ext_handler_i.get_handler_state(), self.handler_state) + self.assertEquals( + self.ext_handler_i.get_handler_status().status, + self.handler_status.status) + return + + def test_migration_skips_if_empty(self): + self._prepare_handler_config() + + migrate_handler_state() + + self.assertFalse( + os.path.isfile(os.path.join(self.ext_handler_i.get_conf_dir(), "HandlerState"))) + self.assertFalse( + os.path.isfile(os.path.join(self.ext_handler_i.get_conf_dir(), "HandlerStatus"))) + return + + def test_migration_cleans_up(self): + self._prepare_handler_state() + self._prepare_handler_config() + + migrate_handler_state() + + self.assertFalse(os.path.isdir(os.path.join(conf.get_lib_dir(), "handler_state"))) + return + + def test_migration_does_not_overwrite(self): + self._prepare_handler_state() + self._prepare_handler_config() + + state = "Installed" + status = "NotReady" + code = 1 + message = "A message" + self.assertNotEquals(state, self.handler_state) + self.assertNotEquals(status, self.handler_status.status) + self.assertNotEquals(code, self.handler_status.code) + self.assertNotEquals(message, self.handler_status.message) + + self.ext_handler_i.set_handler_state(state) + self.ext_handler_i.set_handler_status(status=status, code=code, message=message) + + migrate_handler_state() + + self.assertEquals(self.ext_handler_i.get_handler_state(), state) + handler_status = self.ext_handler_i.get_handler_status() + self.assertEquals(handler_status.status, status) + self.assertEquals(handler_status.code, code) + self.assertEquals(handler_status.message, message) + return + + @patch("shutil.move", side_effect=Exception) + def test_migration_ignores_move_errors(self, shutil_mock): + self._prepare_handler_state() + self._prepare_handler_config() + + try: + migrate_handler_state() + except Exception as e: + self.assertTrue(False, "Unexpected exception: {0}".format(str(e))) + return + + @patch("shutil.rmtree", side_effect=Exception) + def test_migration_ignores_tree_remove_errors(self, shutil_mock): + self._prepare_handler_state() + self._prepare_handler_config() + + try: + migrate_handler_state() + except Exception as e: + self.assertTrue(False, "Unexpected exception: {0}".format(str(e))) + return + @patch("azurelinuxagent.common.protocol.wire.CryptUtil") @patch("azurelinuxagent.common.utils.restutil.http_get") class TestExtension(AgentTestCase): @@ -33,7 +162,7 @@ class TestExtension(AgentTestCase): self.assertNotEquals(0, len(vm_status.vmAgent.extensionHandlers)) handler_status = vm_status.vmAgent.extensionHandlers[0] self.assertEquals(expected_status, handler_status.status) - self.assertEquals("OSTCExtensions.ExampleHandlerLinux", + self.assertEquals("OSTCExtensions.ExampleHandlerLinux", handler_status.name) self.assertEquals(version, handler_status.version) self.assertEquals(expected_ext_count, len(handler_status.extensions)) @@ -157,7 +286,51 @@ class TestExtension(AgentTestCase): mock_fileutil.write_file.return_value = IOError("Mock IO Error") exthandlers_handler.run() - def _assert_ext_status(self, report_ext_status, expected_status, + def test_handle_ext_handlers_on_hold_true(self, *args): + test_data = WireProtocolData(DATA_FILE) + exthandlers_handler, protocol = self._create_mock(test_data, *args) + exthandlers_handler.ext_handlers, exthandlers_handler.last_etag = protocol.get_ext_handlers() + protocol.get_artifacts_profile = MagicMock() + exthandlers_handler.protocol = protocol + + # Disable extension handling blocking + conf.get_enable_overprovisioning = Mock(return_value=False) + with patch.object(ExtHandlersHandler, 'handle_ext_handler') as patch_handle_ext_handler: + exthandlers_handler.handle_ext_handlers() + patch_handle_ext_handler.assert_called() + + # enable extension handling blocking + conf.get_enable_overprovisioning = Mock(return_value=True) + with patch.object(ExtHandlersHandler, 'handle_ext_handler') as patch_handle_ext_handler: + exthandlers_handler.handle_ext_handlers() + patch_handle_ext_handler.assert_not_called() + + + def test_handle_ext_handlers_on_hold_false(self, *args): + test_data = WireProtocolData(DATA_FILE) + exthandlers_handler, protocol = self._create_mock(test_data, *args) + exthandlers_handler.ext_handlers, exthandlers_handler.last_etag = protocol.get_ext_handlers() + exthandlers_handler.protocol = protocol + + # enable extension handling blocking + conf.get_enable_overprovisioning = Mock(return_value=True) + + #Test when is_on_hold returns False + from azurelinuxagent.common.protocol.wire import InVMArtifactsProfile + mock_in_vm_artifacts_profile = InVMArtifactsProfile(MagicMock()) + mock_in_vm_artifacts_profile.is_on_hold = Mock(return_value=False) + protocol.get_artifacts_profile = Mock(return_value=mock_in_vm_artifacts_profile) + with patch.object(ExtHandlersHandler, 'handle_ext_handler') as patch_handle_ext_handler: + exthandlers_handler.handle_ext_handlers() + patch_handle_ext_handler.assert_called_once() + + #Test when in_vm_artifacts_profile is not available + protocol.get_artifacts_profile = Mock(return_value=None) + with patch.object(ExtHandlersHandler, 'handle_ext_handler') as patch_handle_ext_handler: + exthandlers_handler.handle_ext_handlers() + patch_handle_ext_handler.assert_called_once() + + def _assert_ext_status(self, report_ext_status, expected_status, expected_seq_no): self.assertTrue(report_ext_status.called) args, kw = report_ext_status.call_args |