Merge "Fix two typos on tempest documentation"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 27d65e6..724bff4 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -72,7 +72,7 @@
#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
# List of logger=LEVEL pairs. (list value)
-#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN
+#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN
# Enables or disables publication of error events. (boolean value)
#publish_errors = false
diff --git a/setup.cfg b/setup.cfg
index 36b2270..f28c481 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -32,7 +32,8 @@
tempest-cleanup = tempest.cmd.cleanup:main
tempest-account-generator = tempest.cmd.account_generator:main
tempest = tempest.cmd.main:main
-
+tempest.cm =
+ init = tempest.cmd.init:TempestInit
oslo.config.opts =
tempest.config = tempest.config:list_opts
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 396327b..9e27f33 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -98,7 +98,7 @@
def _test_create_interface_by_network_id(self, server, ifs):
network_id = ifs[0]['net_id']
iface = self.client.create_interface(server['id'],
- network_id=network_id)
+ net_id=network_id)
iface = self.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface, network_id=network_id)
@@ -179,7 +179,7 @@
self.assertTrue(interface_count > 0)
self._check_interface(ifs[0])
network_id = ifs[0]['net_id']
- self.client.add_fixed_ip(server['id'], network_id)
+ self.client.add_fixed_ip(server['id'], networkId=network_id)
# Remove the fixed IP from server.
server_detail = self.os.servers_client.show_server(
server['id'])
@@ -192,4 +192,4 @@
break
if fixed_ip is not None:
break
- self.client.remove_fixed_ip(server['id'], fixed_ip)
+ self.client.remove_fixed_ip(server['id'], address=fixed_ip)
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
new file mode 100644
index 0000000..c13fbe5
--- /dev/null
+++ b/tempest/cmd/init.py
@@ -0,0 +1,99 @@
+# Copyright 2015 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.
+
+import os
+import shutil
+import subprocess
+
+from cliff import command
+from oslo_log import log as logging
+from six import moves
+
+LOG = logging.getLogger(__name__)
+
+TESTR_CONF = """[DEFAULT]
+test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \\
+ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \\
+ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \\
+ ${PYTHON:-python} -m subunit.run discover -t %s %s $LISTOPT $IDOPTION
+test_id_option=--load-list $IDFILE
+test_list_option=--list
+group_regex=([^\.]*\.)*
+"""
+
+
+class TempestInit(command.Command):
+ """Setup a local working environment for running tempest"""
+
+ def get_parser(self, prog_name):
+ parser = super(TempestInit, self).get_parser(prog_name)
+ parser.add_argument('dir', nargs='?', default=os.getcwd())
+ parser.add_argument('--config-dir', '-c', default='/etc/tempest')
+ return parser
+
+ def generate_testr_conf(self, local_path):
+ testr_conf_path = os.path.join(local_path, '.testr.conf')
+ top_level_path = os.path.dirname(os.path.dirname(__file__))
+ discover_path = os.path.join(top_level_path, 'test_discover')
+ testr_conf = TESTR_CONF % (top_level_path, discover_path)
+ with open(testr_conf_path, 'w+') as testr_conf_file:
+ testr_conf_file.write(testr_conf)
+
+ def update_local_conf(self, conf_path, lock_dir, log_dir):
+ config_parse = moves.configparser.SafeConfigParser()
+ config_parse.optionxform = str
+ with open(conf_path, 'w+') as conf_file:
+ config_parse.readfp(conf_file)
+ # Set local lock_dir in tempest conf
+ if not config_parse.has_section('oslo_concurrency'):
+ config_parse.add_section('oslo_concurrency')
+ config_parse.set('oslo_concurrency', 'lock_path', lock_dir)
+ # Set local log_dir in tempest conf
+ config_parse.set('DEFAULT', 'log_dir', log_dir)
+ # Set default log filename to tempest.log
+ config_parse.set('DEFAULT', 'log_file', 'tempest.log')
+
+ def copy_config(self, etc_dir, config_dir):
+ shutil.copytree(config_dir, etc_dir)
+
+ def create_working_dir(self, local_dir, config_dir):
+ # Create local dir if missing
+ if not os.path.isdir(local_dir):
+ LOG.debug('Creating local working dir: %s' % local_dir)
+ os.mkdir(local_dir)
+ lock_dir = os.path.join(local_dir, 'tempest_lock')
+ etc_dir = os.path.join(local_dir, 'etc')
+ config_path = os.path.join(etc_dir, 'tempest.conf')
+ log_dir = os.path.join(local_dir, 'logs')
+ testr_dir = os.path.join(local_dir, '.testrepository')
+ # Create lock dir
+ if not os.path.isdir(lock_dir):
+ LOG.debug('Creating lock dir: %s' % lock_dir)
+ os.mkdir(lock_dir)
+ # Create log dir
+ if not os.path.isdir(log_dir):
+ LOG.debug('Creating log dir: %s' % log_dir)
+ os.mkdir(log_dir)
+ # Create and copy local etc dir
+ self.copy_config(etc_dir, config_dir)
+ # Update local confs to reflect local paths
+ self.update_local_conf(config_path, lock_dir, log_dir)
+ # Generate a testr conf file
+ self.generate_testr_conf(local_dir)
+ # setup local testr working dir
+ if not os.path.isdir(testr_dir):
+ subprocess.call(['testr', 'init'], cwd=local_dir)
+
+ def take_action(self, parsed_args):
+ self.create_working_dir(parsed_args.dir, parsed_args.config_dir)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index ff58eea..e676063 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -244,7 +244,7 @@
old_port = port_list[0]
interface = self.interface_client.create_interface(
server_id=server['id'],
- network_id=self.new_net.id)
+ net_id=self.new_net.id)
self.addCleanup(self.network_client.wait_for_resource_deletion,
'port',
interface['port_id'])
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index e8b2b64..c437c08 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -29,16 +29,8 @@
return service_client.ResponseBodyList(resp,
body['interfaceAttachments'])
- def create_interface(self, server_id, port_id=None, network_id=None,
- fixed_ip=None):
- post_body = dict(interfaceAttachment=dict())
- if port_id:
- post_body['interfaceAttachment']['port_id'] = port_id
- if network_id:
- post_body['interfaceAttachment']['net_id'] = network_id
- if fixed_ip:
- fip = dict(ip_address=fixed_ip)
- post_body['interfaceAttachment']['fixed_ips'] = [fip]
+ def create_interface(self, server_id, **kwargs):
+ post_body = {'interfaceAttachment': kwargs}
post_body = json.dumps(post_body)
resp, body = self.post('servers/%s/os-interface' % server_id,
body=post_body)
@@ -59,26 +51,18 @@
self.validate_response(schema.delete_interface, resp, body)
return service_client.ResponseBody(resp, body)
- def add_fixed_ip(self, server_id, network_id):
+ def add_fixed_ip(self, server_id, **kwargs):
"""Add a fixed IP to input server instance."""
- post_body = json.dumps({
- 'addFixedIp': {
- 'networkId': network_id
- }
- })
+ post_body = json.dumps({'addFixedIp': kwargs})
resp, body = self.post('servers/%s/action' % server_id,
post_body)
self.validate_response(servers_schema.server_actions_common_schema,
resp, body)
return service_client.ResponseBody(resp, body)
- def remove_fixed_ip(self, server_id, ip_address):
+ def remove_fixed_ip(self, server_id, **kwargs):
"""Remove input fixed IP from input server instance."""
- post_body = json.dumps({
- 'removeFixedIp': {
- 'address': ip_address
- }
- })
+ post_body = json.dumps({'removeFixedIp': kwargs})
resp, body = self.post('servers/%s/action' % server_id,
post_body)
self.validate_response(servers_schema.server_actions_common_schema,
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 4ea47ed..88d0567 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -41,59 +41,11 @@
self.validate_response(schema.get_quota_set, resp, body)
return service_client.ResponseBody(resp, body['quota_set'])
- def update_quota_set(self, tenant_id, user_id=None,
- force=None, injected_file_content_bytes=None,
- metadata_items=None, ram=None, floating_ips=None,
- fixed_ips=None, key_pairs=None, instances=None,
- security_group_rules=None, injected_files=None,
- cores=None, injected_file_path_bytes=None,
- security_groups=None):
+ def update_quota_set(self, tenant_id, user_id=None, **kwargs):
"""
Updates the tenant's quota limits for one or more resources
"""
- post_body = {}
-
- if force is not None:
- post_body['force'] = force
-
- if injected_file_content_bytes is not None:
- post_body['injected_file_content_bytes'] = \
- injected_file_content_bytes
-
- if metadata_items is not None:
- post_body['metadata_items'] = metadata_items
-
- if ram is not None:
- post_body['ram'] = ram
-
- if floating_ips is not None:
- post_body['floating_ips'] = floating_ips
-
- if fixed_ips is not None:
- post_body['fixed_ips'] = fixed_ips
-
- if key_pairs is not None:
- post_body['key_pairs'] = key_pairs
-
- if instances is not None:
- post_body['instances'] = instances
-
- if security_group_rules is not None:
- post_body['security_group_rules'] = security_group_rules
-
- if injected_files is not None:
- post_body['injected_files'] = injected_files
-
- if cores is not None:
- post_body['cores'] = cores
-
- if injected_file_path_bytes is not None:
- post_body['injected_file_path_bytes'] = injected_file_path_bytes
-
- if security_groups is not None:
- post_body['security_groups'] = security_groups
-
- post_body = json.dumps({'quota_set': post_body})
+ post_body = json.dumps({'quota_set': kwargs})
if user_id:
resp, body = self.put('os-quota-sets/%s?user_id=%s' %
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
new file mode 100644
index 0000000..6b5af7e
--- /dev/null
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -0,0 +1,66 @@
+# Copyright 2015 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.
+
+import os
+
+import fixtures
+
+from tempest.cmd import init
+from tempest.tests import base
+
+
+class TestTempestInit(base.TestCase):
+
+ def test_generate_testr_conf(self):
+ # Create fake conf dir
+ conf_dir = self.useFixture(fixtures.TempDir())
+
+ init_cmd = init.TempestInit(None, None)
+ init_cmd.generate_testr_conf(conf_dir.path)
+
+ # Generate expected file contents
+ top_level_path = os.path.dirname(os.path.dirname(init.__file__))
+ discover_path = os.path.join(top_level_path, 'test_discover')
+ testr_conf_file = init.TESTR_CONF % (top_level_path, discover_path)
+
+ conf_path = conf_dir.join('.testr.conf')
+ conf_file = open(conf_path, 'r')
+ self.addCleanup(conf_file.close)
+ self.assertEqual(conf_file.read(), testr_conf_file)
+
+ def test_create_working_dir(self):
+ fake_local_dir = self.useFixture(fixtures.TempDir())
+ fake_local_conf_dir = self.useFixture(fixtures.TempDir())
+ # Create a fake conf file
+ fake_file = fake_local_conf_dir.join('conf_file.conf')
+ open(fake_file, 'w').close()
+ init_cmd = init.TempestInit(None, None)
+ init_cmd.create_working_dir(fake_local_dir.path,
+ fake_local_conf_dir.path)
+ # Assert directories are created
+ lock_path = os.path.join(fake_local_dir.path, 'tempest_lock')
+ etc_dir = os.path.join(fake_local_dir.path, 'etc')
+ log_dir = os.path.join(fake_local_dir.path, 'logs')
+ testr_dir = os.path.join(fake_local_dir.path, '.testrepository')
+ self.assertTrue(os.path.isdir(lock_path))
+ self.assertTrue(os.path.isdir(etc_dir))
+ self.assertTrue(os.path.isdir(log_dir))
+ self.assertTrue(os.path.isdir(testr_dir))
+ # Assert file creation
+ fake_file_moved = os.path.join(etc_dir, 'conf_file.conf')
+ local_conf_file = os.path.join(etc_dir, 'tempest.conf')
+ local_testr_conf = os.path.join(fake_local_dir.path, '.testr.conf')
+ self.assertTrue(os.path.isfile(fake_file_moved))
+ self.assertTrue(os.path.isfile(local_conf_file))
+ self.assertTrue(os.path.isfile(local_testr_conf))
diff --git a/tox.ini b/tox.ini
index cf7013d..389fee2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -40,6 +40,16 @@
find . -type f -name "*.pyc" -delete
bash tools/pretty_tox.sh '{posargs}'
+[testenv:all-plugin]
+sitepackages = True
+# 'all' includes slow tests
+setenv = {[tempestenv]setenv}
+ OS_TEST_TIMEOUT=1200
+deps = {[tempestenv]deps}
+commands =
+ find . -type f -name "*.pyc" -delete
+ bash tools/pretty_tox.sh '{posargs}'
+
[testenv:full]
sitepackages = {[tempestenv]sitepackages}
setenv = {[tempestenv]setenv}