Add basic job for Rally task

* Rename zuul.yaml -> .zuul.yaml to hide this file from the top level of
  root directory

* Remove all redundant scripts which were used in the old CI

* Modify devstack plugin to print information about Rally-OpenStack

* Add simple task file with one workload to check the single job

* Add an index html page for the new job. It is quite simple, doesn't
  use template, so no need to special script which will make this file.
  Also, we do not need to ship this file with python package since it is
  located in proper place.

* Add a basic job which launchs Rally task based on input arguments:
  - rally_task_file - a patch to Rally task file in relative way to
       project path (project which where the job is launched)
  - rally_task_args_file - an optional path to a file with arguments to
       Rally task. It is also relative to the project path
  - use_existing_users - Defaults to False. Whethere to create and put
       existing users to Rally deployment/enviroment or not.

Change-Id: Ib3b021914ac7d565df05c5397b378037ca0c0b00
This commit is contained in:
Andrey Kurilin 2018-02-27 15:23:26 +02:00
parent b387e96637
commit 209337291c
29 changed files with 595 additions and 803 deletions

79
.zuul.yaml Normal file
View File

@ -0,0 +1,79 @@
- job:
name: rally-tox-pep8
parent: tox
description: |
Run test for rally project.
Uses tox with the ``pep8`` environment.
vars:
tox_envlist: pep8
- job:
name: rally-tox-py27
parent: tox
description: |
Run test for rally project.
Uses tox with the ``py27`` environment.
vars:
tox_envlist: py27
- job:
name: rally-tox-py35
parent: tox
description: |
Run test for rally project.
Uses tox with the ``py35`` environment.
vars:
tox_envlist: py35
- job:
name: rally-task-at-devstack
parent: devstack
description: Base job for launching Rally task at Devstack
required-projects:
- name: openstack-dev/devstack
- name: openstack-infra/devstack-gate
- name: openstack/rally
- name: openstack/rally-openstack
timeout: 7200
roles:
- zuul: openstack-dev/devstack
vars:
devstack_plugins:
rally-openstack: https://git.openstack.org/openstack/rally-openstack
devstack_services:
rally-openstack: true
cinder: true
# disable redundant services for the job
ceilometer-acentral: false
ceilometer-acompute: false
ceilometer-alarm-evaluator: false
ceilometer-alarm-notifier: false
ceilometer-anotification: false
ceilometer-api: false
ceilometer-collector: false
horizon: false
tempest: false
run: tests/ci/playbooks/run-rally-task.yaml
post-run: tests/ci/playbooks/post-rally-task.yaml
- job:
name: rally-task-simple-job
parent: rally-task-at-devstack
vars:
rally_task: rally-jobs/simple-cinder.yaml
- project:
check:
jobs:
- rally-tox-pep8
- rally-tox-py27
- rally-tox-py35
- rally-task-simple-job
gate:
jobs:
- rally-tox-pep8
- rally-tox-py27
- rally-tox-py35

View File

@ -8,13 +8,13 @@ DIR=$(dirname ${BASH_SOURCE[0]})
source $DIR/lib/rally
if [[ "$1" == "stack" && "$2" == "install" ]]; then
echo_summary "Installing Rally"
echo_summary "Installing Rally-OpenStack"
install_rally
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
echo_summary "Configuring Rally"
echo_summary "Configuring Rally-OpenStack"
configure_rally
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
echo_summary "Initializing Rally"
echo_summary "Initializing Rally-OpenStack"
init_rally
fi

View File

@ -0,0 +1,20 @@
---
version: 2
title: Task for rally-task-simple-job
description: Testing just one cinder scenario to verify that rally-task-job works
subtasks:
-
title: CinderVolumes.create_volume tests
workloads:
-
scenario:
CinderVolumes.create_volume:
size: 1
runner:
constant:
times: 2
concurrency: 2
contexts:
users:
tenants: 2
users_per_tenant: 2

View File

