diff options
-rw-r--r-- | qtip/cli/commands/cmd_metric.py | 3 | ||||
-rw-r--r-- | qtip/cli/commands/cmd_plan.py | 45 | ||||
-rw-r--r-- | qtip/cli/commands/cmd_qpi.py | 35 | ||||
-rw-r--r-- | qtip/cli/commands/cmd_suite.py | 54 | ||||
-rw-r--r-- | qtip/cli/entry.py | 9 | ||||
-rwxr-xr-x | qtip/scripts/fetch_compute_ips.sh (renamed from legacy/scripts/fetch_compute_ips.sh) | 2 | ||||
-rwxr-xr-x | qtip/scripts/qtip_creds.sh (renamed from legacy/scripts/qtip_creds.sh) | 0 | ||||
-rw-r--r-- | qtip/util/env.py | 137 | ||||
-rw-r--r-- | tests/unit/cli/test_metric.py | 9 | ||||
-rw-r--r-- | tests/unit/cli/test_options.py | 2 | ||||
-rw-r--r-- | tests/unit/cli/test_plan.py | 31 | ||||
-rw-r--r-- | tests/unit/cli/test_qpi.py | 31 |
12 files changed, 269 insertions, 89 deletions
diff --git a/qtip/cli/commands/cmd_metric.py b/qtip/cli/commands/cmd_metric.py index 7f5c18d3..d2fbd58f 100644 --- a/qtip/cli/commands/cmd_metric.py +++ b/qtip/cli/commands/cmd_metric.py @@ -28,6 +28,7 @@ def cmd_list(ctx): @cli.command('run', help='Run tests to collect Performance Metrics') +@click.argument('name') @pass_context -def cmd_run(ctx): +def cmd_run(ctx, name): pass diff --git a/qtip/cli/commands/cmd_plan.py b/qtip/cli/commands/cmd_plan.py index 6f622e5a..0c0a3c12 100644 --- a/qtip/cli/commands/cmd_plan.py +++ b/qtip/cli/commands/cmd_plan.py @@ -1,4 +1,4 @@ -############################################################################# +############################################################################## # Copyright (c) 2016 ZTE Corp and others. # # All rights reserved. This program and the accompanying materials @@ -7,38 +7,39 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## + import click -from prettytable import PrettyTable -from qtip.loader.plan import Plan +from qtip.cli.entry import Context + + +pass_context = click.make_pass_decorator(Context, ensure=False) @click.group() -def cli(): +@pass_context +def cli(ctx): + ''' Bechmarking Plan ''' pass -@cli.group() -def plan_cmd(): +@cli.command('init', help='Initialize Environment') +@click.option('--inst_type', prompt='Installer Type') +@click.option('--inst_ip', prompt='Installer IP') +@click.option('--ext_net', prompt='Openstack External Network') +@pass_context +def init(ctx, inst_type, inst_ip, ext_net): pass -@plan_cmd.command('list', help='List the different TestPlans.') -def list_all(): - plans = Plan.list_all() - table = PrettyTable(["Testplans"]) - table.align = 'l' - for plan in plans: - table.add_row([plan['name']]) - click.echo(table) +@cli.command('list', help='List the Plans') +@pass_context +def list(ctx): + pass -@plan_cmd.command('show', help='Show details of specified TestPlan.') +@cli.command('run', help='Execute a Plan') @click.argument('name') -def show(name): - plan = Plan(name) - results = plan.content() - table = PrettyTable(["Name", "Description"]) - table.align = 'l' - table.add_row([results['name'], results['description']]) - click.echo(table) +@pass_context +def run(ctx, name): + pass diff --git a/qtip/cli/commands/cmd_qpi.py b/qtip/cli/commands/cmd_qpi.py new file mode 100644 index 00000000..f33f0104 --- /dev/null +++ b/qtip/cli/commands/cmd_qpi.py @@ -0,0 +1,35 @@ +############################################################################## +# Copyright (c) 2016 ZTE Corp and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +import click + +from qtip.cli.entry import Context + +pass_context = click.make_pass_decorator(Context, ensure=False) + + +@click.group() +@pass_context +def cli(ctx): + ''' Collection of performance tests ''' + pass + + +@cli.command('list', help='List all the QPI specs') +@pass_context +def cmd_list(ctx): + pass + + +@cli.command('run', help='Run performance tests for the specified QPI') +@click.argument('name') +@pass_context +def run(ctx, name): + pass diff --git a/qtip/cli/commands/cmd_suite.py b/qtip/cli/commands/cmd_suite.py deleted file mode 100644 index 45c739df..00000000 --- a/qtip/cli/commands/cmd_suite.py +++ /dev/null @@ -1,54 +0,0 @@ -############################################################################## -# Copyright (c) 2016 ZTE Corp and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from prettytable import PrettyTable -import os -import click -from qtip.cli import helper - - -class Suite: - - def __init__(self): - self.path = os.path.join(helper.fetch_root(), 'suite') - - def list(self): - table = PrettyTable(["Name"]) - table.align = 'l' - suites = os.listdir(self.path) - for suite in suites: - table.add_row([suite]) - click.echo(table) - - def run(self): - print("Run a suite") - - -@click.group() -def cli(): - pass - - -@cli.group() -@click.pass_context -def suite(ctx): - pass - - -_suite = Suite() - - -@suite.command("list", help="Lists all the available suites") -def list(): - _suite.list() - - -@suite.command("run", help="Execute one complete suite") -def execute(): - _suite.run() diff --git a/qtip/cli/entry.py b/qtip/cli/entry.py index 0ecb06cd..9f51f25e 100644 --- a/qtip/cli/entry.py +++ b/qtip/cli/entry.py @@ -22,7 +22,6 @@ class Context(object): def __init__(self): self.verbose = False self.debug = False - self.version = 'qtip-1.0.0' def log(self, msg, *args): ''' Log message to stderr ''' @@ -32,10 +31,6 @@ class Context(object): ''' Log message to stderr when verbose ''' pass - def version(self): - ''' Display programs version ''' - pass - def debug(self, msg, *args): ''' Log message to debug ''' pass @@ -72,7 +67,7 @@ class QtipCli(click.MultiCommand): invoke_without_command=True) @click.option('-v', '--verbose', is_flag=True, help='Enable verbose mode.') @click.option('-d', '--debug', is_flag=True, help='Enable debug mode.') -@click.option('--version', is_flag=True, help='Shows program current version.') +@click.version_option('dev') @pass_context -def cli(ctx, verbose, version, debug): +def cli(ctx, verbose, debug): pass diff --git a/legacy/scripts/fetch_compute_ips.sh b/qtip/scripts/fetch_compute_ips.sh index 4bdc9a48..a2618ec9 100755 --- a/legacy/scripts/fetch_compute_ips.sh +++ b/qtip/scripts/fetch_compute_ips.sh @@ -2,7 +2,6 @@ ############################################################################## #Copyright (c) 2016 Ericsson AB, ZTE and others. #jose.lausuch@ericsson.com -#wu.zhihui1@zte.com.cn #All rights reserved. This program and the accompanying materials #are made available under the terms of the Apache License, Version 2.0 #which accompanies this distribution, and is available at @@ -109,6 +108,7 @@ if [ -z "$IPS" ]; then error "The compute node $IPS are not up. Please check that the POD is correctly deployed." else echo "-------- all compute node ips: --------" + rm $HOME/ips.log touch $HOME/ips.log echo "$IPS" > $HOME/qtip/ips.log echo $IPS diff --git a/legacy/scripts/qtip_creds.sh b/qtip/scripts/qtip_creds.sh index af051ac5..af051ac5 100755 --- a/legacy/scripts/qtip_creds.sh +++ b/qtip/scripts/qtip_creds.sh diff --git a/qtip/util/env.py b/qtip/util/env.py new file mode 100644 index 00000000..4e7a31c7 --- /dev/null +++ b/qtip/util/env.py @@ -0,0 +1,137 @@ +############################################################################## +# Copyright (c) 2016 Dell Inc, ZTE and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import os +import paramiko +import socket +import time +from os import path +from os.path import expanduser + +SCRIPT_DIR = path.join(path.dirname(__file__), path.pardir, 'scripts') +CONFIG_DIR = path.join(path.dirname(__file__), path.pardir, path.pardir, + 'config') +PRIVATE_KEY = CONFIG_DIR + '/QtipKey' +PUBLIC_KEY = CONFIG_DIR + '/QtipKey.pub' +IPS_FILE = expanduser('~') + "/qtip/ips.log" +HOST_FILE = CONFIG_DIR + "/host" + + +def fetch_compute_ips_via_installer(): + clean_file(IPS_FILE) + + installer_type = str(os.environ['INSTALLER_TYPE'].lower()) + installer_ip = str(os.environ['INSTALLER_IP']) + if installer_type not in ["fuel"]: + raise RuntimeError("%s is not supported" % installer_type) + if not installer_ip: + raise RuntimeError("undefine environment variable INSTALLER_IP") + + cmd = "bash %s/fetch_compute_ips.sh -i %s -a %s" % \ + (SCRIPT_DIR, installer_type, installer_ip) + os.system(cmd) + if path.isfile(IPS_FILE): + return True + else: + return False + + +def parse_ips(): + ip_list = [] + with open(IPS_FILE, "r") as outfile: + data = outfile.read() + if data: + ip_list.extend(data.rstrip('\n').split('\n')) + return ip_list + + +def ssh_test(ip): + os.system('ssh-keyscan %s >> /root/.ssh/known_hosts' % ip) + time.sleep(2) + + ssh_cmd = '%s/qtip_creds.sh %s' % (SCRIPT_DIR, ip) + os.system(ssh_cmd) + + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect(ip, key_filename='{0}/QtipKey'.format(CONFIG_DIR)) + + for attempts in range(100): + try: + stdin, stdout, stderr = ssh.exec_command('uname') + if not stderr.readlines(): + print("{0}: SSH test successful") + return True + except socket.error: + if attempts == 99: + return False + time.sleep(2) + + +def ping_test(ip, attempts=30): + ping_cmd = 'ping -D -c1 {0}'.format(ip) + for i in range(attempts): + if os.system(ping_cmd): + print('\nWaiting for machine\n') + time.sleep(10) + else: + print('\n\n %s is UP \n\n ' % ip) + return True + if i == 29: + return False + + +def check_nodes_connectivity(): + ip_list = parse_ips() + for ip in ip_list: + if not ping_test(ip): + raise RuntimeError("{0}: Ping test failed".format(ip)) + if not ssh_test(ip): + raise RuntimeError("{0}: SSH test failed".format(ip)) + + +def generate_host_file(): + ip_list = parse_ips() + with open(HOST_FILE, 'w') as host_file: + for index, item in enumerate(ip_list): + host_file.write("[host_{0}]\n".format(index)) + host_file.write(item + '\n') + + +def generate_keypair(): + """Generating ssh keypair""" + if not clean_keypair(): + raise RuntimeError("Cann't remove old keypair") + + cmd = "ssh-keygen -t rsa -N "" -f {0} -q".format(PRIVATE_KEY) + os.system(cmd) + + if path.isfile(PRIVATE_KEY) and path.isfile(PUBLIC_KEY): + return True + else: + return False + + +def clean_file(file_path): + try: + if path.isfile(file_path): + os.remove(file_path) + print("Removed: " + file_path) + else: + print("Not exists: " + file_path) + except OSError, error: + print("Not able to Remove: " + file_path, error) + return False + return True + + +def clean_keypair(): + flag = True + flag &= clean_file(PRIVATE_KEY) + flag &= clean_file(PUBLIC_KEY) + return flag diff --git a/tests/unit/cli/test_metric.py b/tests/unit/cli/test_metric.py index ed10689c..239da96e 100644 --- a/tests/unit/cli/test_metric.py +++ b/tests/unit/cli/test_metric.py @@ -10,7 +10,7 @@ import pytest from click.testing import CliRunner -from qtip.cli.commands.cmd_metric import cli +from qtip.cli.entry import cli @pytest.fixture() @@ -19,10 +19,13 @@ def runner(): def test_list(runner): - result = runner.invoke(cli, ['list']) + result = runner.invoke(cli, ['metric', 'list']) assert result.output == '' def test_run(runner): - result = runner.invoke(cli, ['run']) + result = runner.invoke(cli, ['metric', 'run', 'fake-metric']) assert result.output == '' + + result = runner.invoke(cli, ['metric', 'run']) + assert 'Missing argument "name".' in result.output diff --git a/tests/unit/cli/test_options.py b/tests/unit/cli/test_options.py index 5129b5cc..f9472814 100644 --- a/tests/unit/cli/test_options.py +++ b/tests/unit/cli/test_options.py @@ -25,7 +25,7 @@ class TestClass(object): def test_version(self, runner): result = runner.invoke(cli, ['--version']) - assert '' in result.output + assert 'dev' in result.output def test_debug(self, runner): result = runner.invoke(cli, ['-d']) diff --git a/tests/unit/cli/test_plan.py b/tests/unit/cli/test_plan.py new file mode 100644 index 00000000..3ce3766e --- /dev/null +++ b/tests/unit/cli/test_plan.py @@ -0,0 +1,31 @@ +############################################################### +# Copyright (c) 2016 ZTE Corp and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import pytest +from click.testing import CliRunner + +from qtip.cli.entry import cli + + +@pytest.fixture() +def runner(): + return CliRunner() + + +def test_list(runner): + result = runner.invoke(cli, ['plan', 'list']) + assert result.output == '' + + +def test_run(runner): + result = runner.invoke(cli, ['plan', 'run', 'fake-plan']) + assert result.output == '' + + result = runner.invoke(cli, ['plan', 'run']) + assert 'Missing argument "name".' in result.output diff --git a/tests/unit/cli/test_qpi.py b/tests/unit/cli/test_qpi.py new file mode 100644 index 00000000..992c85d7 --- /dev/null +++ b/tests/unit/cli/test_qpi.py @@ -0,0 +1,31 @@ +############################################################### +# Copyright (c) 2016 ZTE Corp and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import pytest +from click.testing import CliRunner + +from qtip.cli.entry import cli + + +@pytest.fixture() +def runner(): + return CliRunner() + + +def test_list(runner): + result = runner.invoke(cli, ['qpi', 'list']) + assert result.output == '' + + +def test_run(runner): + result = runner.invoke(cli, ['qpi', 'run', 'fake-qpi']) + assert result.output == '' + + result = runner.invoke(cli, ['qpi', 'run']) + assert 'Missing argument "name".' in result.output |