Added script support to shell-executer

Added ability to run scripts to shell-executer.
Fixed unit tests for the shell-executer.

Change-Id: I092b083417082b54c304ccf5322d1357d7582d4e
This commit is contained in:
Sergey Belous 2015-03-19 19:35:40 +03:00
parent 44f30011b7
commit 1af4738ff3
8 changed files with 96 additions and 29 deletions

View File

@ -13,3 +13,10 @@ execution:
title: List all files
class: shell
method: ls -al
-
title: Run sample script
class: shell
script: |
#!/bin/bash
echo "hello"
echo "world"

View File

@ -13,7 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import shlex
import tempfile
import time
from oslo_concurrency import processutils
@ -55,6 +57,27 @@ def send_reply(socket, agent_id, result):
return res
def run_command(command):
command_stdout, command_stderr = None, None
if command['type'] == 'program':
command_stdout, command_stderr = processutils.execute(
*shlex.split(command['data']), check_exit_code=False)
elif command['type'] == 'script':
fd = tempfile.mkstemp()
os.write(fd[0], command['data'])
os.close(fd[0])
LOG.debug('stored script into %s', fd[1])
command_stdout, command_stderr = processutils.execute(
*shlex.split('bash %s' % fd[1]), check_exit_code=False)
else:
command_stderr = 'Unknown command type : %s' % command['type']
return dict(stdout=command_stdout, stderr=command_stderr)
def main():
utils.init_config_and_logging(config.COMMON_OPTS + config.AGENT_OPTS)
@ -81,13 +104,9 @@ def main():
time.sleep(start_at - now)
# do something useful
command_stdout, command_stderr = processutils.execute(
*shlex.split(command), check_exit_code=False)
send_reply(socket, agent_id, {
'stdout': command_stdout,
'stderr': command_stderr,
})
result = run_command(command)
send_reply(socket, agent_id, result)
elif task['operation'] == 'configure':
if 'polling_interval' in task:
polling_interval = task.get('polling_interval')

View File

@ -13,18 +13,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from shaker.engine.executors import base
from shaker.engine.executors import iperf
from shaker.engine.executors import netperf
from shaker.engine.executors import shell
EXECUTORS = {
'shell': base.ShellExecutor,
'shell': shell.ShellExecutor,
'netperf': netperf.NetperfExecutor,
'iperf': iperf.IperfExecutor,
'iperf_graph': iperf.IperfGraphExecutor,
'netperf_wrapper': netperf.NetperfWrapperExecutor,
'_default': base.ShellExecutor,
'_default': shell.ShellExecutor,
}

View File

@ -21,15 +21,23 @@ LOG = logging.getLogger(__name__)
class CommandLine(object):
def __init__(self, command):
self.commands = [command]
self.tokens = [command]
def add(self, param_name, param_value=None):
self.commands.append('%s' % param_name)
self.tokens.append('%s' % param_name)
if param_value:
self.commands.append(str(param_value))
self.tokens.append(str(param_value))
def make(self):
return ' '.join(self.commands)
return dict(type='program', data=' '.join(self.tokens))
class Script(object):
def __init__(self, script):
self.script = script
def make(self):
return dict(type='script', data=self.script)
class BaseExecutor(object):
@ -48,8 +56,3 @@ class BaseExecutor(object):
stderr=message.get('stderr'),
command=self.get_command(),
agent=self.agent)
class ShellExecutor(BaseExecutor):
def get_command(self):
return self.test_definition['method']

View File

@ -0,0 +1,30 @@
# Copyright (c) 2015 Mirantis 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 oslo_log import log as logging
from shaker.engine.executors import base
LOG = logging.getLogger(__name__)
class ShellExecutor(base.BaseExecutor):
def get_command(self):
if 'method' in self.test_definition:
cmd = base.CommandLine(self.test_definition['method'])
elif 'script' in self.test_definition:
cmd = base.Script(self.test_definition['script'])
return cmd.make()

View File

@ -27,18 +27,20 @@ class TestIperfGraphExecutor(testtools.TestCase):
def test_get_command(self):
executor = iperf.IperfGraphExecutor({}, AGENT)
expected = ('sudo nice -n -20 iperf --client %s --format m --nodelay '
'--len 8k --time 60 --parallel 1 '
'--reportstyle C --interval 1') % IP
expected = {'data': ('sudo nice -n -20 iperf --client %s --format m '
'--nodelay --len 8k --time 60 --parallel 1 '
'--reportstyle C --interval 1') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())
def test_get_command_udp(self):
executor = iperf.IperfGraphExecutor(
{'udp': True, 'time': 30}, AGENT)
expected = ('sudo nice -n -20 iperf --client %s --format m --nodelay '
'--len 8k --udp --time 30 --parallel 1 '
'--reportstyle C --interval 1') % IP
expected = {'data': ('sudo nice -n -20 iperf --client %s --format m '
'--nodelay --len 8k --udp --time 30 --parallel 1 '
'--reportstyle C --interval 1') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())
def test_process_reply(self):

View File

@ -27,12 +27,14 @@ class TestNetperfExecutor(testtools.TestCase):
def test_get_command(self):
executor = netperf.NetperfExecutor({}, AGENT)
expected = 'netperf -H %s -l 60 -t TCP_STREAM' % IP
expected = {'data': ('netperf -H %s -l 60 -t TCP_STREAM') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())
def test_get_command_options(self):
executor = netperf.NetperfExecutor(
{'method': 'UDP_STREAM', 'time': 30}, AGENT)
expected = 'netperf -H %s -l 30 -t UDP_STREAM' % IP
expected = {'data': ('netperf -H %s -l 30 -t UDP_STREAM') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())

View File

@ -27,14 +27,18 @@ class TestNetperfWrapperExecutor(testtools.TestCase):
def test_get_command(self):
executor = netperf.NetperfWrapperExecutor({}, AGENT)
expected = 'netperf-wrapper -H %s -l 60 -s 1 -f csv tcp_download' % IP
expected = {'data': ('netperf-wrapper -H %s -l 60 -s 1 '
'-f csv tcp_download') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())
def test_get_command_with_params(self):
executor = netperf.NetperfWrapperExecutor(
dict(method='ping', time=10, interval=0.5), AGENT)
expected = 'netperf-wrapper -H %s -l 10 -s 0.5 -f csv ping' % IP
expected = {'data': ('netperf-wrapper -H %s -l 10 -s 0.5 '
'-f csv ping') % IP,
'type': 'program'}
self.assertEqual(expected, executor.get_command())
def test_process_reply(self):