making tdd [somewhat] bearable on openstack
DESCRIPTION
OpenStack Summit May 2014TRANSCRIPT
Hart Hoover
Making Test-Driven Development [Somewhat] Bearable on OpenStack
@hhoover#rackstackatl
#rackstackatl
RACKSPACE VISION
To be recognized as one of the world’s great service companies.
#rackstackatl
WELL TESTED = GOOD SERVICE
#rackstackatl
TEST-DRIVEN DEVELOPMENT (TRADITIONAL)
Test-driven development is a software development process that relies on the repetition of a very short development cycle.
First the developer writes an (initially failing) automated test case that defines a desired improvement or new function,
then produces the minimum amount of code to pass that test,
then finally refactors the new code to acceptable standards.
#rackstackatl
PLAN CODE BUILD TEST RELEASE DEPLOY OPS
THIS IS NOT TDDTHIS IS NOT “DEVOPS”
#rackstackatl
PLAN CODE BUILD TEST RELEASE DEPLOY OPS
TESTTHAT’S A BIT BETTER(STILL NOT “DEVOPS”)
#rackstackatl
TESTING IS A GOOD IDEA
FIND MISTAKES BEFORE
THEY HAPPEN
#rackstackatl
TESTING IS A GOOD IDEA
YOUR TEAM WON’T HATE
YOU
#rackstackatl
TESTING IS A GOOD IDEA
YOUR CUSTOMERS WON’T HATE
YOU
#rackstackatl
THE PROBLEM…
#rackstackatl
Object Placeholder
HERO CULTURE
#rackstackatl
LAZINESS OR ARROGANCE
“I just want to write code, not tests.”
“My code works when I push it.”
“It works on my machine.”
“QA does the tests.”
#rackstackatl
LEADERSHIP PRESSURE
#rackstackatl
TIME IS MONEY
DEV TIME IS A LOT OF MONEY
&
#rackstackatl
ONE SOLUTION: BE THE CHANGE YOU WANT TO SEE IN THE WORLD
#rackstackatl
ANOTHER SOLUTION: CONTINUOUS TESTING
#rackstackatl
TOOLS OF THE TRADE…
#rackstackatl
http://hart.io
#rackstackatl
#rackstackatl
#rackstackatl
#rackstackatl
DEPLOY A CHEF SERVER WITH HEAT
https://github.com/rackspace-orchestration-templates/chef-server
#rackstackatl
CHEF DEVELOPMENT KIT
http://www.getchef.com/downloads/chef-dk/
#rackstackatl
chefCHEF DEVELOPMENT KIT: CLI TOOLS
knifechef-‐client
Chef Zero
Ohai
#rackstackatl
CHEF DEVELOPMENT KIT
#rackstackatl
CHEF DEVELOPMENT KIT - BERKSHELF
source ‘https://api.berkshelf.com' metadata !cookbook ‘apt’, ‘~> 2.0’ cookbook ‘minitest-‐handler’ cookbook ‘yum’, ‘~> 2.0’ cookbook ‘build-‐essential’, github: ‘opscode-‐cookbooks/build-‐essential’ cookbook ‘mysql_test’, :path => ‘test/cookbooks/mysql_test’
#rackstackatl
CHEF DEVELOPMENT KIT - BERKSHELF
source ‘https://api.berkshelf.com' metadata !cookbook ‘apt’, ‘~> 2.0’ cookbook ‘minitest-‐handler’ cookbook ‘yum’, ‘~> 2.0’ cookbook ‘build-‐essential’, github: ‘opscode-‐cookbooks/build-‐essential’ cookbook ‘mysql_test’, :path => ‘test/cookbooks/mysql_test’
#rackstackatl
CHEF DEVELOPMENT KIT - BERKSHELF
source ‘https://api.berkshelf.com' metadata !cookbook ‘apt’, ‘~> 2.0’ cookbook ‘minitest-‐handler’ cookbook ‘yum’, ‘~> 2.0’ cookbook ‘build-‐essential’, github: ‘opscode-‐cookbooks/build-‐essential’ cookbook ‘mysql_test’, :path => ‘test/cookbooks/mysql_test’
#rackstackatl
CHEF DEVELOPMENT KIT - BERKSHELF
source ‘https://api.berkshelf.com' metadata !cookbook ‘apt’, ‘~> 2.0’ cookbook ‘minitest-‐handler’ cookbook ‘yum’, ‘~> 2.0’ cookbook ‘build-‐essential’, github: ‘opscode-‐cookbooks/build-‐essential’ cookbook ‘mysql_test’, :path => ‘test/cookbooks/mysql_test’
#rackstackatl
CHEF DEVELOPMENT KIT - BERKSHELF
source ‘https://api.berkshelf.com' metadata !cookbook ‘apt’, ‘~> 2.0’ cookbook ‘minitest-‐handler’ cookbook ‘yum’, ‘~> 2.0’ cookbook ‘build-‐essential’, github: ‘opscode-‐cookbooks/build-‐essential’ cookbook ‘mysql_test’, :path => ‘test/cookbooks/mysql_test’
#rackstackatl
kitchen.ci/docs/guide
CHEF DEVELOPMENT KIT
Test Kitchen
#rackstackatl
-‐-‐-‐ provisioner: name: chef_solo !platforms: -‐ name: ubuntu-‐14.04 !driver: name: rackspace rackspace_region: IAD server_name: rackspace-‐ubuntu1404 image_id: bb02b1a3-‐bc77-‐4d17-‐ab5b-‐421d89850fca flavor_id: performance1-‐1 require_chef_omnibus: latest !suites: -‐ name: default run_list: recipe[cookbook::default] attributes:
#rackstackatl
-‐-‐-‐ provisioner: name: chef_solo !platforms: -‐ name: ubuntu-‐14.04 !driver: name: rackspace rackspace_region: IAD server_name: rackspace-‐ubuntu1404 image_id: bb02b1a3-‐bc77-‐4d17-‐ab5b-‐421d89850fca flavor_id: performance1-‐1 require_chef_omnibus: latest !suites: -‐ name: default run_list: recipe[cookbook::default] attributes:
#rackstackatl
-‐-‐-‐ provisioner: name: chef_solo !platforms: -‐ name: ubuntu-‐14.04 !driver: name: rackspace rackspace_region: IAD server_name: rackspace-‐ubuntu1404 image_id: bb02b1a3-‐bc77-‐4d17-‐ab5b-‐421d89850fca flavor_id: performance1-‐1 require_chef_omnibus: latest !suites: -‐ name: default run_list: recipe[cookbook::default] attributes:
#rackstackatl
-‐-‐-‐ provisioner: name: chef_solo !platforms: -‐ name: ubuntu-‐14.04 !driver: name: rackspace rackspace_region: IAD server_name: rackspace-‐ubuntu1404 image_id: bb02b1a3-‐bc77-‐4d17-‐ab5b-‐421d89850fca flavor_id: performance1-‐1 require_chef_omnibus: latest !suites: -‐ name: default run_list: recipe[cookbook::default] attributes:
#rackstackatl
-‐-‐-‐ provisioner: name: chef_solo !platforms: -‐ name: ubuntu-‐14.04 !driver: name: rackspace rackspace_region: IAD server_name: rackspace-‐ubuntu1404 image_id: bb02b1a3-‐bc77-‐4d17-‐ab5b-‐421d89850fca flavor_id: performance1-‐1 require_chef_omnibus: latest !suites: -‐ name: default run_list: recipe[cookbook::default] attributes:
#rackstackatl
CHEF DEVELOPMENT KIT
#rackstackatl
CHEF DEVELOPMENT KIT
ChefSpec• Built on RSpec• Converges a Chef run in memory• Overrides all providers to take no action• Mock Ohai data with Fauxhai
#rackstackatl
CHEF DEVELOPMENT KIT: CHEFSPEC
https://github.com/sethvargo/chefspec/tree/master/examples
#rackstackatl
CHEF DEVELOPMENT KIT: CHEFSPECrequire 'chefspec' !describe 'apt_package::install' do let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } ! it 'installs a apt_package with the default action' do expect(chef_run).to install_apt_package('default_action') expect(chef_run).to_not install_apt_package('not_default_action') end end
#rackstackatl
CHEF DEVELOPMENT KIT: CHEFSPECrequire 'chefspec' !describe 'apt_package::install' do let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } ! it 'installs a apt_package with the default action' do expect(chef_run).to install_apt_package('default_action') expect(chef_run).to_not install_apt_package('not_default_action') end end
#rackstackatl
CHEF DEVELOPMENT KIT: CHEFSPECrequire 'chefspec' !describe 'apt_package::install' do let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } ! it 'installs a apt_package with the default action' do expect(chef_run).to install_apt_package('default_action') expect(chef_run).to_not install_apt_package('not_default_action') end end
#rackstackatl
HONORABLE MENTIONS
#rackstackatl
SERVERSPEC
• Built on RSpec• Uses SSH to test your servers’ state
#rackstackatl
SERVERSPECdescribe package('httpd') do it { should be_installed } end !describe service('httpd') do it { should be_enabled } it { should be_running } end !describe port(80) do it { should be_listening } end
#rackstackatl
meez
https://github.com/paulczar/meez
#rackstackatl
RUBOCOP: STYLE
RUBY STYLE GUIDE
• code layout• strings• syntax
• regex• more
#rackstackatl
GUARD: TEST WHILE YOU WORK
#rackstackatl
#rackstackatl
source 'https://rubygems.org' !gem 'berkshelf' gem 'chef' gem 'meez' gem 'guard' gem 'guard-‐kitchen' gem 'rubocop' gem 'foodcritic' gem 'chefspec' gem 'test-‐kitchen' gem 'kitchen-‐rackspace' gem 'kitchen-‐openstack'
#rackstackatl
GET TO THE OPENSTACK STUFF
#rackstackatl
source 'https://rubygems.org' !gem 'berkshelf' gem 'chef' gem 'meez' gem 'guard' gem 'guard-‐kitchen' gem 'rubocop' gem 'foodcritic' gem 'chefspec' gem 'test-‐kitchen' gem 'kitchen-‐rackspace' gem 'kitchen-‐openstack'
#rackstackatl
DEMO TIME!
#rackstackatl54
#rackstackatl55
#rackstackatl
162.242.253.111LET’S PLAY ON THE CLOUD
#rackstackatl
WE’RE HIRING
http://rackertalent.com
#rackstackatl
RACKSPACE® HOSTING | 5000 WALZEM ROAD | SAN ANTONIO, TX 78218 US SALES: 1-800-961-2888 | US SUPPORT: 1-800-961-4454 | WWW.RACKSPACE.COM
RACKSPACE® HOSTING | © RACKSPACE US, INC. | RACKSPACE® AND FANATICAL SUPPORT® ARE SERVICE MARKS OF RACKSPACE US, INC. REGISTERED IN THE UNITED STATES AND OTHER COUNTRIES. | WWW.RACKSPACE.COMRACKSPACE® HOSTING | © RACKSPACE US, INC. | RACKSPACE® AND FANATICAL SUPPORT® ARE SERVICE MARKS OF RACKSPACE US, INC. REGISTERED IN THE UNITED STATES AND OTHER COUNTRIES. | WWW.RACKSPACE.COM
Hart Hoover @hhoover