diff options
Diffstat (limited to 'qtip')
27 files changed, 929 insertions, 159 deletions
diff --git a/qtip/driver/ansible.py b/qtip/cli/commands/cmd_report.py index cd17625d..c780e847 100644 --- a/qtip/driver/ansible.py +++ b/qtip/cli/commands/cmd_report.py @@ -1,5 +1,5 @@ ############################################################################## -# Copyright (c) 2016 ZTE Corp and others. +# Copyright (c) 2017 taseer94@gmail.com and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 @@ -7,8 +7,21 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from qtip.driver.base import BaseDriver +import click +from qtip.cli.entry import Context -class AnsibleDriver(BaseDriver): - """driver for running performance tests with Ansible""" +pass_context = click.make_pass_decorator(Context, ensure=False) + + +@click.group() +@pass_context +def cli(ctx): + """ View Qtip results""" + pass + + +@cli.command('show') +@pass_context +def show(ctx): + pass diff --git a/qtip/cli/entry.py b/qtip/cli/entry.py index 9f51f25e..6cf78b58 100644 --- a/qtip/cli/entry.py +++ b/qtip/cli/entry.py @@ -1,5 +1,5 @@ ############################################################################## -# Copyright (c) 2016 ZTE Corp and others. +# Copyright (c) 2017 taseer94@gmail.com and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 @@ -7,33 +7,19 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +import click import os import sys -import click CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) +# TODO (taseer) define user friendly error messages +sys.tracebacklimit = 0 -class Context(object): - - ''' TODO(taseer) implementation''' - - def __init__(self): - self.verbose = False - self.debug = False - - def log(self, msg, *args): - ''' Log message to stderr ''' - pass - def verbose(self, msg, *args): - ''' Log message to stderr when verbose ''' - pass - - def debug(self, msg, *args): - ''' Log message to debug ''' - pass +class Context(object): + """ Load configuration and pass to subcommands """ pass_context = click.make_pass_decorator(Context, ensure=True) @@ -70,4 +56,5 @@ class QtipCli(click.MultiCommand): @click.version_option('dev') @pass_context def cli(ctx, verbose, debug): - pass + if debug: + sys.tracebacklimit = 8 diff --git a/qtip/driver/ansible_api.py b/qtip/driver/ansible_api.py new file mode 100644 index 00000000..5c5baffc --- /dev/null +++ b/qtip/driver/ansible_api.py @@ -0,0 +1,58 @@ +############################################################################## +# Copyright (c) 2017 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 collections import namedtuple + +from ansible.executor.playbook_executor import PlaybookExecutor +from ansible.inventory import Inventory +from ansible.parsing.dataloader import DataLoader +from ansible.vars import VariableManager + + +class AnsibleApi(object): + + def __init__(self): + self.variable_manager = VariableManager() + self.loader = DataLoader() + self.passwords = {} + self.playbook_executor = None + + def execute_playbook(self, playbook_path, hosts_file=None, + key_file=None, extra_vars=None): + inventory = Inventory(loader=self.loader, + variable_manager=self.variable_manager, + host_list=hosts_file) + Options = namedtuple('Options', + ['listtags', 'listtasks', 'listhosts', 'syntax', + 'connection', 'module_path', 'forks', 'remote_user', + 'private_key_file', 'ssh_common_args', 'ssh_extra_args', + 'sftp_extra_args', 'scp_extra_args', 'become', + 'become_method', 'become_user', 'verbosity', 'check']) + options = Options(listtags=False, listtasks=False, listhosts=False, + syntax=False, connection='ssh', module_path=None, + forks=100, remote_user='root', private_key_file=key_file, + ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, + scp_extra_args=None, become=None, become_method=None, + become_user='root', verbosity=None, check=False) + self.variable_manager.extra_vars = extra_vars + + self.playbook_executor = PlaybookExecutor(playbooks=[playbook_path], + inventory=inventory, + variable_manager=self.variable_manager, + loader=self.loader, + options=options, + passwords=self.passwords) + return self.playbook_executor.run() + + def get_detail_playbook_stats(self): + if self.playbook_executor: + stats = self.playbook_executor._tqm._stats + return map(lambda x: (x, stats.summarize(x)), stats.processed.keys()) + else: + return None diff --git a/qtip/driver/ansible_driver.py b/qtip/driver/ansible_driver.py new file mode 100644 index 00000000..1cd7918d --- /dev/null +++ b/qtip/driver/ansible_driver.py @@ -0,0 +1,85 @@ +############################################################################## +# Copyright (c) 2017 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 collections import defaultdict +from os import path + +from qtip.driver.ansible_api import AnsibleApi +from qtip.util.env import AnsibleEnvSetup +from qtip.util.logger import QtipLogger + +logger = QtipLogger('ansible_driver').get +PLAYBOOK_DIR = path.join(path.dirname(__file__), 'playbook') + + +class AnsibleDriver(object): + """driver for running performance tests with Ansible""" + + def __init__(self, config={}): + self.config = config + self.env = AnsibleEnvSetup() + self.env_setup_flag = False + + @staticmethod + def merge_two_dicts(x, y): + ''' + It is from http://stackoverflow.com/questions/38987/ + how-can-i-merge-two-python-dictionaries-in-a-single-expression + ''' + z = x.copy() + z.update(y) + return z + + def pre_run(self): + if self.env_setup_flag: + logger.info("Already setup environment......") + else: + logger.info("Starting to setup test environment...") + self.env.setup(self.config) + self.env_setup_flag = True + logger("Done!") + + def run(self, metric_list, **kwargs): + if 'args' in self.config: + extra_vars = self.merge_two_dicts(kwargs, self.config['args']) + else: + extra_vars = kwargs + logger.info("extra_var: {0}".format(extra_vars)) + + # TODO zhihui: will add a new property named "tool" for metrics, hardcode it now. + tool_to_metrics = defaultdict(list) + for metric in metric_list: + if metric in ['dhrystone', 'whetstone']: + tool_to_metrics['unixbench'].append(metric) + extra_vars[metric] = True + elif metric == 'ssl': + tool_to_metrics['openssl'].append(metric) + else: + tool_to_metrics[metric].append(metric) + + ansible_api = AnsibleApi() + map(lambda tool: self._run_metric(ansible_api, tool, + tool_to_metrics[tool], extra_vars), + tool_to_metrics) + + def _run_metric(self, ansible_api, tool, metrics, extra_vars): + logger.info('Using {0} to measure metrics {1}'.format(tool, metrics)) + + for metric in metrics: + extra_vars[metric] = True + + logger.debug("extra_vars: {0}".format(extra_vars)) + + for item in ['setup', 'run', 'clean']: + pbook = "{0}/{1}/{2}.yaml".format(PLAYBOOK_DIR, tool, item) + logger.debug("Start to run {0}".format(pbook)) + ansible_api.execute_playbook(pbook, self.env.hostfile, + self.env.keypair['private'], extra_vars) + playbook_stat = ansible_api.get_detail_playbook_stats() + logger.debug("playbook_stat: {0}".format(playbook_stat)) diff --git a/qtip/driver/playbook/bwn_ng.yaml b/qtip/driver/playbook/bwn_ng.yaml index 99477856..f79bb04e 100644 --- a/qtip/driver/playbook/bwn_ng.yaml +++ b/qtip/driver/playbook/bwn_ng.yaml @@ -20,4 +20,6 @@ when: ansible_os_family == "Debian" - name: Run bwm-ng - shell: bwm-ng -o plain -c 1 > $HOME/qtip_result/bwm-dump.log
\ No newline at end of file + shell: bwm-ng -o plain -c 1 > bwm-dump.log + args: + chdir: '{{ dest_path }}/'
\ No newline at end of file diff --git a/qtip/driver/playbook/dhrystone/run.yaml b/qtip/driver/playbook/dhrystone/run.yaml deleted file mode 100644 index 55de6597..00000000 --- a/qtip/driver/playbook/dhrystone/run.yaml +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################## -# Copyright (c) 2017 ZTE Corporation 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 -############################################################################## - -- hosts: hosts - become: yes - remote_user: root - - tasks: - - name: Get current timestamp - set_fact: - timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H-%M') }}" - - - name: Checking home directory - shell: echo $HOME - register: home_dir - - - name: Fetch hostname - shell: hostname - register: host_name - - - name: Make UnixBench - shell: make --directory $HOME/tempT/UnixBench/ - - - name: Make some directories needed - file: - path: '{{ home_dir.stdout }}/qtip_result/{{ timestamp }}/{{ host_name.stdout }}' - state: directory - - - include: ../inxi.yaml - - - include: ../top.yaml - - - name: Run dhrystone - shell: ./Run -v dhrystone - args: - chdir: '{{ home_dir.stdout }}/tempT/UnixBench/' - - - name: Copying result to qtip result directory - shell: cp -r $HOME/tempT/UnixBench/results/* ./ - args: - chdir: '{{ home_dir.stdout }}/qtip_result/{{ timestamp }}/{{ host_name.stdout }}' - - - name: Copy top log to qtip result directory - shell: mv $HOME/qtip_result/top.log ./ - args: - chdir: '{{ home_dir.stdout }}/qtip_result/{{ timestamp }}/{{ host_name.stdout }}' - - - name: Copy inxi log to qtip result directory - shell: mv $HOME/qtip_result/inxi.log ./ - args: - chdir: '{{ home_dir.stdout }}/qtip_result/{{ timestamp }}/{{ host_name.stdout }}' - - - name: Fetch result files to local manchine - synchronize: - mode: pull - src: '{{ home_dir.stdout }}/qtip_result/' - dest: '{{ result_dir }}/dhrystone/logs/' diff --git a/qtip/driver/playbook/dpi/clean.yaml b/qtip/driver/playbook/dpi/clean.yaml new file mode 100644 index 00000000..0b9f9291 --- /dev/null +++ b/qtip/driver/playbook/dpi/clean.yaml @@ -0,0 +1,23 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning tempD + file: + path: '{{ ansible_env.HOME }}/tempD' + state: absent + + - name: Cleaning qtip_result + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent diff --git a/qtip/driver/playbook/dpi/dpi_average.sh b/qtip/driver/playbook/dpi/dpi_average.sh new file mode 100644 index 00000000..6f038053 --- /dev/null +++ b/qtip/driver/playbook/dpi/dpi_average.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +COUNTER=0 +WDIR=$PWD +while [ $COUNTER -lt 10 ]; do + echo $WDIR + $( ./ndpiReader -i test.pcap >> $WDIR/dpi_dump.txt ) + let COUNTER=COUNTER+1 + echo "Run number: $COUNTER" +done
\ No newline at end of file diff --git a/qtip/driver/playbook/dpi/run.yaml b/qtip/driver/playbook/dpi/run.yaml new file mode 100644 index 00000000..58f7eb2f --- /dev/null +++ b/qtip/driver/playbook/dpi/run.yaml @@ -0,0 +1,46 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Get current timestamp + set_fact: + timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H-%M') }}" + + - name: Make some directories needed + file: + path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + state: directory + + - include: ../inxi.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + + - include: ../top.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + + - name: Run nDPI benchmark + shell: ./dpi_average.sh + args: + chdir: '{{ ansible_env.HOME }}/tempD/nDPI/example/' + + - name: Copying result and system info to qtip result directory + command: cp $HOME/tempD/nDPI/example/dpi_dump.txt ./ + args: + chdir: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + + - name: Fetch result files to local manchine + synchronize: + mode: pull + src: '{{ ansible_env.HOME }}/qtip_result/' + dest: '{{ result_dir }}/dpi/logs/' diff --git a/qtip/driver/playbook/dpi/setup.yaml b/qtip/driver/playbook/dpi/setup.yaml new file mode 100644 index 00000000..c1b45450 --- /dev/null +++ b/qtip/driver/playbook/dpi/setup.yaml @@ -0,0 +1,93 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: localhost + connection: local + gather_facts: no + + tasks: + - name: Making Dpi directory + file: + path: '{{ result_dir }}/dpi/logs/' + state: directory + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning tempD directory + file: + path: '{{ ansible_env.HOME }}/tempD' + state: absent + + - name: Cleaning qtip_result directory + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent + + - include: ../prepare_env.yaml + + - name: Installing nDPI dependencies if CentOS + yum: + name: '{{ item }}' + state: present + when: ansible_os_family == "RedHat" + with_items: + - git + - gcc + - patch + - perl-Time-HiRes + - autofconf + - automake + - libpcap-devel libtool + + - name: Installing nDPI dependencies if Ubuntu + apt: + name: '{{ item }}' + state: present + when: ansible_os_family == "Debian" + with_items: + - git + - gcc + - patch + - autoconf + - automake + - libpcap-dev + - libtool + + - name: Making nDPI temporary directory + file: + path: '{{ ansible_env.HOME }}/tempD' + state: directory + + - name: Clone nDPI + git: + repo: https://github.com/ntop/nDPI.git + dest: '{{ ansible_env.HOME }}/tempD/nDPI' + + - name: Run autogen && configure Dpi && make Dpi + command: '{{ item }}' + with_items: + - ./autogen.sh + - ./configure + - make + args: + chdir: '{{ ansible_env.HOME }}/tempD/nDPI/' + + - name: Fetching Test_pcap file + get_url: + url: http://build.opnfv.org/artifacts.opnfv.org/qtip/utilities/test.pcap + dest: '{{ ansible_env.HOME }}/tempD/nDPI/example/test.pcap' + + - name: Fetch Averaging script + copy: + src: ./dpi_average.sh + dest: '{{ ansible_env.HOME }}/tempD/nDPI/example' + mode: 777
\ No newline at end of file diff --git a/qtip/driver/playbook/inxi.yaml b/qtip/driver/playbook/inxi.yaml index f6a0311d..a06da042 100644 --- a/qtip/driver/playbook/inxi.yaml +++ b/qtip/driver/playbook/inxi.yaml @@ -20,4 +20,6 @@ when: ansible_os_family == "Debian" - name: Run inxi - shell: inxi -b -c0 -n > $HOME/qtip_result/inxi.log + shell: inxi -b -c0 -n > inxi.log + args: + chdir: '{{ dest_path }}/' diff --git a/qtip/driver/playbook/openssl/clean.yaml b/qtip/driver/playbook/openssl/clean.yaml new file mode 100644 index 00000000..0139ba54 --- /dev/null +++ b/qtip/driver/playbook/openssl/clean.yaml @@ -0,0 +1,23 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning Open_SSL + file: + path: '{{ ansible_env.HOME }}/Open_SSL' + state: absent + + - name: Cleaning qtip_result + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent diff --git a/qtip/driver/playbook/openssl/run.yaml b/qtip/driver/playbook/openssl/run.yaml new file mode 100644 index 00000000..241cac61 --- /dev/null +++ b/qtip/driver/playbook/openssl/run.yaml @@ -0,0 +1,49 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Get current timestamp + set_fact: + timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H-%M') }}" + + - name: Make some directories needed + file: + path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + state: directory + + - include: ../inxi.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - include: ../top.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - name: Benchmarking RSA signatures and AES-128-cbc cipher encryption throughput + shell: '{{ item }}' + with_items: + - ./openssl speed rsa >> RSA_dump + - ./openssl speed -evp aes-128-cbc >> AES-128-CBC_dump + args: + chdir: '{{ ansible_env.HOME }}/Open_SSL/openssl-1.0.2f/apps' + + - name: Copying result to qtip result directory + shell: cp ~/Open_SSL/openssl-1.0.2f/apps/*_dump ./ + args: + chdir: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - name: Fetch result files to local manchine + synchronize: + mode: pull + src: '{{ ansible_env.HOME }}/qtip_result/' + dest: '{{ result_dir }}/ssl/logs/' diff --git a/qtip/driver/playbook/openssl/setup.yaml b/qtip/driver/playbook/openssl/setup.yaml new file mode 100644 index 00000000..e93bfb8e --- /dev/null +++ b/qtip/driver/playbook/openssl/setup.yaml @@ -0,0 +1,87 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: localhost + connection: local + gather_facts: no + + tasks: + - name: Making ssl directory + file: + path: '{{ result_dir }}/ssl/logs/' + state: directory + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning Open_SSL directory + file: + path: '{{ ansible_env.HOME }}/Open_SSL' + state: absent + + - name: Cleaning qtip_result directory + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent + + - include: ../prepare_env.yaml + + - name: Installing UnixBench dependencies if CentOS + yum: + name: '{{ item }}' + state: present + when: ansible_os_family == "RedHat" + with_items: + - git + - gcc + - patch + - perl-Time-HiRes + - wget + - autofconf + - automake + - libpcap-devel + - libtool + + - name: Installing UnixBench dependencies if Ubuntu + apt: + name: '{{ item }}' + state: present + when: ansible_os_family == "Debian" + with_items: + - git + - gcc + - patch + - perl + - wget + - autoconf + - automake + - libpcap-dev + - libtool + + - name: Make Open_SSL directory + file: + path: '{{ ansible_env.HOME }}/Open_SSL' + state: directory + + - name: Untar OpenSSL + unarchive: + src: http://artifacts.opnfv.org/qtip/utilities/openssl-1.0.2f.tar.gz + dest: '{{ ansible_env.HOME }}/Open_SSL/' + remote_src: True + + - name: Configure && Make && Install OpenSSL + shell: "{{ item }}" + with_items: + - ./config + - make + - make install + args: + chdir: '{{ ansible_env.HOME }}/Open_SSL/openssl-1.0.2f'
\ No newline at end of file diff --git a/qtip/driver/playbook/ramspeed/clean.yaml b/qtip/driver/playbook/ramspeed/clean.yaml new file mode 100644 index 00000000..f0188159 --- /dev/null +++ b/qtip/driver/playbook/ramspeed/clean.yaml @@ -0,0 +1,23 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning ramspeed + file: + path: '{{ ansible_env.HOME }}/ramspeed' + state: absent + + - name: Cleaning qtip_result + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent diff --git a/qtip/driver/playbook/ramspeed/run.yaml b/qtip/driver/playbook/ramspeed/run.yaml new file mode 100644 index 00000000..33c9a6ef --- /dev/null +++ b/qtip/driver/playbook/ramspeed/run.yaml @@ -0,0 +1,44 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Get current timestamp + set_fact: + timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H-%M') }}" + + - name: Make some directories needed + file: + path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + state: directory + + - include: ../inxi.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - include: ../top.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - name: Benchmarking IntMem Bandwidth and FloatMem Bandwidth + shell: '{{ item }}' + with_items: + - ~/ramspeed/ramsmp-3.5.0/ramsmp -b 3 -l 5 -p 1 >> Intmem + - ~/ramspeed/ramsmp-3.5.0/ramsmp -b 6 -l 5 -p 1 >> Floatmem + args: + chdir: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}/' + + - name: Fetch result files to local manchine + synchronize: + mode: pull + src: '{{ ansible_env.HOME }}/qtip_result/' + dest: '{{ result_dir }}/ramspeed/logs/' diff --git a/qtip/driver/playbook/ramspeed/setup.yaml b/qtip/driver/playbook/ramspeed/setup.yaml new file mode 100644 index 00000000..60368605 --- /dev/null +++ b/qtip/driver/playbook/ramspeed/setup.yaml @@ -0,0 +1,70 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## + +- hosts: localhost + connection: local + gather_facts: no + + tasks: + - name: Making ramspeed directory + file: + path: '{{ result_dir }}/ramspeed/logs/' + state: directory + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - name: Cleaning ramspeed directory + file: + path: '{{ ansible_env.HOME }}/ramspeed' + state: absent + + - name: Cleaning qtip_result directory + file: + path: '{{ ansible_env.HOME }}/qtip_result' + state: absent + + - include: ../prepare_env.yaml + + - name: Installing RAM_Speed dependencies if CentOS + yum: + name: '{{ item }}' + state: present + when: ansible_os_family == "RedHat" + with_items: + - gcc + - wget + + - name: Installing RAM_Speed dependencies if Ubuntu + apt: + name: '{{ item }}' + state: present + when: ansible_os_family == "Debian" + with_items: + - gcc + - wget + + - name: Making ramspeed temporary directory + file: + path: '{{ ansible_env.HOME }}/ramspeed' + state: directory + + - name: Fetch and untar ramspeed.tar.gz + unarchive: + # TODO: Need to upload this file to http://artifacts.opnfv.org/qtip/utilities + src: https://docs.google.com/uc?id=0B92Bp5LZTM7gRFctalZLMktTNDQ + dest: '{{ ansible_env.HOME }}/ramspeed/' + remote_src: True + + - name: Build ramsmp + shell: ./build.sh + args: + chdir: '{{ ansible_env.HOME }}/ramspeed/ramsmp-3.5.0' diff --git a/qtip/driver/playbook/top.yaml b/qtip/driver/playbook/top.yaml index 8de7e3d6..64584338 100644 --- a/qtip/driver/playbook/top.yaml +++ b/qtip/driver/playbook/top.yaml @@ -7,4 +7,6 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## - name: Collect cpu usage - shell: top -bn1 > $HOME/qtip_result/top.log + shell: top -bn1 > top.log + args: + chdir: '{{ dest_path }}/' diff --git a/qtip/driver/playbook/dhrystone/clean.yaml b/qtip/driver/playbook/unixbench/clean.yaml index 72bfab7e..a7cb2540 100644 --- a/qtip/driver/playbook/dhrystone/clean.yaml +++ b/qtip/driver/playbook/unixbench/clean.yaml @@ -1,6 +1,6 @@ ############################################################################## # Copyright (c) 2017 ZTE Corporation and others. -# +# zhihui.wu1@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 @@ -12,16 +12,14 @@ remote_user: root tasks: - - name: Checking home directory - shell: echo $HOME - register: home_dir - - name: Cleaning tempT file: - path: '{{ home_dir.stdout }}/tempT' + path: '{{ ansible_env.HOME }}/tempT' state: absent - name: Cleaning qtip_result file: - path: '{{ home_dir.stdout }}/qtip_result' + path: '{{ ansible_env.HOME }}/qtip_result' state: absent + + diff --git a/qtip/driver/playbook/unixbench/dhrystone.yaml b/qtip/driver/playbook/unixbench/dhrystone.yaml new file mode 100644 index 00000000..431814dd --- /dev/null +++ b/qtip/driver/playbook/unixbench/dhrystone.yaml @@ -0,0 +1,27 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation and others. +# zhihui.wu1@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 +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +- name: Run dhrystone + shell: ./Run -v dhrystone + args: + chdir: '{{ ansible_env.HOME }}/tempT/UnixBench/' + +- name: Copying result and system info to qtip result directory + shell: '{{ item }}' + with_items: + - mv ~/tempT/UnixBench/results/* ./ + - cp ~/qtip_result/inxi.log ~/qtip_result/top.log ./ + args: + chdir: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + +- name: Fetch dhrystone result files to local manchine + synchronize: + mode: pull + src: '{{ ansible_env.HOME }}/qtip_result/' + dest: '{{ result_dir }}/dhrystone/logs/' diff --git a/qtip/driver/playbook/unixbench/run.yaml b/qtip/driver/playbook/unixbench/run.yaml new file mode 100644 index 00000000..acef36a7 --- /dev/null +++ b/qtip/driver/playbook/unixbench/run.yaml @@ -0,0 +1,37 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation and others. +# zhihui.wu1@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 +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +- hosts: hosts + become: yes + remote_user: root + + tasks: + - set_fact: + is_dhrystone: "{{ dhrystone | default(False) }}" + is_whetstone: "{{ whetstone | default(False) }}" + timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d-%H-%M') }}" + + - name: Make some directories needed + file: + path: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + state: directory + + - include: ../inxi.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/' + + - include: ../top.yaml + vars: + dest_path: '{{ ansible_env.HOME }}/qtip_result/' + + - include: ./dhrystone.yaml + when: "{{ is_dhrystone }}" + + - include: ./whetstone.yaml + when: "{{ is_whetstone }}"
\ No newline at end of file diff --git a/qtip/driver/playbook/dhrystone/setup.yaml b/qtip/driver/playbook/unixbench/setup.yaml index 430670c1..283884ac 100644 --- a/qtip/driver/playbook/dhrystone/setup.yaml +++ b/qtip/driver/playbook/unixbench/setup.yaml @@ -1,39 +1,46 @@ -############################################################################## +############################################################################# # Copyright (c) 2017 ZTE Corporation and others. -# +# zhihui.wu1@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 # http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## +############################################################################# - hosts: localhost connection: local gather_facts: no tasks: + - set_fact: + is_dhrystone: "{{ dhrystone | default(False) }}" + is_whetstone: "{{ whetstone | default(False) }}" + - name: Making dhrystone directory file: path: '{{ result_dir }}/dhrystone/logs/' state: directory + when: '{{ is_dhrystone }}' + + - name: Making whetstone directory + file: + path: '{{ result_dir }}/whetstone/logs/' + state: directory + when: '{{ is_whetstone }}' - hosts: hosts become: yes remote_user: root tasks: - - name: Checking home directory - shell: echo $HOME - register: home_dir - - name: Cleaning tempT directory file: - path: '{{ home_dir.stdout }}/tempT' + path: '{{ ansible_env.HOME }}/tempT' state: absent - name: Cleaning qtip_result directory file: - path: '{{ home_dir.stdout }}/qtip_result' + path: '{{ ansible_env.HOME }}/qtip_result' state: absent - include: ../prepare_env.yaml @@ -60,7 +67,10 @@ - patch - perl - - name: Clone unixbench + - name: Clone UnixBench git: repo: https://github.com/kdlucas/byte-unixbench.git - dest: '{{ home_dir.stdout }}/tempT' + dest: '{{ ansible_env.HOME }}/tempT/' + + - name: Make UnixBench + shell: make --directory $HOME/tempT/UnixBench/
\ No newline at end of file diff --git a/qtip/driver/playbook/unixbench/whetstone.yaml b/qtip/driver/playbook/unixbench/whetstone.yaml new file mode 100644 index 00000000..f09e4e53 --- /dev/null +++ b/qtip/driver/playbook/unixbench/whetstone.yaml @@ -0,0 +1,28 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation and others. +# zhihui.wu1@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 +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +- name: Run whetstone + shell: ./Run -v whetstone + when: whetstone + args: + chdir: '{{ ansible_env.HOME }}/tempT/UnixBench/' + +- name: Copying result and system info to qtip result directory + shell: '{{ item }}' + with_items: + - mv ~/tempT/UnixBench/results/* ./ + - cp ~/qtip_result/inxi.log ~/qtip_result/top.log ./ + args: + chdir: '{{ ansible_env.HOME }}/qtip_result/{{ timestamp }}/{{ ansible_hostname }}' + +- name: Fetch whetstone result files to local manchine + synchronize: + mode: pull + src: '{{ ansible_env.HOME }}/qtip_result/' + dest: '{{ result_dir }}/whetstone/logs/' diff --git a/qtip/reporter/console.py b/qtip/reporter/console.py index 24c98e74..2b5130a6 100644 --- a/qtip/reporter/console.py +++ b/qtip/reporter/console.py @@ -1,5 +1,5 @@ ############################################################################## -# Copyright (c) 2016 ZTE Corp and others. +# Copyright (c) 2017 taseer94@gmail.com and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 @@ -7,6 +7,9 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +from jinja2 import Environment +from jinja2 import FileSystemLoader +from os import path from qtip.base import BaseActor @@ -16,8 +19,12 @@ class ConsoleReporter(BaseActor): """ def __init__(self, config, parent=None): super(ConsoleReporter, self).__init__(config, parent=parent) - # TODO(yujunz) remove PoC code - self._fmt = "{title}: {description}" + + # TODO (taseer) load template from config + tpl_loader = FileSystemLoader(path.join(path.dirname(__file__), 'templates')) + env = Environment(loader=tpl_loader) + self._template = env.get_template('timeline.j2') def render(self, var_dict): - return self._fmt.format(**var_dict) + out = self._template.render(var_dict) + return out diff --git a/qtip/reporter/templates/report.j2 b/qtip/reporter/templates/report.j2 new file mode 100644 index 00000000..766e6dde --- /dev/null +++ b/qtip/reporter/templates/report.j2 @@ -0,0 +1,22 @@ +{{ title }} + +Plan: {{ plan.name }} + +{{ qpi.name }}: {{ qpi.score }} +Sections: +{% for section in sections %} + {{ section.name }}: {{ section.score }} + + Formula: {{ section.formula }} + Metrics: + {% for metric in section.metrics %} + {{ metric.name }}: {{ metric.score }} + Formula: {{ metric.formula }} + Workloads: + {% for workload in workloads %} + {{ workload.name }}: {{ workload.score }} + {% endfor %} + {% endfor %} +{% endfor %} + +{{ signature }} diff --git a/qtip/reporter/templates/timeline.j2 b/qtip/reporter/templates/timeline.j2 index 9c18a996..d4c95c46 100644 --- a/qtip/reporter/templates/timeline.j2 +++ b/qtip/reporter/templates/timeline.j2 @@ -1,4 +1,4 @@ -{% title %} +{{ title }} {% for phase in phases %} {{ phase.name|upper }}{{ "TIME" }} {% for cp in phase.checkpoints %} diff --git a/qtip/util/env.py b/qtip/util/env.py index 0585a4c1..24e08658 100644 --- a/qtip/util/env.py +++ b/qtip/util/env.py @@ -1,15 +1,18 @@ ############################################################################## -# Copyright (c) 2016 Dell Inc, ZTE and others. +# Copyright (c) 2017 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 ############################################################################## +from collections import defaultdict import os +from os import path +import re import socket +import sys import time -from os import path import paramiko @@ -51,50 +54,134 @@ def clean_file(*files): return len(results) == len(files) and False not in results -def generate_host_file(hostfile=HOST_FILE): - installer_type = str(os.environ['INSTALLER_TYPE'].lower()) - installer_ip = str(os.environ['INSTALLER_IP']) - - if installer_type not in ["fuel"]: - raise ValueError("%s is not supported" % installer_type) - if not installer_ip: - raise ValueError("The value of environment variable INSTALLER_IP is empty") - - cmd = "bash %s/generate_host_file.sh -i %s -a %s -d %s" % \ - (SCRIPT_DIR, installer_type, installer_ip, hostfile) - os.system(cmd) - return all_files_exist(hostfile) - - -def generate_keypair(keyname='QtipKey'): - """Generating ssh keypair""" - cmd = "ssh-keygen -t rsa -N "" -f {0} -q -b 2048".format(keyname) - os.system(cmd) - return all_files_exist(PRIVATE_KEY, PUBLIC_KEY) - - -def pass_keypair(ip, private_key=PRIVATE_KEY): - os.system('ssh-keyscan %s >> /root/.ssh/known_hosts' % ip) - time.sleep(2) - - ssh_cmd = '%s/qtip_creds.sh %s %s' % (SCRIPT_DIR, ip, private_key) - os.system(ssh_cmd) +class AnsibleEnvSetup(object): + def __init__(self): + self.keypair = defaultdict(str) + self.hostfile = None + self.host_ip_list = [] + def setup(self, config={}): + try: + if 'hostfile' in config: + self.check_hostfile(config['hostfile']) + else: + self.generate_default_hostfile() + self.fetch_host_ip_from_hostfile() + if 'keypair' in config: + self.check_keypair(config['keypair']) + else: + self.generate_default_keypair() + self.pass_keypair_to_remote() + self.check_hosts_ssh_connectivity() + except Exception as error: + print(error) + sys.exit(1) + + def check_keypair(self, keypair): + self.keypair = defaultdict(str) + if all_files_exist(keypair, '{0}.pub'.format(keypair)): + self.keypair['private'] = keypair + self.keypair['public'] = '{0}.pub'.format(keypair) + else: + raise RuntimeError("The keypairs you in the configuration file" + " is invalid or not existed.") + + def generate_default_keypair(self): + if not all_files_exist(PRIVATE_KEY, PUBLIC_KEY): + print("Generate default keypair {0} under " + "{1}".format(KEYNAME, os.environ['HOME'])) + cmd = '''ssh-keygen -t rsa -N "" -f {0} -q -b 2048'''.format( + PRIVATE_KEY) + os.system(cmd) + self.keypair['private'] = PRIVATE_KEY + self.keypair['public'] = PUBLIC_KEY + + def pass_keypair_to_remote(self): + results = map(lambda ip: self._pass_keypair(ip, self.keypair['private']), + self.host_ip_list) + + if not (len(results) == len(self.host_ip_list) and False not in results): + raise RuntimeError("Failed on passing keypair to remote.") + + @staticmethod + def _pass_keypair(ip, private_key): + try: + os.system('ssh-keyscan %s >> /root/.ssh/known_hosts' % ip) + time.sleep(2) + ssh_cmd = '%s/qtip_creds.sh %s %s' % (SCRIPT_DIR, ip, private_key) + os.system(ssh_cmd) + print('Pass keypair to remote hosts {0} successfully'.format(ip)) + return True + except Exception as error: + print(error) + return False -def ssh_is_ok(ip, private_key=PRIVATE_KEY, attempts=100): - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - ssh.connect(ip, key_filename=private_key) + def check_hostfile(self, hostfile): + if all_files_exist(hostfile): + self.hostfile = hostfile + else: + raise RuntimeError( + "The hostfile {0} is invalid or not existed.".format(hostfile)) - for attempt in range(attempts): + def generate_default_hostfile(self): try: - stdin, stdout, stderr = ssh.exec_command('uname') - if not stderr.readlines(): - print("{0}: SSH test successful".format(ip)) - return True - except socket.error: - if attempt == (attempts - 1): - return False - print("%s times ssh test......failed" % attempt) - time.sleep(2) - return False + # check whether the file is already existed + self.check_hostfile(HOST_FILE) + except Exception: + print("Generate default hostfile {0} under " + "{1}".format(HOST_FILE, os.environ['HOME'])) + self._generate_hostfile_via_installer() + + def _generate_hostfile_via_installer(self): + self.hostfile = None + + installer_type = str(os.environ['INSTALLER_TYPE'].lower()) + installer_ip = str(os.environ['INSTALLER_IP']) + + if installer_type not in ["fuel"]: + raise ValueError("{0} is not supported".format(installer_type)) + if not installer_ip: + raise ValueError( + "The value of environment variable INSTALLER_IP is empty.") + + cmd = "bash %s/generate_host_file.sh -t %s -i %s -d %s" % \ + (SCRIPT_DIR, installer_type, installer_ip, HOST_FILE) + os.system(cmd) + + self.hostfile = HOST_FILE + + def fetch_host_ip_from_hostfile(self): + self.host_ip_list = [] + print('Fetch host ips from hostfile...') + with open(self.hostfile, 'r') as f: + self.host_ip_list = re.findall('\d+.\d+.\d+.\d+', f.read()) + if self.host_ip_list: + print("The remote compute nodes: {0}".format(self.host_ip_list)) + else: + raise ValueError("The hostfile doesn't include host ip addresses.") + + def check_hosts_ssh_connectivity(self): + results = map(lambda ip: self._ssh_is_ok(ip, self.keypair['private']), + self.host_ip_list) + if not (len(results) == len(self.host_ip_list) and False not in results): + raise RuntimeError("Failed on checking hosts ssh connectivity.") + + @staticmethod + def _ssh_is_ok(ip, private_key, attempts=100): + print('Check hosts {0} ssh connectivity...'.format(ip)) + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect(ip, key_filename=private_key) + + for attempt in range(attempts): + try: + stdin, stdout, stderr = ssh.exec_command('uname') + if not stderr.readlines(): + print("{0}: SSH test successful.".format(ip)) + return True + except socket.error: + print("%s times ssh test......failed." % str(attempt + 1)) + if attempt == (attempts - 1): + return False + time.sleep(2) + return False |