예제 #1
0
    def test_put_vm_log_should_raise_an_exception_when_request_fails(self):
        def http_put_handler(url, *args, **kwargs):  # pylint: disable=inconsistent-return-statements
            if self.is_host_plugin_put_logs_request(url):
                http_put_handler.args, http_put_handler.kwargs = args, kwargs
                return MockResponse(body=ustr('Gone'), status_code=410)

        http_put_handler.args, http_put_handler.kwargs = [], {}

        with mock_wire_protocol(DATA_FILE,
                                http_put_handler=http_put_handler) as protocol:
            test_goal_state = protocol.client.get_goal_state()

            host_client = wire.HostPluginProtocol(
                wireserver_url, test_goal_state.container_id,
                test_goal_state.role_config_name)

            self.assertFalse(host_client.is_initialized,
                             "Host plugin should not be initialized!")

            with self.assertRaises(HttpError) as context_manager:
                content = b"test"
                host_client.put_vm_log(content)

            self.assertIsInstance(context_manager.exception, HttpError)
            self.assertIn("410", ustr(context_manager.exception))
            self.assertIn("Gone", ustr(context_manager.exception))
예제 #2
0
    def test_validate_get_extension_artifacts(self):
        with mock_wire_protocol(DATA_FILE) as protocol:
            test_goal_state = protocol.client._goal_state  # pylint: disable=protected-access

            expected_url = hostplugin.URI_FORMAT_GET_EXTENSION_ARTIFACT.format(
                wireserver_url, hostplugin.HOST_PLUGIN_PORT)
            expected_headers = {
                'x-ms-version': '2015-09-01',
                "x-ms-containerid": test_goal_state.container_id,
                "x-ms-host-config-name": test_goal_state.role_config_name,
                "x-ms-artifact-location": sas_url
            }

            host_client = wire.HostPluginProtocol(
                wireserver_url, test_goal_state.container_id,
                test_goal_state.role_config_name)
            self.assertFalse(host_client.is_initialized)
            self.assertTrue(host_client.api_versions is None)
            self.assertTrue(host_client.health_service is not None)

            with patch.object(wire.HostPluginProtocol,
                              "get_api_versions",
                              return_value=api_versions) as patch_get:  # pylint: disable=unused-variable
                actual_url, actual_headers = host_client.get_artifact_request(
                    sas_url)
                self.assertTrue(host_client.is_initialized)
                self.assertFalse(host_client.api_versions is None)
                self.assertEqual(expected_url, actual_url)
                for k in expected_headers:
                    self.assertTrue(k in actual_headers)
                    self.assertEqual(expected_headers[k], actual_headers[k])
예제 #3
0
    def test_validate_get_extension_artifacts(self):
        test_goal_state = wire.GoalState(
            WireProtocolData(DATA_FILE).goal_state)
        expected_url = hostplugin.URI_FORMAT_GET_EXTENSION_ARTIFACT.format(
            wireserver_url, hostplugin.HOST_PLUGIN_PORT)
        expected_headers = {
            'x-ms-version': '2015-09-01',
            "x-ms-containerid": test_goal_state.container_id,
            "x-ms-host-config-name": test_goal_state.role_instance_config_name,
            "x-ms-artifact-location": sas_url
        }

        host_client = wire.HostPluginProtocol(
            wireserver_url, test_goal_state.container_id,
            test_goal_state.role_instance_config_name)
        self.assertFalse(host_client.is_initialized)
        self.assertTrue(host_client.api_versions is None)

        with patch.object(wire.HostPluginProtocol,
                          "get_api_versions",
                          return_value=api_versions) as patch_get:
            actual_url, actual_headers = host_client.get_extension_artifact_url_and_headers(
                sas_url)
            self.assertTrue(host_client.is_initialized)
            self.assertFalse(host_client.api_versions is None)
            self.assertEqual(expected_url, actual_url)
            for k in expected_headers:
                self.assertTrue(k in actual_headers)
                self.assertEqual(expected_headers[k], actual_headers[k])
