From 43bdf9debe5377216aed0086bff2aad864f6ba82 Mon Sep 17 00:00:00 2001 From: Ɓukasz 'sil2100' Zemczak Date: Mon, 3 Jul 2017 13:44:00 +0200 Subject: Import patches-unapplied version 2.2.14-0ubuntu1 to ubuntu/artful-proposed Imported using git-ubuntu import. Changelog parent: 4fb0b5a09b26135ade285844da5d7dfe582a8d4c New changelog entries: * New upstream release (LP: #1701350). * debian/copyright: - Refreshed copyright content. --- tests/common/osutil/test_bigip.py | 29 ----------------- tests/common/test_event.py | 66 +++++++++++++++++++++++++++++++++++++++ tests/common/test_logger.py | 66 +++++++++++++++++++++++++++++++++++++++ tests/ga/test_update.py | 36 +++++++++++++++++++++ tests/pa/test_deprovision.py | 38 +++++++++++++++++++--- tests/protocol/test_hostplugin.py | 57 ++++++++++++++++++++++++++++++++- tests/protocol/test_wire.py | 24 +++++++++----- 7 files changed, 275 insertions(+), 41 deletions(-) create mode 100644 tests/common/test_logger.py (limited to 'tests') diff --git a/tests/common/osutil/test_bigip.py b/tests/common/osutil/test_bigip.py index 4d1b006..f5958cf 100644 --- a/tests/common/osutil/test_bigip.py +++ b/tests/common/osutil/test_bigip.py @@ -282,35 +282,6 @@ class TestBigIpOSUtil_mount_dvd(AgentTestCase): self.assertEqual(args[1].call_count, 1) -class TestBigIpOSUtil_set_admin_access_to_ip(AgentTestCase): - - @patch.object(shellutil, "run", return_value=0) - @patch.object(osutil.BigIpOSUtil, - '_set_accept_admin_access_to_ip', return_value=None) - @patch.object(osutil.BigIpOSUtil, - '_set_drop_admin_access_to_ip', return_value=None) - def test_success(self, *args): - osutil.BigIpOSUtil.set_admin_access_to_ip( - osutil.BigIpOSUtil(), '192.168.10.10' - ) - self.assertEqual(args[0].call_count, 1) - self.assertEqual(args[1].call_count, 1) - - @patch.object(shellutil, "run", return_value=0) - def test_accept_access(self, *args): - osutil.BigIpOSUtil._set_accept_admin_access_to_ip( - osutil.BigIpOSUtil(), '192.168.10.10' - ) - self.assertEqual(args[0].call_count, 2) - - @patch.object(shellutil, "run", return_value=0) - def test_drop_access(self, *args): - osutil.BigIpOSUtil._set_drop_admin_access_to_ip( - osutil.BigIpOSUtil(), '192.168.10.10' - ) - self.assertEqual(args[0].call_count, 2) - - class TestBigIpOSUtil_route_add(AgentTestCase): @patch.object(shellutil, "run", return_value=0) diff --git a/tests/common/test_event.py b/tests/common/test_event.py index f535411..a485edf 100644 --- a/tests/common/test_event.py +++ b/tests/common/test_event.py @@ -17,12 +17,78 @@ from __future__ import print_function +from datetime import datetime + +import azurelinuxagent.common.event as event +import azurelinuxagent.common.logger as logger + from azurelinuxagent.common.event import init_event_logger, add_event from azurelinuxagent.common.future import ustr +from azurelinuxagent.common.version import CURRENT_VERSION + from tests.tools import * class TestEvent(AgentTestCase): + + @patch('azurelinuxagent.common.event.EventLogger.add_event') + def test_periodic_emits_if_not_previously_sent(self, mock_event): + init_event_logger(tempfile.mkdtemp()) + event.__event_logger__.reset_periodic() + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + mock_event.assert_called_once() + + @patch('azurelinuxagent.common.event.EventLogger.add_event') + def test_periodic_does_not_emit_if_previously_sent(self, mock_event): + init_event_logger(tempfile.mkdtemp()) + event.__event_logger__.reset_periodic() + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(1, mock_event.call_count) + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(1, mock_event.call_count) + + @patch('azurelinuxagent.common.event.EventLogger.add_event') + def test_periodic_emits_if_forced(self, mock_event): + init_event_logger(tempfile.mkdtemp()) + event.__event_logger__.reset_periodic() + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(1, mock_event.call_count) + + event.add_periodic(logger.EVERY_DAY, "FauxEvent", force=True) + self.assertEqual(2, mock_event.call_count) + + @patch('azurelinuxagent.common.event.EventLogger.add_event') + def test_periodic_emits_after_elapsed_delta(self, mock_event): + init_event_logger(tempfile.mkdtemp()) + event.__event_logger__.reset_periodic() + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(1, mock_event.call_count) + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(1, mock_event.call_count) + + h = hash("FauxEvent"+""+ustr(True)+"") + event.__event_logger__.periodic_messages[h] = \ + datetime.now() - logger.EVERY_DAY - logger.EVERY_HOUR + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + self.assertEqual(2, mock_event.call_count) + + @patch('azurelinuxagent.common.event.EventLogger.add_event') + def test_periodic_forwards_args(self, mock_event): + init_event_logger(tempfile.mkdtemp()) + event.__event_logger__.reset_periodic() + + event.add_periodic(logger.EVERY_DAY, "FauxEvent") + mock_event.assert_called_once_with( + "FauxEvent", + duration=0, evt_type='', is_internal=False, is_success=True, + log_event=True, message='', op='', version=str(CURRENT_VERSION)) + def test_save_event(self): tmp_evt = tempfile.mkdtemp() init_event_logger(tmp_evt) diff --git a/tests/common/test_logger.py b/tests/common/test_logger.py new file mode 100644 index 0000000..9e298b3 --- /dev/null +++ b/tests/common/test_logger.py @@ -0,0 +1,66 @@ +# Copyright 2016 Microsoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Requires Python 2.4+ and Openssl 1.0+ +# + +from datetime import datetime + +import azurelinuxagent.common.logger as logger + +from tests.tools import * + +_MSG = "This is our test logging message {0} {1}" +_DATA = ["arg1", "arg2"] + +class TestLogger(AgentTestCase): + + @patch('azurelinuxagent.common.logger.Logger.info') + def test_periodic_emits_if_not_previously_sent(self, mock_info): + logger.reset_periodic() + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + mock_info.assert_called_once() + + @patch('azurelinuxagent.common.logger.Logger.info') + def test_periodic_does_not_emit_if_previously_sent(self, mock_info): + logger.reset_periodic() + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + self.assertEqual(1, mock_info.call_count) + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + self.assertEqual(1, mock_info.call_count) + + @patch('azurelinuxagent.common.logger.Logger.info') + def test_periodic_emits_after_elapsed_delta(self, mock_info): + logger.reset_periodic() + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + self.assertEqual(1, mock_info.call_count) + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + self.assertEqual(1, mock_info.call_count) + + logger.DEFAULT_LOGGER.periodic_messages[hash(_MSG)] = \ + datetime.now() - logger.EVERY_DAY - logger.EVERY_HOUR + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + self.assertEqual(2, mock_info.call_count) + + @patch('azurelinuxagent.common.logger.Logger.info') + def test_periodic_forwards_message_and_args(self, mock_info): + logger.reset_periodic() + + logger.periodic(logger.EVERY_DAY, _MSG, *_DATA) + mock_info.assert_called_once_with(_MSG, *_DATA) diff --git a/tests/ga/test_update.py b/tests/ga/test_update.py index a83db95..0c8642c 100644 --- a/tests/ga/test_update.py +++ b/tests/ga/test_update.py @@ -23,6 +23,7 @@ import json import shutil from azurelinuxagent.common.protocol.hostplugin import * +from azurelinuxagent.common.protocol.metadata import * from azurelinuxagent.common.protocol.wire import * from azurelinuxagent.common.utils.fileutil import * from azurelinuxagent.ga.update import * @@ -1019,6 +1020,21 @@ class TestUpdate(UpdateTestCase): self.assertEqual(kept_agents, self.update_handler.agents) return + @patch('azurelinuxagent.common.protocol.wire.WireClient.get_host_plugin') + def test_get_host_plugin_returns_host_for_wireserver(self, mock_get_host): + protocol = WireProtocol('12.34.56.78') + mock_get_host.return_value = "faux host" + host = self.update_handler._get_host_plugin(protocol=protocol) + mock_get_host.assert_called_once() + self.assertEqual("faux host", host) + + @patch('azurelinuxagent.common.protocol.wire.WireClient.get_host_plugin') + def test_get_host_plugin_returns_none_otherwise(self, mock_get_host): + protocol = MetadataProtocol() + host = self.update_handler._get_host_plugin(protocol=protocol) + mock_get_host.assert_not_called() + self.assertEqual(None, host) + def test_get_latest_agent(self): latest_version = self.prepare_agents() @@ -1324,6 +1340,24 @@ class TestUpdate(UpdateTestCase): self.assertEqual(1, latest_agent.error.failure_count) return + def test_run_latest_exception_does_not_blacklist_if_terminating(self): + self.prepare_agents() + + latest_agent = self.update_handler.get_latest_agent() + self.assertTrue(latest_agent.is_available) + self.assertEqual(0.0, latest_agent.error.last_failure) + self.assertEqual(0, latest_agent.error.failure_count) + + with patch('azurelinuxagent.ga.update.UpdateHandler.get_latest_agent', return_value=latest_agent): + self.update_handler.running = False + self._test_run_latest(mock_child=ChildMock(side_effect=Exception("Attempt blacklisting"))) + + self.assertTrue(latest_agent.is_available) + self.assertFalse(latest_agent.error.is_blacklisted) + self.assertEqual(0.0, latest_agent.error.last_failure) + self.assertEqual(0, latest_agent.error.failure_count) + return + @patch('signal.signal') def test_run_latest_captures_signals(self, mock_signal): self._test_run_latest() @@ -1462,12 +1496,14 @@ class TestUpdate(UpdateTestCase): def test_shutdown(self): self.update_handler._set_sentinal() self.update_handler._shutdown() + self.assertFalse(self.update_handler.running) self.assertFalse(os.path.isfile(self.update_handler._sentinal_file_path())) return def test_shutdown_ignores_missing_sentinal_file(self): self.assertFalse(os.path.isfile(self.update_handler._sentinal_file_path())) self.update_handler._shutdown() + self.assertFalse(self.update_handler.running) self.assertFalse(os.path.isfile(self.update_handler._sentinal_file_path())) return diff --git a/tests/pa/test_deprovision.py b/tests/pa/test_deprovision.py index c4cd9b4..b2f7f0c 100644 --- a/tests/pa/test_deprovision.py +++ b/tests/pa/test_deprovision.py @@ -15,6 +15,7 @@ # Requires Python 2.4+ and Openssl 1.0+ # +import signal import tempfile import azurelinuxagent.common.utils.fileutil as fileutil @@ -25,16 +26,44 @@ from tests.tools import * class TestDeprovision(AgentTestCase): + @patch('signal.signal') + @patch('azurelinuxagent.common.osutil.get_osutil') + @patch('azurelinuxagent.common.protocol.get_protocol_util') + @patch('azurelinuxagent.pa.deprovision.default.read_input') + def test_confirmation(self, + mock_read, mock_protocol, mock_util, mock_signal): + dh = DeprovisionHandler() + + dh.setup = Mock() + dh.setup.return_value = ([], []) + dh.do_actions = Mock() + + # Do actions if confirmed + mock_read.return_value = "y" + dh.run() + self.assertEqual(1, dh.do_actions.call_count) + + # Skip actions if not confirmed + mock_read.return_value = "n" + dh.run() + self.assertEqual(1, dh.do_actions.call_count) + + # Do actions if forced + mock_read.return_value = "n" + dh.run(force=True) + self.assertEqual(2, dh.do_actions.call_count) + @patch("azurelinuxagent.pa.deprovision.default.DeprovisionHandler.cloud_init_dirs") @patch("azurelinuxagent.pa.deprovision.default.DeprovisionHandler.cloud_init_files") def test_del_cloud_init_without_once(self, mock_files, mock_dirs): deprovision_handler = get_deprovision_handler("","","") - deprovision_handler.del_cloud_init([], [], include_once=False) + deprovision_handler.del_cloud_init([], [], + include_once=False, deluser=False) mock_dirs.assert_called_with(include_once=False) - mock_files.assert_called_with(include_once=False) + mock_files.assert_called_with(include_once=False, deluser=False) @patch("signal.signal") @patch("azurelinuxagent.common.protocol.get_protocol_util") @@ -59,10 +88,11 @@ class TestDeprovision(AgentTestCase): mock_files.return_value = files deprovision_handler = get_deprovision_handler("","","") - deprovision_handler.del_cloud_init(warnings, actions) + deprovision_handler.del_cloud_init(warnings, actions, + deluser=True) mock_dirs.assert_called_with(include_once=True) - mock_files.assert_called_with(include_once=True) + mock_files.assert_called_with(include_once=True, deluser=True) self.assertEqual(len(warnings), 0) self.assertEqual(len(actions), 2) diff --git a/tests/protocol/test_hostplugin.py b/tests/protocol/test_hostplugin.py index e203615..b18b691 100644 --- a/tests/protocol/test_hostplugin.py +++ b/tests/protocol/test_hostplugin.py @@ -19,7 +19,7 @@ import base64 import json import sys - +from azurelinuxagent.common.future import ustr if sys.version_info[0] == 3: import http.client as httpclient @@ -224,6 +224,61 @@ class TestHostPlugin(AgentTestCase): test_goal_state, exp_method, exp_url, exp_data) + def test_read_response_error(self): + """ + Validate the read_response_error method handles encoding correctly + """ + responses = ['message', b'message', '\x80message\x80'] + response = MagicMock() + response.status = 'status' + response.reason = 'reason' + with patch.object(response, 'read') as patch_response: + for s in responses: + patch_response.return_value = s + result = hostplugin.HostPluginProtocol.read_response_error(response) + self.assertTrue('[status: reason]' in result) + self.assertTrue('message' in result) + + def test_read_response_bytes(self): + response_bytes = '7b:0a:20:20:20:20:22:65:72:72:6f:72:43:6f:64:65:22:' \ + '3a:20:22:54:68:65:20:62:6c:6f:62:20:74:79:70:65:20:' \ + '69:73:20:69:6e:76:61:6c:69:64:20:66:6f:72:20:74:68:' \ + '69:73:20:6f:70:65:72:61:74:69:6f:6e:2e:22:2c:0a:20:' \ + '20:20:20:22:6d:65:73:73:61:67:65:22:3a:20:22:c3:af:' \ + 'c2:bb:c2:bf:3c:3f:78:6d:6c:20:76:65:72:73:69:6f:6e:' \ + '3d:22:31:2e:30:22:20:65:6e:63:6f:64:69:6e:67:3d:22:' \ + '75:74:66:2d:38:22:3f:3e:3c:45:72:72:6f:72:3e:3c:43:' \ + '6f:64:65:3e:49:6e:76:61:6c:69:64:42:6c:6f:62:54:79:' \ + '70:65:3c:2f:43:6f:64:65:3e:3c:4d:65:73:73:61:67:65:' \ + '3e:54:68:65:20:62:6c:6f:62:20:74:79:70:65:20:69:73:' \ + '20:69:6e:76:61:6c:69:64:20:66:6f:72:20:74:68:69:73:' \ + '20:6f:70:65:72:61:74:69:6f:6e:2e:0a:52:65:71:75:65:' \ + '73:74:49:64:3a:63:37:34:32:39:30:63:62:2d:30:30:30:' \ + '31:2d:30:30:62:35:2d:30:36:64:61:2d:64:64:36:36:36:' \ + '61:30:30:30:22:2c:0a:20:20:20:20:22:64:65:74:61:69:' \ + '6c:73:22:3a:20:22:22:0a:7d'.split(':') + expected_response = '[status: reason] {\n "errorCode": "The blob ' \ + 'type is invalid for this operation.",\n ' \ + '"message": "' \ + 'InvalidBlobTypeThe ' \ + 'blob type is invalid for this operation.\n' \ + 'RequestId:c74290cb-0001-00b5-06da-dd666a000",' \ + '\n "details": ""\n}' + + response_string = ''.join(chr(int(b, 16)) for b in response_bytes) + response = MagicMock() + response.status = 'status' + response.reason = 'reason' + with patch.object(response, 'read') as patch_response: + patch_response.return_value = response_string + result = hostplugin.HostPluginProtocol.read_response_error(response) + self.assertEqual(result, expected_response) + try: + raise HttpError("{0}".format(result)) + except HttpError as e: + self.assertTrue(result in ustr(e)) + def test_no_fallback(self): """ Validate fallback to upload status using HostGAPlugin is not happening diff --git a/tests/protocol/test_wire.py b/tests/protocol/test_wire.py index ba9fc7d..02976ca 100644 --- a/tests/protocol/test_wire.py +++ b/tests/protocol/test_wire.py @@ -80,26 +80,36 @@ class TestWireProtocolGetters(AgentTestCase): url = testurl headers = {} - # no kwargs + # no kwargs -- Default to True WireClient.call_storage_service(http_req) - # kwargs, no chk_proxy + + # kwargs, no chk_proxy -- Default to True WireClient.call_storage_service(http_req, url, headers) - # kwargs, chk_proxy False + + # kwargs, chk_proxy None -- Default to True + WireClient.call_storage_service(http_req, + url, + headers, + chk_proxy=None) + + # kwargs, chk_proxy False -- Keep False WireClient.call_storage_service(http_req, url, headers, chk_proxy=False) - # kwargs, chk_proxy True + + # kwargs, chk_proxy True -- Keep True WireClient.call_storage_service(http_req, url, headers, chk_proxy=True) # assert - self.assertTrue(http_patch.call_count == 4) - for c in http_patch.call_args_list: - self.assertTrue(c[-1]['chk_proxy'] == True) + self.assertTrue(http_patch.call_count == 5) + for i in range(0,5): + c = http_patch.call_args_list[i][-1]['chk_proxy'] + self.assertTrue(c == (True if i != 3 else False)) def test_status_blob_parsing(self, *args): wire_protocol_client = WireProtocol(wireserver_url).client -- cgit v1.2.3