@ -1,91 +0,0 @@
===============
Rally Gate Jobs
===============
For each patch submitted for review on Gerrit, there is a set of tests called
**gate jobs** to be run against it. These tests check whether the Rally code
works correctly after applying the patch and provide additional guarantees that
it won't break the software when it gets merged. Rally gate jobs contain tests
checking the codestyle (via *pep8*), unit tests suites, functional tests and a
set of Rally benchmark tasks that are executed against a real *devstack*
deployment.
rally-gate.sh
-------------
This script runs a set of real Rally benchmark tasks and fetches their results
in textual / visualized form (available via a special html page by clicking the
corresponding job title in Gerrit). It checks that scenarios don't fail while
being executed against a devstack deployment and also tests SLA criteria to
ensure that benchmark tasks have completed successfully.
Jenkins uses this script by runnint the 'gate-rally-dsvm-rally' job,
'gate-rally-dsvm-manila-multibackend' job and 'gate-rally-dsvm-neutron-rally'
job.
rally_verify.py
---------------
This script runs various "rally verify" commands. This set of commands allow us
to perform Tempest tests of OpenStack live cloud and display verification
results.
The verification results obtained by running various "rally verify <cmd>"
commands including "start", "show", "list" are compared using the "rally verify
results" command, which are then saved in csv, html and json formats in the
"rally-verify" directory.
Jenkins uses this script by running the 'gate-rally-dsvm-verify' job.
test_install.sh
---------------
This script tests the correct working of the install_rally.sh, used for the
installation of Rally. Jenkins tests this script by running it against Centos7
and Ubuntu 16.04 in the corresponding jobs 'gate-rally-install-centos-7' and
'gate-rally-install-ubuntu-xenial'.
Jenkins
-------
Jenkins is a Continuous Integration system which works as the scheduler. It
receives events related to proposed changes, triggers tests based on those
events, and reports back.
For each patch that is uploaded for review on Gerrit, Jenkins runs it against
the various rally gate jobs listed below along with their functions and local
equivalents:
* gate-rally-pep8 : code style check
(equal to tox -epep8)
* gate-rally-docs : documention generation
(equal to tox -edocs)
* gate-rally-python27 : unit tests against python27
(equal to tox -epy27)
* gate-rally-python35 : unit tests against python35
(equal to tox -epy35)
* rally-coverage : generates unit test
coverage
(equal to tox -cover)
* gate-rally-install-centos-7 : testing of test_install.sh
(described above) against
Centos7
* gate-rally-install-ubuntu-xenial : testing of test_install.sh
(described above) against
Ubuntu 16.04
* gate-rally-dsvm-rally : runs rally-gate.sh
(described above) against
OpenStack deployed by
devstack with nova-network
(It is standard dsvm job)
* gate-rally-dsvm-manila-multibackend(non-voting) : runs rally-gate.sh against
manila
* gate-rally-dsvm-neutron-rally : runs rally-gate.sh against
OpenStack deployed by
devastack with neutron
* gate-rally-dsvm-cli : runs tests/functional/*
(equal to tox -ecli)
* gate-rally-dsvm-verify(non-voting) : runs rally_verify.py and
tests Rally and Tempest
integration in all possible
ways
* gate-rally-tox-self(non-voting) : not yet used
and a success in these tests(except non-voting) would mean that the patch is
approved by Jenkins.

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $SCRIPT_DIR/../rally_gate_functions.sh
setUp
TASK=$RALLY_DIR/tasks/openstack/task.yaml
TASK_ARGS=$RALLY_DIR/rally-jobs/certifcation_task_args.yaml
TASK_ARGS="--task-args-file $TASK_ARGS"
run $TASK $TASK_ARGS

View File

@ -0,0 +1,121 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rally | Performance job results</title>
<script type="text/javascript"></script>
<style>
body { margin:0; padding:0 0 50px; font-size:14px; font-family:Helvetica,Arial,sans-serif }
a, a:active, a:focus, a:visited { text-decoration:none; outline:none }
p { margin:0; padding:5px 0 }
p.thesis { padding:10px 0 }
h1 { color:#666; margin:0 0 20px; font-size:30px; font-weight:normal }
h2, .h2 { color:#666; margin:24px 0 6px; font-size:25px; font-weight:normal }
h3, .h3 { color:#777; margin:12px 0 4px; font-size:18px; font-weight:normal }
table { border-collapse:collapse; border-spacing:0; width:100%; font-size:12px; margin:0 0 10px }
table th { text-align:left; padding:8px; color:#000; border:2px solid #ddd; border-width:0 0 2px 0 }
table th.sortable { cursor:pointer }
table td { text-align:left; border-top:1px solid #ddd; padding:8px; color:#333 }
table.compact td { padding:4px 8px }
table.striped tr:nth-child(odd) td { background:#f9f9f9 }
table.linked tbody tr:hover { background:#f9f9f9; cursor:pointer }
.pointer { cursor:pointer }
.rich, .rich td { font-weight:bold }
.oblique { font-style:italic }
.code { padding:10px; font-size:13px; color:#333; background:#f6f6f6; border:1px solid #e5e5e5; border-radius:4px }
.header { text-align:left; background:#333; font-size:18px; padding:13px 0; margin-bottom:20px; color:#fff; background-image:linear-gradient(to bottom, #444 0px, #222 100%) }
.header a, .header a:visited, .header a:focus { color:#999 }
.notify-error { padding:5px 10px; background:#fee; color:red }
.status-skip, .status-skip td { color:grey }
.status-pass, .status-pass td { color:green }
.status-fail, .status-fail td { color:red }
.capitalize { text-transform:capitalize }
li { margin:2px 0 }
a, a:visited { color:#039 }
code { padding:0 5px; color:#888 }
.columns li { position:relative }
.columns li > :first-child { display:block }
.columns li > :nth-child(2) { display:block; position:static; left:165px; top:0; white-space:nowrap }
.content-wrap { margin:0 auto; padding:0 5px; }
@media only screen and (min-width: 320px) { .content-wrap { width:400px } }
@media only screen and (min-width: 520px) { .content-wrap { width:500px } }
@media only screen and (min-width: 620px) { .content-wrap { width:90% } .columns li > :nth-child(2) { position:absolute } }
@media only screen and (min-width: 720px) { .content-wrap { width:70% } }
</style>
</head>
<body>
<div class="header" id="page-header">
<div class="content-wrap">
<a href="https://github.com/openstack/rally">Rally</a>&nbsp;
<span>performance job results</span>
</div>
</div>
<div class="content-wrap" id="page-content">
<h2>Status of the job</h2>
<p><span id="status-message" class="rich">Everything is ok! (All workloads passed their SLA and all tests resources were removed as expected)</span></p>
<h2>Logs and files</h2>
<ul class="columns">
<li><a href="job-output.txt.gz" class="rich check-gz">Rally Task Logs</a> <code>job-output.txt.gz</code>
<li><a href="zuul-info/">Zuul info</a> <code>zuul-info</code>
<li><a href="controller/logs/">Logs of controller node</a> <code>controller/logs/</code>
<li><a href="ara/">ARA | Ansible Run Analysis</a>
</ul>
<h2>Job results, in different formats</h2>
<ul class="columns">
<li><a href="results/report.html.gz" class="rich">HTML report</a> <code>$ rally task report</code>
<li><a href="results/detailed.txt.gz">Text report</a> <code>$ rally task detailed</code>
<li><a href="results/detailed_with_iterations.txt.gz">Text report detailed</a> <code>$ rally task detailed --iterations-data</code>
<li><a href="results/sla.txt">Success criteria (SLA)</a> <code>$ rally task sla_check</code>
<li><a href="results/report.json.gz">JSON report</a> <code>$ rally task report --json</code>
<li><a href="results/results.json.gz">Old json results</a> <code>$ rally task results</code>
<li><a href="results/junit.xml.gz">JUNIT-XML report</a> <code>$ rally task export --type junit-xml</code>
<li><a href="results/elasticsearch.txt.gz">ElasticSearch x5 dump file</a> <code>$ rally task export --type elastic</code>
</ul>
<h2>About Rally</h2>
<p>Rally is tool & framework that allows one to write simple plugins and combine them in
complex tests scenarios that allows to perform all kinds of testing!
</p>
<ul>
<li><a href="https://git.openstack.org/cgit/openstack/rally">Rally git repository</a> (<a href="https://github.com/openstack/rally">GitHub mirror</a>)
<li><a href="https://git.openstack.org/cgit/openstack/rally-openstack">Git repository with OpenStack plugins for Rally</a> (<a href="https://github.com/openstack/rally-openstack">GitHub mirror</a>)
<li><a href="https://rally.readthedocs.org/en/latest/">Documentation</a>
<li><a href="https://rally.readthedocs.io/en/latest/quick_start/tutorial.html">How to use Rally (locally)</a>
<li><a href="https://rally.readthedocs.io/en/latest/quick_start/gates.html">How to add Rally job to your project</a>
</ul>
<h2>Steps to repeat locally</h2>
<ol>
<li>Fetch rally task from <a href="results/task.yaml">here</a></li>
<li>Fetch rally plugins from <a href="results/plugins.tar.gz">here</a></li>
<li>Install OpenStack and Rally using <a href="https://github.com/openstack/rally-openstack/tree/master/devstack">this instruction</a></li>
<li>Unzip plugins and put to <code>.rally/plugins/</code> directory</li>
<li>Run rally task: <code>$ rally task start task.yaml</code></li>
</ol>
</div>
<script type="text/javascript">
var errorMessage = null;
if (errorMessage) {
var statusMessage = document.getElementById("status-message");
statusMessage.style.color = 'red';
statusMessage.innerHTML = errorMessage
}
</script>
</body>
</html>

View File

@ -1,41 +0,0 @@
- hosts: primary
tasks:
- name: Copy files from {{ ansible_user_dir }}/workspace/ on node
synchronize:
src: '{{ ansible_user_dir }}/workspace/'
dest: '{{ zuul.executor.log_root }}'
mode: pull
copy_links: true
verify_host: true
rsync_opts:
- --include=/logs/**
- --include=*/
- --exclude=*
- --prune-empty-dirs
- name: Copy files from {{ ansible_user_dir }}/workspace/ on node
synchronize:
src: '{{ ansible_user_dir }}/workspace/'
dest: '{{ zuul.executor.log_root }}'
mode: pull
copy_links: true
verify_host: true
rsync_opts:
- --include=/rally-plot/**
- --include=*/
- --exclude=*
- --prune-empty-dirs
- name: Copy files from {{ ansible_user_dir }}/workspace/ on node
synchronize:
src: '{{ ansible_user_dir }}/workspace/'
dest: '{{ zuul.executor.log_root }}'
mode: pull
copy_links: true
verify_host: true
rsync_opts:
- --include=/rally-plot/extra/index.html
- --include=*/
- --exclude=*
- --prune-empty-dirs

