Don't Shrug! Using Ruby Testing Frameworks To Bring Sanity to Your Infrastructure FOSDEM 2013, Bryan W. Berry @bryanwb Code for this demo: https://github.com/bryanwb/tk-demo
You should use Ruby for Integration Testing ● Lightweight (mostly) ● Great libraries (mostly) ● Awesome Test DSLs like Rspec ● Easy to mock services (Sinatra) ● Vagrant, Vagrant, Vagrant Note: not the current Vagrant logo
Prod,QA,Dev,Vagrant Vagrant is your Development environment QA,Dev in use by developers are almost production ● VirtualBox ● Openstack* ● KVM* * support coming Note: not the current Vagrant logo
Basic Vagrantfile Vagrant::Config.run do |config| config.vm.box = "lucid32" config.vm.provision :chef_solo do |chef| # We're going to download our cookbooks from the web chef.recipe_url = "http://files.vagrantup.com/cookbooks.tar.gz" # Tell chef what recipe to run chef.add_recipe("vagrant_main") end end
Workflow and Vagrant ● Vagrantfile defines vms but not actions ● Need a separate tool for this, Rake or shell script ● Start Apache, haproxy, and back-end web service, then test communication between all 3
Multi-VM Vagrantfile Vagrant::Config.run do |config| config.vm.define “apache” do # . . . end config.vm.define “haproxy” do # . . . end config.vm.define “backend-app” do # . . . end end
Workflow with Rake task :up do puts "About to run vagrant-up..." $env = Vagrant::Environment.new $env.vms.each do |vm| vm.cli(“up”) end end task :test => :up do sleep 100 # wait a long time result = $env.vms[“apache”].cli('curl localhost | grep “Hello World”') exit result # result is 0 or 1 to indicate success or failure end
minitest-chef-handler ● Runs minitest suites after Chef recipes ● Has full access to the node object, chef-server ● Can also access underlying system minitest supports more traditional TestCase syntax and Rspec style expectations
Apache # apache2/files/default/minitest/default_test.rb describe_recipe “apache2::default” do it “responds with 'It Works!'” do response = Faraday.get “localhost” assert_match response.content, /It works/ end end
More Apache Tests It “installs httpd package” do package('httpd').must_be_installed end It “starts httpd service” do service('httpd').must_be_running end
Chef Integration It “installs httpd package” do package(node['apache2']['package']).must_be_installed end It “starts httpd service” do service(node['apache2']['package']).must_be_running end
Custom Matchers It “installs httpd package” do package('httpd').must_be_installed end It “starts httpd service” do service('httpd').must_be_running end extensions to minitest
Test-Kitchen ● Framework to test a single cookbook across different operating systems ● Can run tests on VirtualBox or Openstack ● Supports minitest or cucumber ● Configuration DSL
$ kitchen test Runs each configuration in each of the defined platforms (4) Number of Test Runs = 4 x No. of configurations Apache cookbook 96 test runs = 4 x 24 configurations
Our Test # apache2/files/default/minitest/default_test.rb require 'faraday' describe_recipe “apache2::default” do it “responds with 'Hello World!'” do response = Faraday.get “localhost” assert_match response.content, /Hello World/ end end
Disadvantages ● Designed for single-node configurations ● Doesn't expose underlying Vagrant config ● Test runs are sequential, no support for concurrent test runs
Jamie-CI Test-Kitchen 1.0 ● Written by Fletcher Nichol ● Only does two things 1. Defines machines 2. Exposes Driver interface for different virtualization backends ● Drivers* exist for: ● Linux containers ● Vagrant ● EC2 *Some still need to be renamed
Test-Kitchen 1.0 ● Define VMs using a single yaml file ● Supports Librarian-Chef and Berkshelf ● Tests VMs concurrently! ● No Workflow! Not opinionated! ● No docs either!
.kitchen.yml ● Why YAML? ● Expressive ● Easy for other programming languages to parse ● Platforms – base VMs with a minimum config ● Suite – actual configuration you want tested ● Number of test runs = Platforms x Suites Note: There is debate whether there will also be code-based configuration for Test-Kitchen 1.0. Stay tuned . . .
Chef-Workflow ● Written by Erik Hollensbe ● 3 libraries ● Chef-workflow ● chef-workflow-tasklib ● chef-workflow-testlib ● Deserves more attention than it is given here
In Summary ● You can do basic integration testing right now with vagrant + rake ● Concurrent VM task execution important ● Need DSL for integration tests ● Test-Kitchen is still alpha but very exciting ● There is gold in Chef-Workflow ● We need Public CI for chef cookbooks, puppet modules, and cfengine bundles