Merge "Make `boot_runcommand_delete' accept command-dict"

This commit is contained in:
Jenkins 2015-07-14 02:26:00 +00:00 committed by Gerrit Code Review
commit 557f1ef21e
6 changed files with 128 additions and 27 deletions

View File

@ -599,8 +599,20 @@
name: {{image_name}}
floating_network: "public"
use_floatingip: true
script: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
command:
script_inline: |
time_seconds(){ (time -p $1 ) 2>&1 |awk '/real/{print $2}'; }
file=/tmp/test.img
c=100 #100M
write_seq=$(time_seconds "dd if=/dev/zero of=$file bs=1M count=$c")
read_seq=$(time_seconds "dd if=$file of=/dev/null bs=1M count=$c")
[ -f $file ] && rm $file
echo "{
\"write_seq\": $write_seq,
\"read_seq\": $read_seq
}"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"
@ -623,8 +635,9 @@
volume_args:
size: 2
use_floatingip: true
script: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
command:
script_file: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"
@ -645,8 +658,9 @@
image:
name: {{image_name}}
use_floatingip: false
script: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
command:
script_file: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"

View File

@ -295,8 +295,9 @@
name: "TestVM|cirros.*uec"
floating_network: "net04_ext"
use_floatingip: true
script: "/home/rally/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
command:
script_file: "/home/rally/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"

View File

@ -459,8 +459,9 @@
name: "m1.tiny"
image:
name: {{image_name}}
script: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
command:
script_file: "/home/jenkins/.rally/extra/instance_dd_test.sh"
interpreter: "/bin/sh"
username: "cirros"
runner:
type: "constant"

View File

@ -47,7 +47,8 @@ class VMScenario(base.Scenario):
:param ssh: A SSHClient instance.
:param command: Dictionary specifying command to execute.
See `validation.valid_command' docstring for details.
See `rally info find VMTasks.boot_runcommand_delete' parameter
`command' docstring for explanation.
:returns: tuple (exit_status, stdout, stderr)
"""
@ -150,7 +151,8 @@ class VMScenario(base.Scenario):
:param username: str. ssh username for server
:param password: Password for SSH authentication
:param command: Dictionary specifying command to execute.
See `valiation.valid_command' docstring for explanation.
See `rally info find VMTasks.boot_runcommand_delete' parameter
`command' docstring for explanation.
:param pkey: key for SSH authentication
:returns: tuple (exit_status, stdout, stderr)

View File

