Refactor integration tests

This changes the logic so that we use the Berksfile in the cookbook
we're doing changes in instead of what's included in openstack-chef.
This should allow us to properly deal with cookbook dependencies in a
saner fashion with Gerrit without getting into depends-on hell.

This also required refactoring the Rakefile and roles used in Gerrit and
test-kitchen. Each cookbook now has their own role and test role which
includes specific Tempest configuration settings. This will require
updates in most cookbooks' Berksfile to include missing cookbook
dependencies such as ops-database, ops-messaging and integration-test.

Other major changes includes migrating to using InSpec for integration
testing instead of relying on simple commands included in the Rakefile.
I have replaced most of what was included in _run_basic_queries as
InSpec tests which also improves our coverage overall. Currently the
InSpec coverage is fairly basic and should probably include additional
tests, but in general it covers the following:

I've also added minimal non-voting jobs for both platforms so we can
catch any issue we might have missed downstream.

- Services are enabled and running
- Basic commands return sane output
- Openstack users, services and endpoints are correct

The all suites exclude running Tempest due to the fact that InSpec
doesn't have the ability to change the command timeout beyond 600
seconds [1] which is an issue I've run into. It's recommended to run
tempest manually when using test-kitchen.

NOTE: I haven't made any updates to the multi-node test-kitchen
environment in this patch and will plan on doing that later. I don't
believe this will break anything there.

Other various minor changes include:

- Replaced bare-metal cookbook with block-storage in minimal role
- Print out the command that run_command is going to run to help with
  debugging.
- Use different public_ip so that it doesn't interfere with people using
  10.0.0.0/24 locally (like me!).
- Add forwarded port to access Horizon
- Switch to using Chef 15 with test-kitchen
- Include log files from additional services that we were missing
- Add missing databag for aodh and telemetry_metric
- Include a real rndc key in the databag to assist with testing
- Use OSUOSL for EPEL mirror to work around public mirror issues

[1] https://github.com/inspec/inspec/issues/1675

Depends-On: https://review.opendev.org/703882

Change-Id: Idebc87ebb6acad7d0af222fb9025fefcb9bf5a1e
This commit is contained in:
Lance Albertson 2020-01-15 15:03:34 -08:00
parent e536f52ba2
commit cbc1b9bcf4
99 changed files with 1558 additions and 192 deletions

View File

@ -1,5 +1,5 @@
<%
public_ip = "10.0.0.81"
public_ip = "10.10.0.81"
%>
---
driver:
@ -7,10 +7,9 @@ driver:
customize:
cpus: 4
memory: 8192
client_rb:
treat_deprecation_warnings_as_errors: true
resource_cloning: false
network:
- ["forwarded_port", {guest: 443, host: 9443}]
- ["private_network", {ip: <%= public_ip %>}]
provisioner:
name: chef_zero
@ -20,7 +19,7 @@ provisioner:
# always_update_cookbooks: <%= !ENV['CI'] %>
always_update_cookbooks: true
product_name: chef
product_version: 14
product_version: 15
# Copy secret to /tmp/kitchen on test VM. Kitchen tries to gather secrets
# before any recipes had a chance to run -> we cannot use a recipe to put the
# secrets file in place.
@ -31,6 +30,11 @@ provisioner:
openstack:
secret:
key_path: /tmp/kitchen/encrypted_data_bag_secret
client_rb:
environment: integration
treat_deprecation_warnings_as_errors: true
resource_cloning: false
chef_license: accept
verifier:
name: inspec
@ -48,25 +52,78 @@ suites:
run_list:
- recipe[openstack_test]
- role[allinone]
driver_config:
network:
- ["private_network", {ip: <%= public_ip %>}]
- role[minimal_test]
provisioner:
client_rb:
environment: allinone
verifier:
inspec_tests:
- test/tempest/default
- name: minimal
run_list:
- recipe[openstack_test]
- role[minimal]
driver_config:
network:
- ["private_network", {ip: <%= public_ip %>}]
provisioner:
client_rb:
environment: integration
verifier:
inspec_tests:
- test/tempest/default
- role[minimal_test]
- name: common
run_list:
- recipe[openstack_test]
- role[common]
- name: openstackclient
run_list:
- recipe[openstack_test]
- role[openstackclient]
- name: ops-database
run_list:
- recipe[openstack_test]
- role[ops_database]
- name: ops-messaging
run_list:
- recipe[openstack_test]
- role[ops_messaging]
- name: identity
run_list:
- recipe[openstack_test]
- role[identity]
- role[identity_test]
- name: image
run_list:
- recipe[openstack_test]
- role[image]
- role[image_test]
- name: network
run_list:
- recipe[openstack_test]
- role[network]
- role[network_test]
- name: compute
run_list:
- recipe[openstack_test]
- role[compute]
- role[compute_test]
- name: orchestration
run_list:
- recipe[openstack_test]
- role[orchestration]
- role[orchestration_test]
- name: block-storage
run_list:
- recipe[openstack_test]
- role[block_storage]
- role[block_storage_test]
- name: bare-metal
run_list:
- recipe[openstack_test]
- role[bare_metal]
- role[bare_metal_test]
- name: telemetry
run_list:
- recipe[openstack_test]
- role[telemetry]
- role[telemetry_test]
- name: dns
run_list:
- recipe[openstack_test]
- role[dns]
- role[dns_test]
- name: dashboard
run_list:
- recipe[openstack_test]
- role[dashboard]
- role[dashboard_test]

View File

@ -18,6 +18,18 @@
post-run: playbooks/post.yaml
timeout: 5400
- job:
name: openstack-chef-minimal-integration-ubuntu
parent: base
nodeset: ubuntu-bionic
description: Run minimal integration tests with openstack-chef on Ubuntu Bionic
required-projects: openstack/openstack-chef
pre-run: playbooks/pre-integration.yaml
run: playbooks/minimal.yaml
post-run: playbooks/post.yaml
timeout: 5400
voting: false
- job:
name: openstack-chef-integration-centos
parent: base
@ -29,6 +41,18 @@
post-run: playbooks/post.yaml
timeout: 5400
- job:
name: openstack-chef-minimal-integration-centos
parent: base
nodeset: centos-7
description: Run minimal integration tests with openstack-chef on CentOS 7
required-projects: openstack/openstack-chef
pre-run: playbooks/pre-integration.yaml
run: playbooks/minimal.yaml
post-run: playbooks/post.yaml
timeout: 5400
voting: false
- project-template:
name: openstack-chef-jobs
check:
@ -36,12 +60,16 @@
- openstack-chef-delivery
- openstack-chef-integration-ubuntu
- openstack-chef-integration-centos
- openstack-chef-minimal-integration-ubuntu
- openstack-chef-minimal-integration-centos
gate:
queue: openstack-chef
jobs:
- openstack-chef-delivery
- openstack-chef-integration-ubuntu
- openstack-chef-integration-centos
- openstack-chef-minimal-integration-ubuntu
- openstack-chef-minimal-integration-centos
- project:
templates:

View File

@ -1,9 +1,9 @@
source 'https://supermarket.chef.io'
solver :ruby, :required
%w(
integration-test
orchestration
telemetry
bare-metal
block-storage
common
compute
@ -11,10 +11,12 @@ source 'https://supermarket.chef.io'
dns
identity
image
integration-test
network
ops-database
ops-messaging
bare-metal
orchestration
telemetry
).each do |cookbook|
if Dir.exist?("../cookbook-openstack-#{cookbook}")
cookbook "openstack-#{cookbook}", path: "../cookbook-openstack-#{cookbook}"
@ -31,3 +33,6 @@ end
cookbook 'openstack_test', path: 'test/cookbooks/openstack_test'
cookbook 'statsd', github: 'librato/statsd-cookbook'
# TODO(ramereth): Remove after this PR is merged
# https://github.com/joyofhex/cookbook-bind/pull/60
cookbook 'bind', github: 'ramereth/cookbook-bind', branch: 'fix-notifies-with-delayed-actions'

View File

@ -29,7 +29,7 @@ paths to HA.
Prerequisites
-------------
- Chef 14 or higher
- Chef 15 or higher
- `ChefDK`_ 3.2.30 or later
- `Vagrant`_ 2.0 or later with `VirtualBox>`_ or some other provider
@ -64,9 +64,17 @@ Kitchen Deploy Commands
These commands will produce various OpenStack cluster configurations,
the simplest being a monolithic Compute Controller with Neutron
(allinone). These deployments are not intended to be production-ready,
and will need adaptation to your environment. This is intended for
development and proof of concept deployments.
(allinone) which contains all supported cookbooks being deployed.
Due to memory constraints with our CI environment, we also have the
minimal suite which only tests keystone, glance, neutron, cinder and
nova. Running this suite should duplicate what we do in our CI pipeline.
We also have individual suites for each cookbook if you are just working
on a single cookbook and don't require the allinone suite.
These deployments are not intended to be production-ready, and will need
adaptation to your environment. This is intended for development and
proof of concept deployments.
Kitchen Test Scenarios
----------------------
@ -83,8 +91,8 @@ Everything self-contained (allinone)
.. code-block:: console
# allinone with Neutron
$ kitchen test [centos|ubuntu]
# allinone with all supported cookbooks
$ kitchen test "default-(centos|ubuntu)"
Access the machine
~~~~~~~~~~~~~~~~~~

155
Rakefile
View File

