1 of 20

Foodtaster

Тестирование Chef-кода с помощью

RSpec и Vagrant

Докладчик: Михаил Лапшин

2 of 20

DevOps Are Coders

  • Несмотря на то, что существует множество open-source кукбуков, приходится писать свои, в частности интеграционные

  • Однако, общепринятый workflow так и не выработан

3 of 20

DevOps Are Coders...

… but without TDD/BDD

OKAY

4 of 20

Common DevOp Workflow

  1. Вносим правки в кукбук
  2. vagrant provision/up
  3. vagrant ssh
  4. goto 1

5 of 20

Common DevOp Workflow

Недостатки:

  • отсутствие уверенности в коде

  • проблема “первого/последующих запусков”

6 of 20

Poor Man’s Cookbook Testing

# cookbook/recipes/test.rb

ruby_block “cookbook test” do

block do

if !File.exists?(“...”)

raise “No config file”

end

end

end

7 of 20

Poor Man’s Cookbook Testing

Минусы:

  • не прогнать все тесты одной командой
  • следовательно, не сделать CI

  • нет DSL, нет хелперов, нет матчеров

  • нет интеграционного (многомашинного) тестирования

8 of 20

9 of 20

Foodtaster!

10 of 20

DevOp Workflow 2.0

  1. Правим спеки/кукбук
  2. rspec spec
  3. vagrant ssh (если нужно)
  4. goto 1

11 of 20

Архитектура Foodtaster

Foodtaster

+

RSpec

DRb

Vagrant

+

Foodtaster

DRb Server

VM0

VM1

VM2

vm up

vm down

vm rollback

run chef

execute command

12 of 20

Архитектура Foodtaster

vm0.should have_file(“/tmp/foo”)

то же самое, что

vm0.execute(“ls /tmp/foo”).should be_successful

13 of 20

Chef Repo (“Kitchen”) Layout

acme-infrastructure

├── cookbooks

│ ├── apt

├── site-cookbooks

│ ├── my_cookbook

├── spec

│ ├── my_cookbook_spec.rb

│ └── spec_helper.rb

├── Gemfile

└── Vagrantfile

14 of 20

Spec Example

describe "nginx::default" do� run_chef_on :vm0 do |c|� c.json = {}� c.add_recipe 'nginx'� end�� it "should install nginx as a daemon" do� vm0.should have_package 'nginx'� vm0.should have_user('www-data').in_group('www-data')� vm0.should listen_port(80)� end�� it "should have valid nginx config" do� result = vm0.execute("nginx -t")�� result.should be_successfull� result.stdout.should include("/etc/nginx/nginx.conf syntax is ok")� endend

15 of 20

Integration Spec Example

describe "pg cookbook" do

run_chef_on :vm0 do |chef|

chef.add_recipe "test::pg_master"

end

run_chef_on :vm1 do |chef|

chef.add_recipe "test::pg_stadby"

end

def exec_sql(vm, sql)

command = %Q[env psql -p 5555 postgres -c "#{sql}"]

res = vm.execute(command)

res.stdout

end

16 of 20

Integration Spec Example

it "should setup hot-standby replication" do

value = Time.now.to_s

exec_sql(vm0, "create table if not exists test (num varchar)")

exec_sql(vm0, "insert into test values('#{key}')")

timeout 5 do

begin

res = exec_sql(vm1, "select value from test")

sleep 1

end while !res.include?(key)

end

end

17 of 20

Foodtaster Current Limitations

  • only VirtualBox is supported

  • only Chef-Solo is supported

  • not a rich set of matchers

18 of 20

Links

GitHub:

mlapshin/foodtaster

mlapshin/foodtaster-example

Questions?

PM via GitHub or

E-mail: mikhail.a.lapshin@gmail.com

19 of 20

Questions?

20 of 20

FIN