$30 off During Our Annual Pro Sale. View Details »

TDDing tmux

TDDing tmux

Seth Vargo

April 04, 2013
Tweet

More Decks by Seth Vargo

Other Decks in Technology

Transcript

  1. tmux
    TDDing

    View Slide

  2. ?
    Ruby

    View Slide

  3. ?
    Operations

    View Slide

  4. View Slide

  5. http://www.wikihow.com/Make-Friends

    View Slide

  6. How to apply the testing
    cookbooks
    to chef
    know in Ruby
    stuff you already
    because Chef
    is just Ruby and you already know Ruby, so strap in

    View Slide

  7. t
    f
    g
    sethvargo

    View Slide

  8. t
    f
    g
    sethvargo

    View Slide

  9. View Slide

  10. opscode.com/careers
    8
    FSF)JSJOH

    View Slide

  11. Let's talk about testing

    View Slide

  12. It all starts on
    git clone git://github.com/opscode/chef-repo.git

    View Slide

  13. github.com/opscode/chef-repo

    View Slide

  14. source 'https://rubygems.org'
    gem 'chef'
    gem 'chefspec'
    gem 'fauxhai'
    gem 'foodcritic'
    gem 'strainer'
    # Guard
    gem 'guard'
    gem 'guard-bundler'
    gem 'guard-rspec'
    gem 'rb-fsevent'
    gem 'terminal-notifier-guard'
    Gemfile

    View Slide

  15. Chef

    View Slide

  16. ChefSpec

    View Slide

  17. Fauxhai

    View Slide

  18. Foodcritic

    View Slide

  19. Strainer

    View Slide

  20. Guard

    View Slide

  21. 1
    Create Cookbook

    View Slide

  22. $ knife cookbook create tmux

    View Slide

  23. $ knife cookbook create tmux
    ** Creating cookbook tmux
    ** Creating README for cookbook: tmux
    ** Creating CHANGELOG for cookbook: tmux
    ** Creating metadata for cookbook: tmux

    View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. maintainer 'everyone'
    maintainer_email '[email protected]'
    license 'apache2'
    description 'Installs and configures tmux'
    long_description # ...
    version '0.1.0'
    metadata.rb

    View Slide

  28. 2
    Write Specs

    View Slide

  29. require 'chefspec'
    spec/spec_helper.rb

    View Slide

  30. require 'spec_helper'
    describe 'tmux::default' do
    end
    spec/default_spec.rb

    View Slide

  31. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    end
    spec/default_spec.rb

    View Slide

  32. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    it 'installs the tmux package' do
    expect(runner).to install_package('tmux')
    end
    end
    spec/default_spec.rb

    View Slide

  33. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    it 'installs the tmux package' do
    expect(runner).to install_package('tmux')
    end
    it 'creates the tmux.conf file' do
    expect(runner).to create_file('/etc/tmux.conf')
    end
    end
    spec/default_spec.rb

    View Slide

  34. Wat?

    View Slide

  35. View Slide

  36. Pour some sugar on me!

    View Slide

  37. Pour some sugar on me!
    color

    View Slide

  38. --color
    .rspec

    View Slide

  39. $ rspec cookbooks/tmux/spec/default_spec.rb

    View Slide

  40. $ rspec cookbooks/tmux/spec/default_spec.rb
    Failures:
    1) tmux::default should install the tmux package
    Failure/Error: let(:runner)
    { ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    TypeError:
    can't convert Symbol into Integer
    # ./cookbooks/bluepill/attributes/default.rb:
    18:in `[]'
    # ./cookbooks/bluepill/attributes/default.rb:
    18:in `from_file'
    # ./cookbooks/tmux/spec/default_spec.rb:4:in
    `block (2 levels) in '
    # ./cookbooks/tmux/spec/default_spec.rb:7:in
    `block (2 levels) in '
    2) tmux::default should create the tmux.conf file
    Failure/Error: let(:runner)
    { ChefSpec::ChefRunner.new.converge('tmux::default')
    }

    View Slide

  41. View Slide

  42. require 'spec_helper'
    describe 'tmux::default' do
    before {
    Fauxhai.mock(platform: 'ubuntu', version: '12.04')
    }
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    end
    Before

    View Slide

  43. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new(
    platform: 'ubuntu', version: '12.04'
    ).converge('tmux::default')
    }
    end
    After

    View Slide

  44. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new(
    platform: 'ubuntu', version: '12.04'
    ).converge('tmux::default')
    }
    it 'installs the tmux package' do
    expect(runner).to install_package('tmux')
    end
    it 'creates the tmux.conf file' do
    expect(runner).to create_file('/etc/tmux.conf')
    end
    end
    After

    View Slide

  45. $ rspec cookbooks/tmux/spec/default_spec.rb

    View Slide

  46. $ rspec cookbooks/tmux/spec/default_spec.rb
    Failures:
    1) tmux::default should install the tmux package
    Failure/Error: runner.should install_package
    'tmux'
    No package resource named 'tmux' with
    action :install found.
    # ./cookbooks/tmux/spec/default_spec.rb:8:in
    `block (2 levels) in '
    2) tmux::default should create the tmux.conf file
    Failure/Error: runner.should create_file('/etc/
    tmux.conf')
    No file resource named '/etc/tmux.conf' with
    action :create found.
    # ./cookbooks/tmux/spec/default_spec.rb:12:in
    `block (2 levels) in '
    Finished in 0.14994 seconds
    2 examples, 2 failures

    View Slide

  47. 3
    Setup Guard

    View Slide

  48. $ guard init

    View Slide

  49. $ guard init
    Writing new Guardfile to [...]/Guardfile

    View Slide

  50. guard 'rspec', spec_paths: ['spec', 'cookbooks/*/spec'] do
    end
    Guardfile

    View Slide

  51. guard 'rspec', spec_paths: ['spec', 'cookbooks/*/spec'] do
    watch(%r{^spec/.+_spec\.rb$})
    end
    Guardfile

    View Slide

  52. guard 'rspec', spec_paths: ['spec', 'cookbooks/*/spec'] do
    watch(%r{^spec/.+_spec\.rb$})
    watch('spec/spec_helper.rb') { 'spec' }
    end
    Guardfile

    View Slide

  53. guard 'rspec', spec_paths: ['spec', 'cookbooks/*/spec'] do
    watch(%r{^spec/.+_spec\.rb$})
    watch('spec/spec_helper.rb') { 'spec' }
    watch(%r{^cookbooks/(.+)/recipes/(.+)\.rb$}) do |m|
    "cookbooks/#{m[1]}/spec/#{m[2]}_spec.rb"
    end
    end
    Guardfile

    View Slide

  54. guard 'rspec', spec_paths: ['spec', 'cookbooks/*/spec'] do
    watch(%r{^spec/.+_spec\.rb$})
    watch('spec/spec_helper.rb') { 'spec' }
    watch(%r{^cookbooks/(.+)/recipes/(.+)\.rb$}) do |m|
    "cookbooks/#{m[1]}/spec/#{m[2]}_spec.rb"
    end
    watch(%r{^cookbooks/([A-Za-z]+)/(.+)(\..*)?$}) do |m|
    "cookbooks/#{m[1]}/spec/*.rb"
    end
    end
    Guardfile

    View Slide

  55. $ guard

    View Slide

  56. $ guard
    Guard is now watching at '[...]/chef-repo'
    Guard::RSpec is running
    Running all specs
    Failures:
    1) tmux::default should install the tmux package
    Failure/Error: runner.should install_package
    'tmux'
    No package resource named 'tmux' with
    action :install found.
    # ./cookbooks/tmux/spec/default_spec.rb:8:in
    `block (2 levels) in '
    2) tmux::default should create the tmux.conf file
    Failure/Error: runner.should create_file('/etc/
    tmux.conf')
    No file resource named '/etc/tmux.conf' with
    action :create found.
    # ./cookbooks/tmux/spec/default_spec.rb:12:in
    `block (2 levels) in '

    View Slide

  57. recipes/default.rb
    # Install the tmux package
    package 'tmux'

    View Slide

  58. # Install the tmux package
    package 'tmux'
    # Drop the tmux configuration template
    template '/etc/tmux.conf' do
    source 'tmux.conf.erb'
    mode '0644'
    end
    recipes/default.rb

    View Slide

  59. $ guard
    Guard is now watching at '[...]/chef-repo'
    Guard::RSpec is running
    Running all specs
    **
    Finished in 0.0003 seconds
    2 examples, 0 failures

    View Slide

  60. Wat?

    View Slide

  61. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    it 'installs the tmux package' do
    expect(runner).to install_package('tmux')
    end
    it 'creates the tmux.conf file' do
    expect(runner).to create_file('/etc/tmux.conf')
    end
    end
    spec/default_spec.rb

    View Slide

  62. require 'spec_helper'
    describe 'tmux::default' do
    let(:runner) {
    ChefSpec::ChefRunner.new.converge('tmux::default')
    }
    it 'installs the tmux package' do
    expect(runner).to install_package('tmux')
    end
    it 'creates the tmux.conf file' do
    expect(runner).to create_file('/etc/tmux.conf').
    with_content('set -g prefix C-a')
    end
    end
    spec/default_spec.rb

    View Slide

  63. $ guard
    Guard is now watching at '[...]/chef-repo'
    Guard::RSpec is running
    Running all specs
    *F
    Failures:
    1) tmux::default should create the tmux.conf file
    Failure/Error: runner.should create_file('/etc/
    tmux.conf')
    No source template named 'tmux.conf.erb' found
    in the default locations.
    # ./cookbooks/tmux/spec/default_spec.rb:12:in
    `block (2 levels) in '
    Finished in 0.15691 seconds
    2 examples, 1 passed, 1 failures

    View Slide

  64. # Use a better prefix:
    set -g prefix C-a
    unbind C-b
    # Change the default delay:
    set -sg escape-time 1
    # Set the window and panes index
    set -g base-index 1
    setw -g pane-base-index 1
    # Send prefix to other apps:
    bind C-a send-prefix
    # Split windows with more logical keys
    bind | split-window -h
    bind - split-window -v
    # Remap movement keys
    bind h select-pane -L
    bind j select-pane -D
    bind k select-pane -U
    bind l select-pane -R
    templates/default/tmux.conf.erb

    View Slide

  65. $ guard
    Guard is now watching at '[...]/chef-repo'
    Guard::RSpec is running
    Running all specs
    **
    Finished in 0.0003 seconds
    2 examples, 0 failures

    View Slide

  66. 4
    Moar Tests

    View Slide

  67. $ foodcritic cookbooks/tmux

    View Slide

  68. $ foodcritic -I my-rules/* cookbooks/tmux

    View Slide

  69. $ foodcritic -I my-rules/* cookbooks/tmux
    FC045: Consider setting cookbook name in metadata:
    cookbooks/tmux/metadata.rb:1

    View Slide

  70. $ foodcritic -I my-rules/* cookbooks/tmux
    FC045: Consider setting cookbook name in metadata:
    cookbooks/tmux/metadata.rb:1
    $ echo $?
    0

    View Slide

  71. $ foodcritic -I my-rules/* -f any cookbooks/tmux
    FC045: Consider setting cookbook name in metadata:
    cookbooks/tmux/metadata.rb:1
    $ echo $?
    3

    View Slide

  72. name 'tmux'
    maintainer 'everyone'
    maintainer_email '[email protected]'
    license 'apache2'
    description 'Installs and configures tmux'
    long_description # ...
    version '0.1.0'
    metadata.rb

    View Slide

  73. $ knife cookbook test tmux

    View Slide

  74. $ knife cookbook test tmux
    checking tmux
    Running syntax check on tmux
    Validating ruby files
    Validating templates

    View Slide

  75. 5
    Simplify

    View Slide

  76. ChefSpec
    foodcritic
    knife test

    View Slide

  77. ChefSpec
    foodcritic
    knife test
    Strainer

    View Slide

  78. knife: knife cookbook test $COOKBOOK
    foodcritic: foodcritic -f any $SANDBOX/$COOKBOOK
    chefspec: bundle exec rspec $SANDBOX/$COOKBOOK
    Strainerfile

    View Slide

  79. $ strainer test tmux
    # Straining 'tmux (v0.0.1)'
    knife | knife cookbook test tmux
    knife | checking tmux
    knife | Running syntax check on tmux
    knife | Validating ruby files
    knife | Validating templates
    knife | SUCCESS!
    foodcritic | foodcritic -f any /Users/
    sethvargo/Development/chef-is/cookbooks/tmux
    foodcritic | SUCCESS!
    chefspec | bundle exec rspec /Users/
    sethvargo/Development/chef-is/cookbooks/tmux
    chefspec | No examples found.
    chefspec | Finished in 0.00006 seconds
    chefspec | 0 examples, 0 failures
    chefspec | SUCCESS!

    View Slide

  80. ?
    Bonus

    View Slide

  81. #!/bin/bash
    set -e
    set +x
    git submodule update --init 2>&1 > /dev/null
    bundle install --quiet
    rm -Rf .colander
    strainer test `echo $JOB_NAME | sed 's/_cookbook//'`
    script/ci

    View Slide

  82. script/ci

    View Slide

  83. View Slide

  84. ?
    Questions

    View Slide