Add simple test for Neutron GET /

A fundamental operation for most OpenStack services is providing
information about what versions of an API are available to clients.
A version document can be retrieved by sending an unauthenticated
GET request to the root URL ("/") for most services, including
Neutron.  This capability is important for discovery in that clients
can learn how to interact with the cloud in question, and DefCore
considers it an important capability for interoperability and has
added similar capabilities to it's Guidelines for other services.[1][2]
As Neutron moves toward microversioning [3], being able to retrieve
a version document will be increasingly important for clients.
However, there are currently no tests for GET /, so DefCore cannot
make this a required Capability.

This patch adds a simple test for GET / that performs checks on
document structure and version information.

[1] http://git.openstack.org/cgit/openstack/defcore/tree/2016.01.json#n117
[2] http://git.openstack.org/cgit/openstack/defcore/tree/2016.01.json#n1379
[3] https://etherpad.openstack.org/p/newton-neutron-future-neutron-api

Closes-Bug: #1577410

Change-Id: I606b98cb6648bd4dd45f0dfdd634b1012aeae2ac
This commit is contained in:
Mark T. Voelker 2016-04-29 12:03:04 -05:00
parent 0a6dceb0bf
commit abd4cbd010
6 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,4 @@
---
features:
- Adds a network version client for querying
Neutron's API version discovery URL ("GET /").

View File

@ -80,6 +80,7 @@ class BaseNetworkTest(tempest.test.BaseTestCase):
cls.security_groups_client = cls.os.security_groups_client
cls.security_group_rules_client = (
cls.os.security_group_rules_client)
cls.network_versions_client = cls.os.network_versions_client
@classmethod
def resource_setup(cls):

View File

@ -0,0 +1,40 @@
# Copyright 2016 VMware, Inc.
#
# 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.
from tempest.api.network import base
from tempest import test
class NetworksApiDiscovery(base.BaseNetworkTest):
@test.attr(type='smoke')
@test.idempotent_id('cac8a836-c2e0-4304-b556-cd299c7281d1')
def test_api_version_resources(self):
"""Test that GET / returns expected resources.
The versions document returned by Neutron returns a few other
resources other than just available API versions: it also
states the status of each API version and provides links to
schema.
"""
result = self.network_versions_client.list_versions()
expected_versions = ('v2.0')
expected_resources = ('id', 'links', 'status')
received_list = result.values()
for item in received_list:
for version in item:
for resource in expected_resources:
self.assertIn(resource, version)
self.assertIn(version['id'], expected_versions)

View File

@ -101,6 +101,8 @@ from tempest.lib.services.network.security_groups_client import \
SecurityGroupsClient
from tempest.lib.services.network.subnetpools_client import SubnetpoolsClient
from tempest.lib.services.network.subnets_client import SubnetsClient
from tempest.lib.services.network.versions_client import \
NetworkVersionsClient
from tempest import manager
from tempest.services.baremetal.v1.json.baremetal_client import \
BaremetalClient
@ -281,6 +283,8 @@ class Manager(manager.Manager):
self.auth_provider, **params)
self.security_groups_client = SecurityGroupsClient(
self.auth_provider, **params)
self.network_versions_client = NetworkVersionsClient(
self.auth_provider, **params)
def _set_image_clients(self):
params = {

View File

@ -0,0 +1,45 @@
# Copyright 2016 VMware, Inc. 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 time
from oslo_serialization import jsonutils as json
from six.moves import urllib
from tempest.lib.services.network import base
class NetworkVersionsClient(base.BaseNetworkClient):
def list_versions(self):
"""Do a GET / to fetch available API version information."""
endpoint = self.base_url
url = urllib.parse.urlparse(endpoint)
version_url = '%s://%s/' % (url.scheme, url.netloc)
# Note: we do a raw_request here because we want to use
# an unversioned URL, not "v2/$project_id/".
# Since raw_request doesn't log anything, we do that too.
start = time.time()
self._log_request_start('GET', version_url)
response, body = self.raw_request(version_url, 'GET')
end = time.time()
self._log_request('GET', version_url, response,
secs=(end - start), resp_body=body)
self.response_checker('GET', response, body)
self.expected_success(200, response.status)
body = json.loads(body)
return body

View File

@ -0,0 +1,77 @@
# Copyright 2016 VMware, Inc. 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 copy
from tempest.lib.services.network.versions_client import NetworkVersionsClient
from tempest.tests.lib import fake_auth_provider
from tempest.tests.lib.services import base
class TestNetworkVersionsClient(base.BaseServiceTest):
FAKE_INIT_VERSION = {
"version": {
"id": "v2.0",
"links": [
{
"href": "http://openstack.example.com/v2.0/",
"rel": "self"
},
{
"href": "http://docs.openstack.org/",
"rel": "describedby",
"type": "text/html"
}
],
"status": "CURRENT",
"updated": "2013-07-23T11:33:21Z",
"version": "2.0",
"min_version": "2.0"
}
}
FAKE_VERSIONS_INFO = {
"versions": [FAKE_INIT_VERSION["version"]]
}
FAKE_VERSION_INFO = copy.deepcopy(FAKE_INIT_VERSION)
FAKE_VERSION_INFO["version"]["media-types"] = [
{
"base": "application/json",
"type": "application/vnd.openstack.network+json;version=2.0"
}
]
def setUp(self):
super(TestNetworkVersionsClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
self.versions_client = (
NetworkVersionsClient
(fake_auth, 'compute', 'regionOne'))
def _test_versions_client(self, bytes_body=False):
self.check_service_client_function(
self.versions_client.list_versions,
'tempest.lib.common.rest_client.RestClient.raw_request',
self.FAKE_VERSIONS_INFO,
bytes_body,
200)
def test_list_versions_client_with_str_body(self):
self._test_versions_client()
def test_list_versions_client_with_bytes_body(self):
self._test_versions_client(bytes_body=True)