View File

@ -0,0 +1,6 @@
- hosts: controller
vars:
rally_home_dir: '/opt/stack/.rally'
rally_results_dir: '{{ rally_home_dir }}/results'
roles:
- fetch-rally-task-results

View File

@ -1,34 +0,0 @@
- hosts: all
name: a run script for rally-install-ubuntu-xenial and rally-install-centos-7 jobs
tasks:
- shell:
cmd: |
sudo yum remove -y python-crypto || true
# NOTE(pabelanger): We run apt-get update to ensure we dont have a stale
# package cache in the gate.
sudo apt-get update || true
sudo ./install_rally.sh --system --yes
rally deployment list
[ -d /etc/bash_completion.d ] && cat /etc/bash_completion.d/rally.bash_completion || true
sudo ./install_rally.sh --system --yes
rally deployment list
sudo ./install_rally.sh --yes -d /tmp/rallytest_root/
/tmp/rallytest_root/bin/rally deployment list
cat /tmp/rallytest_root/etc/bash_completion.d/rally.bash_completion
sudo rm -fr ~/.rally
./install_rally.sh --yes -d /tmp/rallytest_user
/tmp/rallytest_user/bin/rally deployment list
./install_rally.sh --overwrite --dbtype sqlite
executable: /bin/sh
chdir: '{{ zuul.project.src_dir }}'

View File

@ -0,0 +1,7 @@
- name: Check OpenStack resources after Rally launch
become: yes
become_user: stack
shell: "python ./tests/ci/osresources.py --compare-with-list {{ rally_resources_at_start }}"
args:
chdir: "{{ zuul.projects['git.openstack.org/openstack/rally-openstack'].src_dir }}"

View File

@ -0,0 +1,4 @@
- name: Check SLA of the last task
become: True
become_user: stack
shell: "rally task sla-check > {{ rally_results_dir }}/sla.txt"

View File