@ -8,8 +8,10 @@ task test: %i(rubocop berks_vendor json_check)
def run_command(command)
if File.exist?('/opt/chef/bin/chef-client')
puts "PATH=/opt/chef/embedded/bin:$PATH #{command}"
sh %(PATH=/opt/chef/embedded/bin:$PATH #{command})
else
puts "chef exec #{command}"
sh %(chef exec #{command})
end
end
@ -20,7 +22,12 @@ end
desc 'Vendor your cookbooks/'
task :berks_vendor do
run_command('berks vendor cookbooks')
if ENV['CHEF_MINIMAL'] == 'yes'
run_command('berks vendor cookbooks')
else
berksfile = ENV['PROJECT_DIR'] + '/Berksfile'
run_command("berks vendor -b #{berksfile} #{current_dir}/cookbooks")
end
end
desc 'Create Chef Key'
@ -70,64 +77,75 @@ end
# use the correct environment depending on platform
if File.exist?('/usr/bin/apt-get')
@platform = 'ubuntu16'
@platform = 'ubuntu18'
elsif File.exist?('/usr/bin/yum')
@platform = 'centos7'
end
# Helper for looking at the starting environment
def _run_env_queries
_run_commands('basic common env queries', {
'uname' => ['-a'],
'pwd' => [''],
'env' => [''],
},
false)
_run_commands(
'basic common env queries', {
'uname' => ['-a'],
'pwd' => [''],
'env' => [''],
'/opt/chef/embedded/bin/chef-client' => ['--chef-license accept --version'],
'/opt/chef/embedded/bin/inspec' =>
[
'version --chef-license accept',
'detect --chef-license accept',
],
},
false
)
case @platform
when 'ubuntu16'
_run_commands('basic debian env queries', {
'ifconfig' => [''],
'cat' => ['/etc/apt/sources.list'],
},
false)
when 'ubuntu18'
_run_commands(
'basic debian env queries', {
'ifconfig' => [''],
'cat' => ['/etc/apt/sources.list'],
},
false
)
when 'centos7'
_run_commands('basic rhel env queries', {
'/usr/sbin/ip' => ['addr'],
'cat' => ['/etc/yum.repos.d/*'],
},
false)
end
end
# Helper for setting up basic query tests
def _run_basic_queries
_run_commands('basic common test queries',
'sudo netstat' => ['-nlp'],
'nova-manage' => ['version', 'db version'],
'nova' => %w(--version service-list hypervisor-list flavor-list),
'glance-manage' => %w(db_version),
'glance' => %w(--version image-list),
'keystone-manage' => %w(db_version),
'openstack' => ['--version', 'user list', 'endpoint list', 'role list',
'service list', 'project list',
'network agent list', 'extension list --network ',
'network list', 'subnet list'],
'ovs-vsctl' => %w(show))
case @platform
when 'ubuntu16'
_run_commands('basic debian test queries',
'rabbitmqctl' => %w(cluster_status),
'ip' => ['addr', 'route', '-6 route'])
when 'centos7'
_run_commands('basic rhel test queries',
'/usr/sbin/rabbitmqctl' => %w(cluster_status),
'/usr/sbin/ip' => ['addr', 'route', '-6 route'])
_run_commands(
'basic rhel env queries', {
'/usr/sbin/ip' => ['addr'],
'cat' => ['/etc/yum.repos.d/*'],
},
false
)
end
end
def _save_logs(prefix, log_dir)
sh %(sleep 25)
%w(nova neutron keystone glance httpd apache2 rabbitmq mysql mysql-default openvswitch mariadb).each do |project|
sh %(mkdir -p #{log_dir}/#{prefix})
sh %(sudo journalctl -l > #{log_dir}/#{prefix}/journalctl.log)
case @platform
when 'ubuntu18'
sh %(sudo /bin/ss -tunlp > #{log_dir}/#{prefix}/netstat.log)
when 'centos7'
sh %(sudo /sbin/ss -tunlp > #{log_dir}/#{prefix}/netstat.log)
end
%w(
apache2
ceilometer
cinder
designate
glance
gnocchi
heat
httpd
keystone
mariadb
mysql
mysql-default
neutron
nova
openvswitch
rabbitmq
).each do |project|
sh %(mkdir -p #{log_dir}/#{prefix}/#{project})
sh %(sudo cp -rL /etc/#{project} #{log_dir}/#{prefix}/#{project}/etc || true)
sh %(sudo cp -rL /var/log/#{project} #{log_dir}/#{prefix}/#{project}/log || true)
@ -138,6 +156,28 @@ desc 'Integration test on Infra'
task integration: %i(create_key berks_vendor) do
log_dir = ENV['WORKSPACE'] + '/logs'
sh %(mkdir #{log_dir})
# Translates project name into shorter names with underscores
project_name = ENV['PROJECT_NAME'].gsub('cookbook-openstack-', '').tr('-', '_')
# Use special roles for openstack-chef and cookbook-openstackclient projects
project_name =
case project_name
when 'openstack_chef'
'minimal'
when 'cookbook_openstackclient'
'openstackclient'
else
project_name
end
if ENV['CHEF_MINIMAL'] == 'yes'
if project_name == 'minimal'
puts 'Project is openstack-chef, no need to run this job twice so exiting...'
exit
end
# If CHEF_MINIMAL is set, then let's assume we're running the full minimal suite
project_name = 'minimal'
end
inspec_dir = 'test/integration/' + project_name.tr('_', '-') + '/inspec'
run_list = "role[#{project_name}],role[#{project_name}_test]"
# This is a workaround for allowing chef-client to run in local mode
sh %(sudo mkdir -p /etc/chef && sudo cp .chef/encrypted_data_bag_secret /etc/chef/openstack_data_bag_secret)
_run_env_queries
@ -148,8 +188,7 @@ task integration: %i(create_key berks_vendor) do
begin
puts "####### Pass #{i}"
# Kick off chef client in local mode, will converge OpenStack right on the gate job "in place"
sh %(sudo chef-client #{client_opts} -E integration -r 'role[minimal]' > #{log_dir}/chef-client-pass#{i}.txt 2>&1 )
_run_basic_queries
sh %(sudo chef-client #{client_opts} -E integration -r '#{run_list}' > #{log_dir}/chef-client-pass#{i}.txt 2>&1)
rescue => e
raise "####### Pass #{i} failed with #{e.message}"
ensure
@ -159,4 +198,24 @@ task integration: %i(create_key berks_vendor) do
sh %(sudo chmod -R go+rx #{log_dir}/pass#{i})
end
end
# Run InSpec & Tempest tests
puts '## InSpec & Tempest'
begin
sh %(sudo /opt/chef/embedded/bin/inspec exec --no-color #{inspec_dir} --reporter=cli html:#{log_dir}/inspec.html)
if File.exist?('/opt/tempest-venv/tempest.sh')
# Run Tempest separately from InSpec due to no way of extending the command timeout beyond 600s
# https://github.com/inspec/inspec/issues/3866
sh %(sudo /opt/tempest-venv/tempest.sh)
else
puts 'Skipping Tempest tests...'
end
rescue => e
raise "####### InSpec & Tempest failed with #{e.message}"
ensure
# make sure logs are saved, pass or fail
_save_logs('inspec', log_dir)
sh %(sudo chown -R $USER #{log_dir}/inspec)
sh %(sudo chmod -R go+rx #{log_dir}/inspec)
end
end

View File

@ -0,0 +1,10 @@
{
"id": "aodh",
"aodh": {
"encrypted_data": "3ZAJfRHrUR52u9bIjaCZHJ8+41lFtMQ=\n",
"iv": "Bx1C+ROcknzL/AQi\n",
"auth_tag": "lhyZREBnQQwhY22a/ci9aw==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@ -1,10 +1,10 @@
{
"id": "designate_rndc",
"designate_rndc": {
"encrypted_data": "v6R5rtaKl8kX8he8+mQCLAXDzEPRwQrXe/z492sBuU7LFKJT46QZ6h2lS1z2\niwZl\n",
"iv": "2KB8EXtT5QlZt84x\n",
"auth_tag": "w4jeqIoZ4qdjYeVexlHt/w==\n",
"encrypted_data": "9rdQuzH6xux8LHdsEDmhih6yK6wWAEhBEc8/nOm0BAVd+GoQWHH1JWM1qdkq\npbxIUUEqNym0laAFVFyxUjFE\n",
"iv": "sLHnFUuEGfVuF/KQ\n",
"auth_tag": "8jKSLquqe/ciqzZF9ku33g==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}
},
"id": "designate_rndc"
}

View File

@ -0,0 +1,10 @@
{
"id": "openstack-aodh",
"openstack-aodh": {
"encrypted_data": "bWQZwHj/WzfyeJdmnwAUHii1dQWi8gXeMh6W/j5hB1RE\n",
"iv": "4XMES2igC/0KyGY+\n",
"auth_tag": "tbUxSd8tpdBVqsz8HNCyxg==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@ -0,0 +1,10 @@
{
"id": "openstack-telemetry_metric",
"openstack-telemetry_metric": {
"encrypted_data": "RimQJHhxsSnI9vHNPD43KWVbfojAKDzkQFHQq6xXehD+VgYh9lwNUT+DFvz/\n",
"iv": "tbYMioDdeXAs7XY+\n",
"auth_tag": "BV3qn/iDujKxEckGq/HW1Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@ -14,6 +14,13 @@
"apt_repository": {
"base_url": "ftp.osuosl.org/pub/mariadb/repo"
}
},
"yum": {
"epel": {
"baseurl": "http://epel.osuosl.org/7/$basearch",
"mirrorlist": null,
"gpgkey": "http://epel.osuosl.org/RPM-GPG-KEY-EPEL-7"
}
}
},
"override_attributes": {
@ -29,15 +36,6 @@
}
}
},
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"heat": false,
"horizon": false
}
}
},
"dashboard": {
"server_hostname": "localhost"
},

View File

@ -6,3 +6,5 @@
chdir: '{{ ansible_user_dir }}/src/opendev.org/openstack/openstack-chef'
environment:
WORKSPACE: '{{ ansible_user_dir }}'
PROJECT_DIR: '{{ ansible_user_dir }}/{{ zuul.project.src_dir }}'
PROJECT_NAME: '{{ zuul.project.short_name }}'

11
playbooks/minimal.yaml Normal file
View File

@ -0,0 +1,11 @@
- hosts: all
tasks:
- name: run integration
shell:
cmd: /opt/chef/embedded/bin/rake integration
chdir: '{{ ansible_user_dir }}/src/opendev.org/openstack/openstack-chef'
environment:
CHEF_MINIMAL: 'yes'
WORKSPACE: '{{ ansible_user_dir }}'
PROJECT_DIR: '{{ ansible_user_dir }}/{{ zuul.project.src_dir }}'
PROJECT_NAME: '{{ zuul.project.short_name }}'

View File

@ -2,63 +2,18 @@
"name": "allinone",
"description": "This will deploy all of the services for Openstack Compute to function on a single box.",
"run_list": [
"recipe[openstack-common]",
"recipe[openstack-common::logging]",
"recipe[openstack-common::sysctl]",
"recipe[openstack-common::client]",
"recipe[openstack-common::etcd]",
"recipe[openstack-ops-database::server]",
"recipe[openstack-ops-database::openstack-db]",
"recipe[openstack-ops-messaging::rabbitmq-server]",
"recipe[openstack-identity::server-apache]",
"recipe[openstack-identity::registration]",
"recipe[openstack-identity::openrc]",
"recipe[openstack-image::api]",
"recipe[openstack-image::identity_registration]",
"recipe[openstack-network::identity_registration]",
"recipe[openstack-network::ml2_core_plugin]",
"recipe[openstack-network::ml2_openvswitch]",
"recipe[openstack-network]",
"recipe[openstack-network::openvswitch]",
"recipe[openstack-network::_bridge_config_example]",
"recipe[openstack-network::plugin_config]",
"recipe[openstack-network::server]",
"recipe[openstack-network::l3_agent]",
"recipe[openstack-network::dhcp_agent]",
"recipe[openstack-network::metadata_agent]",
"recipe[openstack-network::openvswitch_agent]",
"recipe[openstack-compute::nova-setup]",
"recipe[openstack-compute::identity_registration]",
"recipe[openstack-compute::conductor]",
"recipe[openstack-compute::api-os-compute]",
"recipe[openstack-compute::api-metadata]",
"recipe[openstack-compute::placement_api]",
"recipe[openstack-compute::scheduler]",
"recipe[openstack-compute::vncproxy]",
"recipe[openstack-compute::compute]",
"recipe[openstack-compute::identity_registration]",
"recipe[openstack-block-storage::api]",
"recipe[openstack-block-storage::volume_driver_lvm]",
"recipe[openstack-block-storage::volume]",
"recipe[openstack-block-storage::scheduler]",
"recipe[openstack-block-storage::backup]",
"recipe[openstack-block-storage::identity_registration]",
"recipe[openstack-bare-metal::api]",
"recipe[openstack-bare-metal::conductor]",
"recipe[openstack-bare-metal::identity_registration]",
"recipe[openstack-orchestration::engine]",
"recipe[openstack-orchestration::api]",
"recipe[openstack-orchestration::api-cfn]",
"recipe[openstack-orchestration::identity_registration]",
"recipe[openstack-dns::api]",
"recipe[openstack-dns::central]",
"recipe[openstack-dns::sink]",
"recipe[openstack-dns::identity_registration]",
"recipe[openstack-image::image_upload]",
"recipe[openstack-dashboard::horizon]",
"recipe[openstack-dashboard::neutron-lbaas-dashboard]",
"recipe[openstack-integration-test::create_network]",
"recipe[openstack-integration-test::setup]",
"recipe[openstack-integration-test::run_tempest]"
"role[common]",
"role[ops_database]",
"role[ops_messaging]",
"role[identity]",
"role[image]",
"role[network]",
"role[compute]",
"role[block_storage]",
"role[bare_metal]",
"role[orchestration]",
"role[telemetry]",
"role[dns]",
"role[dashboard]"
]
}

12
roles/bare_metal.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "bare_metal",
"description": "Deploy bare metal services",
"run_list": [
"role[identity]",
"role[image]",
"role[network]",
"recipe[openstack-bare-metal::api]",
"recipe[openstack-bare-metal::conductor]",
"recipe[openstack-bare-metal::identity_registration]"
]
}

View File

@ -0,0 +1,24 @@
{
"name": "bare_metal_test",
"description": "Bare metal cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": true,
"heat": false,
"horizon": false,
"nova": false,
"neutron": true,
"ironic": true
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

14
roles/block_storage.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "block_storage",
"description": "Deploy block_storage services",
"run_list": [
"role[identity]",
"role[image]",
"recipe[openstack-block-storage::api]",
"recipe[openstack-block-storage::volume_driver_lvm]",
"recipe[openstack-block-storage::volume]",
"recipe[openstack-block-storage::scheduler]",
"recipe[openstack-block-storage::backup]",
"recipe[openstack-block-storage::identity_registration]"
]
}

View File

@ -0,0 +1,23 @@
{
"name": "block_storage_test",
"description": "Block storage cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": false,
"heat": false,
"horizon": false,
"nova": false,
"cinder": true
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

10
roles/common.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "common",
"description": "Deploys common cookbook",
"run_list": [
"recipe[openstack-common]",
"recipe[openstack-common::logging]",
"recipe[openstack-common::sysctl]",
"recipe[openstack-common::client]"
]
}

7
roles/common_test.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "common_test",
"description": "common cookbook tests",
"override_attributes": {},
"run_list": [
]
}

18
roles/compute.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "image",
"description": "Deploy image services",
"run_list": [
"role[identity]",
"role[image]",
"role[network]",
"recipe[openstack-compute::nova-setup]",
"recipe[openstack-compute::identity_registration]",
"recipe[openstack-compute::conductor]",
"recipe[openstack-compute::api-os-compute]",
"recipe[openstack-compute::api-metadata]",
"recipe[openstack-compute::placement_api]",
"recipe[openstack-compute::scheduler]",
"recipe[openstack-compute::vncproxy]",
"recipe[openstack-compute::compute]"
]
}

23
roles/compute_test.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "compute_test",
"description": "compute cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": true,
"heat": false,
"horizon": false,
"nova": true,
"neutron": true
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

9
roles/dashboard.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "dashboard",
"description": "Deploy dashboard services",
"run_list": [
"role[identity]",
"recipe[memcached]",
"recipe[openstack-dashboard::horizon]"
]
}

View File

@ -0,0 +1,5 @@
{
"name": "dashboard_test",
"description": "Dashboard cookbook tests",
"run_list": []
}

15
roles/dns.json Normal file
View File

@ -0,0 +1,15 @@
{
"name": "dns",
"description": "Deploy dns services",
"run_list": [
"role[identity]",
"recipe[openstack-integration-test::dns]",
"recipe[openstack-dns::api]",
"recipe[openstack-dns::central]",
"recipe[openstack-dns::sink]",
"recipe[openstack-dns::mdns]",
"recipe[openstack-dns::producer]",
"recipe[openstack-dns::worker]",
"recipe[openstack-dns::identity_registration]"
]
}

7
roles/dns_test.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "dns_test",
"description": "dns cookbook tests",
"override_attributes": {},
"run_list": [
]
}

12
roles/identity.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "identity",
"description": "Deploy identity cookbook",
"run_list": [
"role[common]",
"role[ops_database]",
"role[ops_messaging]",
"recipe[openstack-identity::server-apache]",
"recipe[openstack-identity::registration]",
"recipe[openstack-identity::openrc]"
]
}

22
roles/identity_test.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "identity_test",
"description": "Identity cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": false,
"heat": false,
"horizon": false,
"nova": false
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

10
roles/image.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "image",
"description": "Deploy image services",
"run_list": [
"role[identity]",
"recipe[openstack-image::api]",
"recipe[openstack-image::identity_registration]",
"recipe[openstack-image::image_upload]"
]
}

22
roles/image_test.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "image_test",
"description": "Image cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": true,
"heat": false,
"horizon": false,
"nova": false
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

View File

@ -0,0 +1,7 @@
{
"name": "integration_test",
"description": "Run integration-test cookbook",
"run_list": [
"recipe[openstack-integration-test::setup]"
]
}

View File

@ -2,45 +2,13 @@
"name": "minimal",
"description": "This will deploy a minimal set of services for Openstack Compute to function for integration testing.",
"run_list": [
"recipe[openstack-common]",
"recipe[openstack-common::logging]",
"recipe[openstack-common::sysctl]",
"recipe[openstack-common::client]",
"recipe[openstack-ops-database::server]",
"recipe[openstack-ops-database::openstack-db]",
"recipe[openstack-ops-messaging::rabbitmq-server]",
"recipe[openstack-identity::server-apache]",
"recipe[openstack-identity::registration]",
"recipe[openstack-identity::openrc]",
"recipe[openstack-image::api]",
"recipe[openstack-image::identity_registration]",
"recipe[openstack-network::identity_registration]",
"recipe[openstack-network::ml2_core_plugin]",
"recipe[openstack-network::ml2_openvswitch]",
"recipe[openstack-network]",
"recipe[openstack-network::openvswitch]",
"recipe[openstack-network::_bridge_config_example]",
"recipe[openstack-network::plugin_config]",
"recipe[openstack-network::server]",
"recipe[openstack-network::l3_agent]",
"recipe[openstack-network::dhcp_agent]",
"recipe[openstack-network::metadata_agent]",
"recipe[openstack-network::openvswitch_agent]",
"recipe[openstack-compute::nova-setup]",
"recipe[openstack-compute::identity_registration]",
"recipe[openstack-compute::conductor]",
"recipe[openstack-compute::api-os-compute]",
"recipe[openstack-compute::api-metadata]",
"recipe[openstack-compute::placement_api]",
"recipe[openstack-compute::scheduler]",
"recipe[openstack-compute::vncproxy]",
"recipe[openstack-compute::compute]",
"recipe[openstack-bare-metal::api]",
"recipe[openstack-bare-metal::conductor]",
"recipe[openstack-bare-metal::identity_registration]",
"recipe[openstack-image::image_upload]",
"recipe[openstack-integration-test::create_network]",
"recipe[openstack-integration-test::setup]",
"recipe[openstack-integration-test::run_tempest]"
"role[common]",
"role[ops_database]",
"role[ops_messaging]",
"role[identity]",
"role[image]",
"role[network]",
"role[block_storage]",
"role[compute]"
]
}

21
roles/minimal_test.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "minimal_test",
"description": "Minimal tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"cinder": true,
"glance": true,
"neutron": true,
"nova": true
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

20
roles/network.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "network",
"description": "Deploy network services",
"run_list": [
"role[identity]",
"recipe[openstack-network::identity_registration]",
"recipe[openstack-network::ml2_core_plugin]",
"recipe[openstack-network::ml2_openvswitch]",
"recipe[openstack-network]",
"recipe[openstack-network::openvswitch]",
"recipe[openstack-network::_bridge_config_example]",
"recipe[openstack-network::plugin_config]",
"recipe[openstack-network::server]",
"recipe[openstack-network::l3_agent]",
"recipe[openstack-network::dhcp_agent]",
"recipe[openstack-network::metadata_agent]",
"recipe[openstack-network::openvswitch_agent]",
"recipe[openstack-integration-test::create_network]"
]
}

23
roles/network_test.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "network_test",
"description": "Network cookbook tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": false,
"heat": false,
"horizon": false,
"nova": false,
"neutron": true
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

View File

@ -0,0 +1,7 @@
{
"name": "openstackclient",
"description": "Deploy openstackclient cookbook",
"run_list": [
"role[identity]"
]
}

View File

@ -0,0 +1,22 @@
{
"name": "openstackclient_test",
"description": "Identity openstackclient tests",
"override_attributes": {
"openstack": {
"integration-test": {
"conf": {
"service_available": {
"ceilometer": false,
"glance": false,
"heat": false,
"horizon": false,
"nova": false
}
}
}
}
},
"run_list": [
"role[integration_test]"
]
}

9
roles/ops_database.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "ops_database",
"description": "Deploy ops-database cookbook",
"run_list": [
"role[common]",
"recipe[openstack-ops-database::server]",
"recipe[openstack-ops-database::openstack-db]"
]
}

View File

@ -0,0 +1,5 @@
{
"name": "ops_database_test",
"description": "Ops Database cookbook tests",
"run_list": []
}

8
roles/ops_messaging.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "ops_messaging",
"description": "Deploy ops-messaging cookbook",
"run_list": [
"role[common]",
"recipe[openstack-ops-messaging::rabbitmq-server]"
]
}

View File

@ -0,0 +1,5 @@
{
"name": "ops_messaging_test",
"description": "Ops Messaging cookbook tests",
"run_list": []
}

14
roles/orchestration.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "orchestration",
"description": "Deploy orchestration services",
"run_list": [
"role[identity]",
"role[image]",
"role[network]",
"role[compute]",
"recipe[openstack-orchestration::engine]",
"recipe[openstack-orchestration::api]",
"recipe[openstack-orchestration::api-cfn]",
"recipe[openstack-orchestration::identity_registration]"
]
}

View File

@ -0,0 +1,8 @@
{
"name": "orchestration_test",
"description": "Orchestration cookbook tests",
"override_attributes": {},
"run_list": [
"recipe[openstack-integration-test::orchestration]"
]
}

13
roles/telemetry.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "telemetry",
"description": "Deploy telemetry services",
"run_list": [
"role[identity]",
"recipe[openstack-telemetry::agent-central]",
"recipe[openstack-telemetry::agent-notification]",
"recipe[openstack-telemetry::identity_registration]",
"recipe[openstack-telemetry::aodh]",
"recipe[openstack-telemetry::gnocchi_install]",
"recipe[openstack-telemetry::gnocchi_configure]"
]
}

View File

@ -0,0 +1,7 @@
{
"name": "telemetry_test",
"description": "telemetry cookbook tests",
"override_attributes": {},
"run_list": [
]
}

View File

@ -0,0 +1,46 @@
ironic_service = os.family == 'redhat' ? 'openstack-ironic-conductor' : 'ironic-conductor'
openrc = 'bash -c "source /root/openrc && '
describe port '6385' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
describe service ironic_service do
it { should be_enabled }
it { should be_running }
end
describe command "#{openrc} openstack baremetal node create --driver ipmi\"" do
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack baremetal chassis create\"" do
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack baremetal node list -f value -c 'Provisioning State'\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^enroll$/ }
end
describe command "#{openrc} openstack baremetal chassis list -f value -c Description\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^None$/ }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^ironic$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^ironic bare_metal$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{ironic bare_metal True public http://127.0.0.1:6385} }
its('stdout') { should match %r{ironic bare_metal True internal http://127.0.0.1:6385} }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,52 @@
openrc = 'bash -c "source /root/openrc && '
cinder_services =
if os.family == 'redhat'
%w(
openstack-cinder-backup
openstack-cinder-scheduler
openstack-cinder-volume
)
else
%w(
cinder-backup
cinder-scheduler
cinder-volume
)
end
describe port '8776' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
cinder_services.each do |cinder_service|
describe service cinder_service do
it { should be_enabled }
it { should be_running }
end
end
describe command "#{openrc} cinder-manage db version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^123$/ }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^cinder$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^cinderv2 volumev2$/ }
its('stdout') { should match /^cinderv3 volumev3$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{cinderv2 volumev2 True internal http://127.0.0.1:8776/v2/%\(tenant_id\)s} }
its('stdout') { should match %r{cinderv2 volumev2 True public http://127.0.0.1:8776/v2/%\(tenant_id\)s} }
its('stdout') { should match %r{cinderv3 volumev3 True internal http://127.0.0.1:8776/v3/%\(tenant_id\)s} }
its('stdout') { should match %r{cinderv3 volumev3 True public http://127.0.0.1:8776/v3/%\(tenant_id\)s} }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,69 @@
describe kernel_parameter 'net.ipv4.conf.all.rp_filter' do
its('value') { should eq 0 }
end
describe kernel_parameter 'net.ipv4.conf.default.rp_filter' do
its('value') { should eq 0 }
end
os_family = os.family
describe command 'openstack --version' do
its('exit_status') { should eq 0 }
if os_family == 'redhat'
its('stderr') { should match /^openstack 3.16.[0-9]+$/ }
else
its('stdout') { should match /^openstack 3.16.[0-9]+$/ }
end
end
if os.family == 'redhat'
%w(
centos-release-qemu-ev
python
python2-openstackclient
python2-pip
python2-setuptools
python2-wheel
python-devel
python-virtualenv
).each do |pkg|
describe package pkg do
it { should be_installed }
end
end
describe yum.repo('RDO-rocky') do
it { should exist }
it { should be_enabled }
end
describe yum.repo('RDO-rocky-deps') do
it { should_not exist }
it { should_not be_enabled }
end
else
%w(
python3
python3-dev
python3-openstackclient
python3-pip
python3-setuptools
python3-virtualenv
python3-wheel
virtualenv
).each do |pkg|
describe package pkg do
it { should be_installed }
end
end
# apt InSpec resource is not working properly
describe file '/etc/apt/sources.list.d/openstack-ppa.list' do
its('content') { should include 'http://ubuntu-cloud.archive.canonical.com/ubuntu bionic-updates/rocky main' }
end
describe file '/etc/apt/sources.list.d/openstack-ppa-proposed.list' do
it { should_not exist }
end
end

View File

@ -0,0 +1,69 @@
%w(
6080
8774
8775
8778
).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
end
nova_services =
if os.family == 'redhat'
%w(
openstack-nova-compute
openstack-nova-conductor
openstack-nova-consoleauth
openstack-nova-novncproxy
openstack-nova-scheduler
)
else
%w(
nova-compute
nova-conductor
nova-consoleauth
nova-novncproxy
nova-scheduler
)
end
nova_services.each do |nova_service|
describe service nova_service do
it { should be_enabled }
it { should be_running }
end
end
openrc = 'bash -c "source /root/openrc && '
describe command "#{openrc} nova-manage version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^18.[0-9]+/ }
end
describe command "#{openrc} nova-manage db version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^390$/ }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^nova$/ }
its('stdout') { should match /^placement$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^nova compute$/ }
its('stdout') { should match /^nova-placement placement$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{nova compute True public http://127.0.0.1:8774/v2.1/%\(tenant_id\)s} }
its('stdout') { should match %r{nova compute True internal http://127.0.0.1:8774/v2.1/%\(tenant_id\)s} }
its('stdout') { should match %r{nova-placement placement True public http://127.0.0.1:8778} }
its('stdout') { should match %r{nova-placement placement True internal http://127.0.0.1:8778} }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../network/inspec/network_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,24 @@
%w(80 443).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '0.0.0.0' }
end
end
# Simulate logging into horizon with curl and test the output to ensure the
# application is running correctly
horizon_command =
# 1. Get initial cookie for curl
# 2. Grab the CSRF token
# 3. Try logging into the site with the token
'curl -so /dev/null -k -c c.txt -b c.txt https://localhost/auth/login/ && ' \
'token=$(grep csrftoken c.txt | cut -f7) &&' \
'curl -H \'Referer:https://localhost/auth/login/\' -k -c c.txt -b c.txt -d ' \
'"login=admin&password=admin&csrfmiddlewaretoken=${token}" -v ' \
'https://localhost/auth/login/ 2>&1'
describe command(horizon_command) do
its('stdout') { should match(/subject: CN=controller.example.com/) }
its('stdout') { should match(/< HTTP.*200 OK/) }
its('stdout') { should_not match(/CSRF verification failed. Request aborted./) }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,89 @@
openrc = 'bash -c "source /root/openrc && '
%w(53 953).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
its('processes') { should include 'named' }
end
end
describe port '9001' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
its('processes') { should include 'designate-api' }
end
describe port '5354' do
it { should be_listening }
its('addresses') { should include '0.0.0.0' }
its('processes') { should include 'designate-mdns' }
end
%w(
designate-api
designate-central
designate-mdns
designate-producer
designate-sink
designate-worker
).each do |designate_service|
describe service designate_service do
it { should be_enabled }
it { should be_running }
end
end
describe command "#{openrc} designate-manage database version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^Current: 100 Latest: 100$/ }
end
describe command "#{openrc} openstack dns service list -f value -c service_name -c status\"" do
its('exit_status') { should eq 0 }
%w(
central
api
producer
mdns
worker
).each do |service|
its('stdout') { should match /^#{service} UP$/ }
end
end
describe command "#{openrc} openstack zone create --email dnsmaster@example.com example.com.\"" do
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack recordset create --record '10.0.0.1' --type A example.com. www && sleep 10\"" do
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack zone list -f value -c name -c type -c status -c action\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^example.com. PRIMARY ACTIVE NONE$/ }
end
describe command "#{openrc} openstack recordset list example.com. -f value -c name -c type -c records -c status -c action\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^example.com. SOA ns1.example.org. dnsmaster.example.com. [0-9]+ [0-9]+ 600 86400 3600 ACTIVE NONE$/ }
its('stdout') { should match /^example.com. NS ns1.example.org. ACTIVE NONE$/ }
its('stdout') { should match /^www.example.com. A 10.0.0.1 ACTIVE NONE$/ }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^designate$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^designate dns$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{designate dns True internal http://127.0.0.1:9001} }
its('stdout') { should match %r{designate dns True public http://127.0.0.1:9001} }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,4 @@
describe command '/opt/tempest-venv/tempest.sh' do
its('exit_status') { should eq 0 }
its('stdout') { should match /^ - Failed: 0$/ }
end

View File

@ -0,0 +1,31 @@
openrc = 'bash -c "source /root/openrc && '
describe port '5000' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^admin$/ }
end
describe command("#{openrc} openstack token issue\"") do
its('stdout') { should match(/expires.*[0-9]{4}-[0-9]{2}-[0-9]{2}/) }
its('stdout') { should match(/id\s*\|\s[0-9a-z]{32}/) }
its('stdout') { should match(/project_id\s*\|\s[0-9a-z]{32}/) }
its('stdout') { should match(/user_id\s*\|\s[0-9a-z]{32}/) }
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^keystone identity$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{keystone identity True admin http://127.0.0.1:5000/v3} }
its('stdout') { should match %r{keystone identity True internal http://127.0.0.1:5000/v3} }
its('stdout') { should match %r{keystone identity True public http://127.0.0.1:5000/v3} }
end

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1,44 @@
glance_service = os.family == 'redhat' ? 'openstack-glance-api' : 'glance-api'
openrc = 'bash -c "source /root/openrc && '
describe port '9292' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
describe service glance_service do
it { should be_enabled }
it { should be_running }
end
describe command "#{openrc} glance-manage db_version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should include 'rocky' }
end
describe command "#{openrc} openstack image list -f value -c Name\"" do
its('exit_status') { should eq 0 }
%w(
cirros
cirros-test1
cirros-test2
).each do |image|
its('stdout') { should match /^#{image}$/ }
end
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^glance$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^glance image$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{glance image True internal http://127.0.0.1:9292} }
its('stdout') { should match %r{glance image True public http://127.0.0.1:9292} }
end

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1 @@
../../block-storage/inspec/block_storage_spec.rb

View File

@ -0,0 +1 @@
../../common/inspec/common_spec.rb

View File

@ -0,0 +1 @@
../../compute/inspec/compute_spec.rb

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../image/inspec/image_spec.rb

View File

@ -0,0 +1 @@
../../network/inspec/network_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1,123 @@
openrc = 'bash -c "source /root/openrc && '
%w(
9696
6633
).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
end
%w(
neutron-dhcp-agent
neutron-l3-agent
neutron-metadata-agent
neutron-openvswitch-agent
neutron-server
).each do |s|
describe service s do
it { should be_enabled }
it { should be_running }
end
end
describe command "#{openrc} openstack network show local_net -f shell -c admin_state_up -c status\"" do
its('exit_status') { should eq 0 }
its('stdout') { should include 'admin_state_up="UP"' }
its('stdout') { should include 'status="ACTIVE"' }
end
describe command "#{openrc} openstack subnet show local_subnet -f shell -c enable_dhcp -c cidr -c allocation_pools\"" do
its('exit_status') { should eq 0 }
its('stdout') { should include 'allocation_pools="192.168.180.2-192.168.180.254"' }
its('stdout') { should include 'cidr="192.168.180.0/24"' }
its('stdout') { should include 'enable_dhcp="True"' }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^neutron$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^neutron network$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{neutron network True public http://127.0.0.1:9696} }
its('stdout') { should match %r{neutron network True internal http://127.0.0.1:9696} }
end
describe command "#{openrc} openstack network agent list -f value -c Binary -c State -c Alive\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^:-\) UP neutron-dhcp-agent$/ }
its('stdout') { should match /^:-\) UP neutron-metadata-agent$/ }
its('stdout') { should match /^:-\) UP neutron-l3-agent$/ }
its('stdout') { should match /^:-\) UP neutron-openvswitch-agent$/ }
end
describe command "#{openrc} openstack extension list --network -f value -c Alias\"" do
its('exit_status') { should eq 0 }
%w(
address-scope
agent
allowed-address-pairs
auto-allocated-topology
availability_zone
availability_zone_filter
binding
binding-extended
default-subnetpools
dhcp_agent_scheduler
dvr
empty-string-filtering
external-net
ext-gw-mode
extra_dhcp_opt
extraroute
filter-validation
fip-port-details
flavors
ip-substring-filtering
l3_agent_scheduler
l3-flavors
l3-ha
multi-provider
net-mtu
net-mtu-writable
network_availability_zone
network-ip-availability
pagination
port-mac-address-regenerate
port-security-groups-filtering
project-id
provider
quota_details
quotas
rbac-policies
revision-if-match
router
router_availability_zone
security-group
service-type
sorting
standard-attr-description
standard-attr-revisions
standard-attr-tag
standard-attr-timestamp
subnet_allocation
subnet-service-types
).each do |ext|
its('stdout') { should match /^#{ext}$/ }
end
end
describe command 'ovs-vsctl show' do
its('exit_status') { should eq 0 }
its('stdout') { should match /Manager "ptcp:6640:127.0.0.1"/ }
its('stdout') { should match /is_connected: true/ }
end

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,47 @@
describe port '3306' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
describe service 'mysql' do
it { should be_running }
it { should be_enabled }
end
my_cnf = os.family == 'redhat' ? '/etc/my.cnf.d/openstack.cnf' : '/etc/mysql/conf.d/openstack.cnf'
describe mysql_conf(my_cnf).params('mysqld') do
its('default-storage-engine') { should eq 'InnoDB' }
its('innodb_autoinc_lock_mode') { should eq '1' }
its('innodb_file_per_table') { should eq 'OFF' }
its('innodb_thread_concurrency') { should eq '0' }
its('innodb_commit_concurrency') { should eq '0' }
its('innodb_read_io_threads') { should eq '4' }
its('innodb_flush_log_at_trx_commit') { should eq '1' }
its('innodb_buffer_pool_size') { should eq '134217728' }
its('innodb_log_file_size') { should eq '5242880' }
its('innodb_log_buffer_size') { should eq '8388608' }
its('character-set-server') { should eq 'latin1' }
its('query_cache_size') { should eq '0' }
its('max_connections') { should eq '307' }
end
describe mysql_session('root', 'mypass', '127.0.0.1').query('show databases;') do
%w(
ceilometer
cinder
designate
glance
gnocchi
heat
horizon
ironic
keystone
neutron
nova
nova_api
nova_cell0
).each do |db|
its('stdout') { should include db }
end
end

View File

@ -0,0 +1,19 @@
describe port '5672' do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
describe service 'rabbitmq-server' do
it { should be_running }
it { should be_enabled }
end
describe command 'rabbitmqctl list_users' do
its('exit_status') { should eq 0 }
its('stdout') { should match /admin\t\[administrator\]\n/ }
end
describe command 'rabbitmqctl list_vhosts' do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{^Listing vhosts\n/\n$} }
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,126 @@
openrc = 'bash -c "source /root/openrc && '
%w(
8000
8004
).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
end
heat_services =
if os.family == 'redhat'
%w(
openstack-heat-api-cfn
openstack-heat-api
openstack-heat-engine
)
else
%w(
heat-api-cfn
heat-api
heat-engine
)
end
heat_services.each do |heat_service|
describe service heat_service do
it { should be_enabled }
it { should be_running }
end
end
describe command "#{openrc} heat-manage db_version\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^86$/ }
end
describe command("#{openrc} openstack stack create -t /tmp/heat.yml stack\"") do
its('exit_status') { should eq 0 }
end
describe command("#{openrc} openstack stack show stack -c stack_status -f value\"") do
its('exit_status') { should eq 0 }
its('stdout') { should match(/^CREATE_IN_PROGRESS|CREATE_COMPLETE$/) }
end
describe command("#{openrc} openstack stack delete -y stack\"") do
its('exit_status') { should eq 0 }
end
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^heat_domain_admin$/ }
its('stdout') { should match /^heat$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^heat-cfn cloudformation$/ }
its('stdout') { should match /^heat orchestration$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{heat orchestration True internal http://127.0.0.1:8004/v1/%\(tenant_id\)s} }
its('stdout') { should match %r{heat orchestration True public http://127.0.0.1:8004/v1/%\(tenant_id\)s} }
its('stdout') { should match %r{heat-cfn cloudformation True public http://127.0.0.1:8000/v1} }
its('stdout') { should match %r{heat-cfn cloudformation True internal http://127.0.0.1:8000/v1} }
end
describe command "#{openrc} openstack orchestration resource type list -f value\"" do
its('exit_status') { should eq 0 }
%w(
AWS::AutoScaling::AutoScalingGroup
AWS::AutoScaling::LaunchConfiguration
AWS::AutoScaling::ScalingPolicy
AWS::CloudFormation::Stack
AWS::CloudFormation::WaitCondition
AWS::CloudFormation::WaitConditionHandle
AWS::EC2::InternetGateway
AWS::EC2::SecurityGroup
AWS::ElasticLoadBalancing::LoadBalancer
AWS::IAM::AccessKey
AWS::IAM::User
AWS::RDS::DBInstance
OS::Heat::AccessPolicy
OS::Heat::AutoScalingGroup
OS::Heat::CloudConfig
OS::Heat::Delay
OS::Heat::DeployedServer
OS::Heat::InstanceGroup
OS::Heat::MultipartMime
OS::Heat::None
OS::Heat::RandomString
OS::Heat::ResourceChain
OS::Heat::ResourceGroup
OS::Heat::ScalingPolicy
OS::Heat::SoftwareComponent
OS::Heat::SoftwareConfig
OS::Heat::SoftwareDeployment
OS::Heat::SoftwareDeploymentGroup
OS::Heat::Stack
OS::Heat::StructuredConfig
OS::Heat::StructuredDeployment
OS::Heat::StructuredDeploymentGroup
OS::Heat::TestResource
OS::Heat::UpdateWaitConditionHandle
OS::Heat::Value
OS::Heat::WaitCondition
OS::Heat::WaitConditionHandle
OS::Keystone::Domain
OS::Keystone::Endpoint
OS::Keystone::Group
OS::Keystone::GroupRoleAssignment
OS::Keystone::Project
OS::Keystone::Region
OS::Keystone::Role
OS::Keystone::Service
OS::Keystone::User
OS::Keystone::UserRoleAssignment
).each do |resource|
its('stdout') { should match /^#{resource}$/ }
end
end

View File

@ -0,0 +1 @@
../../identity/inspec/identity_spec.rb

View File

@ -0,0 +1 @@
../../ops-database/inspec/ops_database_spec.rb

View File

@ -0,0 +1 @@
../../ops-messaging/inspec/ops_messaging_spec.rb

View File

@ -0,0 +1,59 @@
openrc = 'bash -c "source /root/openrc && '
%w(
8041
8042
).each do |p|
describe port p do
it { should be_listening }
its('addresses') { should include '127.0.0.1' }
end
end
telemetry_services =
if os.family == 'redhat'
%w(
openstack-ceilometer-central
openstack-ceilometer-notification
gnocchi-metricd
)
else
%w(
ceilometer-agent-central
ceilometer-agent-notification
gnocchi-metricd
)
end
telemetry_services.each do |telemetry_service|
describe service telemetry_service do
it { should be_enabled }
it { should be_running }
end
end
# TODO: Add tests for 'openstack metric list' which requires setting up
# a redis server and fixing the api-paste.ini file we provide.
describe command "#{openrc} openstack user list -f value -c Name\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^gnocchi$/ }
its('stdout') { should match /^ceilometer$/ }
end
describe command "#{openrc} openstack service list -f value -c Name -c Type\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match /^ceilometer metering$/ }
its('stdout') { should match /^gnocchi metric$/ }
its('stdout') { should match /^aodh alarming$/ }
end
describe command "#{openrc} openstack endpoint list -f value -c 'Service Name' -c 'Service Type' -c Enabled -c Interface -c URL\"" do
its('exit_status') { should eq 0 }
its('stdout') { should match %r{aodh alarming True internal http://127.0.0.1:8042} }
its('stdout') { should match %r{aodh alarming True public http://127.0.0.1:8042} }
its('stdout') { should match %r{ceilometer metering True internal http://127.0.0.1} }
its('stdout') { should match %r{ceilometer metering True public http://127.0.0.1} }
its('stdout') { should match %r{gnocchi metric True internal http://127.0.0.1:8041} }
its('stdout') { should match %r{gnocchi metric True public http://127.0.0.1:8041} }
end