cucumber-chef 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.document +5 -0
  2. data/.gitignore +45 -0
  3. data/Gemfile +21 -0
  4. data/LICENSE +201 -0
  5. data/README.md +83 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/bin/cucumber-chef +162 -0
  9. data/cookbooks/cucumber-chef/README.rdoc +8 -0
  10. data/cookbooks/cucumber-chef/files/default/add-git-identity +2 -0
  11. data/cookbooks/cucumber-chef/files/default/controller-first-boot +1 -0
  12. data/cookbooks/cucumber-chef/files/default/cucumber-net +5 -0
  13. data/cookbooks/cucumber-chef/files/default/cucumber-private-key +27 -0
  14. data/cookbooks/cucumber-chef/files/default/cucumber-run_list +1 -0
  15. data/cookbooks/cucumber-chef/files/default/git-private-key +27 -0
  16. data/cookbooks/cucumber-chef/files/default/install-chef +1 -0
  17. data/cookbooks/cucumber-chef/files/default/lxc-controller-network-config +5 -0
  18. data/cookbooks/cucumber-chef/files/default/lxc-lucid-chef +377 -0
  19. data/cookbooks/cucumber-chef/files/default/permissive-ssh-config +3 -0
  20. data/cookbooks/cucumber-chef/metadata.rb +6 -0
  21. data/cookbooks/cucumber-chef/recipes/controller.rb +50 -0
  22. data/cookbooks/cucumber-chef/recipes/lxc.rb +35 -0
  23. data/cookbooks/cucumber-chef/recipes/test_lab.rb +23 -0
  24. data/cookbooks/cucumber-chef/recipes/testrunner.rb +46 -0
  25. data/cookbooks/cucumber-chef/roles/controller.rb +7 -0
  26. data/cookbooks/cucumber-chef/roles/test_lab_test.rb +9 -0
  27. data/cookbooks/cucumber-chef/templates/default/controller-client.erb +5 -0
  28. data/cookbooks/cucumber-chef/templates/default/lxc-lucid-chef +385 -0
  29. data/cucumber-chef.gemspec +118 -0
  30. data/features/installing.feature +10 -0
  31. data/features/steps/installing_steps.rb +34 -0
  32. data/features/steps/setup_steps.rb +32 -0
  33. data/features/steps/upload_steps.rb +11 -0
  34. data/features/steps/usage_steps.rb +62 -0
  35. data/features/support/env.rb +25 -0
  36. data/features/support/filetools.rb +9 -0
  37. data/features/support/silent_system.rb +4 -0
  38. data/features/usage.feature +26 -0
  39. data/lib/cucumber-chef.rb +1 -0
  40. data/lib/cucumber/chef.rb +195 -0
  41. data/lib/cucumber/chef/handy.rb +87 -0
  42. data/lib/cucumber/chef/templates/controller.erb +35 -0
  43. data/lib/cucumber/chef/templates/env.rb +16 -0
  44. data/lib/cucumber/chef/templates/example_feature.erb +11 -0
  45. data/lib/cucumber/chef/templates/example_step.erb +19 -0
  46. data/lib/cucumber/chef/templates/readme.erb +28 -0
  47. data/lib/cucumber/chef/templates/ubuntu10.04-gems.erb +43 -0
  48. data/lib/cucumber/chef/version.rb +5 -0
  49. data/lib/cucumber/ec2_server_create.rb +99 -0
  50. data/spec/unit/cucumber_chef_spec.rb +270 -0
  51. metadata +213 -0
