Using Test Kitchen With Puppet


Bicycle

From the kitchen.ci homepage:

Your infrastructure deserves tests too.

So lets write some integration test for our puppet code. We will use a super simple puppet manifest just deploying ntp as a hello world example focusing on test-kitchen instead.

Prerequisites

You need git (you should use it ;-) , ruby (use > 2.0) and bundler installed

Cover Your Bases

So let us start by creating a directory and a github repo for our project:

1mkdir puppet-kitchen-example
2cd puppet-kitchen-example
3git init
4hub create # this is optional

Next up we want to leverage bundler so lets create a Gemfile

bundle init
Writing new Gemfile to puppet-kitchen-example/Gemfile

We want to use test-kitchen and the kitchen-puppet gem. Until the patch gets pulled in we use a fork here:

echo 'gem "test-kitchen"' >> Gemfile
echo 'gem "kitchen-puppet"' >> Gemfile

bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Using kitchen-puppet (0.0.7 804c905)
Using mixlib-shellout (1.4.0)
Using net-ssh (2.9.0)
Using net-scp (1.2.1)
Using safe_yaml (1.0.3)
Using thor (0.19.1)
Using test-kitchen (1.2.1)
Using bundler (1.5.3)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

No we are able to initialize test-kitchen

1kitchen init
2      create  .kitchen.yml
3      create  test/integration/default
4      create  .gitignore
5      append  .gitignore
6      append  .gitignore
7      append  Gemfile
8You must run `bundle install' to fetch any new gems.

So lets do as advised and install the new dependencies

bundle install

Resolving dependencies...
Using kitchen-puppet (0.0.8)
Using mixlib-shellout (1.4.0)
Using net-ssh (2.9.0)
Using net-scp (1.2.1)
Using safe_yaml (1.0.3)
Using thor (0.19.1)
Using test-kitchen (1.2.1)
Using kitchen-vagrant (0.15.0)
Using bundler (1.5.3)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Now we have to update the kitchen.yml file with puppet specific options from the kitchen-puppet gem See kitchen-puppet and provisioner options for details

cat > .kitchen.yml <<YAML
---
driver:
  name: vagrant

provisioner:
  name: puppet_apply
  manifests_path: manifests
  modules_path: modules
  hiera_data_path: hieradata

platforms:
  - name: nocm_ubuntu-12.04
    driver_plugin: vagrant
    driver_config:
      box: nocm_ubuntu-12.04
      box_url: http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box
  - name: centos-6.5
    driver_plugin: vagrant
    driver_config:
      box: nocm_centos-6.5
      box_url: http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box

suites:
  - name: default
    manifest: site.pp
YAML

With this configuration in place we should be able to create the instances:

± kitchen create
-----> Starting Kitchen (v1.2.1)
-----> Creating <default-nocm-ubuntu-1204>...
       Bringing machine 'default' up with 'virtualbox' provider...
       ==> default: Box 'nocm_ubuntu-12.04' could not be found. Attempting to find and install...
           default: Box Provider: virtualbox
           default: Box Version: >= 0
       ==> default: Adding box 'nocm_ubuntu-12.04' (v0) for provider: virtualbox
           default: Downloading: http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box
       ==> default: Successfully added box 'nocm_ubuntu-12.04' (v0) for 'virtualbox'!
       ==> default: Importing base box 'nocm_ubuntu-12.04'...
       ==> default: Matching MAC address for NAT networking...
       ==> default: Setting the name of the VM: default-nocm-ubuntu-1204_default_1399308985043_82278
       ==> default: Clearing any previously set forwarded ports...
       ==> default: Clearing any previously set network interfaces...
       ==> default: Preparing network interfaces based on configuration...
           default: Adapter 1: nat
       ==> default: Forwarding ports...
           default: 22 => 2222 (adapter 1)
       ==> default: Booting VM...
       ==> default: Waiting for machine to boot. This may take a few minutes...
           default: SSH address: 127.0.0.1:2222
           default: SSH username: vagrant
           default: SSH auth method: private key
           default: Warning: Connection timeout. Retrying...
       ==> default: Machine booted and ready!
       ==> default: Checking for guest additions in VM...
           default: The guest additions on this VM do not match the installed version of
           default: VirtualBox! In most cases this is fine, but in rare cases it can
           default: prevent things such as shared folders from working properly. If you see
           default: shared folder errors, please make sure the guest additions within the
           default: virtual machine match the version of VirtualBox you have installed on
           default: your host and reload your VM.
           default:
           default: Guest Additions Version: 4.2.10
           default: VirtualBox Version: 4.3
       ==> default: Setting hostname...
       Vagrant instance <default-nocm-ubuntu-1204> created.
       Finished creating <default-nocm-ubuntu-1204> (2m15.59s).
-----> Creating <default-centos-65>...
       Bringing machine 'default' up with 'virtualbox' provider...
       ==> default: Box 'nocm_centos-6.5' could not be found. Attempting to find and install...
           default: Box Provider: virtualbox
           default: Box Version: >= 0
       ==> default: Adding box 'nocm_centos-6.5' (v0) for provider: virtualbox
           default: Downloading: http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box
       ==> default: Successfully added box 'nocm_centos-6.5' (v0) for 'virtualbox'!
       ==> default: Importing base box 'nocm_centos-6.5'...
       ==> default: Matching MAC address for NAT networking...
       ==> default: Setting the name of the VM: default-centos-65_default_1399309228645_16849
       ==> default: Fixed port collision for 22 => 2222. Now on port 2200.
       ==> default: Clearing any previously set network interfaces...
       ==> default: Preparing network interfaces based on configuration...
           default: Adapter 1: nat
       ==> default: Forwarding ports...
           default: 22 => 2200 (adapter 1)
       ==> default: Booting VM...
       ==> default: Waiting for machine to boot. This may take a few minutes...
           default: SSH address: 127.0.0.1:2200
           default: SSH username: vagrant
           default: SSH auth method: private key
           default: Warning: Connection timeout. Retrying...
       ==> default: Machine booted and ready!
       ==> default: Checking for guest additions in VM...
       ==> default: Setting hostname...
       Vagrant instance <default-centos-65> created.
       Finished creating <default-centos-65> (4m15.89s).
-----> Kitchen is finished. (6m31.73s)

This looks very promising. Lets verify the current state kitchen list

± kitchen list
Instance                  Driver   Provisioner  Last Action
default-nocm-ubuntu-1204  Vagrant  PuppetApply  Created
default-centos-65         Vagrant  PuppetApply  Created

Add Puppet and librarian-puppet To The Mix

Since we are trying to test a puppet-apply run we have to add puppet to the mix. Unfortunately the librarian-puppet integration with kitchen-puppet got me some errors. Let us use it anyways to fetch the puppet modules and move it out of the way afterwards.

echo 'gem "puppet"' >> Gemfile
echo 'gem "librarian-puppet"' >> Gemfile
bundle install
Resolving dependencies...
Using CFPropertyList (2.2.7)
Using facter (2.0.1)
Using json_pure (1.8.1)
Using hiera (1.3.2)
Using highline (1.6.21)
Using json (1.8.1)
Using kitchen-puppet (0.0.8)
Using mixlib-shellout (1.4.0)
Using net-ssh (2.9.0)
Using net-scp (1.2.1)
Using safe_yaml (1.0.3)
Using thor (0.19.1)
Using test-kitchen (1.2.1)
Using kitchen-vagrant (0.15.0)
Using librarian (0.1.2)
Using librarian-puppet (1.0.1)
Using rgen (0.6.6)
Using puppet (3.5.1)
Using bundler (1.5.3)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

Now we can use librarian-puppet to create our Puppetfile

± librarian-puppet init
      create  Puppetfile

We want to use the Puppetlabs ntp module. lets change the Puppetfile to fetch it.

# OSX/BSD
sed -i '' 's#modulefile#mod "puppetlabs/ntp"#' Puppetfile

# Linux
sed -i 's#modulefile#mod "puppetlabs/ntp"#' Puppetfile

cat Puppetfile
#!/usr/bin/env ruby
#^syntax detection

forge "http://forge.puppetlabs.com"

# use dependencies defined in Modulefile
mod "puppetlabs/ntp"

# mod 'puppetlabs/stdlib'

# mod 'ntp',
#   :git => 'git://github.com/puppetlabs/puppetlabs-ntp.git'

# mod 'apt',
#   :git => 'https://github.com/puppetlabs/puppetlabs-apt.git',
#   :ref => 'feature/master/dans_refactor'

run

librarian-puppet install

and it will fetch the needed modules

ls modules
ntp    stdlib

to actually install ntp we have to create a manifest. Our test suite will run site.pp so let us create a simple one.

mkdir manifests
cat > manifests/site.pp << SITE

class { '::ntp':
  servers => [ '0.pool.ntp.org', '1.pool.ntp.org' ],
}

SITE

First Step To Success: Convergence

The infrastructure code is in place. The infrastructure itself is ready (read created), so we can do our operations work and install ntp on the nodes.

I have truncated the output a little bit.

  1kitchen converge
  2-----> Starting Kitchen (v1.2.1)
  3-----> Converging <default-nocm-ubuntu-1204>...
  4       Preparing files for transfer
  5       Preparing modules
  6       Preparing manifests
  7       Preparing hiera data
  8       Finished Preparing files for transfer
  9       Installing puppet, will try to determine platform os
 10--2014-05-08 16:12:02--  http://apt.puppetlabs.com/puppetlabs-release-precise.deb
 11Resolving apt.puppetlabs.com (apt.puppetlabs.com)... 198.58.114.168, 2600:3c00::f03c:91ff:fe69:6bf0
 12Connecting to apt.puppetlabs.com (apt.puppetlabs.com)|198.58.114.168|:80... connected.
 13HTTP request sent, awaiting response... 200 OK
 14Length: 3430 (3.3K) [application/x-debian-package]
 15Saving to: `puppetlabs-release-precise.deb'
 16
 17100%[======================================>] 3,430       --.-K/s   in 0s
 18
 192014-05-08 16:12:03 (318 MB/s) - `puppetlabs-release-precise.deb' saved [3430/3430]
 20
 21Selecting previously unselected package puppetlabs-release.
 22
 23[ ... snipped content ...]
 24
 25Fetched 5,163 kB in 12s (409 kB/s)
 26        package lists... Done
 27        package lists... Done
 28       g dependency tree
 29        state information... Done
 30The following extra packages will be installed:
 31  augeas-lenses debconf-utils facter hiera libaugeas-ruby libaugeas-ruby1.8
 32  libaugeas0 libjson-ruby libruby libruby1.8 libshadow-ruby1.8 puppet-common
 33  ruby ruby-json ruby-rgen ruby1.8 virt-what
 34Suggested packages:
 35  augeas-doc augeas-tools puppet-el vim-puppet ruby-selinux libselinux-ruby1.8
 36  librrd-ruby1.9.1 librrd-ruby1.8 ri ruby-dev ruby1.8-examples ri1.8
 37Recommended packages:
 38  rdoc
 39The following NEW packages will be installed:
 40  augeas-lenses debconf-utils facter hiera libaugeas-ruby libaugeas-ruby1.8
 41  libaugeas0 libjson-ruby libruby libruby1.8 libshadow-ruby1.8 puppet
 42  puppet-common ruby ruby-json ruby-rgen ruby1.8 virt-what
 430 upgraded, 18 newly installed, 0 to remove and 123 not upgraded.
 44Need to get 3,771 kB of archives.
 45After this operation, 14.6 MB of additional disk space will be used.
 46
 47[ ... snipped content ...]
 48
 49Fetched 3,771 kB in 5s (629 kB/s)
 50Selecting previously unselected package augeas-lenses.
 51(Reading database ... 54000 files and directories currently installed.)
 52Unpacking augeas-lenses (from .../augeas-lenses_0.10.0-0ubuntu4_all.deb) ...
 53Selecting previously unselected package debconf-utils.
 54Unpacking debconf-utils (from .../debconf-utils_1.5.42ubuntu1_all.deb) ...
 55Selecting previously unselected package libruby1.8.
 56Unpacking libruby1.8 (from .../libruby1.8_1.8.7.352-2ubuntu1.4_amd64.deb) ...
 57Selecting previously unselected package ruby1.8.
 58Unpacking ruby1.8 (from .../ruby1.8_1.8.7.352-2ubuntu1.4_amd64.deb) ...
 59Selecting previously unselected package ruby.
 60Unpacking ruby (from .../apt/archives/ruby_4.8_all.deb) ...
 61Selecting previously unselected package virt-what.
 62Unpacking virt-what (from .../virt-what_1.11-1_amd64.deb) ...
 63Selecting previously unselected package facter.
 64Unpacking facter (from .../facter_2.0.1-1puppetlabs1_amd64.deb) ...
 65Selecting previously unselected package libaugeas0.
 66Unpacking libaugeas0 (from .../libaugeas0_0.10.0-0ubuntu4_amd64.deb) ...
 67Selecting previously unselected package libaugeas-ruby1.8.
 68Unpacking libaugeas-ruby1.8 (from .../libaugeas-ruby1.8_0.3.0-1.1ubuntu4_amd64.deb) ...
 69Selecting previously unselected package libaugeas-ruby.
 70Unpacking libaugeas-ruby (from .../libaugeas-ruby_0.3.0-1.1ubuntu4_all.deb) ...
 71Selecting previously unselected package ruby-json.
 72Unpacking ruby-json (from .../ruby-json_1.6.3-1_amd64.deb) ...
 73Selecting previously unselected package libjson-ruby.
 74Unpacking libjson-ruby (from .../libjson-ruby_1.6.3-1_all.deb) ...
 75Selecting previously unselected package libruby.
 76Unpacking libruby (from .../archives/libruby_4.8_all.deb) ...
 77Selecting previously unselected package libshadow-ruby1.8.
 78Unpacking libshadow-ruby1.8 (from .../libshadow-ruby1.8_1.4.1-8build1_amd64.deb) ...
 79Selecting previously unselected package hiera.
 80Unpacking hiera (from .../hiera_1.3.2-1puppetlabs1_all.deb) ...
 81Selecting previously unselected package ruby-rgen.
 82Unpacking ruby-rgen (from .../ruby-rgen_0.6.5-1puppetlabs1_all.deb) ...
 83Selecting previously unselected package puppet-common.
 84Unpacking puppet-common (from .../puppet-common_3.5.1-1puppetlabs1_all.deb) ...
 85Selecting previously unselected package puppet.
 86Unpacking puppet (from .../puppet_3.5.1-1puppetlabs1_all.deb) ...
 87Processing triggers for man-db ...
 88Processing triggers for ureadahead ...
 89ureadahead will be reprofiled on next reboot
 90Setting up augeas-lenses (0.10.0-0ubuntu4) ...
 91Setting up debconf-utils (1.5.42ubuntu1) ...
 92Setting up libruby1.8 (1.8.7.352-2ubuntu1.4) ...
 93Setting up ruby1.8 (1.8.7.352-2ubuntu1.4) ...
 94update-alternatives: using /usr/bin/ruby1.8 to provide /usr/bin/ruby (ruby) in auto mode.
 95Setting up ruby (4.8) ...
 96Setting up virt-what (1.11-1) ...
 97Setting up facter (2.0.1-1puppetlabs1) ...
 98Setting up libaugeas0 (0.10.0-0ubuntu4) ...
 99Setting up libaugeas-ruby1.8 (0.3.0-1.1ubuntu4) ...
100Setting up libaugeas-ruby (0.3.0-1.1ubuntu4) ...
101Setting up ruby-json (1.6.3-1) ...
102Setting up libjson-ruby (1.6.3-1) ...
103Setting up libruby (4.8) ...
104Setting up libshadow-ruby1.8 (1.4.1-8build1) ...
105Setting up hiera (1.3.2-1puppetlabs1) ...
106Setting up ruby-rgen (0.6.5-1puppetlabs1) ...
107Setting up puppet-common (3.5.1-1puppetlabs1) ...
108Setting up puppet (3.5.1-1puppetlabs1) ...
109 * Starting puppet agent
110puppet not configured to start, please edit /etc/default/puppet to enable
111                                                                         [ OK ]
112Processing triggers for libc-bin ...
113ldconfig deferred processing now taking place
114-----> Installing Chef Omnibus to install busser to run tests
115  % Total    % Received %        Xferd  Average Speed   Time    Time     Time  Current
116
117         Dload  Upload   Total   Spent    Left  Speed
118
119100 15934  100 15934           0     0  15250      0  0:00:01  0:00:01 --:--:-- 26035
120Downloading Chef  for ubuntu...
121downloading https://www.getchef.com/chef/metadata?v=&prerelease=false&nightlies=false&p=ubuntu&pv=12.04&m=x86_64
122  to file /tmp/install.sh.2139/metadata.txt
123trying wget...
124url https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.12.4-1_amd64.deb
125md5 c45e1d4f7842af1048f788c4452d6cc0
126sha256  595cd1e884efd21f8f5e34bdbe878421a9d5c1c24abd3c669a84e8ed261317a3
127downloaded metadata file looks valid...
128downloading https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.12.4-1_amd64.deb
129  to file /tmp/install.sh.2139/chef_11.12.4-1_amd64.deb
130trying wget...
131Comparing checksum with sha256sum...
132Installing Chef
133installing with dpkg...
134Selecting previously unselected package chef.
135(Reading database ... 56644 files and directories currently installed.)
136Unpacking chef (from .../chef_11.12.4-1_amd64.deb) ...
137Setting up chef (11.12.4-1) ...
138Thank you for installing Chef!
139       Transfering files to <default-nocm-ubuntu-1204>
140Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults
141Notice: Compiled catalog for default-nocm-ubuntu-1204.vagrantup.com in environment production in 0.32 seconds
142Notice: /Stage[main]/Ntp::Config/File[/etc/ntp.conf]/content: content changed '{md5}32280703a4ba7aa1148c48895097ed07' to '{md5}4af276f148adc7960235ad4ba09cad48'
143       Notice: /Stage[main]/Ntp::Service/Service[ntp]: Triggered 'refresh' from 1 events
144Notice: Finished catalog run in 2.21 seconds

This is the first part. Converge on Ubuntu. An interesting point: the testing code we are about to add needs a ruby on the system. test-kitchen started as a community project around chef. So test-kitchen leverages the ruby which comes with chef. That's why chef gets installed alongside puppet.

And the same command shines a light on test-kitchens beauty. We run it on as many OS as we put in the yml. How cool is that :-)

  1-----> Converging <default-centos-65>...
  2       Preparing files for transfer
  3       Preparing modules
  4       Preparing manifests
  5       Preparing hiera data
  6       Finished Preparing files for transfer
  7       Installing puppet, will try to determine platform os
  8       which: no puppet in (/usr/local/bin:/bin:/usr/bin)
  9       Retrieving https://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm
 10       warning: /var/tmp/rpm-tmp.TtvWua: Header V4 RSA/SHA1 Signature, key ID 4bd6ec30: NOKEY
 11Preparing...                #####  ########################################### [100%]
 12   1:puppetlabs-release            ########################################### [100%]
 13       Loaded plugins: fastestmirror, security
 14       Determining fastest mirrors
 15        * base: ftp.fau.de
 16        * extras: ftp.fau.de
 17        * updates: mirror.de.leaseweb.net
 18base                                                     | 3.7 kB     00:00
 19base/group_gz                                            | 220 kB     00:00
 20base/filelists_db                                        | 5.9 MB     00:01
 21base/primary_db                                          | 4.4 MB     00:00
 22base/other_db                                            | 2.8 MB     00:01
 23extras                                                   | 3.4 kB     00:00
 24extras/filelists_db                                      |  11 kB     00:00
 25extras/prestodelta                                       |  907 B     00:00
 26extras/primary_db                                        |  19 kB     00:00
 27extras/other_db                                          | 5.8 kB     00:00
 28puppetlabs-deps                                          | 2.5 kB     00:00
 29puppetlabs-deps/filelists_db                             | 182 kB     00:00
 30puppetlabs-deps/primary_db                               |  23 kB     00:00
 31puppetlabs-deps/other_db                                 |  16 kB     00:00
 32puppetlabs-products                                      | 2.5 kB     00:00
 33puppetlabs-products/filelists_db                         | 921 kB     00:00
 34puppetlabs-products/primary_db                           | 107 kB     00:00
 35puppetlabs-products/other_db                             | 145 kB     00:00
 36updates                                                  | 3.4 kB     00:00
 37updates/filelists_db                                     | 1.7 MB     00:00
 38updates/prestodelta                                      | 262 kB     00:00
 39updates/primary_db                                       | 2.6 MB     00:00
 40updates/other_db                                         |  21 MB     00:04
 41       Metadata Cache Created
 42       Loaded plugins: fastestmirror, security
 43       Loading mirror speeds from cached hostfile
 44        * base: ftp.fau.de
 45        * extras: ftp.fau.de
 46        * updates: mirror.de.leaseweb.net
 47       Setting up Install Process
 48       Resolving Dependencies
 49       --> Running transaction check
 50       ---> Package puppet.noarch 0:3.5.1-1.el6 will be installed
 51       --> Processing Dependency: facter >= 1:1.7.0 for package: puppet-3.5.1-1.el6.noarch
 52       --> Processing Dependency: ruby >= 1.8.7 for package: puppet-3.5.1-1.el6.noarch
 53       --> Processing Dependency: hiera >= 1.0.0 for package: puppet-3.5.1-1.el6.noarch
 54       --> Processing Dependency: ruby >= 1.8 for package: puppet-3.5.1-1.el6.noarch
 55       --> Processing Dependency: ruby-rgen >= 0.6.5 for package: puppet-3.5.1-1.el6.noarch
 56       --> Processing Dependency: ruby(selinux) for package: puppet-3.5.1-1.el6.noarch
 57       --> Processing Dependency: /usr/bin/ruby for package: puppet-3.5.1-1.el6.noarch
 58       --> Processing Dependency: rubygem-json for package: puppet-3.5.1-1.el6.noarch
 59       --> Processing Dependency: ruby-shadow for package: puppet-3.5.1-1.el6.noarch
 60       --> Processing Dependency: ruby-augeas for package: puppet-3.5.1-1.el6.noarch
 61       --> Running transaction check
 62       ---> Package facter.x86_64 1:2.0.1-1.el6 will be installed
 63       ---> Package hiera.noarch 0:1.3.2-1.el6 will be installed
 64       ---> Package libselinux-ruby.x86_64 0:2.0.94-5.3.el6_4.1 will be installed
 65       ---> Package ruby.x86_64 0:1.8.7.352-13.el6 will be installed
 66       --> Processing Dependency: ruby-libs = 1.8.7.352-13.el6 for package: ruby-1.8.7.352-13.el6.x86_64
 67       --> Processing Dependency: libruby.so.1.8()(64bit) for package: ruby-1.8.7.352-13.el6.x86_64
 68       ---> Package ruby-augeas.x86_64 0:0.4.1-3.el6 will be installed
 69       --> Processing Dependency: augeas-libs >= 0.8.0 for package: ruby-augeas-0.4.1-3.el6.x86_64
 70       --> Processing Dependency: libaugeas.so.0(AUGEAS_0.12.0)(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 71       --> Processing Dependency: libaugeas.so.0(AUGEAS_0.8.0)(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 72       --> Processing Dependency: libaugeas.so.0(AUGEAS_0.11.0)(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 73       --> Processing Dependency: libaugeas.so.0(AUGEAS_0.1.0)(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 74       --> Processing Dependency: libaugeas.so.0(AUGEAS_0.10.0)(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 75       --> Processing Dependency: libaugeas.so.0()(64bit) for package: ruby-augeas-0.4.1-3.el6.x86_64
 76       ---> Package ruby-rgen.noarch 0:0.6.5-2.el6 will be installed
 77       ---> Package ruby-shadow.x86_64 1:2.2.0-2.el6 will be installed
 78       ---> Package rubygem-json.x86_64 0:1.5.5-1.el6 will be installed
 79       --> Processing Dependency: rubygems for package: rubygem-json-1.5.5-1.el6.x86_64
 80       --> Running transaction check
 81       ---> Package augeas-libs.x86_64 0:1.0.0-5.el6_5.1 will be installed
 82       ---> Package ruby-libs.x86_64 0:1.8.7.352-13.el6 will be installed
 83       --> Processing Dependency: libreadline.so.5()(64bit) for package: ruby-libs-1.8.7.352-13.el6.x86_64
 84       ---> Package rubygems.noarch 0:1.3.7-5.el6 will be installed
 85       --> Processing Dependency: ruby-rdoc for package: rubygems-1.3.7-5.el6.noarch
 86       --> Running transaction check
 87       ---> Package compat-readline5.x86_64 0:5.2-17.1.el6 will be installed
 88       ---> Package ruby-rdoc.x86_64 0:1.8.7.352-13.el6 will be installed
 89       --> Processing Dependency: ruby-irb = 1.8.7.352-13.el6 for package: ruby-rdoc-1.8.7.352-13.el6.x86_64
 90       --> Running transaction check
 91       ---> Package ruby-irb.x86_64 0:1.8.7.352-13.el6 will be installed
 92       --> Finished Dependency Resolution
 93
 94       Dependencies Resolved
 95
 96       ================================================================================
 97        Package            Arch     Version                Repository             Size
 98       ================================================================================
 99       Installing:
100        puppet             noarch   3.5.1-1.el6            puppetlabs-products   1.2 M
101       Installing for dependencies:
102        augeas-libs        x86_64   1.0.0-5.el6_5.1        updates               309 k
103        compat-readline5   x86_64   5.2-17.1.el6           base                  130 k
104        facter             x86_64   1:2.0.1-1.el6          puppetlabs-products    84 k
105        hiera              noarch   1.3.2-1.el6            puppetlabs-products    23 k
106        libselinux-ruby    x86_64   2.0.94-5.3.el6_4.1     base                   99 k
107        ruby               x86_64   1.8.7.352-13.el6       updates               534 k
108        ruby-augeas        x86_64   0.4.1-3.el6            puppetlabs-deps        21 k
109        ruby-irb           x86_64   1.8.7.352-13.el6       updates               314 k
110        ruby-libs          x86_64   1.8.7.352-13.el6       updates               1.6 M
111        ruby-rdoc          x86_64   1.8.7.352-13.el6       updates               377 k
112        ruby-rgen          noarch   0.6.5-2.el6            puppetlabs-deps       237 k
113        ruby-shadow        x86_64   1:2.2.0-2.el6          puppetlabs-deps        13 k
114        rubygem-json       x86_64   1.5.5-1.el6            puppetlabs-deps       763 k
115        rubygems           noarch   1.3.7-5.el6            base                  207 k
116
117       Transaction Summary
118       ================================================================================
119       Install      15 Package(s)
120
121       Total download size: 5.9 M
122       Installed size: 14 M
123       Downloading Packages:
124(1/15): augeas-libs-1.0.0-5.el6_5.1.x86_64.rpm           | 309 kB     00:00
125(2/15): compat-readline5-5.2-17.1.el6.x86_64.rpm         | 130 kB     00:00
126(3/15): facter-2.0.1-1.el6.x86_64.rpm                    |  84 kB     00:00
127(4/15): hiera-1.3.2-1.el6.noarch.rpm                     |  23 kB     00:00
128(5/15): libselinux-ruby-2.0.94-5.3.el6_4.1.x86_64.rpm    |  99 kB     00:00
129(6/15): puppet-3.5.1-1.el6.noarch.rpm                    | 1.2 MB     00:01
130(7/15): ruby-1.8.7.352-13.el6.x86_64.rpm                 | 534 kB     00:00
131(8/15): ruby-augeas-0.4.1-3.el6.x86_64.rpm               |  21 kB     00:00
132(9/15): ruby-irb-1.8.7.352-13.el6.x86_64.rpm             | 314 kB     00:00
133(10/15): ruby-libs-1.8.7.352-13.el6.x86_64.rpm           | 1.6 MB     00:00
134(11/15): ruby-rdoc-1.8.7.352-13.el6.x86_64.rpm           | 377 kB     00:00
135(12/15): ruby-rgen-0.6.5-2.el6.noarch.rpm                | 237 kB     00:00
136(13/15): ruby-shadow-2.2.0-2.el6.x86_64.rpm              |  13 kB     00:00
137(14/15): rubygem-json-1.5.5-1.el6.x86_64.rpm             | 763 kB     00:00
138(15/15): rubygems-1.3.7-5.el6.noarch.rpm                 | 207 kB     00:00
139       --------------------------------------------------------------------------------
140       Total                                           253 kB/s | 5.9 MB     00:23
141       warning: rpmts_HdrFromFdno: Header V4 RSA/SHA512 Signature, key ID 4bd6ec30: NOKEY
142       Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
143       Importing GPG key 0x4BD6EC30:
144        Userid : Puppet Labs Release Key (Puppet Labs Release Key) <info@puppetlabs.com>
145        Package: puppetlabs-release-6-10.noarch (installed)
146        From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-puppetlabs
147       Running rpm_check_debug
148       Running Transaction Test
149       Transaction Test Succeeded
150       Running Transaction
151       Warning: RPMDB altered outside of yum.
152  Installing : augeas-libs-1.0.0-5.el6_5.1.x86_64                          1/15
153  Installing : libselinux-ruby-2.0.94-5.3.el6_4.1.x86_64                   2/15
154  Installing : compat-readline5-5.2-17.1.el6.x86_64                        3/15
155  Installing : ruby-libs-1.8.7.352-13.el6.x86_64                           4/15
156  Installing : ruby-1.8.7.352-13.el6.x86_64                                5/15
157  Installing : ruby-rgen-0.6.5-2.el6.noarch                                6/15
158  Installing : 1:facter-2.0.1-1.el6.x86_64                                 7/15
159  Installing : ruby-irb-1.8.7.352-13.el6.x86_64                            8/15
160  Installing : ruby-rdoc-1.8.7.352-13.el6.x86_64                           9/15
161  Installing : rubygems-1.3.7-5.el6.noarch                                10/15
162  Installing : rubygem-json-1.5.5-1.el6.x86_64                            11/15
163  Installing : hiera-1.3.2-1.el6.noarch                                   12/15
164  Installing : 1:ruby-shadow-2.2.0-2.el6.x86_64                           13/15
165  Installing : ruby-augeas-0.4.1-3.el6.x86_64                             14/15
166  Installing : puppet-3.5.1-1.el6.noarch                                  15/15
167  Verifying  : ruby-rgen-0.6.5-2.el6.noarch                                1/15
168  Verifying  : puppet-3.5.1-1.el6.noarch                                   2/15
169  Verifying  : ruby-1.8.7.352-13.el6.x86_64                                3/15
170  Verifying  : 1:facter-2.0.1-1.el6.x86_64                                 4/15
171  Verifying  : compat-readline5-5.2-17.1.el6.x86_64                        5/15
172  Verifying  : ruby-rdoc-1.8.7.352-13.el6.x86_64                           6/15
173  Verifying  : ruby-irb-1.8.7.352-13.el6.x86_64                            7/15
174  Verifying  : libselinux-ruby-2.0.94-5.3.el6_4.1.x86_64                   8/15
175  Verifying  : 1:ruby-shadow-2.2.0-2.el6.x86_64                            9/15
176  Verifying  : rubygems-1.3.7-5.el6.noarch                                10/15
177  Verifying  : ruby-libs-1.8.7.352-13.el6.x86_64                          11/15
178  Verifying  : rubygem-json-1.5.5-1.el6.x86_64                            12/15
179  Verifying  : hiera-1.3.2-1.el6.noarch                                   13/15
180  Verifying  : ruby-augeas-0.4.1-3.el6.x86_64                             14/15
181  Verifying  : augeas-libs-1.0.0-5.el6_5.1.x86_64                         15/15
182
183       Installed:
184         puppet.noarch 0:3.5.1-1.el6
185
186       Dependency Installed:
187         augeas-libs.x86_64 0:1.0.0-5.el6_5.1
188         compat-readline5.x86_64 0:5.2-17.1.el6
189         facter.x86_64 1:2.0.1-1.el6
190         hiera.noarch 0:1.3.2-1.el6
191         libselinux-ruby.x86_64 0:2.0.94-5.3.el6_4.1
192         ruby.x86_64 0:1.8.7.352-13.el6
193         ruby-augeas.x86_64 0:0.4.1-3.el6
194         ruby-irb.x86_64 0:1.8.7.352-13.el6
195         ruby-libs.x86_64 0:1.8.7.352-13.el6
196         ruby-rdoc.x86_64 0:1.8.7.352-13.el6
197         ruby-rgen.noarch 0:0.6.5-2.el6
198         ruby-shadow.x86_64 1:2.2.0-2.el6
199         rubygem-json.x86_64 0:1.5.5-1.el6
200         rubygems.noarch 0:1.3.7-5.el6
201
202       Complete!
203-----> Installing Chef Omnibus to install busser to run tests
204         % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
205                                 Dload  Upload   Total   Spent    Left  Speed
206  0     0    0     0    0     0      0      0 --:--:--  0:00:05 --:--:--     0
207100 15934  100 15934    0     0   2756      0  0:00:05  0:00:05 --:--:-- 57111
208       Downloading Chef  for el...
209       downloading https://www.getchef.com/chef/metadata?v=&prerelease=false&nightlies=false&p=el&pv=6&m=x86_64
210         to file /tmp/install.sh.2242/metadata.txt
211       trying wget...
212       url  https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.12.4-1.el6.x86_64.rpm
213       md5  959acd5df77c25f4f69d1f786f3c7360
214       sha256 d4eacc6b16c448a628367e7201922a4c58997f68808c5f698676e8a5eaf169b5
215       downloaded metadata file looks valid...
216       downloading https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.12.4-1.el6.x86_64.rpm
217         to file /tmp/install.sh.2242/chef-11.12.4-1.el6.x86_64.rpm
218       trying wget...
219       Comparing checksum with sha256sum...
220       Installing Chef
221       installing with rpm...
222       warning: /tmp/install.sh.2242/chef-11.12.4-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
223Preparing...                #####  ########################################### [100%]
224   1:chef                          ########################################### [100%]
225       Thank you for installing Chef!
226       Transfering files to <default-centos-65>
227       Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults
228       Notice: Compiled catalog for default-centos-65.vagrantup.com in environment production in 0.68 seconds
229       Notice: /Stage[main]/Ntp::Config/File[/etc/ntp.conf]/content: content changed '{md5}7fda24f62b1c7ae951db0f746dc6e0cc' to '{md5}4af276f148adc7960235ad4ba09cad48'
230       Notice: /Stage[main]/Ntp::Service/Service[ntp]/ensure: ensure changed 'stopped' to 'running'
231       Notice: Finished catalog run in 0.36 seconds
232       Finished converging <default-centos-65> (2m25.37s).
233-----> Kitchen is finished. (3m44.54s)

Very cool. And is ntp running? Sure it is:

 1± kitchen login default-nocm-ubuntu-1204
 2Welcome to Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-23-generic x86_64)
 3
 4 * Documentation:  https://help.ubuntu.com/
 5Last login: Thu May  8 16:13:18 2014 from 10.0.2.2
 6vagrant@default-nocm-ubuntu-1204:~$ ps -ef |grep ntp
 7ntp       2391     1  0 16:13 ?        00:00:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 103:108
 8vagrant   2514  2415  0 16:20 pts/0    00:00:00 grep --color=auto ntp
 9
10± kitchen login default-centos-65
11Last login: Thu May  8 09:15:43 2014 from 10.0.2.2
12Welcome to your Packer-built virtual machine.
13[vagrant@default-centos-65 ~]$ ps -ef|grep ntp
14ntp       2485     1  0 09:15 ?        00:00:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
15vagrant   2513  2495  0 09:21 pts/0    00:00:00 grep ntp

But this feels manual. It actually is. So lets automate the tests!

Create Some Integration Tests: Here Comes Bats

First we need a place for the testing code. Test kitchen creates a default location, so lets use that.

1ls test/integration/default

This is empty and has to be filled with our testing code. Lets start simple and add our manual test. A very interesting testing framework for this kind of tests is Bats: Bash Automated Testing System

mkdir test/integration/default/bats

cat > test/integration/default/bats/verify_installed.bats <<TEST

@test 'ntp is up and running' {
  pgrep ntp
}

@test 'ntp.conf contains correct servers' {
  grep 0.pool.ntp.org /etc/ntp.conf
}

TEST

Verify What We Have Got

Test kitchen uses busser to automate the heavy lifting. It will sync the local test folder to the nodes, install the test dependencies, and invoke the test on the node.

kitchen verify
-----> Starting Kitchen (v1.2.1)
-----> Setting up <default-nocm-ubuntu-1204>...
Fetching: thor-0.19.0.gem (100%)
Fetching: busser-0.6.2.gem (100%)
Successfully installed thor-0.19.0
Successfully installed busser-0.6.2
2 gems installed
-----> Setting up Busser
       Creating BUSSER_ROOT in /tmp/busser
       Creating busser binstub
       Plugin bats installed (version 0.2.0)
-----> Running postinstall for bats plugin
Installed Bats to /tmp/busser/vendor/bats/bin/bats
       Finished setting up <default-nocm-ubuntu-1204> (0m54.06s).
-----> Verifying <default-nocm-ubuntu-1204>...
       Suite path directory /tmp/busser/suites does not exist, skipping.
Uploading /tmp/busser/suites/bats/verify_installed.bats (mode=0644)
-----> Running bats test suite
 ✓ ntp is up and running
 ✓ ntp.conf contains correct servers

2 tests, 0 failures
       Finished verifying <default-nocm-ubuntu-1204> (0m0.89s).
-----> Setting up <default-centos-65>...
Fetching: thor-0.19.0.gem (100%)
Fetching: busser-0.6.2.gem (100%)
       Successfully installed thor-0.19.0
       Successfully installed busser-0.6.2
       2 gems installed
-----> Setting up Busser
       Creating BUSSER_ROOT in /tmp/busser
       Creating busser binstub
       Plugin bats installed (version 0.2.0)
-----> Running postinstall for bats plugin
       Installed Bats to /tmp/busser/vendor/bats/bin/bats
       Finished setting up <default-centos-65> (0m57.40s).
-----> Verifying <default-centos-65>...
       Suite path directory /tmp/busser/suites does not exist, skipping.
       Uploading /tmp/busser/suites/bats/verify_installed.bats (mode=0644)
-----> Running bats test suite
 ✓ ntp is up and running
   ntp.conf contains correct servers                                        2/2
 ✓ ntp.conf contains correct servers

       2 tests, 0 failures
       Finished verifying <default-centos-65> (0m0.87s).
-----> Kitchen is finished. (1m53.64s)

Very cool. But we knew that already. And the coolest part of it: It will run on all the OS flavors specified. Hook this up to a CI/CB system and have some extra productive time back :-)

Add Some More Tests. Serverspec To The Rescue

 1mkdir test/integration/default/serverspec
 2
 3cat > test/integration/default/serverspec/ntp_spec.rb <<TEST
 4require 'serverspec'
 5
 6include Serverspec::Helper::Exec
 7include Serverspec::Helper::DetectOS
 8
 9RSpec.configure do |c|
10  c.before :all do
11    c.path = '/sbin:/usr/sbin'
12  end
13end
14
15describe package('ntp') do
16  it { should be_installed }
17end
18
19describe service('ntp') do
20  it { should be_running }
21end
22TEST

Running kitchen verify now will not do the right thing. It will copy the serverspec but not run it. Run a kitchen converge first and kitchen will pick up the serverspec tests.

kitchen verify
-----> Starting Kitchen (v1.2.1)
-----> Verifying <default-nocm-ubuntu-1204>...
       Removing /tmp/busser/suites/bats
       Removing /tmp/busser/suites/serverspec
Uploading /tmp/busser/suites/bats/verify_installed.bats (mode=0644)
Uploading /tmp/busser/suites/serverspec/ntp_spec.rb (mode=0644)
-----> Running bats test suite
 ✓ ntp is up and running
 ✓ ntp.conf contains correct servers

2 tests, 0 failures
-----> Running serverspec test suite
/opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/ntp_spec.rb --color --format documentation

Package "ntp"
  should be installed

Service "ntp"
  should be running

Finished in 0.06612 seconds
2 examples, 0 failures
       Finished verifying <default-nocm-ubuntu-1204> (0m1.95s).
-----> Verifying <default-centos-65>...
       Removing /tmp/busser/suites/bats
       Removing /tmp/busser/suites/serverspec
       Uploading /tmp/busser/suites/bats/verify_installed.bats (mode=0644)
       Uploading /tmp/busser/suites/serverspec/ntp_spec.rb (mode=0644)
-----> Running bats test suite
 ✓ ntp is up and running
   ntp.conf contains correct servers                                        2/2
 ✓ ntp.conf contains correct servers

       2 tests, 0 failures
-----> Running serverspec test suite
       /opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/ntp_spec.rb --color --format documentation

       Package "ntp"
         should be installed

       Service "ntp"
         should be running

       Finished in 0.0413 seconds
       2 examples, 0 failures
       Finished verifying <default-centos-65> (0m1.62s).
-----> Kitchen is finished. (0m3.96s)

Now we can be sure that we have a cross plattform puppet module :-)

Final Notes

Have a look at

Old Errors

 1bundle exec kitchen converge default-nocm-ubuntu-1204
 2-----> Starting Kitchen (v1.2.1)
 3-----> Converging <default-nocm-ubuntu-1204>...
 4       Preparing files for transfer
 5       Preparing modules
 6       Resolving module dependencies with Librarian-Puppet 1.0.1...
 7>>>>>> ------Exception-------
 8>>>>>> Class: Kitchen::ActionFailed
 9>>>>>> Message: Failed to complete #converge action: [undefined method `puppet_gem_version' for Librarian::Puppet:Module]
10>>>>>> ----------------------
11>>>>>> Please see .kitchen/logs/kitchen.log for more details
12>>>>>> Also try running `kitchen diagnose --all` for configuration

Ouch. Nasty error. This is the librarian puppet integration not working for me on osx. So let us move it out of the way for now as we already have installed the modules.

mv Puppetfile Puppetfile.
Go Back explore our courses

We are here for you

You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.

Contact us