Merge "Make `boot_runcommand_delete' accept command-dict"
This commit is contained in:
commit
557f1ef21e
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user