Commit 954a08e5 authored by Kiall Mac Innes's avatar Kiall Mac Innes

Remove contrib/tempest, as they have moved to the tempest plugin

Change-Id: Id553e2aff03617ebe8021894889ccf5a50c2e5bd
Depends-On: Idc31c00c95fde96087f4f222ae9c17e554e6b1fc
parent 0fa16852
Designate API Testing using Tempest Framework.
==============================================
This is a set of Designate API tests written for Tempest Framework
to be run against a live OpenStack cluster with Designate service
enabled.
Configuration
-------------
Detailed configuration of Designate tests and configuration files is
the scope of this document.
Added all the required parameters in etc/tempest.conf.sample
to enable Designate service.
The sample config file is auto generated using the script
(based on parameters added in config.py):
tools/generate_sample.sh
To run Tempest, you first need to create a configuration file that will
tell Tempest where to find the designate service.
The easiest way to create a configuration file is to copy the sample
(tempest.conf.sample) one in the etc/ directory.
$> cd $TEMPEST_ROOT_DIR
$> cp etc/tempest.conf.sample etc/tempest.conf
After that, open up the etc/tempest.conf file and edit the configuration
variables to match valid data in your environment. This includes your
Keystone endpoint, a valid user and credentials, and reference
data to be used in testing.
Tests and Clients for Designate feature
---------------------------------------
1> Added tests for Domains, Records, Servers of Designate API
under dns_tests folder.
2> Added respective supporting functions for Json Interface
under dns_clients folder.
3> Modified respective clients.py and config.py files with respect
to Designate service and should be placed under'tempest' folder.
4> Implemented Schema validation for all the Designate operations as per
current Tempest framework under dns_schema.
Steps to execute Designate API tests.
-------------------------------------
In order to run Designate API tests against Tempest Suite, all the above
test scripts and client files has to be placed in paths as mentioned below.
1> Clone Tempest
git clone https://github.com/openstack/tempest.git
2> Add the following files
$> cp tempest.conf.sample $TEMPEST_ROOT_DIR/tempest/etc
$> cp config.py TEMPEST_ROOT_DIR/tempest
$> cp clients.py TEMPEST_ROOT_DIR/tempest
$> cp -r dns_clients TEMPEST_ROOT_DIR/tempest/services/dns
$> cp -r dns_schema TEMPEST_ROOT_DIR/tempest/api_schema/dns
$> cp -r dns_tests TEMPEST_ROOT_DIR/tempest/api/dns
After setting up your configuration files, you can execute the set of
designate tests by using testr.
$> testr run --parallel
To run one single test
$> testr run --parallel tempest.api.dns.test_domains.DnsDomainsTest.test_list_domains
This diff is collapsed.
This diff is collapsed.
# Copyright 2014 Hewlett-Packard Development Company, L.P
# 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 json
from tempest.api_schema.dns import domains as schema
from tempest.common import rest_client
from tempest import config
CONF = config.CONF
class DomainsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(DomainsClientJSON, self).__init__(auth_provider)
self.service = CONF.dns.catalog_type
def list_domains(self, params=None):
"""List all domains."""
resp, body = self.get("v1/domains")
body = json.loads(body)
self.validate_response(schema.list_domains, resp, body)
return resp, body['domains']
def get_domain(self, domain_id):
"""Get the details of a domain."""
resp, body = self.get("v1/domains/%s" % str(domain_id))
body = json.loads(body)
self.validate_response(schema.get_zone, resp, body)
return resp, body
def delete_domain(self, domain_id):
"""Delete the given domain."""
resp, body = self.delete("v1/domains/%s" % str(domain_id))
self.validate_response(schema.delete_zone, resp, body)
return resp, body
def create_domain(self, name, email, **kwargs):
"""Creates a domain."""
post_body = {
"name": name,
"email": email
}
for option in ['ttl', 'description']:
post_param = option
value = kwargs.get(option)
if value is not None:
post_body[post_param] = value
resp, body = self.post('v1/domains', json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.create_zone, resp, body)
return resp, body
def update_domain(self, domain_id, **kwargs):
"""Updates a domain."""
post_body = {}
for option in ['email', 'name', 'ttl', 'description']:
post_param = option
value = kwargs.get(option)
if value is not None:
post_body[post_param] = value
resp, body = self.put('v1/domains/%s' % domain_id,
json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.update_zone, resp, body)
return resp, body
# Copyright 2014 Hewlett-Packard Development Company, L.P
# 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 json
from tempest.api_schema.dns import records as schema
from tempest.common import rest_client
from tempest import config
CONF = config.CONF
class RecordsClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(RecordsClientJSON, self).__init__(auth_provider)
self.service = CONF.dns.catalog_type
def list_records(self, domain_id):
"""List all records."""
resp, body = self.get("v1/domains/%s/records" % (domain_id))
body = json.loads(body)
self.validate_response(schema.list_records, resp, body)
return resp, body['records']
def get_record(self, domain_id, record_id):
"""Get the details of a record."""
resp, body = self.get("v1/domains/%s/records/%s" % (domain_id,
record_id))
body = json.loads(body)
self.validate_response(schema.get_record, resp, body)
return resp, body
def delete_record(self, domain_id, record_id):
"""Delete the given record."""
resp, body = self.delete("v1/domains/%s/records/%s" % (domain_id,
record_id))
self.validate_response(schema.delete_record, resp, body)
return resp, body
def create_record(self, domain_id, name, type, data, **kwargs):
"""Creates a record."""
post_body = {
"name": name,
"type": type,
"data": data
}
for option in ['ttl', 'priority', 'description']:
post_param = option
value = kwargs.get(option)
if value is not None:
post_body[post_param] = value
uri = "v1/domains/%s/records" % (domain_id)
resp, body = self.post(uri, json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.create_record, resp, body)
return resp, body
def update_record(self, domain_id, record_id, **kwargs):
"""Updates a record."""
post_body = {}
for option in ['name', 'type', 'data', 'ttl', 'priority',
'description']:
post_param = option
value = kwargs.get(option)
if value is not None:
post_body[post_param] = value
resp, body = self.put('v1/domains/%s/records/%s' % (domain_id,
record_id), json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.update_record, resp, body)
return resp, body
# Copyright 2014 Hewlett-Packard Development Company, L.P
# 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 json
from tempest.api_schema.dns import servers as schema
from tempest.common import rest_client
from tempest import config
CONF = config.CONF
class ServersClientJSON(rest_client.RestClient):
def __init__(self, auth_provider):
super(ServersClientJSON, self).__init__(auth_provider)
self.service = CONF.dns.catalog_type
def list_servers(self, params=None):
"""List all servers."""
resp, body = self.get("v1/servers")
body = json.loads(body)
self.validate_response(schema.list_servers, resp, body)
return resp, body['servers']
def get_server(self, server_id):
"""Get the details of a server."""
resp, body = self.get("v1/servers/%s" % str(server_id))
body = json.loads(body)
self.validate_response(schema.get_server, resp, body)
return resp, body
def delete_server(self, server_id):
"""Delete the given server."""
resp, body = self.delete("v1/servers/%s" % str(server_id))
self.validate_response(schema.delete_server, resp, body)
return resp, body
def create_server(self, name, **kwargs):
"""Creates a server."""
post_body = {
"name": name,
}
for option in ['max-width', 'variable', 'prefix']:
value = kwargs.get(option)
post_param = option
if value is not None:
post_body[post_param] = value
resp, body = self.post('v1/servers', json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.create_server, resp, body)
return resp, body
def update_server(self, server_id, **kwargs):
"""Updates a server."""
name = kwargs.get('name')
post_body = {
'name': name
}
resp, body = self.put('v1/servers/%s' % server_id,
json.dumps(post_body))
body = json.loads(body)
self.validate_response(schema.update_server, resp, body)
return resp, body
# Copyright 2014 Hewlett-Packard Development Company, L.P
#
# 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.
list_domains = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"domains": {
"type": "array",
"items": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"description": {
"anyOf": [{'type': 'string'}, {"type": "null"}]},
"email": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"serial": {"type": "number"},
"ttl": {"type": "number"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
'required': ['id', 'name', 'email', 'ttl']
}
}
},
'required': ['domains']
}
}
create_domain = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"domain": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"description": {
"anyOf": [{'type': 'string'}, {"type": "null"}]},
"email": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"serial": {"type": "number"},
"ttl": {"type": "number"},
"updated_at": {"type": "null"}
},
"required": ['id', 'name', 'email', 'ttl']
}
}
},
"required": ['domain']
}
update_domain = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"domain": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"description": {
"anyOf": [{'type': 'string'}, {"type": "null"}]},
"email": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"serial": {"type": "number"},
"ttl": {"type": "number"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
"required": ['id', 'name', 'email', 'ttl']
}
}
},
"required": ['domain']
}
get_domain = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"domain": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"description": {
"anyOf": [{'type': 'string'}, {"type": "null"}]},
"email": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"serial": {"type": "number"},
"ttl": {"type": "number"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
"required": ['id', 'name', 'email', 'ttl']
}
}
},
"required": ['domain']
}
delete_domain = {
'status_code': [200],
}
# Copyright 2014 Hewlett-Packard Development Company, L.P
#
# 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.
access_ip_v4 = {
'type': 'string',
'anyOf': [{'format': 'ipv4'}, {'enum': ['']}]
}
access_ip_v6 = {
'type': 'string',
'anyOf': [{'format': 'ipv6'}, {'enum': ['']}]
}
# Copyright 2014 Hewlett-Packard Development Company, L.P
#
# 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_schema.dns import parameter_types
list_records = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"records": {
"type": "array",
"items": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"data": {
"anyOf": [parameter_types.access_ip_v4,
parameter_types.access_ip_v6]},
"description": {"type": "null"},
"domain_id": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"priority": {"type": "null"},
"ttl": {"type": "null"},
"type": {"type": "string"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
'required': ['id', 'name', 'type', 'data']
}
}
},
'required': ['records']
}
}
create_record = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"record": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"data": {
"anyOf": [parameter_types.access_ip_v4,
parameter_types.access_ip_v6]},
"description": {"type": "null"},
"domain_id": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"priority": {"type": "null"},
"ttl": {"type": "null"},
"type": {"type": "string"},
"updated_at": {"type": "null"}
},
"required": ['id', 'name', 'type', 'domain_id']
}
}
},
"required": ['record']
}
update_record = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"record": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"data": {
"anyOf": [parameter_types.access_ip_v4,
parameter_types.access_ip_v6]},
"description": {"type": "null"},
"domain_id": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"priority": {"type": "null"},
"ttl": {"type": "null"},
"type": {"type": "string"},
"updated_at": {"type": "string"}
},
"required": ['id', 'name', 'type', 'domain_id']
}
}
},
"required": ['record']
}
get_record = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"record": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"data": {
"anyOf": [parameter_types.access_ip_v4,
parameter_types.access_ip_v6]},
"description": {"type": "null"},
"domain_id": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"priority": {"type": "null"},
"ttl": {"type": "null"},
"type": {"type": "string"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
"required": ['id', 'name', 'type', 'domain_id']
}
}
},
"required": ['record']
}
delete_record = {
'status_code': [200],
}
# Copyright 2014 Hewlett-Packard Development Company, L.P
#
# 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.
list_servers = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"servers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
'required': ['id', 'name']
}
}
},
'required': ['servers']
}
}
create_server = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"server": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"updated_at": {"type": "null"}
},
"required": ['id', 'name']
}
}
},
"required": ['server']
}
update_server = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"server": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"updated_at": {"type": "string"}
},
"required": ['id', 'name']
}
}
},
"required": ['server']
}
get_server = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"server": {
"type": "object",
"properties": {
"created_at": {"type": "string"},
"id": {"type": "string"},
"name": {"type": "string"},
"updated_at": {
"anyOf": [{'type': 'string'}, {"type": "null"}]}
},
"required": ['id', 'name']
}
}
},
"required": ['server']
}
delete_server = {
'status_code': [200],
}
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# 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
#