@ -0,0 +1,48 @@
- name: Gzip results files
become: yes
become_user: stack
shell: "gzip * -9 -q"
args:
chdir: '{{ rally_results_dir }}'
- name: Gzip custom plugins
become: yes
become_user: stack
shell: "tar -czf {{ rally_results_dir }}/plugins.tar.gz ./plugins"
args:
chdir: '{{ rally_home_dir }}'
- name: Copy Rally results
become: yes
synchronize:
src: '{{ rally_results_dir }}'
dest: '{{ zuul.executor.log_root }}'
mode: pull
copy_links: true
verify_host: true
rsync_opts:
- --include=/**
- --include=*/
- --exclude=*
- --prune-empty-dirs
- name: Change the status message
become: yes
shell:
cmd: |
set -e
#sed -i -- "s/var errorMessage = null\;/var errorMessage = \'TBD\';/g" {{ zuul.projects['git.openstack.org/openstack/rally-openstack'].src_dir }}/tests/ci/pages/task-index.html
- name: Put index.html in the right place
become: yes
synchronize:
src: "{{ zuul.projects['git.openstack.org/openstack/rally-openstack'].src_dir }}/tests/ci/pages/task-index.html"
dest: '{{ zuul.executor.log_root }}/index.html'
mode: pull
copy_links: true
verify_host: true
rsync_opts:
- --include=/**
- --include=*/
- --exclude=*
- --prune-empty-dirs

View File

@ -0,0 +1,9 @@
- name: Import a current JSON report
become: True
become_user: stack
command: rally task import --file {{ rally_results_dir }}/report.json
- name: Import an old JSON report
become: True
become_user: stack
command: rally task import --file {{ rally_results_dir }}/results.json

View File

@ -0,0 +1,6 @@
existing_user_name_1: "rally-test-user-1"
existing_user_password_1: "rally-test-password-1"
existing_user_project_1: "rally-test-project-1"
existing_user_name_2: "rally-test-user-2"
existing_user_password_2: "rally-test-password-2"
existing_user_project_2: "rally-test-project-2"

View File

@ -0,0 +1,198 @@
- name: Create Rally home directory
become: True
become_user: stack
file:
path: '{{ rally_home_dir }}'
state: directory
owner: stack
group: stack
- name: Create directory for Rally results
become: True
become_user: stack
file:
path: '{{ rally_home_dir }}/results'
state: directory
owner: stack
group: stack
- name: Create a directory for custom plugins
become: True
become_user: stack
file:
path: '{{ rally_home_dir }}/plugins'
state: directory
owner: stack
group: stack
- name: Check the existence of custom plugins
stat:
path: '{{ zuul.project.src_dir }}/rally-jobs/plugins'
register: custom_plugins_stat
- name: Copy custom plugins, if they are presented
become: True
become_user: stack
command: cp -r {{ zuul.project.src_dir }}/rally-jobs/plugins {{ rally_home_dir }}/
when: custom_plugins_stat.stat.exists == True
- name: Create a directory for extra files
become: True
become_user: stack
file:
path: '{{ rally_home_dir }}/extra'
state: directory
owner: stack
group: stack
- name: Check the existence of extra files
stat:
path: '{{ zuul.project.src_dir }}/rally-jobs/extra'
register: extra_files_stat
- name: Copy extra files, if they are presented
become: True
become_user: stack
command: cp -r {{ zuul.project.src_dir }}/rally-jobs/extra {{ rally_home_dir }}/extra
when: extra_files_stat.stat.exists == True
- name: Check the existence of fake image
stat:
path: '{{ rally_fake_image_path }}'
register: fake_image_stat
- name: Create a fake image
become: True
become_user: stack
file:
path: '{{ rally_fake_image_path }}'
state: touch
when: fake_image_stat.stat.exists == False
- name: List glance, cinder, neutron resources
become: True
become_user: stack
shell:
executable: /bin/sh
cmd: |
set -e
rally deployment use --deployment devstack
. {{ rally_home_dir }}/openrc admin admin
OPENSTACK_SERVICES=$(openstack service list)
if [[ $OPENSTACK_SERVICES == *"glance"* ]]; then
openstack image list
fi
if [[ $OPENSTACK_SERVICES == *"cinder"* ]]; then
openstack volume list --all-projects
fi
if [[ $OPENSTACK_SERVICES == *"neutron"* ]]; then
openstack network list
fi
- name: Create new projects and users
become: True
become_user: stack
shell:
executable: /bin/sh
cmd: |
set -e
. {{ rally_home_dir }}/openrc admin admin
openstack --version
openstack project create {{ existing_user_project_1 }}
openstack user create --project {{ existing_user_project_1 }} --password {{ existing_user_password_1 }} {{ existing_user_name_1 }}
openstack role add --project {{ existing_user_project_1 }} --user {{ existing_user_name_1 }} Member
openstack project create {{ existing_user_project_2 }}
openstack user create --project {{ existing_user_project_2 }} --password {{ existing_user_password_2 }} {{ existing_user_name_2 }}
openstack role add --project {{ existing_user_project_2 }} --user {{ existing_user_name_2 }} Member
set +e
NEUTRON_EXISTS=$(openstack --os-interface admin service list | grep neutron)
set -e
if [ "$NEUTRON_EXISTS" ]; then
OS_QUOTA_STR="--networks -1 --subnets -1 --routers -1 --floating-ips -1 --subnetpools -1 --secgroups -1 --secgroup-rules -1 --ports -1"
openstack --debug quota set $OS_QUOTA_STR {{ existing_user_project_1 }}
openstack --debug quota show {{ existing_user_project_1 }}
openstack --debug quota set $OS_QUOTA_STR {{ existing_user_project_2 }}
openstack --debug quota show {{ existing_user_project_2 }}
fi
when: rally_use_existing_users == True
- name: Capture Keystone auth URL
become: True
become_user: stack
shell: ". {{ rally_home_dir }}/openrc admin admin > /dev/null && echo $OS_AUTH_URL"
register: keystone_auth_url
when: rally_use_existing_users == True
- name: Make Rally Environment spec with existing users
become: True
become_user: stack
template:
src: env.yaml.j2
dest: "{{ rally_existing_users_config }}"
when: rally_use_existing_users == True
- name: Create new projects and users
become: True
become_user: stack
shell: rally env create --name devstask-with-users --spec {{ rally_existing_users_config }}
when: rally_use_existing_users == True
- name: Print Rally deployment config
become: True
become_user: stack
command: "rally deployment config"
- name: Check Environment works
become: True
become_user: stack
command: "rally env check"
- name: Print Environment info
become: True
become_user: stack
command: "rally env info"
- name: Create nova flavor
become: True
become_user: stack
shell:
executable: /bin/sh
cmd: |
set -e
. {{ rally_home_dir }}/openrc admin admin
if rally deployment check | grep 'nova' | grep 'Available' > /dev/null;
then
nova flavor-create m1.nano 42 64 0 1
fi
- name: Copy task file
become: True
become_user: stack
command: cp -r {{ zuul.project.src_dir }}/{{ rally_task }} {{ rally_home_dir }}/task.yaml
- name: Check the existence of task_args_file
stat:
path: '{{ zuul.project.src_dir }}/{{ rally_task_args_file }}'
register: task_args_file_stat
- name: Copy task_args_file
become: True
become_user: stack
command: cp {{ zuul.project.src_dir }}/{{ rally_task_args_file }} {{ rally_home_dir }}/task_args_file.yaml
when: task_args_file_stat.stat.exists == True
- name: Create an empty task_args_file
become: True
become_user: stack
command: echo "{}" > {{ rally_home_dir }}/task_args_file.yaml
when: task_args_file_stat.stat.exists == False