@ -15,6 +15,7 @@
import json
from rally.common import utils
from rally import consts
from rally import exceptions
from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils
@ -35,7 +36,10 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
@types.set(image=types.ImageResourceType,
flavor=types.FlavorResourceType)
@validation.image_valid_on_flavor("flavor", "image")
@validation.file_exists("script")
@utils.log_deprecated_args("Use `command' argument instead", "0.0.5",
("script", "interpreter"), once=True)
@validation.file_exists("script", required=False)
@validation.valid_command("command", required=False)
@validation.number("port", minval=1, maxval=65535, nullable=True,
integer_only=True)
@validation.external_network_exists("floating_network")
@ -44,8 +48,11 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
@base.scenario(context={"cleanup": ["nova", "cinder"],
"keypair": {}, "allow_ssh": {}})
def boot_runcommand_delete(self, image, flavor,
script, interpreter, username,
username,
password=None,
script=None,
interpreter=None,
command=None,
volume_args=None,
floating_network=None,
port=22,
@ -58,11 +65,52 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
:param image: glance image name to use for the vm
:param flavor: VM flavor name
:param script: script to run on server, must output JSON mapping
metric names to values (see the sample script below)
:param interpreter: server's interpreter to run the script
:param username: ssh username on server, str
:param password: Password on SSH authentication
:param script: DEPRECATED. Use `command' instead. Script to run on
server, must output JSON mapping metric names to values (see the
sample script below)
:param interpreter: DEPRECATED. Use `command' instead. server's
interpreter to run the script
:param command: Command-specifying dictionary that either specifies
remote command path via `remote_path', an inline script via
`script_inline' or a local script file path using `script_file'.
The `script_file' is checked to be accessible by the `file_exists'
validator.
The `script_inline' and `script_file' both require an `interpreter'
value to specify the interpreter script should be run with.
Note that any of `interpreter' and `remote_path' can be an array
prefixed with environment variables and suffixed with args for
the `interpreter' command.
Examples::
# Run a `local_script.pl' file sending it to a remote
# Perl interpreter
command = {
"script_file": "local_script.pl",
"interpreter": "/usr/bin/perl"
}
# Run an inline script sending it to a remote interpreter
command = {
"script_inline": "echo 'Hello, World!'",
"interpreter": "/bin/sh"
}
# Run a remote command
command = {
"remote_path": "/bin/false"
}
# Run an inline script sending it to a remote interpreter
command = {
"script_inline": "echo \"Hello, ${NAME:-World}\"",
"interpreter": ["NAME=Earth", "/bin/sh"]
}
:param volume_args: volume args for booting server from volume
:param floating_network: external network name, for floating ip
:param port: ssh port for SSH connection
@ -74,6 +122,9 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
errors: str, raw data from the script's stderr stream
"""
if command is None and script and interpreter:
command = {"script_file": script, "interpreter": interpreter}
if volume_args:
volume = self._create_volume(volume_args["size"], imageRef=None)
kwargs["block_device_mapping"] = {"vdrally": "%s:::1" % volume.id}
@ -85,21 +136,20 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario,
**kwargs)
try:
code, out, err = self._run_command(
fip["ip"], port, username, password,
command={"script_file": script, "interpreter": interpreter})
fip["ip"], port, username, password, command=command)
if code:
raise exceptions.ScriptError(
"Error running script %(script)s. "
"Error running command %(command)s. "
"Error %(code)s: %(error)s" % {
"script": script, "code": code, "error": err})
"command": command, "code": code, "error": err})
try:
data = json.loads(out)
except ValueError as e:
raise exceptions.ScriptError(
"Script %(script)s has not output valid JSON: %(error)s. "
"Output: %(output)s" % {
"script": script, "error": str(e), "output": out})
"Command %(command)s has not output valid JSON: %(error)s."
" Output: %(output)s" % {
"command": command, "error": str(e), "output": out})
finally:
self._delete_server_with_fip(server, fip,
force_delete=force_delete)

View File

@ -15,6 +15,8 @@
import mock
from rally.common import log
from rally.common import utils
from rally import exceptions
from rally.plugins.openstack.scenarios.vm import vmtasks
from tests.unit import test
@ -36,9 +38,41 @@ class VMTasksTestCase(test.TestCase):
return_value=(0, "\"foo_out\"", "foo_err"))
def test_boot_runcommand_delete(self):
with log.LogCatcher(utils.LOG) as catcher:
self.scenario.boot_runcommand_delete(
"foo_image", "foo_flavor",
script="foo_script", interpreter="foo_interpreter",
username="foo_username",
password="foo_password",
use_floating_ip="use_fip",
floating_network="ext_network",
force_delete="foo_force",
volume_args={"size": 16},
foo_arg="foo_value")
catcher.assertInLogs(
"Use `command' argument instead (args `script', `interpreter' "
"deprecated in Rally v0.0.5)")
self.scenario._create_volume.assert_called_once_with(
16, imageRef=None)
self.scenario._boot_server_with_fip.assert_called_once_with(
"foo_image", "foo_flavor", use_floating_ip="use_fip",
floating_network="ext_network", key_name="keypair_name",
block_device_mapping={"vdrally": "foo_volume:::1"},
foo_arg="foo_value")
self.scenario._run_command.assert_called_once_with(
"foo_ip", 22, "foo_username", "foo_password",
command={"script_file": "foo_script",
"interpreter": "foo_interpreter"})
self.scenario._delete_server_with_fip.assert_called_once_with(
"foo_server", self.ip, force_delete="foo_force")
def test_boot_runcommand_delete_command(self):
self.scenario.boot_runcommand_delete(
"foo_image", "foo_flavor",
script="foo_script", interpreter="foo_interpreter",
command={"remote_path": "foo"},
username="foo_username",
password="foo_password",
use_floating_ip="use_fip",
@ -57,8 +91,7 @@ class VMTasksTestCase(test.TestCase):
self.scenario._run_command.assert_called_once_with(
"foo_ip", 22, "foo_username", "foo_password",
command={"script_file": "foo_script",
"interpreter": "foo_interpreter"})
command={"remote_path": "foo"})
self.scenario._delete_server_with_fip.assert_called_once_with(
"foo_server", self.ip, force_delete="foo_force")