예제 #4
0
    def test_validate_page_blobs(self):
        """Validate correct set of data is sent for page blobs"""
        with mock_wire_protocol(DATA_FILE) as protocol:
            test_goal_state = protocol.client._goal_state  # pylint: disable=protected-access

            host_client = wire.HostPluginProtocol(
                wireserver_url, test_goal_state.container_id,
                test_goal_state.role_config_name)

            self.assertFalse(host_client.is_initialized)
            self.assertTrue(host_client.api_versions is None)

            status_blob = protocol.client.status_blob
            status_blob.data = faux_status
            status_blob.type = page_blob_type
            status_blob.vm_status = restapi.VMStatus(message="Ready",
                                                     status="Ready")

            exp_method = 'PUT'
            exp_url = hostplugin_status_url

            page_status = bytearray(status_blob.data, encoding='utf-8')
            page_size = int((len(page_status) + 511) / 512) * 512
            page_status = bytearray(status_blob.data.ljust(page_size),
                                    encoding='utf-8')
            page = bytearray(page_size)
            page[0:page_size] = page_status[0:len(page_status)]
            mock_response = MockResponse('', httpclient.OK)

            with patch.object(restutil,
                              "http_request",
                              return_value=mock_response) as patch_http:
                with patch.object(wire.HostPluginProtocol,
                                  "get_api_versions") as patch_get:
                    patch_get.return_value = api_versions
                    host_client.put_vm_status(status_blob, sas_url)

                    self.assertTrue(patch_http.call_count == 3)

                    # first call is to host plugin
                    exp_data = self._hostplugin_data(
                        status_blob.get_page_blob_create_headers(page_size))
                    self._validate_hostplugin_args(
                        patch_http.call_args_list[0], test_goal_state,
                        exp_method, exp_url, exp_data)

                    # second call is to health service
                    self.assertEqual('POST',
                                     patch_http.call_args_list[1][0][0])
                    self.assertEqual(health_service_url,
                                     patch_http.call_args_list[1][0][1])

                    # last call is to host plugin
                    exp_data = self._hostplugin_data(
                        status_blob.get_page_blob_page_headers(0, page_size),
                        page)
                    exp_data['requestUri'] += "?comp=page"
                    self._validate_hostplugin_args(
                        patch_http.call_args_list[2], test_goal_state,
                        exp_method, exp_url, exp_data)
예제 #5
0
    def test_validate_block_blob(self):
        """Validate correct set of data is sent to HostGAPlugin when reporting VM status"""
        wire_protocol_client = wire.WireProtocol(wireserver_url).client
        test_goal_state = wire.GoalState(WireProtocolData(DATA_FILE).goal_state)

        host_client = wire.HostPluginProtocol(wireserver_url,
                                              test_goal_state.container_id,
                                              test_goal_state.role_config_name)
        self.assertFalse(host_client.is_initialized)
        self.assertTrue(host_client.api_versions is None)

        status_blob = wire_protocol_client.status_blob
        status_blob.data = faux_status
        status_blob.type = block_blob_type
        status_blob.vm_status = restapi.VMStatus(message="Ready", status="Ready")

        exp_method = 'PUT'
        exp_url = hostplugin_status_url
        exp_data = self._hostplugin_data(
                        status_blob.get_block_blob_headers(len(faux_status)),
                        bytearray(faux_status, encoding='utf-8'))

        with patch.object(restutil, "http_request") as patch_http:
            patch_http.return_value = Mock(status=httpclient.OK)

            with patch.object(wire.HostPluginProtocol,
                          "get_api_versions") as patch_get:
                patch_get.return_value = api_versions
                host_client.put_vm_status(status_blob, sas_url)

                self.assertTrue(patch_http.call_count == 1)
                self._validate_hostplugin_args(
                    patch_http.call_args_list[0],
                    test_goal_state,
                    exp_method, exp_url, exp_data)