@@ -0,0 +1,87 @@
1
+ module Cucumber
2
+ module Chef
3
+ module Handy
4
+ def create_server(server, ip)
5
+ create_network_config(server, ip)
6
+ create_container(server)
7
+ end
8
+
9
+ def create_network_config(name, ip)
10
+ network_config = File.join("/etc/lxc", name)
11
+ File.open(network_config, 'w') do |f|
12
+ f.puts "lxc.network.type = veth"
13
+ f.puts "lxc.network.flags = up"
14
+ f.puts "lxc.network.link = br0"
15
+ f.puts "lxc.network.name = eth0"
16
+ f.puts "lxc.network.ipv4 = #{ip}/24"
17
+ end
18
+ end
19
+
20
+ def create_container(name)
21
+ unless File.exists?("/var/lib/lxc/#{name}")
22
+ %x[lxc-create -n #{name} -f /etc/lxc/#{name} -t lucid-chef > /dev/null 2>&1 ]
23
+ end
24
+ end
25
+
26
+ def set_run_list(name, run_list)
27
+ rl = Hash.new
28
+ a = Array.new
29
+ a << run_list
30
+ rl['run_list'] = a
31
+ first_boot = File.join('/var/lib/lxc', name, 'rootfs/etc/chef/first-boot.json')
32
+ File.open(first_boot, 'w') do |f|
33
+ f.puts rl.to_json
34
+ end
35
+ end
36
+
37
+ def run_chef_first_time(name)
38
+ %x[chroot /var/lib/lxc/#{name}/rootfs /bin/bash -c 'chef-client -j /etc/chef/first-boot.json > /dev/null 2>&1']
39
+ end
40
+
41
+ def run_chef(name)
42
+ container_path = "/var/lib/lxc/#{name}/rootfs"
43
+ %x[chroot #{container_path} /bin/bash -c 'chef-client > /dev/null 2>&1']
44
+ end
45
+
46
+ def upload_databag_item(databag, item)
47
+ databag_item = ::Chef::DataBagItem.new
48
+ databag_item.data_bag(databag)
49
+ databag_item.raw_data = item
50
+ databag_item.save
51
+ end
52
+
53
+ def create_client_rb(orgname)
54
+ client_rb = File.join('/var/lib/lxc', name, 'rootfs/etc/chef/client.rb')
55
+ File.open(client_rb, 'w') do |f|
56
+ f.puts "log_level :info"
57
+ f.puts "log_location STDOUT"
58
+ f.puts "chef_server_url 'https://api.opscode.com/organizations/#{orgname}'"
59
+ f.puts "validation_client_name '#{orgname}-validator'"
60
+ f.puts "node_name 'cucumber-chef-#{name}'"
61
+ end
62
+ end
63
+
64
+ def start_container(name)
65
+ status = %x[lxc-info -n #{name} 2>&1]
66
+ if status.include?("STOPPED")
67
+ %x[lxc-start -d -n #{name}]
68
+ sleep 5
69
+ end
70
+ end
71
+
72
+ def stop_container(name)
73
+ status = %x[lxc-info -n #{name} 2>&1]
74
+ if status.include?("RUNNING")
75
+ %x[lxc-destroy -d -n #{name}]
76
+ sleep 5
77
+ end
78
+ end
79
+
80
+ def run_remote_command(remote_server, command)
81
+ %x[ssh workstation.testlab 'ssh #{remote_server} #{command}']
82
+ end
83
+
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,35 @@
1
+ bash -c '
2
+ (
3
+ cat <<EOP
4
+ lxc.network.type = veth
5
+ lxc.network.flags = up
6
+ lxc.network.link = br0
7
+ lxc.network.name = eth0
8
+ lxc.network.ipv4 = 192.168.10.10/24
9
+ EOP
10
+ ) > /etc/lxc/controller
11
+
12
+ lxc-create -n controller -f /etc/lxc/controller -t lucid-chef
13
+
14
+ (
15
+ cat <<EOP
16
+
17
+ log_level :info
18
+ log_location STDOUT
19
+ chef_server_url "<%= @config[:chef_server_url] %>"
20
+ validation_client_name "<%= @config[:validation_client_name] %>"
21
+ <% if @config[:chef_node_name] == nil %>
22
+ # Using default node name"
23
+ <% else %>
24
+ node_name "<%= @config[:chef_node_name] %>"
25
+ <% end %>
26
+ EOP
27
+ ) > /var/lib/lxc/controller/rootfs/etc/chef/client.rb
28
+
29
+ cat <<EOP
30
+ { "run_list": [ "recipe[cucumber-chef::controller]" ] }
31
+ EOP
32
+ ) > /var/lib/lxc/controller/rootfs/etc/chef/first-boot.json
33
+
34
+ chroot /var/lib/lxc/controller/rootfs /bin/bash -c "chef-client -j /etc/chef/first-boot.json > /dev/null 2>&1"
35
+ lxc-start -d -n controller && sleep 5 && lxc-start -d -n controller'
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rspec/expectations'
4
+ require 'chef'
5
+ require 'cucumber/chef'
6
+ require 'cucumber/nagios/steps'
7
+ require 'cucumber/chef/handy'
8
+
9
+ class CustomWorld
10
+ include Cucumber::Chef
11
+ include Cucumber::Chef::Handy
12
+ end
13
+
14
+ World do
15
+ CustomWorld.new
16
+ end
@@ -0,0 +1,11 @@
1
+ Feature: Example feature for <%= @project %>
2
+ So that I can be learn how to use cucumber-chef
3
+ As an infrastructure developer
4
+ I can run an example feature that doesn't do much
5
+
6
+ Scenario: Example scenario for <%= @project %>
7
+ Given I have a remote server
8
+ And I apply the <%= @project %> role/recipe
9
+ And run Chef
10
+ When I connect to the remote server from the test server
11
+ Then the <% @project %> server behaves as it should
@@ -0,0 +1,19 @@
1
+ Given /^I have a remote server$/ do
2
+ pending # express the regexp above with the code you wish you had
3
+ end
4
+
5
+ Given /^I apply the <%= @project %> role\/recipe$/ do
6
+ pending # express the regexp above with the code you wish you had
7
+ end
8
+
9
+ Given /^run Chef$/ do
10
+ pending # express the regexp above with the code you wish you had
11
+ end
12
+
13
+ When /^I connect to the remote server from the test server$/ do
14
+ pending # express the regexp above with the code you wish you had
15
+ end
16
+
17
+ Then /^the <%= @project %> server behaves as it should$/ do
18
+ pending # express the regexp above with the code you wish you had
19
+ end
@@ -0,0 +1,28 @@
1
+ Welcome to the <%= @project %> suite of cucumber-chef tests
2
+
3
+ Your general workflow will be to write cucumber features that describe the intended behaviour of '<%= @project %>'. You will then write failing tests by writing steps to test the b$
4
+
5
+ You will then want to create a '<%= @project %>' cookbook, and write recipes that make your tests pass. Upload your cookbook to the Opscode Platform, and then push your cucumber-ch$
6
+
7
+ cucumber-chef upload <%= @project %>
8
+
9
+ Then run your tests with:
10
+
11
+ cucumber-chef test <%= @project %>
12
+
13
+ For an example feature, take a look at ./<%= @project %>/features/example.feature
14
+
15
+ For an example step definition, look at ./<%= @project %>/features/example.feature
16
+
17
+ To get started, you'll need to configure cucumber-chef to use your own Opscode Chef platform credentials, and AWS EC2 keys. You can generate a sample config with:
18
+
19
+ cucumber-chef genconfig
20
+
21
+ This will drop a .cucumber-chef config file in the home directory of the user with which you ran the cucumber-chef command. You'll need to edit the file in order to carry out setup, upload or test functionality.
22
+
23
+ One you've got a configuration in place, run:
24
+
25
+ cucumber-chef setup
26
+
27
+ This will create what we call a 'test lab' in EC2 in which tests will be run.
28
+
@@ -0,0 +1,43 @@
1
+ bash -c '
2
+ if [ ! -f /usr/bin/chef-client ]; then
3
+ apt-get update
4
+ apt-get install -y ruby ruby1.8-dev build-essential wget libruby-extras libruby1.8-extras
5
+ cd /tmp
6
+ wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
7
+ tar zxf rubygems-1.3.7.tgz
8
+ cd rubygems-1.3.7
9
+ ruby setup.rb --no-format-executable
10
+ fi
11
+ gem install ohai chef --no-rdoc --no-ri --verbose <%= '--prerelease' if @config[:prerelease] %>
12
+
13
+ mkdir -p /etc/chef
14
+
15
+ (
16
+ cat <<'EOP'
17
+ <%= IO.read(@config[:validation_key]) %>
18
+ EOP
19
+ ) > /tmp/validation.pem
20
+ awk NF /tmp/validation.pem > /etc/chef/validation.pem
21
+ rm /tmp/validation.pem
22
+
23
+ (
24
+ cat <<'EOP'
25
+ log_level :info
26
+ log_location STDOUT
27
+ chef_server_url "<%= @config[:chef_server_url] %>"
28
+ validation_client_name "<%= @config[:validation_client_name] %>"
29
+ <% if @config[:chef_node_name] == nil %>
30
+ # Using default node name"
31
+ <% else %>
32
+ node_name "<%= @config[:chef_node_name] %>"
33
+ <% end %>
34
+ EOP
35
+ ) > /etc/chef/client.rb
36
+
37
+ (
38
+ cat <<'EOP'
39
+ <%= { "run_list" => @run_list }.to_json %>
40
+ EOP
41
+ ) > /etc/chef/first-boot.json
42
+
43
+ /usr/bin/chef-client -j /etc/chef/first-boot.json'
@@ -0,0 +1,5 @@
1
+ module Cucumber
2
+ module Chef
3
+ VERSION = '0.0.2'
4
+ end
5
+ end
@@ -0,0 +1,99 @@
1
+ require 'fog'
2
+ require 'socket'
3
+ require 'chef/knife'
4
+ require 'chef/knife/bootstrap'
5
+ require 'chef/json_compat'
6
+
7
+ class Chef
8
+ class Knife
9
+ class Ec2ServerCreate < Knife
10
+
11
+ attr_accessor :initial_sleep_delay
12
+
13
+ def tcp_test_ssh(hostname)
14
+ tcp_socket = TCPSocket.new(hostname, 22)
15
+ readable = IO.select([tcp_socket], nil, nil, 5)
16
+ if readable
17
+ Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
18
+ yield
19
+ true
20
+ else
21
+ false
22
+ end
23
+ rescue Errno::ETIMEDOUT
24
+ false
25
+ rescue Errno::ECONNREFUSED
26
+ sleep 2
27
+ false
28
+ ensure
29
+ tcp_socket && tcp_socket.close
30
+ end
31
+
32
+ def run
33
+ require 'fog'
34
+ require 'highline'
35
+ require 'net/ssh/multi'
36
+ require 'readline'
37
+
38
+ $stdout.sync = true
39
+
40
+ connection = Fog::Compute.new(
41
+ :provider => 'AWS',
42
+ :aws_access_key_id => Chef::Config[:knife][:aws_access_key_id],
43
+ :aws_secret_access_key => Chef::Config[:knife][:aws_secret_access_key],
44
+ :region => #REGION
45
+ )
46
+
47
+ # WHAT IS THIS FOR?
48
+ ami = connection.images.get(locate_config_value(:image))
49
+
50
+ server_def = {
51
+ :image_id => locate_config_value(:image),
52
+ :groups => config[:security_groups],
53
+ :flavor_id => locate_config_value(:flavor),
54
+ :key_name => Chef::Config[:knife][:aws_ssh_key_id],
55
+ :availability_zone => Chef::Config[:knife][:availability_zone]
56
+ }
57
+
58
+ server = connection.servers.create(server_def)
59
+
60
+ puts "Instance ID: #{server.id}"
61
+ print "\n#{h.color("Waiting for server", :magenta)}"
62
+
63
+ # wait for it to be ready to do stuff
64
+ server.wait_for { print "."; ready? }
65
+
66
+ puts("\n")
67
+
68
+ puts "Public IP Address #{server.public_ip_address}"
69
+
70
+ print "\n#{h.color("Waiting for sshd", :magenta)}"
71
+
72
+ print(".") until tcp_test_ssh(server.dns_name) { sleep @initial_sleep_delay ||= 10; puts("done") }
73
+
74
+ bootstrap_for_node(server).run
75
+
76
+ end
77
+
78
+ def bootstrap_for_node(server)
79
+ bootstrap = Chef::Knife::Bootstrap.new
80
+ bootstrap.name_args = [server.dns_name]
81
+ bootstrap.config[:run_list] = config[:run_list]
82
+ bootstrap.config[:ssh_user] = config[:ssh_user]
83
+ bootstrap.config[:identity_file] = config[:identity_file]
84
+ bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
85
+ bootstrap.config[:prerelease] = config[:prerelease]
86
+ bootstrap.config[:distro] = locate_config_value(:distro)
87
+ bootstrap.config[:use_sudo] = true
88
+ bootstrap.config[:template_file] = locate_config_value(:template_file)
89
+ bootstrap.config[:environment] = config[:environment]
90
+ bootstrap
91
+ end
92
+
93
+ def locate_config_value(key)
94
+ key = key.to_sym
95
+ Chef::Config[:knife][key] || config[key]
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,270 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
+
5
+ def tcp_test_ssh(hostname)
6
+ tcp_socket = TCPSocket.new(hostname, 22)
7
+ IO.select([tcp_socket], nil, nil, 5)
8
+ rescue Errno::ETIMEDOUT
9
+ false
10
+ rescue Errno::EPERM
11
+ false
12
+ rescue Errno::ECONNREFUSED
13
+ sleep 2
14
+ false
15
+ # This happens on EC2 quite often
16
+ rescue Errno::EHOSTUNREACH
17
+ sleep 2
18
+ false
19
+ ensure
20
+ tcp_socket && tcp_socket.close
21
+ end
22
+
23
+ describe Cucumber::Chef::Config do
24
+ describe "when configuration is missing" do
25
+ it "should raise if it cannot find a configuration" do
26
+ begin
27
+ chef_dir = File.expand_path("~/.chef")
28
+ config_file = File.join(chef_dir, "knife.rb")
29
+ FileUtils.mv(config_file, File.join(chef_dir, "knife.rb.bak"))
30
+ expect { subject.config }.to raise_error(Cucumber::Chef::ConfigError)
31
+ ensure
32
+ FileUtils.mv(File.join(chef_dir, "knife.rb.bak"), config_file)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "when configuration is invalid" do
38
+ config_dir = File.join(File.dirname(__FILE__), "../../.chef")
39
+
40
+ before(:all) { FileUtils.mkdir_p(config_dir) }
41
+ after(:all) { FileUtils.rm_rf(config_dir) }
42
+
43
+ it "should complain about missing keys" do
44
+ config = "node_name ''"
45
+ File.open(Pathname(config_dir) + "knife.rb", 'w') { |f| f.puts config }
46
+ values, missing_keys = subject.display
47
+ missing_keys.should include("node_name")
48
+ missing_keys.should include("knife[:aws_access_key_id]")
49
+ end
50
+ end
51
+
52
+ describe "when configuration is valid" do
53
+ it "should find the configuration" do
54
+ values, missing_keys = subject.display
55
+ missing_keys.should be_empty
56
+ end
57
+
58
+ it "should display the configuration values" do
59
+ values, missing_keys = subject.display
60
+ output = values.join("\n")
61
+ output.should match(/node_name:/)
62
+ output.should match(/knife\[:aws_secret_access_key\]:/)
63
+ end
64
+ end
65
+ end
66
+
67
+ describe Cucumber::Chef::Provisioner do
68
+ before(:all) do
69
+ @config = subject.config
70
+ @config[:mode] = "test"
71
+ end
72
+
73
+ describe "verify_opscode_platform_credentials" do
74
+ describe "when configuration is invalid" do
75
+ config_dir = File.join(File.dirname(__FILE__), "../../.chef")
76
+ knife_file = File.join(config_dir, "knife.rb")
77
+
78
+ before(:all) do
79
+ FileUtils.mkdir_p(config_dir)
80
+ end
81
+
82
+ after(:all) do
83
+ FileUtils.rm_rf(config_dir)
84
+ end
85
+
86
+ describe "when node name is missing" do
87
+ it "should raise" do
88
+ config = "node_name ''"
89
+ File.open(knife_file, 'w') { |f| f.puts config }
90
+ expect {
91
+ subject.verify_opscode_platform_credentials(subject.config)
92
+ }.to raise_error(Cucumber::Chef::ProvisionerError)
93
+ end
94
+ end
95
+
96
+ describe "when node name is invalid" do
97
+ it "should raise" do
98
+ config = "node_name 'REALLYBOGUSORGNAME'"
99
+ File.open(knife_file, 'w') { |f| f.puts config }
100
+ expect {
101
+ subject.verify_opscode_platform_credentials(subject.config)
102
+ }.to raise_error(Cucumber::Chef::ProvisionerError)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "when configuration is valid" do
108
+ it "should not raise" do
109
+ subject.verify_opscode_platform_credentials(subject.config)
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "verify_aws_credentials" do
115
+ describe "when configuration is invalid" do
116
+ config_dir = File.join(File.dirname(__FILE__), "../../.chef")
117
+ knife_file = File.join(config_dir, "knife.rb")
118
+
119
+ before(:all) do
120
+ FileUtils.mkdir_p(config_dir)
121
+ end
122
+
123
+ after(:all) do
124
+ FileUtils.rm_rf(config_dir)
125
+ end
126
+
127
+ describe "when configuration is invalid" do
128
+ it "should raise" do
129
+ config = "knife[:aws_access_key_id] = ''"
130
+ File.open(knife_file, 'w') { |f| f.puts config }
131
+ expect {
132
+ subject.verify_aws_credentials(subject.config)
133
+ }.to raise_error(Cucumber::Chef::ProvisionerError)
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "when configuration is valid" do
139
+ it "should not raise" do
140
+ subject.verify_aws_credentials(subject.config)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "build_test_lab" do
146
+ after(:each) do
147
+ config = @config[:knife]
148
+ connection = Fog::Compute.new(:provider => 'AWS',
149
+ :aws_access_key_id => config[:aws_access_key_id],
150
+ :aws_secret_access_key => config[:aws_secret_access_key],
151
+ :region => config[:region])
152
+ connection.servers.each do |s|
153
+ s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
154
+ end
155
+ end
156
+
157
+ it "should spin up a ec2 instance", :slow => true do
158
+ output = StringIO.new
159
+ subject.build_test_lab(@config, output)
160
+ output.rewind
161
+ output.read.should match(/Platform provisioned/)
162
+ end
163
+
164
+ it "should only spin up one ec2 instance", :slow => true do
165
+ subject.build_test_lab(@config, StringIO.new)
166
+ expect {
167
+ subject.build_test_lab(@config, StringIO.new)
168
+ }.to raise_error(Cucumber::Chef::ProvisionerError)
169
+ end
170
+ end
171
+
172
+ describe "upload_cookbook" do
173
+ before(:each) do
174
+ begin
175
+ cookbook_path = File.expand_path("cookbooks/cucumber-chef")
176
+ version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(cookbook_path)
177
+ version_loader.load_cookbooks
178
+ version = version_loader.cookbook_version
179
+ version.destroy
180
+ rescue Net::HTTPServerException => err
181
+ end
182
+ end
183
+
184
+ it "should upload the cucumber-chef cookbook" do
185
+ subject.upload_cookbook(@config)
186
+ ::Chef::CookbookVersion.list["cucumber-chef"].should be
187
+ end
188
+ end
189
+
190
+ describe "upload_role" do
191
+ before(:each) do
192
+ begin
193
+ role_path = File.expand_path("cookbooks/cucumber-chef/roles")
194
+ ::Chef::Config[:role_path] = role_path
195
+ role = ::Chef::Role.from_disk("test_lab_test")
196
+ role.destroy
197
+ rescue Net::HTTPServerException => err
198
+ end
199
+ end
200
+
201
+ it "should upload the test_lab role" do
202
+ subject.upload_role(@config)
203
+ ::Chef::Role.list["test_lab_test"].should be
204
+ end
205
+ end
206
+
207
+ describe "bootstrap_node" do
208
+ before(:each) do
209
+ server = subject.build_test_lab(@config, StringIO.new)
210
+ @dns_name = server.dns_name
211
+ puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
212
+ puts "Got ssh..."
213
+ sleep(10)
214
+ subject.upload_cookbook(@config)
215
+ subject.upload_role(@config)
216
+ end
217
+
218
+ after(:each) do
219
+ config = @config[:knife]
220
+ connection = Fog::Compute.new(:provider => 'AWS',
221
+ :aws_access_key_id => config[:aws_access_key_id],
222
+ :aws_secret_access_key => config[:aws_secret_access_key],
223
+ :region => config[:region])
224
+ connection.servers.each do |s|
225
+ s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
226
+ end
227
+ end
228
+
229
+ it "should set up platform as a chef client and apply test-lab role" do
230
+ bootstrapper = subject.bootstrap_node(@dns_name, @config)
231
+ bootstrapper.run
232
+ # DEBUG: puts bootstrapper.ui.stdout.string
233
+ node = ::Chef::Node.load("cucumber-chef-test-lab")
234
+ node.run_list.to_s.should match(/role\[test_lab_test\]/)
235
+ end
236
+ end
237
+
238
+ describe "build_controller" do
239
+
240
+ before(:each) do
241
+ server = subject.build_test_lab(@config, StringIO.new)
242
+ @dns_name = server.dns_name
243
+ puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
244
+ puts "Got ssh..."
245
+ sleep(10)
246
+ subject.upload_cookbook(@config)
247
+ subject.upload_role(@config)
248
+ subject.bootstrap_node(@dns_name, @config).run
249
+ end
250
+
251
+ after(:each) do
252
+ config = @config[:knife]
253
+ connection = Fog::Compute.new(:provider => 'AWS',
254
+ :aws_access_key_id => config[:aws_access_key_id],
255
+ :aws_secret_access_key => config[:aws_secret_access_key],
256
+ :region => config[:region])
257
+ connection.servers.each do |s|
258
+ s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
259
+ end
260
+ end
261
+
262
+ it "should build a cucumber-chef controller" do
263
+ controller_builder = subject.build_controller(@dns_name, @config)
264
+ controller_builder.run
265
+ puts controller_builder.ui.stdout.string
266
+ end
267
+
268
+ end
269
+
270
+ end