Merge "introduce test-kitchen"
diff --git a/.kitchen.docker.yml b/.kitchen.docker.yml
new file mode 100644
index 0000000..0a11044
--- /dev/null
+++ b/.kitchen.docker.yml
@@ -0,0 +1,12 @@
+---
+driver:
+ name: docker
+ hostname: neutron.ci.local
+ use_sudo: true
+
+
+provisioner:
+ grains:
+ noservices: True
+
+
diff --git a/.kitchen.openstack.yml b/.kitchen.openstack.yml
new file mode 100644
index 0000000..6dbf7b2
--- /dev/null
+++ b/.kitchen.openstack.yml
@@ -0,0 +1,41 @@
+
+# usage: `KITCHEN_LOCAL_YAML=.kitchen.openstack.yml kitchen test`
+
+# https://docs.chef.io/config_yml_kitchen.html
+# https://github.com/test-kitchen/kitchen-openstack
+
+---
+driver:
+ name: openstack
+ openstack_auth_url: <%= ENV['OS_AUTH_URL'] %>/tokens
+ openstack_username: <%= ENV['OS_USERNAME'] || 'ci' %>
+ openstack_api_key: <%= ENV['OS_PASSWORD'] || 'ci' %>
+ openstack_tenant: <%= ENV['OS_TENANT_NAME'] || 'ci_jenkins' %>
+
+ #floating_ip_pool: <%= ENV['OS_FLOATING_IP_POOL'] || 'nova' %>
+ key_name: <%= ENV['BOOTSTRAP_SSH_KEY_NAME'] || 'bootstrap_insecure' %>
+ private_key_path: <%= ENV['BOOTSTRAP_SSH_KEY_PATH'] || "#{ENV['HOME']}/.ssh/id_rsa_bootstrap_insecure" %>
+
+
+platforms:
+ - name: ubuntu-14.04
+ driver:
+ username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %>
+ image_ref: <%= ENV['OS_UBUNTU_IMAGE_REF'] || 'ubuntu-14-04-x64-1455869035' %>
+ flavor_ref: m1.medium
+ network_ref:
+ <% if ENV['OS_NETWORK_REF'] -%>
+ - <% ENV['OS_NETWORK_REF'] %>
+ <% else -%>
+ - ci-net
+ <% end -%>
+ # force update apt cache on the image
+ run_list:
+ - recipe[apt]
+ attributes:
+ apt:
+ compile_time_update: true
+transport:
+ username: <%= ENV['OS_UBUNTU_IMAGE_USER'] || 'root' %>
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000..eb534c4
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,67 @@
+---
+driver:
+ name: vagrant
+ vm_hostname: neutron.ci.local
+ use_sudo: false
+ customize:
+ memory: 512
+
+
+provisioner:
+ name: salt_solo
+ salt_install: bootstrap
+ salt_bootstrap_url: https://bootstrap.saltstack.com
+ salt_version: latest
+ formula: neutron
+ log_level: info
+ state_top:
+ base:
+ "*":
+ - neutron
+ pillars:
+ top.sls:
+ base:
+ "*":
+ - neutron
+ grains:
+ noservices: False
+
+
+verifier:
+ name: inspec
+ sudo: true
+
+
+platforms:
+ - name: ubuntu-14.04
+ driver:
+ provision_command:
+ - apt-get install -y wget
+ - wget -O - http://apt.tcpcloud.eu/public.gpg | sudo apt-key add -
+ - echo "deb http://apt.tcpcloud.eu/nightly/ trusty main extra tcp liberty oc30" > /etc/apt/sources.list
+ - apt-get update
+ - apt-get install -y salt-minion
+ #- name: ubuntu-16.04
+ #driver:
+ #provision_command:
+ #- apt-get install -y wget
+ #- wget -O - http://apt.tcpcloud.eu/public.gpg | sudo apt-key add -
+ #- echo "deb http://apt.tcpcloud.eu/nightly/ xenial main extra tcp liberty oc30" > /etc/apt/sources.list
+ #- apt-get update
+ #- apt-get install -y salt-minion
+ #- name: centos-7.1
+
+
+suites:
+
+ - name: control-cluster
+ provisioner:
+ pillars-from-files:
+ neutron.sls: tests/pillar/control_cluster.sls
+
+ - name: control-single
+ provisioner:
+ pillars-from-files:
+ neutron.sls: tests/pillar/control_single.sls
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/INTEGRATION.rst b/INTEGRATION.rst
new file mode 100644
index 0000000..6555079
--- /dev/null
+++ b/INTEGRATION.rst
@@ -0,0 +1,114 @@
+
+Continuous Integration
+======================
+
+We are using Jenkins to spin a kitchen instances in Docker or OpenStack environment.
+
+If you would like to repeat, then you may use ``.kitchen.<backend>.yml`` configuration yaml in the main directory
+to override ``.kitchen.yml`` at some points.
+Usage: ``KITCHEN_LOCAL_YAML=.kitchen.<driver>.yml kitchen verify server-ubuntu-1404 -t tests/integration``.
+Example: ``KITCHEN_LOCAL_YAML=.kitchen.docker.yml kitchen verify server-ubuntu-1404 -t tests/integration``.
+
+Be aware of fundamental differences of backends. The formula verification scripts are primarily tested with
+Vagrant driver.
+
+CI uses a tuned `make kitchen` target defined in `Makefile` to perform following (Kitchen Test) actions:
+
+1. *create*, provision an test instance (VM, container)
+2. *converge*, run a provisioner (shell script, kitchen-salt)
+3. *verify*, run a verification (inspec, other may be added)
+4. *destroy*
+
+
+Test Kitchen
+------------
+
+
+To install Test Kitchen is as simple as:
+
+.. code-block:: shell
+
+ # install kitchen
+ gem install test-kitchen
+
+ # install required plugins
+ gem install kitchen-vagrant kitchen-docker kitchen-salt
+
+ # install additional plugins & tools
+ gem install kitchen-openstack kitchen-inspec busser-serverspec
+
+ kitchen list
+ kitchen test
+
+of course you have to have installed Ruby and it's package manager `gem <https://rubygems.org/>`_ first.
+
+One may be satisfied installing it system-wide right from OS package manager which is preferred installation method.
+For advanced users or the sake of complex environments you may use `rbenv <https://github.com/rbenv/rbenv>`_ for user side ruby installation.
+
+ * https://github.com/rbenv/rbenv
+ * http://kitchen.ci/docs/getting-started/installing
+
+An example steps then might be:
+
+.. code-block:: shell
+
+ # get rbenv
+ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
+
+ # configure
+ cd ~/.rbenv && src/configure && make -C src # don't worry if it fails
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"'>> ~/.bash_profile
+ # Ubuntu Desktop note: Modify your ~/.bashrc instead of ~/.bash_profile.
+ cd ~/.rbenv; git fetch
+
+ # install ruby-build, which provides the rbenv install command
+ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
+
+ # list all available versions:
+ rbenv install -l
+
+ # install a Ruby version
+ # maybe you will need additional packages: libssl-dev, libreadline-dev, zlib1g-dev
+ rbenv install 2.0.0-p648
+
+ # activate
+ rbenv local 2.0.0-p648
+
+ # install test kitchen
+ gem install test-kitchen
+
+
+An optional ``Gemfile`` in the main directory may contain Ruby dependencies to be required for Test Kitchen workflow.
+To install them you have to install first ``gem install bundler`` and then run ``bundler install``.
+
+
+
+Verifier
+--------
+
+The `Busser <https://github.com/test-kitchen/busser>`_ *Verifier* goes with test-kitchen by default.
+It is used to setup and run tests implemented in `<repo>/test/integration`. It guess and installs the particular driver to tested instance.
+By default `InSpec <https://github.com/chef/kitchen-inspec>`_ is expected.
+
+You may avoid to install busser framework if you configure specific verifier in `.kitchen.yml` and install it kitchen plugin locally:
+
+ verifier:
+ name: serverspec
+
+If you would to write another verification scripts than InSpec store them in ``<repo>/tests/integration/<suite>/<busser>/*``.
+``Busser <https://github.com/test-kitchen/busser>`` is a test setup and execution framework under test kitchen.
+
+
+
+InSpec
+~~~~~~
+
+Implement integration tests under ``<repo>/tests/integration/<suite>/<busser>/*`` directory with ``_spec.rb`` filename
+suffix.
+
+Docs:
+
+* https://github.com/chef/inspec
+* https://github.com/chef/kitchen-inspec
+
+
diff --git a/Makefile b/Makefile
index fc83783..fa15e0f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,28 @@
DESTDIR=/
SALTENVDIR=/usr/share/salt-formulas/env
RECLASSDIR=/usr/share/salt-formulas/reclass
-FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-]*')
+FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-\_]*')
+
+MAKE_PID := $(shell echo $$PPID)
+JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
+
+ifneq ($(subst -j,,$(JOB_FLAG)),)
+JOBS := $(subst -j,,$(JOB_FLAG))
+else
+JOBS := 1
+endif
+
+KITCHEN_LOCAL_YAML?=.kitchen.yml
+KITCHEN_OPTS?="--concurrency=$(JOBS)"
+KITCHEN_OPTS_CREATE?=""
+KITCHEN_OPTS_CONVERGE?=""
+KITCHEN_OPTS_VERIFY?=""
+KITCHEN_OPTS_TEST?=""
all:
@echo "make install - Install into DESTDIR"
@echo "make test - Run tests"
+ @echo "make kitchen - Run Kitchen CI tests (create, converge, verify)"
@echo "make clean - Cleanup after tests run"
install:
@@ -21,6 +38,29 @@
test:
[ ! -d tests ] || (cd tests; ./run_tests.sh)
+kitchen: kitchen-create kitchen-converge kitchen-verify kitchen-list
+
+kitchen-create:
+ kitchen create ${KITCHEN_OPTS} ${KITCHEN_OPTS_CREATE}
+ [ "$(shell echo $(KITCHEN_LOCAL_YAML)|grep -Eo docker)" = "docker" ] || sleep 120
+
+kitchen-converge:
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE} &&\
+ kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE}
+
+kitchen-verify:
+ [ ! -d tests/integration ] || kitchen verify -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+ [ -d tests/integration ] || kitchen verify ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+
+kitchen-test:
+ [ ! -d tests/integration ] || kitchen test -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+ [ -d tests/integration ] || kitchen test ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+
+kitchen-list:
+ kitchen list
+
clean:
+ [ ! -x "$(shell which kitchen)" ] || kitchen destroy
+ [ ! -d .kitchen ] || rm -rf .kitchen
[ ! -d tests/build ] || rm -rf tests/build
[ ! -d build ] || rm -rf build
diff --git a/README.rst b/README.rst
index 8d87393..9a8bab0 100644
--- a/README.rst
+++ b/README.rst
@@ -249,3 +249,53 @@
Developers should also join the discussion on the IRC list, at:
https://wiki.openstack.org/wiki/Meetings/openstack-salt
+
+Development and testing
+=======================
+
+Development and test workflow with `Test Kitchen <http://kitchen.ci>`_ and
+`kitchen-salt <https://github.com/simonmcc/kitchen-salt>`_ provisioner plugin.
+
+Test Kitchen is a test harness tool to execute your configured code on one or more platforms in isolation.
+There is a ``.kitchen.yml`` in main directory that defines *platforms* to be tested and *suites* to execute on them.
+
+Kitchen CI can spin instances locally or remote, based on used *driver*.
+For local development ``.kitchen.yml`` defines a `vagrant <https://github.com/test-kitchen/kitchen-vagrant>`_ or
+`docker <https://github.com/test-kitchen/kitchen-docker>`_ driver.
+
+To use backend drivers or implement your CI follow the section `INTEGRATION.rst#Continuous Integration`__.
+
+A listing of scenarios to be executed:
+
+.. code-block:: shell
+
+ $ kitchen list
+
+ Instance Driver Provisioner Verifier Transport Last Action
+
+ control-cluster-ubuntu-1404 Vagrant SaltSolo Inspec Ssh <Not Created>
+ control-cluster-ubuntu-1604 Vagrant SaltSolo Inspec Ssh Set Up
+ control-cluster-centos-71 Vagrant SaltSolo Inspec Ssh <Not Created>
+ control-single-ubuntu-1404 Vagrant SaltSolo Inspec Ssh Verified
+ control-single-ubuntu-1604 Vagrant SaltSolo Inspec Ssh <Not Created>
+ control-single-centos-71 Vagrant SaltSolo Inspec Ssh <Not Created>
+
+The `Busser <https://github.com/test-kitchen/busser>`_ *Verifier* is used to setup and run tests
+implementated in `<repo>/test/integration`. It installs the particular driver to tested instance
+(`Serverspec <https://github.com/neillturner/kitchen-verifier-serverspec>`_,
+`InSpec <https://github.com/chef/kitchen-inspec>`_, Shell, Bats, ...) prior the verification is executed.
+
+
+Usage:
+
+.. code-block:: shell
+
+ # list instances and status
+ kitchen list
+
+ # manually execute integration tests
+ kitchen [test || [create|converge|verify|exec|login|destroy|...]] [instance] -t tests/integration
+
+ # use with provided Makefile (ie: within CI pipeline)
+ make kitchen
+
diff --git a/tests/integration/control-cluster/inspec/control-cluster_spec.rb b/tests/integration/control-cluster/inspec/control-cluster_spec.rb
new file mode 100644
index 0000000..e6d422e
--- /dev/null
+++ b/tests/integration/control-cluster/inspec/control-cluster_spec.rb
@@ -0,0 +1,35 @@
+
+neutron = {
+ user: 'root',
+ group: 'neutron',
+}
+
+
+# TODO, load from control-single
+control 'neutron control' do
+ describe file('/etc/neutron/neutron.conf') do
+ it { should exist }
+ it { should be_owned_by neutron[:user] }
+ it { should be_grouped_into neutron[:group] }
+ end
+
+ describe file('/var/log/neutron') do
+ it { should be_directory }
+ end
+
+ describe file('/var/lib/neutron') do
+ it { should be_directory }
+ end
+end
+
+
+# FIXME, there is no opencontrail plugin installed nor configured
+# is the metadata dependency missing?
+#control 'neutron control cluster' do
+ #describe file('/etc/neutron/neutron.conf') do
+ #its ('content') { should match('^core_plugin.*opencontrail.*')}
+ #end
+ #describe file('/etc/neutron/plugins/opencontrail') do
+ #it { should be_directory }
+ #end
+#end
diff --git a/tests/integration/control-single/inspec/control_spec.rb b/tests/integration/control-single/inspec/control_spec.rb
new file mode 100644
index 0000000..f32f926
--- /dev/null
+++ b/tests/integration/control-single/inspec/control_spec.rb
@@ -0,0 +1,50 @@
+
+# TODO, enable helper files once resolved - https://github.com/chef/kitchen-inspec/issues/93
+#require 'neutron_spec'
+#require 'spec_helper'
+
+neutron = {
+ user: 'root',
+ group: 'neutron',
+}
+
+# TODO, pay attention/fix the cfg file ownership
+# -rw-r--r-- 1 root neutron 1017 Jun 18 2015 api-paste.ini
+# -rw-r--r-- 1 root neutron 109 Jun 18 2015 fwaas_driver.ini
+# -rw-r--r-- 1 root neutron 3109 Jun 18 2015 l3_agent.ini
+# -rw-r--r-- 1 root root 1400 Jun 18 2015 lbaas_agent.ini
+# -rw-r--r-- 1 root neutron 17867 Mar 9 18:42 neutron.conf
+# drwxr-xr-x 3 root neutron 4096 Jul 8 06:37 plugins/
+# -rw-r--r-- 1 root neutron 5858 Jun 18 2015 policy.json
+# -rw-r--r-- 1 root root 1216 Jun 18 2015 rootwrap.conf
+# drwxr-xr-x 2 root root 4096 Jul 8 06:38 rootwrap.d/
+# -rw-r--r-- 1 root neutron 526 Jun 18 2015 vpn_agent.ini
+
+# TODO, replace with shared controls
+control 'neutron control' do
+ describe file('/etc/neutron/neutron.conf') do
+ it { should exist }
+ it { should be_owned_by neutron[:user] }
+ it { should be_grouped_into neutron[:group] }
+ end
+
+ describe file('/var/log/neutron') do
+ it { should be_directory }
+ end
+
+ describe file('/var/lib/neutron') do
+ it { should be_directory }
+ end
+end
+
+control 'neutron control single' do
+ describe file('/etc/neutron/neutron.conf') do
+ its ('content') { should match('^core_plugin = neutron_plugin_contrail.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCore')}
+ its ('content') { should match('^vif_types = vrouter')}
+ end
+
+ describe file('/etc/neutron/plugins/ml2') do
+ it { should be_directory }
+ end
+end
+
diff --git a/tests/integration/default/inspec/smoke_spec.rb b/tests/integration/default/inspec/smoke_spec.rb
new file mode 100644
index 0000000..d30f4f6
--- /dev/null
+++ b/tests/integration/default/inspec/smoke_spec.rb
@@ -0,0 +1,7 @@
+
+control "Check run_test.sh" do
+ describe file('/tmp/kitchen/tests/run_tests.sh') do
+ it {should be_file}
+ it {should be_executable}
+ end
+end
diff --git a/tests/pillar/control_cluster.sls b/tests/pillar/control_cluster.sls
index 910265b..99f1048 100644
--- a/tests/pillar/control_cluster.sls
+++ b/tests/pillar/control_cluster.sls
@@ -7,6 +7,12 @@
version: liberty
backend:
engine: contrail
+ host: contrail_discovery_host
+ port: 8082
+ user: admin
+ password: password
+ tenant: admin
+ token: token
bind:
address: 127.0.0.1
port: 9696
@@ -39,4 +45,4 @@
region: RegionOne
user: nova
password: password
- tenant: service
\ No newline at end of file
+ tenant: service
diff --git a/tests/pillar/control_single.sls b/tests/pillar/control_single.sls
index 15f7a8c..0ae2325 100644
--- a/tests/pillar/control_single.sls
+++ b/tests/pillar/control_single.sls
@@ -3,6 +3,12 @@
enabled: true
backend:
engine: contrail
+ host: contrail_discovery_host
+ port: 8082
+ user: admin
+ password: password
+ tenant: admin
+ token: token
fwaas: false
dns_domain: novalocal
tunnel_type: vxlan
@@ -37,4 +43,4 @@
region: RegionOne
user: nova
password: password
- tenant: service
\ No newline at end of file
+ tenant: service