예제 #6
0
    def test_init_put(self):
        expected_url = "http://168.63.129.16:32526/status"
        expected_headers = {'x-ms-version': '2015-09-01'}
        expected_content = '{"content": "b2s=", ' \
                           '"headers": [{"headerName": "x-ms-version", ' \
                           '"headerValue": "2014-02-14"}, ' \
                           '{"headerName": "x-ms-blob-type", "headerValue": ' \
                           '"BlockBlob"}], ' \
                           '"requestUri": "http://sas_url"}'

        host_client = wire.HostPluginProtocol(wireserver_url)
        self.assertFalse(host_client.is_initialized)
        self.assertTrue(host_client.api_versions is None)
        status_blob = wire.StatusBlob(None)
        status_blob.vm_status = restapi.VMStatus()
        status_blob.vm_status.vmAgent.status = 'ok'
        status_blob.type = "BlockBlob"
        with patch.object(wire.HostPluginProtocol,
                          "get_api_versions") as patch_get:
            patch_get.return_value = api_versions
            with patch.object(restapi.restutil, "http_put") as patch_put:
                patch_put.return_value = MagicMock()
                host_client.put_vm_status(status_blob, sas_url)
                self.assertTrue(host_client.is_initialized)
                self.assertFalse(host_client.api_versions is None)
                self.assertTrue(patch_put.call_count == 1)
                self.assertTrue(patch_put.call_args[0][0] == expected_url)
                self.assertTrue(patch_put.call_args[0][1] == expected_content)
                self.assertTrue(patch_put.call_args[0][2] == expected_headers)
예제 #7
0
 def _init_host(self):
     with mock_wire_protocol(DATA_FILE) as protocol:
         test_goal_state = protocol.client.get_goal_state()
         host_plugin = wire.HostPluginProtocol(
             wireserver_url, test_goal_state.container_id,
             test_goal_state.role_config_name)
         self.assertTrue(host_plugin.health_service is not None)
         return host_plugin
예제 #8
0
 def _init_host(self):
     test_goal_state = wire.GoalState(
         WireProtocolData(DATA_FILE).goal_state)
     host_plugin = wire.HostPluginProtocol(wireserver_url,
                                           test_goal_state.container_id,
                                           test_goal_state.role_config_name)
     self.assertTrue(host_plugin.health_service is not None)
     return host_plugin
예제 #9
0
    def test_validate_http_request_for_put_vm_log(self):
        def http_put_handler(url, *args, **kwargs):  # pylint: disable=inconsistent-return-statements
            if self.is_host_plugin_put_logs_request(url):
                http_put_handler.args, http_put_handler.kwargs = args, kwargs
                return MockResponse(body=b'', status_code=200)

        http_put_handler.args, http_put_handler.kwargs = [], {}

        with mock_wire_protocol(DATA_FILE,
                                http_put_handler=http_put_handler) as protocol:
            test_goal_state = protocol.client.get_goal_state()

            expected_url = hostplugin.URI_FORMAT_PUT_LOG.format(
                wireserver_url, hostplugin.HOST_PLUGIN_PORT)
            expected_headers = {
                'x-ms-version':
                '2015-09-01',
                "x-ms-containerid":
                test_goal_state.container_id,
                "x-ms-vmagentlog-deploymentid":
                test_goal_state.role_config_name.split(".")[0],
                "x-ms-client-name":
                AGENT_NAME,
                "x-ms-client-version":
                AGENT_VERSION
            }

            host_client = wire.HostPluginProtocol(
                wireserver_url, test_goal_state.container_id,
                test_goal_state.role_config_name)

            self.assertFalse(host_client.is_initialized,
                             "Host plugin should not be initialized!")

            content = b"test"
            host_client.put_vm_log(content)
            self.assertTrue(host_client.is_initialized,
                            "Host plugin is not initialized!")

            urls = protocol.get_tracked_urls()

            self.assertEqual(expected_url, urls[0], "Unexpected request URL!")
            self.assertEqual(content, http_put_handler.args[0],
                             "Unexpected content for HTTP PUT request!")

            headers = http_put_handler.kwargs['headers']
            for k in expected_headers:
                self.assertTrue(k in headers,
                                "Header {0} not found in headers!".format(k))
                self.assertEqual(expected_headers[k], headers[k],
                                 "Request headers don't match!")

            # Special check for correlation id header value, check for pattern, not exact value
            self.assertTrue("x-ms-client-correlationid" in headers.keys(),
                            "Correlation id not found in headers!")
            self.assertTrue(
                UUID_PATTERN.match(headers["x-ms-client-correlationid"]),
                "Correlation id is not in GUID form!")
