First pass at cookbook-openstack-integration-test

This first pass gets tempest installed to /opt/tempest, and sets up
necessary users for testing.  More work needs to be done on adding
correct configuration to tempest.conf and enabling different features
depending on what exists in the environment.  This will most likely
involve exposing everything via different attributes.

Since we checkout master of tempest, the cookbook assumes tempest
will be executed to use a virtual env.  This will hopefully safe-guard
us from future package-related issues.  Note that at the moment
the python virtual env does NOT build cleanly on RHEL 6.5.  According
to devstack, it appears that a number of work-arounds are required to
make tempest run on RHEL 6.5.

Change-Id: I08224d2f4784d2fc041a5806f221e7411d5b813a
This commit is contained in:
Matt Thompson 2014-05-21 16:16:50 +01:00
parent 3e14407c9d
commit 2debea8459
15 changed files with 1013 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.bundle/
.cookbooks/
.kitchen
.vagrant
.coverage/
*.swp
Berksfile.lock
Vagrantfile

24
.rubocop.yml Normal file
View File

@ -0,0 +1,24 @@
AllCops:
Includes:
- metadata.rb
- Gemfile
- attributes/**
- libraries/**
- providers/**
- recipes/**
- resources/**
- spec/**
Encoding:
Exclude:
- metadata.rb
- Gemfile
NumericLiterals:
Enabled: false
LineLength:
Enabled: false
WordArray:
MinSize: 3

14
Berksfile Normal file
View File

@ -0,0 +1,14 @@
metadata
cookbook "openstack-common",
git: "git://github.com/stackforge/cookbook-openstack-common.git"
cookbook "openstack-identity",
git: "git://github.com/stackforge/cookbook-openstack-identity.git"
cookbook "openstack-image",
git: "git://github.com/stackforge/cookbook-openstack-image.git"
cookbook "openstack-compute",
git: "git://github.com/stackforge/cookbook-openstack-compute.git"
cookbook "openstack-network",
git: "git://github.com/stackforge/cookbook-openstack-network.git"
cookbook "openstack-block-storage",
git: "git://github.com/stackforge/cookbook-openstack-block-storage.git"

9
Gemfile Normal file
View File

@ -0,0 +1,9 @@
source 'https://rubygems.org'
gem 'chef', '~> 11.8'
gem 'json', '<= 1.7.7' # chef 11 dependency
gem 'berkshelf', '~> 2.0.10'
gem 'chefspec', '~> 3.4.0'
gem 'foodcritic', '~> 3.0.3'
gem 'strainer'
gem 'rubocop', '~> 0.18.1'

230
Gemfile.lock Normal file
View File

@ -0,0 +1,230 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (3.2.18)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
addressable (2.3.6)
akami (1.2.2)
gyoku (>= 0.4.0)
nokogiri
ast (2.0.0)
berkshelf (2.0.16)
activesupport (~> 3.2.0)
addressable (~> 2.3.4)
buff-shell_out (~> 0.1)
chozo (>= 0.6.1)
faraday (~> 0.8.0)
faraday (~> 0.8.5)
hashie (>= 2.0.2)
minitar (~> 0.5.4)
rbzip2 (~> 0.2.0)
retryable (~> 1.3.3)
ridley (~> 1.7.0)
solve (~> 0.8.2)
thor (~> 0.18.0)
buff-config (0.4.0)
buff-extensions (~> 0.3)
varia_model (~> 0.1)
buff-extensions (0.5.0)
buff-ignore (1.1.1)
buff-platform (0.1.0)
buff-ruby_engine (0.1.0)
buff-shell_out (0.1.1)
buff-ruby_engine (~> 0.1.0)
builder (3.2.2)
celluloid (0.15.2)
timers (~> 1.1.0)
celluloid-io (0.15.0)
celluloid (>= 0.15.0)
nio4r (>= 0.5.0)
chef (11.12.4)
chef-zero (~> 2.0, >= 2.0.2)
diff-lcs (~> 1.2, >= 1.2.4)
erubis (~> 2.7)
highline (~> 1.6, >= 1.6.9)
json (>= 1.4.4, <= 1.8.1)
mime-types (~> 1.16)
mixlib-authentication (~> 1.3)
mixlib-cli (~> 1.4)
mixlib-config (~> 2.0)
mixlib-log (~> 1.3)
mixlib-shellout (~> 1.4)
net-ssh (~> 2.6)
net-ssh-multi (~> 1.1)
ohai (~> 7.0.4)
pry (~> 0.9)
rest-client (>= 1.0.4, < 1.7.0)
yajl-ruby (~> 1.1)
chef-zero (2.0.2)
hashie (~> 2.0)
json
mixlib-log (~> 1.3)
rack
chefspec (3.4.0)
chef (~> 11.0)
fauxhai (~> 2.0)
rspec (~> 2.14)
chozo (0.6.1)
activesupport (>= 3.2.0)
hashie (>= 2.0.2)
multi_json (>= 1.3.0)
coderay (1.1.0)
diff-lcs (1.2.5)
erubis (2.7.0)
faraday (0.8.9)
multipart-post (~> 1.2.0)
fauxhai (2.1.2)
net-ssh
ohai
ffi (1.9.3)
foodcritic (3.0.3)
erubis
gherkin (~> 2.11.7)
nokogiri (~> 1.5.4)
rake
treetop (~> 1.4.10)
yajl-ruby (~> 1.1.0)
gherkin (2.11.8)
multi_json (~> 1.3)
gssapi (1.0.3)
ffi (>= 1.0.1)
gyoku (1.1.1)
builder (>= 2.1.2)
hashie (2.1.1)
highline (1.6.21)
httpclient (2.3.4.1)
httpi (0.9.7)
rack
i18n (0.6.9)
ipaddress (0.8.0)
json (1.7.7)
little-plugger (1.1.3)
logging (1.8.2)
little-plugger (>= 1.1.3)
multi_json (>= 1.8.4)
method_source (0.8.2)
mime-types (1.25.1)
minitar (0.5.4)
mixlib-authentication (1.3.0)
mixlib-log
mixlib-cli (1.5.0)
mixlib-config (2.1.0)
mixlib-log (1.6.0)
mixlib-shellout (1.4.0)
multi_json (1.10.1)
multipart-post (1.2.0)
net-http-persistent (2.9.4)
net-ssh (2.9.1)
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
net-ssh-multi (1.2.0)
net-ssh (>= 2.6.5)
net-ssh-gateway (>= 1.2.0)
nio4r (1.0.0)
nokogiri (1.5.11)
nori (1.1.5)
ohai (7.0.4)
ipaddress
mime-types (~> 1.16)
mixlib-cli
mixlib-config (~> 2.0)
mixlib-log
mixlib-shellout (~> 1.2)
systemu (~> 2.5.2)
yajl-ruby
parser (2.1.9)
ast (>= 1.1, < 3.0)
slop (~> 3.4, >= 3.4.5)
polyglot (0.3.4)
powerpack (0.0.9)
pry (0.9.12.6)
coderay (~> 1.0)
method_source (~> 0.8)
slop (~> 3.4)
rack (1.5.2)
rainbow (2.0.0)
rake (10.3.2)
rbzip2 (0.2.0)
rest-client (1.6.7)
mime-types (>= 1.16)
retryable (1.3.5)
ridley (1.7.1)
addressable
buff-config (~> 0.2)
buff-extensions (~> 0.3)
buff-ignore (~> 1.1)
buff-shell_out (~> 0.1)
celluloid (~> 0.15)
celluloid-io (~> 0.15)
erubis
faraday (>= 0.8.4)
hashie (>= 2.0.2)
json (>= 1.7.7)
mixlib-authentication (>= 1.3.0)
net-http-persistent (>= 2.8)
net-ssh
retryable
solve (>= 0.4.4)
varia_model (~> 0.1)
winrm (~> 1.1.0)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.8)
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.6)
rubocop (0.18.1)
json (>= 1.7.7, < 2)
parser (~> 2.1.3)
powerpack (~> 0.0.6)
rainbow (>= 1.99.1, < 3.0)
rubyntlm (0.1.1)
savon (0.9.5)
akami (~> 1.0)
builder (>= 2.1.2)
gyoku (>= 0.4.0)
httpi (~> 0.9)
nokogiri (>= 1.4.0)
nori (~> 1.0)
wasabi (~> 1.0)
slop (3.5.0)
solve (0.8.2)
strainer (3.4.0)
berkshelf (>= 2.0, < 4.0)
buff-platform (~> 0.1)
systemu (2.5.2)
thor (0.18.1)
timers (1.1.0)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
uuidtools (2.1.4)
varia_model (0.3.2)
buff-extensions (~> 0.2)
hashie (>= 2.0.2)
wasabi (1.0.0)
nokogiri (>= 1.4.0)
winrm (1.1.3)
gssapi (~> 1.0.0)
httpclient (~> 2.2, >= 2.2.0.2)
logging (~> 1.6, >= 1.6.1)
nokogiri (~> 1.5)
rubyntlm (~> 0.1.1)
savon (= 0.9.5)
uuidtools (~> 2.1.2)
yajl-ruby (1.1.0)
PLATFORMS
ruby
DEPENDENCIES
berkshelf (~> 2.0.10)
chef (~> 11.8)
chefspec (~> 3.4.0)
foodcritic (~> 3.0.3)
json (<= 1.7.7)
rubocop (~> 0.18.1)
strainer

58
README.md Normal file
View File

@ -0,0 +1,58 @@
Description
===========
This cookbook installs the OpenStack Integration Test Suite **Tempest** as part of an OpenStack reference deployment Chef for OpenStack.
Requirements
============
Chef 11 or higher required (for Chef environment use).
Cookbooks
---------
The following cookbooks are dependencies:
* openstack-common
* openstack-identity
* openstack-image
* openstack-compute
* openstack-block-storage
Usage
=====
setup
-----
* Install and configure Tempest
Attributes
==========
Please refer to the [attributes/default.rb](attributes/default.rb) for attribute details.
Testing
=======
Please refer to the [TESTING.md](TESTING.md) for instructions for testing the cookbook.
License and Author
==================
| | |
|:---------------------|:---------------------------------------------------|
| **Author** | Matt Thompson (<matt.thompson@rackspace.co.uk>) |
| | |
| **Copyright** | Copyright (c) 2014, Rackspace US, Inc. |
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

5
Strainerfile Normal file
View File

@ -0,0 +1,5 @@
# Strainerfile
rubocop: rubocop $SANDBOX/$COOKBOOK
knife test: knife cookbook test $COOKBOOK
foodcritic: foodcritic -f any -t ~FC003 -t ~FC023 $SANDBOX/$COOKBOOK
chefspec: rspec $SANDBOX/$COOKBOOK/spec

42
TESTING.md Normal file
View File

@ -0,0 +1,42 @@
# Testing the Cookbook #
This cookbook uses [bundler](http://gembundler.com/), [berkshelf](http://berkshelf.com/), and [strainer](https://github.com/customink/strainer) to isolate dependencies and run tests.
Tests are defined in [Strainerfile](Strainerfile), which in turn calls rubocop, knife, foodcritic and chefspec.
To run all of the tests with Strainer:
$ bundle exec strainer test -s Strainerfile
Or you may run the tests individually:
$ bundle install --path=.bundle # install gem dependencies
$ bundle exec berks install --path=.cookbooks # install cookbook dependencies
$ bundle exec strainer test -s Strainerfile # run tests
## Rubocop ##
[Rubocop](https://github.com/bbatsov/rubocop) is a static Ruby code analyzer, based on the community [Ruby style guide](https://github.com/bbatsov/ruby-style-guide). We are attempting to adhere to this where applicable, slowly cleaning up the cookbooks until we can turn on Rubocop for gating the commits.
### Attribute Rules ###
Since there are slight style differences between the coding of attributes, recipes and metadata files there are specific `.rubocop.yml` files for each of:
[Gemfile and metadata.rb](.rubocop.yml)
[attributes/*.rb](attributes/.rubocop.yml)
[recipes/.rubocop.yml](recipes/.rubocop.yml)
[spec/.rubocop.yml](spec/.rubocop.yml)
## Knife ##
[knife cookbook test](http://docs.opscode.com/chef/knife.html#test) is used to check the cookbook's Ruby and ERB files for basic syntax errors.
## Foodcritic ##
[Foodcritic](http://acrmp.github.io/foodcritic/) is a lint tool for Chef cookbooks. We ignore the following rules:
[FC003](http://acrmp.github.io/foodcritic/#FC003) these cookbooks are not intended for Chef Solo.
## Chefspec
[ChefSpec](http://code.sethvargo.com/chefspec/) is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers.

65
attributes/default.rb Normal file
View File

@ -0,0 +1,65 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-integration-test
# Attributes:: default
#
# Copyright 2014, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
default['openstack']['integration-test'] = {
'branch' => nil,
'disable_ssl_validation' => false,
'tenant_isolation' => true,
'tenant_reuse' => true,
'alt_ssh_user' => 'cirros',
'ssh_user' => 'cirros',
'user1' => {
'user_name' => 'tempest_user1',
'password' => 'tempest_user1_pass',
'tenant_name' => 'tempest_tenant1'
},
'user2' => {
'user_name' => 'tempest_user2',
'password' => 'tempest_user2_pass',
'tenant_name' => 'tempest_tenant2'
},
'image1' => {
'name' => 'cirros',
'id' => nil,
'flavor' => 1
},
'image2' => {
'name' => 'cirros',
'id' => nil,
'flavor' => 1
}
}
# platform-specific settings
case platform_family
when 'fedora', 'rhel' # :pragma-foodcritic: ~FC024 - won't fix this
default['openstack']['integration-test']['platform'] = {
'tempest_packages' => %w{git python-virtualenv libxslt-devel
libxml2-devel python-testrepository
libffi-devel},
'package_overrides' => ''
}
when 'debian'
default['openstack']['integration-test']['platform'] = {
'tempest_packages' => %w{git libxml2-dev libxslt-dev testrepository
python-dev libffi-dev},
'package_overrides' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'"
}
end

22
metadata.rb Normal file
View File

@ -0,0 +1,22 @@
# encoding: UTF-8
name 'openstack-integration-test'
maintainer 'Rackspace US, Inc.'
license 'Apache 2.0'
description 'Installs and configures the Tempest Integration Test Suite'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '9.0.0'
recipe 'openstack-integration-test::setup', 'Installs and configures Tempest'
%w{ ubuntu fedora redhat centos }.each do |os|
supports os
end
%w{
openstack-common
openstack-identity
openstack-image
openstack-compute
openstack-block-storage
}.each do |dep|
depends dep
end

134
recipes/setup.rb Normal file
View File

@ -0,0 +1,134 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-integration-test
# Recipe:: setup
#
# Copyright 2014, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class Chef::Recipe # rubocop:disable Documentation
include ::Openstack
end
class Chef::Resource::RubyBlock # rubocop:disable Documentation
include ::Openstack
end
platform_options = node['openstack']['integration-test']['platform']
platform_options['tempest_packages'].each do |pkg|
package pkg do
options platform_options['package_overrides']
action :upgrade
end
end
identity_admin_endpoint = endpoint 'identity-admin'
identity_api_endpoint = endpoint 'identity-api'
bootstrap_token = get_secret 'openstack_identity_bootstrap_token'
auth_uri = ::URI.decode identity_admin_endpoint.to_s
admin_pass = get_password 'user', node['openstack']['identity']['admin_user']
%w{user1 user2}.each_with_index do |user, i|
i += 1
openstack_identity_register "Register tempest tenant #{i}" do
auth_uri auth_uri
bootstrap_token bootstrap_token
tenant_name node['openstack']['integration-test'][user]['tenant_name']
tenant_description "Tempest tenant #{i}"
action :create_tenant
end
openstack_identity_register "Register tempest user #{i}" do
auth_uri auth_uri
bootstrap_token bootstrap_token
tenant_name node['openstack']['integration-test'][user]['tenant_name']
user_name node['openstack']['integration-test'][user]['user_name']
user_pass node['openstack']['integration-test'][user]['password']
action :create_user
end
openstack_identity_register "Grant 'member' Role to tempest user for tempest tenant ##{i}" do
auth_uri auth_uri
bootstrap_token bootstrap_token
tenant_name node['openstack']['integration-test'][user]['tenant_name']
user_name node['openstack']['integration-test'][user]['user_name']
role_name 'Member'
action :grant_role
end
end
git '/opt/tempest' do
repository 'https://github.com/openstack/tempest'
reference 'master'
action :sync
end
%w{image1 image2}.each do |img|
# NOTE: This has to be done in a ruby_block so it gets executed at execution
# time and not compile time (when glance does not yet exist).
ruby_block "Get and set #{img}'s ID" do
block do
begin
admin_user = node['openstack']['identity']['admin_user']
admin_tenant = node['openstack']['identity']['admin_tenant_name']
image_name = node['openstack']['integration-test'][img]['name']
env = openstack_command_env admin_user, admin_tenant
id = image_id image_name, env
node.set['openstack']['integration-test'][img]['id'] = id
rescue RuntimeError => e
Chef::Log.error("UUID not found for Glance image #{image_name}. Error was #{e.message}")
end
end
not_if { node['openstack']['integration-test'][img]['id'] }
end
end
template '/opt/tempest/etc/tempest.conf' do
source 'tempest.conf.erb'
owner 'root'
group 'root'
mode 00600
# NOTE: We do not pass the image1/image2 node attributes above to the
# template but embed directly in the template itself instead to work
# around the variables being evaluated at compile time (prior to
# get_image_id being executed).
variables(
'tempest_disable_ssl_validation' => node['openstack']['integration-test']['disable_ssl_validation'],
'identity_endpoint_host' => identity_api_endpoint.host,
'identity_endpoint_port' => identity_api_endpoint.port,
'tempest_tenant_isolation' => node['openstack']['integration-test']['tenant_isolation'],
'tempest_tenant_reuse' => node['openstack']['integration-test']['tenant_reuse'],
'tempest_user1' => node['openstack']['integration-test']['user1']['user_name'],
'tempest_user1_pass' => node['openstack']['integration-test']['user1']['password'],
'tempest_user1_tenant' => node['openstack']['integration-test']['user1']['tenant_name'],
'tempest_img_flavor1' => node['openstack']['integration-test']['image1']['flavor'],
'tempest_img_flavor2' => node['openstack']['integration-test']['image2']['flavor'],
'tempest_admin' => node['openstack']['identity']['admin_user'],
'tempest_admin_tenant' => node['openstack']['identity']['admin_tenant_name'],
'tempest_admin_pass' => admin_pass,
'tempest_alt_ssh_user' => node['openstack']['integration-test']['alt_ssh_user'],
'tempest_ssh_user' => node['openstack']['integration-test']['ssh_user'],
'tempest_user2' => node['openstack']['integration-test']['user2']['user_name'],
'tempest_user2_pass' => node['openstack']['integration-test']['user2']['password'],
'tempest_user2_tenant' => node['openstack']['integration-test']['user2']['tenant_name']
)
end

23
spec/setup-redhat_spec.rb Normal file
View File

@ -0,0 +1,23 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-integration-test::setup' do
describe 'redhat' do
let(:runner) { ChefSpec::Runner.new(REDHAT_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
include_context 'tempest-stubs'
it 'installs tempest dependencies' do
packages = %w{git python-virtualenv libxslt-devel libxml2-devel
python-testrepository libffi-devel}
packages.each do |pkg|
expect(chef_run).to upgrade_package(pkg)
end
end
end
end

164
spec/setup_spec.rb Normal file
View File

@ -0,0 +1,164 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-integration-test::setup' do
describe 'ubuntu' do
let(:runner) { ChefSpec::Runner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) do
runner.converge(described_recipe)
end
include_context 'tempest-stubs'
it 'installs tempest dependencies' do
packages = %w{git libxml2-dev libxslt-dev testrepository python-dev
libffi-dev}
packages.each do |pkg|
expect(chef_run).to upgrade_package(pkg)
end
end
it 'registers tenant tempest_tenant1' do
expect(chef_run).to create_tenant_openstack_identity_register(
'Register tempest tenant 1'
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant1',
tenant_description: 'Tempest tenant 1'
)
end
it 'registers user tempest_user1' do
expect(chef_run).to create_user_openstack_identity_register(
'Register tempest user 1'
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant1',
user_name: 'tempest_user1',
user_pass: 'tempest_user1_pass'
)
end
it 'grants member role to tempest_user1 for tempest_tenant1' do
expect(chef_run).to grant_role_openstack_identity_register(
"Grant 'member' Role to tempest user for tempest tenant #1"
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant1',
user_name: 'tempest_user1',
role_name: 'Member'
)
end
it 'registers tenant tempest_tenant2' do
expect(chef_run).to create_tenant_openstack_identity_register(
'Register tempest tenant 2'
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant2',
tenant_description: 'Tempest tenant 2'
)
end
it 'registers user tempest_user2' do
expect(chef_run).to create_user_openstack_identity_register(
'Register tempest user 2'
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant2',
user_name: 'tempest_user2',
user_pass: 'tempest_user2_pass'
)
end
it 'grants member role to tempest_user2 for tempest_tenant2' do
expect(chef_run).to grant_role_openstack_identity_register(
"Grant 'member' Role to tempest user for tempest tenant #2"
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'tempest_tenant2',
user_name: 'tempest_user2',
role_name: 'Member'
)
end
it 'syncs /opt/tempest from github' do
expect(chef_run).to sync_git(
'/opt/tempest'
).with(
repository: 'https://github.com/openstack/tempest',
reference: 'master'
)
end
it 'runs ruby_block for image1' do
expect(chef_run).to run_ruby_block("Get and set image1's ID")
end
it 'runs ruby_block for image2' do
expect(chef_run).to run_ruby_block("Get and set image2's ID")
end
it 'sets attribute when ruby_block is run for for image1' do
# run actual ruby_block resource
chef_run.find_resource(:ruby_block, "Get and set image1's ID").old_run_action(:create)
image_id = chef_run.node['openstack']['integration-test']['image1']['id']
expect(image_id).to eq('5d1ff378-e9c1-4db7-97c1-d35f07824595')
end
it 'sets attribute when ruby_block is run for for image2' do
# run actual ruby_block resource
chef_run.find_resource(:ruby_block, "Get and set image2's ID").old_run_action(:create)
image_id = chef_run.node['openstack']['integration-test']['image2']['id']
expect(image_id).to eq('5d1ff378-e9c1-4db7-97c1-d35f07824595')
end
it 'does not run ruby_block for image1 when id already set' do
image_id = '5F7D0C44-F60E-404C-A28A-62140ADF1412'
node.set['openstack']['integration-test']['image1']['id'] = image_id
expect(chef_run).to_not run_ruby_block("Get and set image1's ID")
end
it 'does not run ruby_block for image2 when id already set' do
image_id = '5F7D0C44-F60E-404C-A28A-62140ADF1413'
node.set['openstack']['integration-test']['image2']['id'] = image_id
expect(chef_run).to_not run_ruby_block("Get and set image2's ID")
end
describe 'tempest.conf' do
let(:file) { chef_run.template('/opt/tempest/etc/tempest.conf') }
it 'creates tempest.conf' do
expect(chef_run).to create_template(file.name).with(
user: 'root',
group: 'root',
mode: 00600
)
end
it 'has a populated entry for image_ref' do
# run actual ruby_block resource
chef_run.find_resource(:ruby_block, "Get and set image1's ID").old_run_action(:create)
expect(chef_run).to render_file(file.name).with_content(
'image_ref = 5d1ff378-e9c1-4db7-97c1-d35f07824595'
)
end
it 'has a populated entry for image_ref_alt' do
# run actual ruby_block resource
chef_run.find_resource(:ruby_block, "Get and set image2's ID").old_run_action(:create)
expect(chef_run).to render_file(file.name).with_content(
'image_ref_alt = 5d1ff378-e9c1-4db7-97c1-d35f07824595'
)
end
end
end
end

46
spec/spec_helper.rb Normal file
View File

@ -0,0 +1,46 @@
# encoding: UTF-8
require 'chefspec'
require 'chefspec/berkshelf'
ChefSpec::Coverage.start! { add_filter 'openstack-integration-test' }
require 'chef/application'
LOG_LEVEL = :fatal
REDHAT_OPTS = {
platform: 'redhat',
version: '6.3',
log_level: LOG_LEVEL
}
UBUNTU_OPTS = {
platform: 'ubuntu',
version: '12.04',
log_level: LOG_LEVEL
}
shared_context 'tempest-stubs' do
before do
env =
{
'OS_USERNAME' => 'admin',
'OS_PASSWORD' => 'admin',
'OS_TENANT_NAME' => 'admin',
'OS_AUTH_URL' => 'http://127.0.0.1:35357/v2.0'
}
Chef::Recipe.any_instance.stub(:get_secret)
.with('openstack_identity_bootstrap_token')
.and_return('bootstrap-token')
Chef::Recipe.any_instance.stub(:get_password)
.with('user', 'admin')
.and_return('admin')
Chef::Resource::RubyBlock.any_instance.stub(:image_id)
.with('cirros', env)
.and_return('5d1ff378-e9c1-4db7-97c1-d35f07824595')
Chef::Resource::RubyBlock.any_instance.stub(:openstack_command_env)
.with('admin', 'admin')
.and_return(env)
Chef::Application.stub(:fatal!)
end
end

View File

@ -0,0 +1,169 @@
[identity]
catalog_type = identity
disable_ssl_certificate_validation = <%= @tempest_disable_ssl_validation %>
uri = http://<%= @identity_endpoint_host %>:<%= @identity_endpoint_port %>/v2.0/
uri_v3 = http://<%= @identity_endpoint_host %>:<%= @identity_endpoint_port %>/v3/
strategy = keystone
region = RegionOne
username = <%= @tempest_user1 %>
password = <%= @tempest_user1_pass %>
tenant_name = <%= @tempest_user1_tenant %>
alt_username = <%= @tempest_user2 %>
alt_password = <%= @tempest_user2_pass %>
alt_tenant_name = <%= @tempest_user2_tenant %>
admin_username = <%= @tempest_admin %>
admin_password = <%= @tempest_admin_pass %>
admin_tenant_name = <%= @tempest_admin_tenant %>
[compute]
image_alt_ssh_user = <%= @tempest_alt_ssh_user %>
image_ssh_user = <%= @tempest_ssh_user %>
allow_tenant_isolation = <%= @tempest_tenant_isolation %>
allow_tenant_reuse = <%= @tempest_tenant_reuse %>
image_ref = <%= node['openstack']['integration-test']['image1']['id'] %>
image_ref_alt = <%= node['openstack']['integration-test']['image2']['id'] %>
flavor_ref = <%= @tempest_img_flavor1 %>
flavor_ref_alt = <%= @tempest_img_flavor2 %>
build_interval = 3
build_timeout = 400
run_ssh = false
ssh_user = <%= @tempest_ssh_user %>
network_for_ssh = private
ip_version_for_ssh = 4
ssh_timeout = 400
ssh_channel_timeout = 60
catalog_type = compute
create_image_enabled = true
resize_available = true
change_password_available=false
live_migration_available = False
use_block_migration_for_live_migration = False
disk_config_enabled_override = true
[identity-feature-enabled]
api_v3 = false
[whitebox]
whitebox_enabled = false
source_dir = /usr/share/pyshared/nova
config_path = /etc/nova/nova.conf
bin_dir = /usr/bin
path_to_private_key =
db_uri =
[compute-admin]
username = <%= @tempest_admin %>
password = <%= @tempest_admin_pass %>
tenant_name = <%= @tempest_admin_tenant %>
[compute-feature-enabled]
api_v3 = false
[image]
catalog_type = image
api_version = 1
[network]
api_version = 2.0
catalog_type = network
tenant_network_cidr = 10.100.0.0/16
tenant_network_mask_bits = 29
tenant_networks_reachable = false
public_network_id =
public_router_id =
quantum_available = false
[volume]
catalog_type = volume
build_interval = 3
build_timeout = 400
backup = false
[object-storage]
catalog_type = object-store
container_sync_timeout = 120
container_sync_interval = 5
[boto]
ssh_user = cirros
ec2_url =
s3_url =
aws_access =
aws_secret =
s3_materials_path = /opt/stack/devstack/files/images/s3-materials/cirros-0.3.0
ari_manifest = cirros-0.3.0-x86_64-initrd.manifest.xml
ami_manifest = cirros-0.3.0-x86_64-blank.img.manifest.xml
aki_manifest = cirros-0.3.0-x86_64-vmlinuz.manifest.xml
instance_type = m1.tiny
http_socket_timeout = 30
num_retries = 1
build_timeout = 400
build_interval = 3
[service_available]
marconi = False
trove = False
savanna = False
ironic = False
ceilometer = False
horizon = True
heat = False
swift = False
neutron = False
glance = True
cinder = True
nova = True