diff --git a/doc/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json b/doc/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json index b2024bd6c034..1afedaee9c4b 100644 --- a/doc/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json +++ b/doc/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json @@ -1,40 +1,17 @@ { - "config_drive": 1, - "cpu_details": [ - { - "time": 17300000000 - } - ], - "disk_details": [ - { - "errors_count": 0, - "id": "fake-disk-id", - "read_requests": 112, - "read_bytes": 262144, - "write_requests": 488, - "write_bytes": 5778432 - } - ], - "driver": "fake", - "hypervisor_os": "fake-os", - "memory_details": { - "maximum": 524288, - "used": 0 - }, - "nic_details": [ - { - "mac_address": "01:23:45:67:89:ab", - "rx_drop": 0, - "rx_errors": 0, - "rx_octets": 2070139, - "rx_packets": 26701, - "tx_drop": 0, - "tx_errors": 0, - "tx_octets": 140208, - "tx_packets": 662 - } - ], - "state": "running", - "uptime": 46664, - "version": "1.0" + "cpu0_time": 17300000000, + "memory": 524288, + "vda_errors": -1, + "vda_read": 262144, + "vda_read_req": 112, + "vda_write": 5778432, + "vda_write_req": 488, + "vnet1_rx": 2070139, + "vnet1_rx_drop": 0, + "vnet1_rx_errors": 0, + "vnet1_rx_packets": 26701, + "vnet1_tx": 140208, + "vnet1_tx_drop": 0, + "vnet1_tx_errors": 0, + "vnet1_tx_packets": 662 } diff --git a/nova/api/openstack/compute/plugins/v3/server_diagnostics.py b/nova/api/openstack/compute/plugins/v3/server_diagnostics.py index 57fe3ae4069d..75fc407ad32a 100644 --- a/nova/api/openstack/compute/plugins/v3/server_diagnostics.py +++ b/nova/api/openstack/compute/plugins/v3/server_diagnostics.py @@ -41,7 +41,12 @@ class ServerDiagnosticsController(object): raise webob.exc.HTTPNotFound(explanation=e.format_message()) try: - return self.compute_api.get_instance_diagnostics(context, instance) + # NOTE(gmann): To make V21 same as V2 API, this method will call + # 'get_diagnostics' instead of 'get_instance_diagnostics'. + # In future, 'get_instance_diagnostics' needs to be called to + # provide VM diagnostics in a defined format for all driver. + # BP - https://blueprints.launchpad.net/nova/+spec/v3-diagnostics. + return self.compute_api.get_diagnostics(context, instance) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'get_diagnostics') @@ -60,7 +65,7 @@ class ServerDiagnostics(extensions.V3APIExtensionBase): def get_resources(self): parent_def = {'member_name': 'server', 'collection_name': 'servers'} resources = [ - extensions.ResourceExtension(ALIAS, + extensions.ResourceExtension('diagnostics', ServerDiagnosticsController(), parent=parent_def)] return resources diff --git a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py index 6ef24004671d..e4d725464b4e 100644 --- a/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py +++ b/nova/tests/api/openstack/compute/contrib/test_server_diagnostics.py @@ -38,24 +38,26 @@ def fake_instance_get(self, _context, instance_uuid, want_objects=False): return {'uuid': instance_uuid} -class ServerDiagnosticsTest(test.NoDBTestCase): +class ServerDiagnosticsTestV21(test.NoDBTestCase): + + def _setup_router(self): + self.router = compute.APIRouterV3(init_only=('servers', + 'os-server-diagnostics')) + + def _get_request(self): + return fakes.HTTPRequestV3.blank( + '/servers/%s/diagnostics' % UUID) def setUp(self): - super(ServerDiagnosticsTest, self).setUp() - self.flags(verbose=True, - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Server_diagnostics']) - - self.router = compute.APIRouter(init_only=('servers', 'diagnostics')) + super(ServerDiagnosticsTestV21, self).setUp() + self._setup_router() @mock.patch.object(compute_api.API, 'get_diagnostics', fake_get_diagnostics) @mock.patch.object(compute_api.API, 'get', fake_instance_get) def test_get_diagnostics(self): - req = fakes.HTTPRequest.blank( - '/fake/servers/%s/diagnostics' % UUID) + req = self._get_request() res = req.get_response(self.router) output = jsonutils.loads(res.body) self.assertEqual(output, {'data': 'Some diagnostic info'}) @@ -65,8 +67,7 @@ class ServerDiagnosticsTest(test.NoDBTestCase): @mock.patch.object(compute_api.API, 'get', side_effect=exception.InstanceNotFound(instance_id=UUID)) def test_get_diagnostics_with_non_existed_instance(self, mock_get): - req = fakes.HTTPRequest.blank( - '/fake/servers/%s/diagnostics' % UUID) + req = self._get_request() res = req.get_response(self.router) self.assertEqual(res.status_int, 404) @@ -75,8 +76,7 @@ class ServerDiagnosticsTest(test.NoDBTestCase): @mock.patch.object(compute_api.API, 'get', fake_instance_get) def test_get_diagnostics_raise_conflict_on_invalid_state(self, mock_get_diagnostics): - req = fakes.HTTPRequest.blank( - '/fake/servers/%s/diagnostics' % UUID) + req = self._get_request() res = req.get_response(self.router) self.assertEqual(409, res.status_int) @@ -85,12 +85,26 @@ class ServerDiagnosticsTest(test.NoDBTestCase): @mock.patch.object(compute_api.API, 'get', fake_instance_get) def test_get_diagnostics_raise_no_notimplementederror(self, mock_get_diagnostics): - req = fakes.HTTPRequest.blank( - '/fake/servers/%s/diagnostics' % UUID) + req = self._get_request() res = req.get_response(self.router) self.assertEqual(501, res.status_int) +class ServerDiagnosticsTestV2(ServerDiagnosticsTestV21): + + def _setup_router(self): + self.flags(verbose=True, + osapi_compute_extension=[ + 'nova.api.openstack.compute.contrib.select_extensions'], + osapi_compute_ext_list=['Server_diagnostics']) + + self.router = compute.APIRouter(init_only=('servers', 'diagnostics')) + + def _get_request(self): + return fakes.HTTPRequest.blank( + '/fake/servers/%s/diagnostics' % UUID) + + class TestServerDiagnosticsXMLSerializer(test.NoDBTestCase): namespace = wsgi.XMLNS_V11 diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_server_diagnostics.py b/nova/tests/api/openstack/compute/plugins/v3/test_server_diagnostics.py deleted file mode 100644 index 4e840419e4fb..000000000000 --- a/nova/tests/api/openstack/compute/plugins/v3/test_server_diagnostics.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright 2011 Eldar Nugaev -# All Rights Reserved. -# -# 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. - -import mock - -from nova.api.openstack import compute -from nova.compute import api as compute_api -from nova import exception -from nova.openstack.common import jsonutils -from nova import test -from nova.tests.api.openstack import fakes - - -UUID = 'abc' - - -def fake_get_instance_diagnostics(self, _context, instance_uuid): - return {'state': 'running', - 'driver': 'fake', - 'uptime': 7, - 'cpu_details': [{'time': 1024}], - 'nic_details': [{'rx_octets': 0, - 'rx_errors': 0, - 'rx_drop': 0, - 'rx_packets': 0, - 'tx_octets': 0, - 'tx_errors': 0, - 'tx_drop': 0, - 'tx_packets': 0}], - 'disk_details': [{'read_bytes': 0, - 'read_requests': 0, - 'write_bytes': 0, - 'write_requests': 0, - 'errors': 0}], - 'memory_details': {'maximum': 512, 'used': 256}, - 'version': '1.0'} - - -def fake_instance_get(self, _context, instance_uuid, want_objects=False): - if instance_uuid != UUID: - raise Exception("Invalid UUID") - return {'uuid': instance_uuid} - - -class ServerDiagnosticsTest(test.NoDBTestCase): - - def setUp(self): - super(ServerDiagnosticsTest, self).setUp() - self.router = compute.APIRouterV3(init_only=('servers', - 'os-server-diagnostics')) - - @mock.patch.object(compute_api.API, 'get_instance_diagnostics', - fake_get_instance_diagnostics) - @mock.patch.object(compute_api.API, 'get', fake_instance_get) - def test_get_diagnostics(self): - req = fakes.HTTPRequestV3.blank( - '/servers/%s/os-server-diagnostics' % UUID) - res = req.get_response(self.router) - output = jsonutils.loads(res.body) - expected = {'state': 'running', - 'driver': 'fake', - 'uptime': 7, - 'cpu_details': [{'time': 1024}], - 'nic_details': [{'rx_octets': 0, - 'rx_errors': 0, - 'rx_drop': 0, - 'rx_packets': 0, - 'tx_octets': 0, - 'tx_errors': 0, - 'tx_drop': 0, - 'tx_packets': 0}], - 'disk_details': [{'read_bytes': 0, - 'read_requests': 0, - 'write_bytes': 0, - 'write_requests': 0, - 'errors': 0}], - 'memory_details': {'maximum': 512, 'used': 256}, - 'version': '1.0'} - self.assertEqual(expected, output) - - @mock.patch.object(compute_api.API, 'get_instance_diagnostics', - fake_get_instance_diagnostics) - @mock.patch.object(compute_api.API, 'get', - side_effect=exception.InstanceNotFound(instance_id=UUID)) - def test_get_diagnostics_with_non_existed_instance(self, mock_get): - req = fakes.HTTPRequestV3.blank( - '/servers/%s/os-server-diagnostics' % UUID) - res = req.get_response(self.router) - self.assertEqual(res.status_int, 404) - - @mock.patch.object(compute_api.API, 'get_instance_diagnostics', - side_effect=exception.InstanceInvalidState('fake message')) - @mock.patch.object(compute_api.API, 'get', fake_instance_get) - def test_get_diagnostics_raise_conflict_on_invalid_state(self, - mock_get_diagnostics): - req = fakes.HTTPRequestV3.blank( - '/servers/%s/os-server-diagnostics' % UUID) - res = req.get_response(self.router) - self.assertEqual(409, res.status_int) - - @mock.patch.object(compute_api.API, 'get_instance_diagnostics', - side_effect=NotImplementedError) - @mock.patch.object(compute_api.API, 'get', fake_instance_get) - def test_get_diagnostics_raise_no_notimplementederror(self, - mock_get_diagnostics): - req = fakes.HTTPRequestV3.blank( - '/servers/%s/os-server-diagnostics' % UUID) - res = req.get_response(self.router) - self.assertEqual(501, res.status_int) diff --git a/nova/tests/integrated/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json.tpl index b2024bd6c034..1afedaee9c4b 100644 --- a/nova/tests/integrated/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json.tpl +++ b/nova/tests/integrated/v3/api_samples/os-server-diagnostics/server-diagnostics-get-resp.json.tpl @@ -1,40 +1,17 @@ { - "config_drive": 1, - "cpu_details": [ - { - "time": 17300000000 - } - ], - "disk_details": [ - { - "errors_count": 0, - "id": "fake-disk-id", - "read_requests": 112, - "read_bytes": 262144, - "write_requests": 488, - "write_bytes": 5778432 - } - ], - "driver": "fake", - "hypervisor_os": "fake-os", - "memory_details": { - "maximum": 524288, - "used": 0 - }, - "nic_details": [ - { - "mac_address": "01:23:45:67:89:ab", - "rx_drop": 0, - "rx_errors": 0, - "rx_octets": 2070139, - "rx_packets": 26701, - "tx_drop": 0, - "tx_errors": 0, - "tx_octets": 140208, - "tx_packets": 662 - } - ], - "state": "running", - "uptime": 46664, - "version": "1.0" + "cpu0_time": 17300000000, + "memory": 524288, + "vda_errors": -1, + "vda_read": 262144, + "vda_read_req": 112, + "vda_write": 5778432, + "vda_write_req": 488, + "vnet1_rx": 2070139, + "vnet1_rx_drop": 0, + "vnet1_rx_errors": 0, + "vnet1_rx_packets": 26701, + "vnet1_tx": 140208, + "vnet1_tx_drop": 0, + "vnet1_tx_errors": 0, + "vnet1_tx_packets": 662 } diff --git a/nova/tests/integrated/v3/test_server_diagnostics.py b/nova/tests/integrated/v3/test_server_diagnostics.py index 51c0488f1f29..9218066ad018 100644 --- a/nova/tests/integrated/v3/test_server_diagnostics.py +++ b/nova/tests/integrated/v3/test_server_diagnostics.py @@ -21,7 +21,7 @@ class ServerDiagnosticsSamplesJsonTest(test_servers.ServersSampleBase): def test_server_diagnostics_get(self): uuid = self._post_server() - response = self._do_get('servers/%s/os-server-diagnostics' % uuid) + response = self._do_get('servers/%s/diagnostics' % uuid) subs = self._get_regexes() self._verify_response('server-diagnostics-get-resp', subs, response, 200)