예제 #10
0
    def test_validate_block_blob(self):
        with mock_wire_protocol(DATA_FILE) as protocol:
            test_goal_state = protocol.client._goal_state  # pylint: disable=protected-access

            host_client = wire.HostPluginProtocol(
                wireserver_url, test_goal_state.container_id,
                test_goal_state.role_config_name)
            self.assertFalse(host_client.is_initialized)
            self.assertTrue(host_client.api_versions is None)
            self.assertTrue(host_client.health_service is not None)

            status_blob = protocol.client.status_blob
            status_blob.data = faux_status
            status_blob.type = block_blob_type
            status_blob.vm_status = restapi.VMStatus(message="Ready",
                                                     status="Ready")

            exp_method = 'PUT'
            exp_url = hostplugin_status_url
            exp_data = self._hostplugin_data(
                status_blob.get_block_blob_headers(len(faux_status)),
                bytearray(faux_status, encoding='utf-8'))

            with patch.object(restutil, "http_request") as patch_http:
                patch_http.return_value = Mock(status=httpclient.OK)

                with patch.object(wire.HostPluginProtocol,
                                  "get_api_versions") as patch_get:
                    patch_get.return_value = api_versions
                    host_client.put_vm_status(status_blob, sas_url)

                    self.assertTrue(patch_http.call_count == 2)

                    # first call is to host plugin
                    self._validate_hostplugin_args(
                        patch_http.call_args_list[0], test_goal_state,
                        exp_method, exp_url, exp_data)

                    # second call is to health service
                    self.assertEqual('POST',
                                     patch_http.call_args_list[1][0][0])
                    self.assertEqual(health_service_url,
                                     patch_http.call_args_list[1][0][1])
예제 #11
0
    def test_validate_http_put(self):
        """Validate correct set of data is sent to HostGAPlugin when reporting VM status"""
        test_goal_state = wire.GoalState(
            WireProtocolData(DATA_FILE).goal_state)
        expected_url = "http://168.63.129.16:32526/status"
        expected_headers = {
            'x-ms-version': '2015-09-01',
            "Content-type": "application/json",
            "x-ms-containerid": test_goal_state.container_id,
            "x-ms-host-config-name": test_goal_state.role_config_name
        }
        expected_content = '{"content": "eyJkdW1teSI6ICJkYXRhIn0=", ' \
                           '"headers": [{"headerName": "x-ms-version", ' \
                           '"headerValue": "2014-02-14"}, ' \
                           '{"headerName": "x-ms-blob-type", "headerValue": ' \
                           '"BlockBlob"}], ' \
                           '"requestUri": "http://sas_url"}'

        host_client = wire.HostPluginProtocol(wireserver_url,
                                              test_goal_state.container_id,
                                              test_goal_state.role_config_name)
        self.assertFalse(host_client.is_initialized)
        self.assertTrue(host_client.api_versions is None)
        status_blob = wire.StatusBlob(None)
        status_blob.vm_status = restapi.VMStatus(message="Ready",
                                                 status="Ready")
        status_blob.data = '{"dummy": "data"}'
        status_blob.type = "BlockBlob"
        with patch.object(wire.HostPluginProtocol,
                          "get_api_versions") as patch_get:
            patch_get.return_value = api_versions
            with patch.object(restapi.restutil, "http_put") as patch_put:
                patch_put.return_value = MagicMock()
                host_client.put_vm_status(status_blob, sas_url)
                self.assertTrue(host_client.is_initialized)
                self.assertFalse(host_client.api_versions is None)
                self.assertTrue(patch_put.call_count == 1)
                self.assertTrue(patch_put.call_args[0][0] == expected_url)
                self.assertTrue(
                    patch_put.call_args[1]['data'] == expected_content)
                self.assertTrue(
                    patch_put.call_args[1]['headers'] == expected_headers)