View File

@ -0,0 +1,19 @@
{
"openstack": {
"users": [
{"username": "{{ existing_user_name_1 }}",
"password": "{{ existing_user_password_1 }}",
"project_name": "{{ existing_user_project_1 }}",
"user_domain_name": "Default",
"project_domain_name": "Default"
},
{"username": "{{ existing_user_name_2 }}",
"password": "{{ existing_user_password_2 }}",
"project_name": "{{ existing_user_project_2 }}",
"user_domain_name": "Default",
"project_domain_name": "Default"
}],
"auth_url": " {{ keystone_auth_url.stdout }}",
"region_name": "RegionOne"
}
}

View File

@ -0,0 +1,34 @@
- name: Generate a HTML report
become: True
become_user: stack
command: rally task report --html-static --out {{ rally_results_dir }}/report.html
- name: Show detailed info about task
become: True
become_user: stack
shell: "rally task detailed > {{ rally_results_dir }}/detailed.txt"
- name: Show detailed info (with per-iteration data) about task
become: True
become_user: stack
shell: "rally task detailed --iterations-data > {{ rally_results_dir }}/detailed_with_iterations.txt"
- name: Generate a JSON report
become: True
become_user: stack
command: rally task report --json --out {{ rally_results_dir }}/report.json
- name: Produce an old results file
become: True
become_user: stack
shell: "rally task results > {{ rally_results_dir }}/results.json"
- name: Make a JUnit report
become: True
become_user: stack
command: rally task export --type junit-xml --to {{ rally_results_dir }}/junit.xml
- name: Make an ElasticSearch file
become: True
become_user: stack
command: rally task export --type elastic --to {{ rally_results_dir }}/elasticsearch.txt

View File

@ -0,0 +1,14 @@
- name: Run Rally task
become: True
become_user: stack
shell:
cmd: |
set +e
rally --rally-debug task start --task {{ rally_home_dir }}/task.yaml #--task-args-file {{ rally_home_dir }}/task_args_file.yaml
retval=$?
if [[ $? -eq 1 ]]; then
# 1 exit code means that something unexpected had happened
exit $retval
fi
executable: /bin/bash

View File

@ -0,0 +1,6 @@
- name: Dump all available OpenStack resources
become: yes
become_user: stack
shell: "python ./tests/ci/osresources.py --dump-list {{ rally_resources_at_start }}"
args:
chdir: "{{ zuul.projects['git.openstack.org/openstack/rally-openstack'].src_dir }}"

View File

@ -0,0 +1,21 @@
- hosts: all
roles:
- run-devstack
- hosts: controller
vars:
rally_home_dir: '/opt/stack/.rally'
rally_fake_image_path: '{{ rally_home_dir }}/extra/fake-image.img'
rally_use_existing_users: false
rally_existing_users_config: '{{ rally_home_dir }}/with-existing-users-config'
rally_results_dir: '{{ rally_home_dir }}/results'
rally_resources_at_start: '{{ rally_results_dir }}/resources_at_start.txt'
rally_task_args_file: "100-percent-not-exist-file"
roles:
- prepare-for-rally-task
- snapshot-available-os-resources
- run-rally-task
- process-task-results
- import-task-results
- check-os-resources
- check-task-sla

View File

@ -1,46 +0,0 @@
#!/bin/bash -ex
#
# 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.
# This script is executed by post_test_hook function in devstack gate.
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $SCRIPT_DIR/rally_gate_functions.sh
PROJECT=`echo $ZUUL_PROJECT | cut -d \/ -f 2`
RALLY_JOB_DIR=$BASE/new/$PROJECT/rally-scenarios
if [ ! -d $RALLY_JOB_DIR ]; then
RALLY_JOB_DIR=$BASE/new/$PROJECT/rally-jobs
fi
echo $RALLY_JOB_DIR
echo $RALLY_DIR
ls $BASE/new/$PROJECT
if [ "$RALLY_SCENARIO" == "rally-keystone-api-v2" ]; then
echo "WARNING: RALLY TASK WILL NOT BE LAUNCHED."
exit 0
fi
setUp $RALLY_JOB_DIR
BASE_FOR_TASK=${RALLY_JOB_DIR}/${RALLY_SCENARIO}
TASK=${BASE_FOR_TASK}.yaml
TASK_ARGS=""
if [ -f ${BASE_FOR_TASK}_args.yaml ]; then
TASK_ARGS="--task-args-file ${BASE_FOR_TASK}_args.yaml"
fi
run $TASK $TASK_ARGS

View File

@ -1,30 +0,0 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# 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.
"""Simple app based on rally api for testing porpuses"""
import sys
from rally import api as rapi
def main():
api = rapi.API(config_args=sys.argv[1:])
print(len(api.task.list()))
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
LOCAL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DB_CONNECTION="$(rally db show)"
if [[ $DB_CONNECTION == sqlite* ]]; then
CONCURRENCY=0
else
# in case of not sqlite db backends we cannot launch tests in parallel due
# to possible conflicts
CONCURRENCY=1
# currently, RCI_KEEP_DB variable is used to not create new databases per
# each test
export RCI_KEEP_DB=1
fi
python $LOCAL_DIR/pytest_launcher.py "tests/functional" --concurrency $CONCURRENCY --posargs=$1

View File

@ -1,169 +0,0 @@
#!/usr/bin/env bash
RALLY_DIR=$BASE/new/rally
RALLY_PLUGINS_DIR=~/.rally/plugins
RALLY_EXTRA_DIR=~/.rally/extra
function setUp () {
set -x
JOB_DIR=$1
mkdir -p $RALLY_PLUGINS_DIR
mkdir -p $RALLY_EXTRA_DIR
if [ -n "$JOB_DIR" ]; then
PLUGINS_DIR=${JOB_DIR}/plugins
EXTRA_DIR=${JOB_DIR}/extra
if [ -d $PLUGINS_DIR ]; then
cp -r $PLUGINS_DIR/ $RALLY_PLUGINS_DIR
fi
if [ -d $EXTRA_DIR ]; then
cp -r $EXTRA_DIR/* ~/.rally/extra/
fi
fi
touch ~/.rally/extra/fake-image.img
env
set -o pipefail
rally deployment use --deployment devstack
source ~/.rally/openrc admin admin
OPENSTACK_SERVICES=$(openstack service list)
if [[ $OPENSTACK_SERVICES == *"glance"* ]]; then
openstack image list
fi
if [[ $OPENSTACK_SERVICES == *"cinder"* ]]; then
openstack volume list --all-projects
fi
if [[ $OPENSTACK_SERVICES == *"neutron"* ]]; then
openstack network list
fi
# NOTE(ikhudoshyn): Create additional users and register a new env
# so that we could run scenarios using 'existing_users' context
if [ "$DEVSTACK_GATE_PREPOPULATE_USERS" = "1" ]; then
openstack --version
openstack project create rally-test-project-1
openstack user create --project rally-test-project-1 --password rally-test-password-1 rally-test-user-1
openstack role add --project rally-test-project-1 --user rally-test-user-1 Member
openstack project create rally-test-project-2
openstack user create --project rally-test-project-2 --password rally-test-password-2 rally-test-user-2
openstack role add --project rally-test-project-2 --user rally-test-user-2 Member
set +e
NEUTRON_EXISTS=$(openstack --os-interface admin service list | grep neutron)
set -e
if [ "$NEUTRON_EXISTS" ]; then
OS_QUOTA_STR="--networks -1 --subnets -1 --routers -1 --floating-ips -1 --subnetpools -1 --secgroups -1 --secgroup-rules -1 --ports -1"
openstack --debug quota set $OS_QUOTA_STR rally-test-project-1
openstack --debug quota show rally-test-project-1
openstack --debug quota set $OS_QUOTA_STR rally-test-project-2
openstack --debug quota show rally-test-project-2
fi
DEPLOYMENT_CONFIG_FILE=~/.rally/with-existing-users-config
echo '
{
"openstack": {
"users": [
{"username": "rally-test-user-1",
"password": "rally-test-password-1",
"project_name": "rally-test-project-1",
"user_domain_name": "Default",
"project_domain_name": "Default"
},
{"username": "rally-test-user-2",
"password": "rally-test-password-2",
"project_name": "rally-test-project-2",
"user_domain_name": "Default",
"project_domain_name": "Default"
}],
"auth_url": "'$OS_AUTH_URL'",
"region_name": "RegionOne"
}
}
' > $DEPLOYMENT_CONFIG_FILE
rally deployment create --name devstask-with-users --filename $DEPLOYMENT_CONFIG_FILE
fi
rally deployment config
rally --debug deployment check
if rally deployment check | grep 'nova' | grep 'Available' > /dev/null;
then
nova flavor-create m1.nano 42 64 0 1
fi
}
function run () {
set -x
TASK=$1
TASK_ARGS="$2 $3"
if [ "$DEVSTACK_GATE_USE_PYTHON3" = "True" ]; then
PYTHON=python3
else
PYTHON=python
fi
$PYTHON $RALLY_DIR/tests/ci/osresources.py --dump-list resources_at_start.txt
set +e
rally --rally-debug task start --task $TASK $TASK_ARGS
retval=$?
if [[ $? -eq 1 ]]; then
exit $retval
fi
set -e
mkdir -p rally-plot/extra
$PYTHON $RALLY_DIR/tests/ci/render.py ci/index.html > rally-plot/extra/index.html
cp $TASK rally-plot/task.txt
tar -czf rally-plot/plugins.tar.gz -C $RALLY_PLUGINS_DIR .
rally task results | python -m json.tool > rally-plot/results.json
rally task import --file rally-plot/results.json
gzip -9 rally-plot/results.json
rally task detailed > rally-plot/detailed.txt
gzip -9 rally-plot/detailed.txt
rally task detailed --iterations-data > rally-plot/detailed_with_iterations.txt
gzip -9 rally-plot/detailed_with_iterations.txt
rally task report --html-static --out rally-plot/results.html
gzip -9 rally-plot/results.html
rally task report --json --out rally-plot/new_results.json
rally task import --file rally-plot/new_results.json
gzip -9 rally-plot/new_results.json
rally task export --type junit-xml --to rally-plot/junit.xml
gzip -9 rally-plot/junit.xml
rally task export --type elastic --to rally-plot/elasticsearch.txt
gzip -9 rally-plot/elasticsearch.txt
# NOTE(stpierre): if the sla check fails, we still want osresources.py
# to run, so we turn off -e and save the return value
set +e
rally task sla-check | tee rally-plot/sla.txt
retval=$?
set -e
cp resources_at_start.txt rally-plot/
if [ "$ZUUL_PROJECT" == "openstack/rally" ];then
$PYTHON $RALLY_DIR/tests/ci/osresources.py\
--compare-with-list resources_at_start.txt
else
$PYTHON $RALLY_DIR/tests/ci/osresources.py\
--compare-with-list resources_at_start.txt\
| gzip > rally-plot/resources_diff.txt.gz
fi
exit $retval
}

View File

@ -1,49 +0,0 @@
#!/bin/bash -ex
#
# 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.
TASK_FILE=$1
PLUGIN_PATHS=rally-jobs/plugins
if [ -n "$ZUUL_PROJECT" ]; then
HTML_REPORT=testr_results.html
JSON_REPORT=testr_results.json
else
HTML_REPORT=rally_self_results.html
JSON_REPORT=rally_self_results.json
fi
RND=$(head /dev/urandom | tr -dc a-z0-9 | head -c 5)
TMP_RALLY_CONF="/tmp/self-rally-$RND.conf"
TMP_RALLY_DB="/tmp/self-rally-$RND.sqlite"
DBCONNSTRING="sqlite:///$TMP_RALLY_DB"
RALLY="rally --config-file $TMP_RALLY_CONF"
# Create temp db
cp etc/rally/rally.conf.sample $TMP_RALLY_CONF
sed -i.bak "s|#connection =.*|connection = \"$DBCONNSTRING\"|" $TMP_RALLY_CONF
rally --config-file $TMP_RALLY_CONF db create
# Create self deployment
$RALLY -d deployment create --name=self
# Run task
$RALLY -d --plugin-paths=$PLUGIN_PATHS task start $TASK_FILE
$RALLY task report --html-static --out $HTML_REPORT
$RALLY task report --json --out $JSON_REPORT
if [ -n "$ZUUL_PROJECT" ]; then
gzip -9 -f $HTML_REPORT
gzip -9 -f $JSON_REPORT
fi
# Check sla (this may fail the job)
$RALLY task sla-check

View File

@ -1,37 +0,0 @@
# Copyright 2015: Mirantis Inc.
# All Rights Reserved.
#
# 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 __future__ import print_function
import re
import sys
from rally.ui import utils
HELP_MESSAGE = (
"Usage:\n\t"
"render.py ci/template.html"
"[<key-1>=<value-1> <key-2>=<value-2> ...]\n\n\t"
"Where key-1,value-1 and key-2,value-2 are key pairs of template.")
if __name__ == "__main__":
args = sys.argv
if (len(args) < 1 or not all(re.match("^[^=]+=[^=]+$",
arg) for arg in args[2:])):
print(HELP_MESSAGE, file=sys.stderr)
sys.exit(1)
render_kwargs = dict([arg.split("=") for arg in args[2:]])
print(utils.get_template(args[1]).render(**render_kwargs))

View File

@ -1,40 +0,0 @@
#!/bin/sh -ex
#
# Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
# 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.
sudo yum remove -y python-crypto || true
# NOTE(pabelanger): We run apt-get update to ensure we don't have a stale
# package cache in the gate.
sudo apt-get update || true
sudo ./install_rally.sh --system --yes
rally deployment list
[ -d /etc/bash_completion.d ] && cat /etc/bash_completion.d/rally.bash_completion || true
sudo ./install_rally.sh --system --yes
rally deployment list
sudo ./install_rally.sh --yes -d /tmp/rallytest_root/
/tmp/rallytest_root/bin/rally deployment list
cat /tmp/rallytest_root/etc/bash_completion.d/rally.bash_completion
sudo rm -fr ~/.rally
./install_rally.sh --yes -d /tmp/rallytest_user
/tmp/rallytest_user/bin/rally deployment list
./install_rally.sh --overwrite --dbtype sqlite

View File

@ -1,190 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2015: Mirantis Inc.
# All Rights Reserved.
#
# 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.
import errno
import json
import os
import pwd
import re
import shutil
import subprocess
import sys
import tempfile
from six.moves.urllib import parse
from rally.ui import utils
def use_keystone_v3():
"""Alter deployment to use keystone v3."""
print("Changing deployment to v3")
config = json.loads(subprocess.check_output(["rally", "deployment",
"config"]))
v3_url = parse.urlsplit(config["auth_url"])._replace(path="v3").geturl()
config["auth_url"] = v3_url
endpoint = config.get("endpoint")
if endpoint:
v3_enpoint = parse.urlsplit(endpoint)._replace(path="v3").geturl()
config["endpoint"] = v3_enpoint
config["project_name"] = config["tenant"]
config["project_domain_name"] = config["tenant"]
cfg_file = tempfile.NamedTemporaryFile()
json.dump(config, cfg_file)
print("New config for keystone v3:")
print(json.dumps(config, indent=2))
cfg_file.flush()
subprocess.call(["rally", "deployment", "create",
"--name", "V3", "--file", cfg_file.name])
print(subprocess.check_output(["rally", "deployment", "check"]))
TAG_HANDLERS = {"v3": use_keystone_v3}
def perror(s):
sys.stderr.write(s + "\n")
sys.stderr.flush()
def run(cmd, stdout=None, gzip=True, check=False):
"""Run shell command.
Save output to file, and gzip-compress if needed.
If exit status is non-zero and check is True then raise exception.
Return exit status otherwise.
"""
print("Starting %s" % " ".join(cmd))
status = subprocess.call(cmd, stdout=open(stdout, "w") if stdout else None)
if stdout and gzip:
subprocess.call(["gzip", "-9", stdout])
if check and status:
raise Exception("Failed with status %d" % status)
return status
def run_task(task, tags=None):
new_home_dir = tempfile.mkdtemp(prefix="rally_gate_")
shutil.copytree(os.path.join(pwd.getpwuid(os.getuid()).pw_dir, ".rally"),
os.path.join(new_home_dir, ".rally"))
print("Setting $HOME to %s" % new_home_dir)
os.environ["HOME"] = new_home_dir
for tag in tags or []:
if tag == "args":
continue
if tag not in TAG_HANDLERS:
perror("Warning! Unknown tag '%s'" % tag)
continue
try:
TAG_HANDLERS[tag]()
except Exception as e:
perror("Error processing tag '%s': %s" % (tag, e))
run(["rally", "task", "validate", "--task", task], check=True)
cmd = ["rally", "task", "start", "--task", task]
args_file, ext = task.rsplit(".", 1)
args_file = args_file + "_args." + ext
if os.path.isfile(args_file):
cmd += ["--task-args-file", args_file]
run(cmd, check=True)
task_name = os.path.split(task)[-1]
pub_dir = os.environ.get("RCI_PUB_DIR", "rally-plot")
try:
os.makedirs(os.path.join(pub_dir, "extra"))
except Exception as e:
if e.errno != errno.EEXIST:
raise
run(["rally", "task", "report", "--out",
"%s/%s.html" % (pub_dir, task_name)])
run(["rally", "task", "results"],
stdout="%s/results-%s.json" % (pub_dir, task_name))
status = run(["rally", "task", "sla-check"],
stdout="%s/%s.sla.txt" % (pub_dir, task_name))
run(["rally", "task", "detailed"],
stdout="rally-plot/detailed-%s.txt" % task_name)
run(["rally", "task", "detailed", "--iterations-data"],
stdout="rally-plot/detailed_with_iterations-%s.txt" % task_name)
return status
def get_name_from_git():
"""Determine org/project name from git."""
r = re.compile(".*/(.*?)/(.*?).git$")
for l in open(".git/config"):
m = r.match(l.strip())
if m:
return m.groups()
raise Exception("Unable to get project name from git")
def get_project_name():
for var in ("ZUUL_PROJECT", "GERRIT_PROJECT"):
if var in os.environ:
return os.environ[var].split("/")
return get_name_from_git()
def main():
statuses = []
org, project = get_project_name()
base = os.environ.get("BASE")
if base:
base_jobs_dir = os.path.join(base, "new", project)
else:
base_jobs_dir = os.path.realpath(".")
rally_root = "/home/rally/rally/"
if not os.path.exists(rally_root):
rally_root = os.environ["BASE"] + "/new/rally/"
jobs_dir = os.path.join(base_jobs_dir, "rally-jobs")
if not os.path.exists(jobs_dir):
# fallback to legacy path
jobs_dir = os.path.join(base_jobs_dir, "rally-scenarios")
if not os.path.exists(jobs_dir):
raise Exception("Rally jobs directory does not exist.")
for directory in ("plugins", "extra"):
dst = os.path.expanduser("~/.rally/%s" % directory)
try:
shutil.copytree(os.path.join(jobs_dir, directory), dst)
except OSError as e:
if e.errno != errno.EEXIST:
raise
scenario = os.environ.get("RALLY_SCENARIO", project).rsplit(".", 1)
scenario_name = scenario.pop(0)
scenario_ext = scenario.pop() if scenario else "yaml"
print("Processing scenario %s" % scenario_name)
for fname in os.listdir(jobs_dir):
print("Processing %s" % fname)
if fname.startswith(scenario_name):
tags = fname[len(scenario_name):-len(scenario_ext) - 1].split("_")
statuses.append(run_task(os.path.join(jobs_dir, fname), tags))
else:
print("Ignoring file %s" % fname)
print("Exit statuses: %r" % statuses)
template = utils.get_template("ci/index.html")
with open("rally-plot/extra/index.html", "w") as output:
output.write(template.render())
return any(statuses)
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,41 +0,0 @@
- job:
name: rally-tox-pep8
parent: tox
description: |
Run test for rally project.
Uses tox with the ``pep8`` environment.
vars:
tox_envlist: pep8
- job:
name: rally-tox-py27
parent: tox
description: |
Run test for rally project.
Uses tox with the ``py27`` environment.
vars:
tox_envlist: py27
- job:
name: rally-tox-py35
parent: tox
description: |
Run test for rally project.
Uses tox with the ``py35`` environment.
vars:
tox_envlist: py35
- project:
check:
jobs:
- rally-tox-pep8
- rally-tox-py27
- rally-tox-py35
gate:
jobs:
- rally-tox-pep8
- rally-tox-py27
- rally-tox-py35