cucumber-chef 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.4
1
+ 0.5.0
data/bin/cucumber-chef CHANGED
@@ -27,46 +27,7 @@ class CucumberChef < Thor
27
27
  File.dirname(__FILE__)
28
28
  end
29
29
 
30
- def initialize(args = [], options = {}, config = {})
31
- @provisioner = ::Cucumber::Chef::Provisioner.new
32
- super(args, options, config)
33
- end
34
-
35
30
  no_tasks do
36
- def tcp_test_ssh(hostname)
37
- tcp_socket = TCPSocket.new(hostname, 22)
38
- IO.select([tcp_socket], nil, nil, 5)
39
- rescue Errno::ETIMEDOUT
40
- false
41
- rescue Errno::EPERM
42
- false
43
- rescue Errno::ECONNREFUSED
44
- sleep 2
45
- false
46
- # This happens on EC2 quite often
47
- rescue Errno::EHOSTUNREACH
48
- sleep 2
49
- false
50
- ensure
51
- tcp_socket && tcp_socket.close
52
- end
53
-
54
- def get_latest_version
55
- installed_versions = []
56
- Gem::source_index.find_name('cucumber-chef').map do |g|
57
- version = g.version.version
58
- if version == ""
59
- version = "0"
60
- end
61
- installed_versions << version
62
- end
63
- version = installed_versions.sort { |a, b| a.to_i <=> b.to_i }.last
64
- if version == "0"
65
- version = ""
66
- end
67
- return "cucumber-chef-" + version
68
- end
69
-
70
31
  def create_directory_structure(project_dir)
71
32
  %w{step_definitions support}.each do |dir|
72
33
  FileUtils.mkdir_p(project_dir + "features" + dir)
@@ -95,12 +56,6 @@ class CucumberChef < Thor
95
56
  warn message
96
57
  exit 255
97
58
  end
98
-
99
- def find_knife_config
100
- @provisioner.config
101
- rescue ::Cucumber::Chef::ProvisionerError => err
102
- error(err.message)
103
- end
104
59
  end
105
60
 
106
61
  desc "project <project name>" , "Create a project template for testing an infrastructure"
@@ -115,35 +70,53 @@ class CucumberChef < Thor
115
70
  method_option :test, :type => :boolean
116
71
  def setup
117
72
  begin
118
- config = find_knife_config
119
73
  if options.test?
120
- config[:mode] = "test"
74
+ config = Cucumber::Chef::Config.test_config
121
75
  else
122
- config[:mode] = "user"
76
+ config = Cucumber::Chef::Config.new
123
77
  end
124
- @provisioner.verify_opscode_platform_credentials(config)
125
- @provisioner.verify_aws_credentials(config)
78
+ config.verify
126
79
  $stdout.sync
127
- server = @provisioner.build_test_lab(config, $stdout)
80
+ provisioner = ::Cucumber::Chef::Provisioner.new
81
+ server = provisioner.build_test_lab(config, $stdout)
128
82
  sleep(10)
129
- @provisioner.upload_cookbook(config)
130
- @provisioner.upload_role(config)
131
- @provisioner.bootstrap_node(server.dns_name, config).run
132
- rescue ::Cucumber::Chef::ProvisionerError => err
83
+ provisioner.upload_cookbook(config)
84
+ provisioner.upload_role(config)
85
+ provisioner.bootstrap_node(server.dns_name, config).run
86
+ rescue ::Cucumber::Chef::Error => err
133
87
  error(err.message)
134
88
  end
135
89
  end
136
90
 
137
91
  desc "displayconfig", "Display the current config from knife.rb"
92
+ method_option :test, :type => :boolean
138
93
  def displayconfig
139
- values, missing_keys = Cucumber::Chef::Config.new.display
140
- puts values.join("\n")
141
- if missing_keys.size > 0
142
- error("Incomplete config file, please specify: #{missing_keys.join(", ")}")
94
+ if options.test?
95
+ config = Cucumber::Chef::Config.test_config
96
+ else
97
+ config = Cucumber::Chef::Config.new
143
98
  end
144
- rescue ::Cucumber::Chef::ProvisionerError => err
99
+ puts config.list.join("\n")
100
+ config.verify
101
+ rescue ::Cucumber::Chef::Error => err
145
102
  error(err.message)
146
103
  end
104
+
105
+ desc "info", "Display information about the current test lab"
106
+ method_option :test, :type => :boolean
107
+ def info
108
+ if options.test?
109
+ config = Cucumber::Chef::Config.test_config
110
+ else
111
+ config = Cucumber::Chef::Config.new
112
+ end
113
+ config.verify
114
+ lab = Cucumber::Chef::TestLab.new(config)
115
+ if lab.exists?
116
+ puts lab.info
117
+ else
118
+ end
119
+ end
147
120
 
148
121
  desc "upload", "Upload a cucumber-chef test suite to the test lab platform"
149
122
  def upload
@@ -156,7 +129,6 @@ class CucumberChef < Thor
156
129
  puts
157
130
  puts "Test results will appear here."
158
131
  end
159
-
160
-
161
132
  end
133
+
162
134
  CucumberChef.start
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cucumber-chef}
8
- s.version = "0.4.4"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Stephen Nelson-Smith"]
12
- s.date = %q{2011-06-06}
12
+ s.date = %q{2011-06-09}
13
13
  s.default_executable = %q{cucumber-chef}
14
14
  s.description = %q{Framework for behaviour-drive infrastructure development.}
15
15
  s.email = %q{stephen@atalanta-systems.com}
@@ -59,6 +59,7 @@ Gem::Specification.new do |s|
59
59
  "features/usage.feature",
60
60
  "lib/cucumber-chef.rb",
61
61
  "lib/cucumber/chef.rb",
62
+ "lib/cucumber/chef/config.rb",
62
63
  "lib/cucumber/chef/handy.rb",
63
64
  "lib/cucumber/chef/templates/controller.erb",
64
65
  "lib/cucumber/chef/templates/env.rb",
@@ -66,9 +67,12 @@ Gem::Specification.new do |s|
66
67
  "lib/cucumber/chef/templates/example_step.erb",
67
68
  "lib/cucumber/chef/templates/readme.erb",
68
69
  "lib/cucumber/chef/templates/ubuntu10.04-gems.erb",
70
+ "lib/cucumber/chef/test_lab.rb",
69
71
  "lib/cucumber/chef/version.rb",
70
72
  "lib/cucumber/ec2_server_create.rb",
71
- "spec/unit/cucumber_chef_spec.rb"
73
+ "spec/unit/config_spec.rb",
74
+ "spec/unit/cucumber_chef_spec.rb",
75
+ "spec/unit/test_lab_spec.rb"
72
76
  ]
73
77
  s.homepage = %q{http://github.com/atalanta/cucumber-chef}
74
78
  s.licenses = ["MIT"]
@@ -22,7 +22,7 @@ When /^the config file contains invalid credentials$/ do
22
22
  end
23
23
 
24
24
  Then /^I should be alerted that my credentials are invalid$/ do
25
- @output.should == "Invalid Opscode platform credentials. Please check.\n"
25
+ @output.should match(/Invalid Opscode platform credentials. Please check/m)
26
26
  end
27
27
 
28
28
  When /^I create a project called test_project$/ do
@@ -0,0 +1,121 @@
1
+ module Cucumber
2
+ module Chef
3
+ class ConfigError < Error ; end
4
+
5
+ class Config
6
+ KEYS = %w[mode node_name chef_server_url client_key validation_key validation_client_name]
7
+ KNIFE_KEYS = %w[aws_access_key_id aws_secret_access_key region availability_zone aws_ssh_key_id identity_file]
8
+
9
+ def initialize
10
+ config[:mode] = "user"
11
+ end
12
+
13
+ def self.test_config
14
+ config = self.new
15
+ config[:mode] = "test"
16
+ config
17
+ end
18
+
19
+ def [](key)
20
+ config[key]
21
+ end
22
+
23
+ def []=(key, value)
24
+ config[key] = value
25
+ end
26
+
27
+ def config
28
+ unless @config
29
+ full_path = Dir.pwd.split(File::SEPARATOR)
30
+ (full_path.length - 1).downto(0) do |i|
31
+ knife_file = File.join(full_path[0..i] + [".chef", "knife.rb"])
32
+ if File.exist?(knife_file)
33
+ ::Chef::Config.from_file(knife_file)
34
+ @config = ::Chef::Config
35
+ return @config
36
+ end
37
+ end
38
+ raise ConfigError.new("Couldn't find knife.rb")
39
+ end
40
+ @config
41
+ end
42
+
43
+ def list
44
+ values = []
45
+ KEYS.each do |key|
46
+ value = config[key]
47
+ values << "#{key}: #{value}"
48
+ end
49
+ KNIFE_KEYS.each do |key|
50
+ value = config[:knife][key.to_sym]
51
+ values << "knife[:#{key}]: #{value}"
52
+ end
53
+ values
54
+ end
55
+
56
+ def verify
57
+ @errors = []
58
+ verify_orgname
59
+ verify_opscode_user
60
+ verify_keys
61
+ verify_opscode_platform_credentials
62
+ verify_aws_credentials
63
+ if @errors.size > 0
64
+ raise ConfigError.new(@errors.join("\n"))
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def verify_orgname
71
+ if !ENV["ORGNAME"] || ENV["ORGNAME"] == ""
72
+ @errors << "Your organisation must be set using the environment variable ORGNAME."
73
+ end
74
+ end
75
+
76
+ def verify_opscode_user
77
+ if !ENV["OPSCODE_USER"] || ENV["OPSCODE_USER"] == ""
78
+ @errors << "Your Opscode platform username must be set using the environment variable OPSCODE_USER."
79
+ end
80
+ end
81
+
82
+ def verify_keys
83
+ missing_keys = []
84
+ KEYS.each do |key|
85
+ value = config[key]
86
+ missing_keys << key unless value && value != ""
87
+ end
88
+ KNIFE_KEYS.each do |key|
89
+ missing_keys << "knife[:#{key}]" unless value = config[:knife][key.to_sym]
90
+ end
91
+ if missing_keys.size > 0
92
+ @errors << "Incomplete config file, please specify: #{missing_keys.join(", ")}."
93
+ end
94
+ end
95
+
96
+ def verify_opscode_platform_credentials
97
+ username = config['node_name']
98
+ if username
99
+ req = Net::HTTP.new('community.opscode.com', 80)
100
+ code = req.request_head("/users/#{username}").code
101
+ end
102
+ if username == "" || code != "200"
103
+ @errors << "Invalid Opscode platform credentials. Please check."
104
+ end
105
+ end
106
+
107
+ def verify_aws_credentials
108
+ if config[:knife][:aws_access_key_id] && config[:knife][:aws_secret_access_key]
109
+ compute = Fog::Compute.new(:provider => 'AWS',
110
+ :aws_access_key_id => config[:knife][:aws_access_key_id],
111
+ :aws_secret_access_key => config[:knife][:aws_secret_access_key])
112
+ compute.describe_availability_zones
113
+ else
114
+ @errors << "Invalid AWS credentials. Please check."
115
+ end
116
+ rescue Fog::Service::Error => err
117
+ @errors << "Invalid AWS credentials. Please check."
118
+ end
119
+ end
120
+ end
121
+ end
@@ -43,7 +43,7 @@ module Cucumber
43
43
  %x[chroot #{container_path} /bin/bash -c 'chef-client > /dev/null 2>&1']
44
44
  end
45
45
 
46
- def databag_from_file(file)
46
+ def databag_item_from_file(file)
47
47
  ::Chef::JSONCompat.from_json(File.read(file))
48
48
  end
49
49
 
@@ -0,0 +1,74 @@
1
+ module Cucumber
2
+ module Chef
3
+ class TestLabError < Error ; end
4
+
5
+ class TestLab
6
+ def initialize(config)
7
+ @config = config
8
+ @connection =
9
+ Fog::Compute.new(:provider => 'AWS',
10
+ :aws_access_key_id => @config[:knife][:aws_access_key_id],
11
+ :aws_secret_access_key => @config[:knife][:aws_secret_access_key],
12
+ :region => @config[:knife][:region])
13
+ @mode = @config[:mode]
14
+ end
15
+
16
+ def build(output)
17
+ if exists?
18
+ raise TestLabError.new("A test lab already exists using the AWS credentials you supplied")
19
+ end
20
+ server_definition = {
21
+ :image_id => "ami-339ca947",
22
+ :groups => "default",
23
+ :flavor_id => "m1.small",
24
+ :key_name => @config[:knife][:aws_ssh_key_id],
25
+ :availability_zone => @config[:knife][:availability_zone],
26
+ :tags => {"purpose" => "cucumber-chef"},
27
+ :identity_file => @config[:knife][:identity_file]
28
+ }
29
+ @server = @connection.servers.create(server_definition)
30
+ output.puts "Provisioning cucumber-chef test lab platform."
31
+ output.print "Waiting for server"
32
+ @server.wait_for { output.print "."; ready? }
33
+ output.puts("\n")
34
+ tag_server
35
+ output.puts "Instance ID: #{@server.id} ; IP Address #{@server.public_ip_address}"
36
+ output.puts "Platform provisioned. Run cucumber-chef project to get started."
37
+ @server
38
+ end
39
+
40
+ def destroy
41
+ @connection.servers.each do |s|
42
+ s.destroy if s.tags['cucumber-chef'] == @mode && s.state == 'running'
43
+ end
44
+ end
45
+
46
+ def exists?
47
+ running_labs_count > 0
48
+ end
49
+
50
+ def info
51
+ if exists?
52
+ query = ::Chef::Search::Query.new
53
+ node, offset, total = query.search("node", URI.escape("roles:test_lab_test"))
54
+ node.first && node.first[:ec2][:public_ipv4]
55
+ end
56
+ end
57
+
58
+ private
59
+ def tag_server
60
+ tag = @connection.tags.new
61
+ tag.resource_id = @server.id
62
+ tag.key = "cucumber-chef"
63
+ tag.value = @mode
64
+ tag.save
65
+ end
66
+
67
+ def running_labs_count
68
+ @connection.servers.select do |s|
69
+ s.tags["cucumber-chef"] == @mode && s.state == "running"
70
+ end.size
71
+ end
72
+ end
73
+ end
74
+ end
data/lib/cucumber/chef.rb CHANGED
@@ -14,44 +14,8 @@ module Cucumber
14
14
  module Chef
15
15
  class Error < StandardError ; end
16
16
 
17
- class ConfigError < Error ; end
18
- class Config
19
- KEYS = %w[node_name chef_server_url client_key validation_key validation_client_name]
20
- KNIFE_KEYS = %w[aws_access_key_id aws_secret_access_key region availability_zone aws_ssh_key_id identity_file]
21
-
22
- def config
23
- full_path = Dir.pwd.split(File::SEPARATOR)
24
- (full_path.length - 1).downto(0) do |i|
25
- knife_file = File.join(full_path[0..i] + [".chef", "knife.rb"])
26
- if File.exist?(knife_file)
27
- ::Chef::Config.from_file(knife_file)
28
- return ::Chef::Config
29
- end
30
- end
31
- raise ConfigError.new("Couldn't find knife.rb")
32
- end
33
-
34
- def display
35
- current_config = config
36
- values, missing_keys = [], []
37
- KEYS.each do |key|
38
- value = current_config[key]
39
- if value && value != ""
40
- values << "#{key}: #{value}"
41
- else
42
- missing_keys << key
43
- end
44
- end
45
- KNIFE_KEYS.each do |key|
46
- if value = current_config[:knife][key.to_sym]
47
- values << "knife[:#{key}]: #{value}"
48
- else
49
- missing_keys << "knife[:#{key}]"
50
- end
51
- end
52
- [values, missing_keys]
53
- end
54
- end
17
+ autoload :Config, "cucumber/chef/config"
18
+ autoload :TestLab, "cucumber/chef/test_lab"
55
19
 
56
20
  class ProvisionerError < Error ; end
57
21
  class Provisioner
@@ -63,27 +27,6 @@ module Cucumber
63
27
  Config.new.config
64
28
  end
65
29
 
66
- def running_labs(connection, mode)
67
- connection.servers.select {|s| s.tags['cucumber-chef'] == mode && s.state == 'running'}
68
- end
69
-
70
- def lab_exists?(connection, mode)
71
- number_of_labs = running_labs(connection, mode).size
72
- if number_of_labs > 0
73
- return true
74
- else
75
- return false
76
- end
77
- end
78
-
79
- def tag_server(connection, id, tag)
80
- t = connection.tags.new
81
- t.resource_id = id
82
- t.key = "cucumber-chef"
83
- t.value = tag
84
- t.save
85
- end
86
-
87
30
  def bootstrap_node(dns_name, config)
88
31
  template_file = File.join(File.dirname(__FILE__),
89
32
  "chef/templates/ubuntu10.04-gems.erb")
@@ -123,26 +66,6 @@ module Cucumber
123
66
  bootstrap
124
67
  end
125
68
 
126
- def verify_opscode_platform_credentials(config)
127
- username = config['node_name']
128
- if username
129
- req = Net::HTTP.new('community.opscode.com', 80)
130
- code = req.request_head("/users/#{username}").code
131
- end
132
- if username == "" || code != "200"
133
- raise ProvisionerError.new("Invalid Opscode platform credentials. Please check.")
134
- end
135
- end
136
-
137
- def verify_aws_credentials(config)
138
- compute = Fog::Compute.new(:provider => 'AWS',
139
- :aws_access_key_id => config[:knife][:aws_access_key_id],
140
- :aws_secret_access_key => config[:knife][:aws_secret_access_key])
141
- compute.describe_availability_zones
142
- rescue Fog::Service::Error => err
143
- raise ProvisionerError.new("Invalid AWS credentials. Please check.")
144
- end
145
-
146
69
  def upload_cookbook(config)
147
70
  version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(@cookbook_path)
148
71
  version_loader.load_cookbooks
@@ -161,25 +84,7 @@ module Cucumber
161
84
  end
162
85
 
163
86
  def build_test_lab(config, output)
164
- connection = Fog::Compute.new(:provider => 'AWS',
165
- :aws_access_key_id => config[:knife][:aws_access_key_id],
166
- :aws_secret_access_key => config[:knife][:aws_secret_access_key],
167
- :region => config[:knife][:region])
168
- mode = config["mode"]
169
- if lab_exists?(connection, mode)
170
- raise ProvisionerError.new("A test lab already exists using the AWS credentials you supplied")
171
- end
172
- ami = connection.images.get("ami-339ca947")
173
- server_def = { :image_id => "ami-339ca947", :groups => "default", :flavor_id => "m1.small", :key_name => config[:knife][:aws_ssh_key_id], :availability_zone => config[:knife][:availability_zone], :tags => {"purpose" => "cucumber-chef"}, :identity_file => config[:knife][:identity_file] }
174
- server = connection.servers.create(server_def)
175
- output.puts "Provisioning cucumber-chef test lab platform."
176
- output.print "Waiting for server"
177
- server.wait_for { output.print "."; ready? }
178
- output.puts("\n")
179
- tag_server(connection, server.id, config["mode"])
180
- output.puts "Instance ID: #{server.id} ; IP Address #{server.public_ip_address}"
181
- output.puts "Platform provisioned. Run cucumber-chef project to get started."
182
- server
87
+ TestLab.new(config).build(output)
183
88
  end
184
89
  end
185
90
  end
@@ -0,0 +1,108 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
+
5
+ describe Cucumber::Chef::Config do
6
+ before(:all) do
7
+ @orgname = ENV["ORGNAME"]
8
+ @opscode_user = ENV["OPSCODE_USER"]
9
+ end
10
+
11
+ after(:each) do
12
+ ENV["ORGNAME"] = @orgname
13
+ ENV["OPSCODE_USER"] = @opscode_user
14
+ end
15
+
16
+ describe "verification" do
17
+ describe "when ORGNAME is not set" do
18
+ it "should raise" do
19
+ ENV["ORGNAME"] = ""
20
+ expect {
21
+ subject.verify
22
+ }.to raise_error(Cucumber::Chef::ConfigError, /ORGNAME/)
23
+ end
24
+ end
25
+
26
+ describe "when OPSCODE_USER is not set" do
27
+ it "should raise" do
28
+ ENV["OPSCODE_USER"] = ""
29
+ expect {
30
+ subject.verify
31
+ }.to raise_error(Cucumber::Chef::ConfigError, /OPSCODE_USER/)
32
+ end
33
+ end
34
+
35
+ describe "when configuration is invalid" do
36
+ it "should complain about missing keys" do
37
+ subject.config[:chef_server_url] = nil
38
+ subject.config[:knife][:aws_access_key_id] = nil
39
+ expect {
40
+ subject.verify
41
+ }.to raise_error(Cucumber::Chef::ConfigError, /chef_server_url.*aws_access_key_id/)
42
+ end
43
+
44
+ describe "when node name is invalid" do
45
+ it "should raise" do
46
+ ENV["OPSCODE_USER"] = "REALLYBOGUSORGNAME"
47
+ expect {
48
+ subject.verify
49
+ }.to raise_error(Cucumber::Chef::ConfigError, /Opscode platform credentials/)
50
+ end
51
+ end
52
+
53
+ describe "when aws_access_key_id is empty" do
54
+ it "should raise" do
55
+ subject.config[:knife][:aws_access_key_id] = "bogus"
56
+ expect {
57
+ subject.verify
58
+ }.to raise_error(Cucumber::Chef::ConfigError, /AWS credentials/)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "when configuration is valid" do
64
+ it "should not raise" do
65
+ subject.verify
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "when knife.rb is missing" do
71
+ it "should raise" do
72
+ begin
73
+ chef_dir = Pathname("~/.chef").expand_path
74
+ (chef_dir + "knife.rb").rename(chef_dir + "knife.rb.bak")
75
+ config_file = chef_dir + "knife.rb"
76
+ expect { subject.config }.to raise_error(Cucumber::Chef::ConfigError)
77
+ ensure
78
+ (chef_dir + "knife.rb.bak").rename(chef_dir + "knife.rb")
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "when configuration is valid" do
84
+ it "should list the configuration values" do
85
+ output = subject.list.join("\n")
86
+ output.should match(/node_name:/)
87
+ output.should match(/knife\[:aws_secret_access_key\]:/)
88
+ end
89
+
90
+ it "should return the configuration values" do
91
+ subject[:node_name].should == @opscode_user
92
+ subject[:knife][:ssh_user].should == "ubuntu"
93
+ end
94
+
95
+ it "should allow setting configuration values" do
96
+ subject[:mode] = "blah"
97
+ subject[:knife][:aws_access_key_id] = "bogus"
98
+ subject[:mode].should == "blah"
99
+ subject[:knife][:aws_access_key_id].should == "bogus"
100
+ end
101
+
102
+ it "should provide a method for getting a test mode configuration" do
103
+ config = Cucumber::Chef::Config.test_config
104
+ config[:mode].should == "test"
105
+ end
106
+ end
107
+ end
108
+
@@ -20,155 +20,12 @@ ensure
20
20
  tcp_socket && tcp_socket.close
21
21
  end
22
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
23
  describe Cucumber::Chef::Provisioner do
68
24
  before(:all) do
69
25
  @config = subject.config
70
26
  @config[:mode] = "test"
71
27
  end
72
28
 
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
29
  describe "upload_cookbook" do
173
30
  before(:each) do
174
31
  begin
@@ -0,0 +1,61 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
+
5
+ describe Cucumber::Chef::TestLab do
6
+ before(:all) do
7
+ @config = Cucumber::Chef::Config.new.config
8
+ @config[:mode] = "test"
9
+ end
10
+
11
+ subject { Cucumber::Chef::TestLab.new(@config) }
12
+
13
+ describe "build" do
14
+ after(:each) { subject.destroy }
15
+
16
+ it "should spin up an ec2 instance", :slow => true do
17
+ output = StringIO.new
18
+ subject.build(output)
19
+ output.rewind
20
+ output.read.should match(/Platform provisioned/)
21
+ end
22
+
23
+ it "should only spin up one ec2 instance", :slow => true do
24
+ subject.build(StringIO.new)
25
+ expect {
26
+ subject.build(StringIO.new)
27
+ }.to raise_error(Cucumber::Chef::TestLabError)
28
+ end
29
+
30
+ end
31
+
32
+ describe "destroy" do
33
+ it "should destroy the running ec2 instance", :slow => true do
34
+ subject.build(StringIO.new)
35
+ subject.destroy
36
+ subject.exists?.should_not be
37
+ end
38
+ end
39
+
40
+ describe "against a bootstrapped lab" do
41
+ before(:each) do
42
+ provisioner = Cucumber::Chef::Provisioner.new
43
+ server = provisioner.build_test_lab(@config, StringIO.new)
44
+ @dns_name = server.dns_name
45
+ @public_ip_address = server.public_ip_address
46
+ puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
47
+ puts "Got ssh..."
48
+ sleep(10)
49
+ provisioner.upload_cookbook(@config)
50
+ provisioner.upload_role(@config)
51
+ provisioner.bootstrap_node(@dns_name, @config).run
52
+ end
53
+
54
+ after(:each) { subject.destroy }
55
+
56
+ it "should report its public ip address", :slow => true do
57
+ subject.info.should == @public_ip_address
58
+ end
59
+ end
60
+ end
61
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber-chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-06 00:00:00.000000000 +00:00
12
+ date: 2011-06-09 00:00:00.000000000 +00:00
13
13
  default_executable: cucumber-chef
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: chef
17
- requirement: &15205680 !ruby/object:Gem::Requirement
17
+ requirement: &24043900 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.10.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *15205680
25
+ version_requirements: *24043900
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: cucumber
28
- requirement: &15205200 !ruby/object:Gem::Requirement
28
+ requirement: &24043420 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *15205200
36
+ version_requirements: *24043420
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: cucumber-nagios
39
- requirement: &15204720 !ruby/object:Gem::Requirement
39
+ requirement: &24042940 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *15204720
47
+ version_requirements: *24042940
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &15204240 !ruby/object:Gem::Requirement
50
+ requirement: &24042460 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *15204240
58
+ version_requirements: *24042460
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: fog
61
- requirement: &15203760 !ruby/object:Gem::Requirement
61
+ requirement: &24041980 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *15203760
69
+ version_requirements: *24041980
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: thor
72
- requirement: &15203280 !ruby/object:Gem::Requirement
72
+ requirement: &24041500 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '0'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *15203280
80
+ version_requirements: *24041500
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: awesome_print
83
- requirement: &15223480 !ruby/object:Gem::Requirement
83
+ requirement: &24041020 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :runtime
90
90
  prerelease: false
91
- version_requirements: *15223480
91
+ version_requirements: *24041020
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: bundler
94
- requirement: &15223000 !ruby/object:Gem::Requirement
94
+ requirement: &24061420 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ~>
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: 1.0.0
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *15223000
102
+ version_requirements: *24061420
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: jeweler
105
- requirement: &15222520 !ruby/object:Gem::Requirement
105
+ requirement: &24060940 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ~>
@@ -110,10 +110,10 @@ dependencies:
110
110
  version: 1.6.2
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *15222520
113
+ version_requirements: *24060940
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: rcov
116
- requirement: &15222040 !ruby/object:Gem::Requirement
116
+ requirement: &24060460 !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements:
119
119
  - - ! '>='
@@ -121,7 +121,7 @@ dependencies:
121
121
  version: '0'
122
122
  type: :development
123
123
  prerelease: false
124
- version_requirements: *15222040
124
+ version_requirements: *24060460
125
125
  description: Framework for behaviour-drive infrastructure development.
126
126
  email: stephen@atalanta-systems.com
127
127
  executables:
@@ -171,6 +171,7 @@ files:
171
171
  - features/usage.feature
172
172
  - lib/cucumber-chef.rb
173
173
  - lib/cucumber/chef.rb
174
+ - lib/cucumber/chef/config.rb
174
175
  - lib/cucumber/chef/handy.rb
175
176
  - lib/cucumber/chef/templates/controller.erb
176
177
  - lib/cucumber/chef/templates/env.rb
@@ -178,9 +179,12 @@ files:
178
179
  - lib/cucumber/chef/templates/example_step.erb
179
180
  - lib/cucumber/chef/templates/readme.erb
180
181
  - lib/cucumber/chef/templates/ubuntu10.04-gems.erb
182
+ - lib/cucumber/chef/test_lab.rb
181
183
  - lib/cucumber/chef/version.rb
182
184
  - lib/cucumber/ec2_server_create.rb
185
+ - spec/unit/config_spec.rb
183
186
  - spec/unit/cucumber_chef_spec.rb
187
+ - spec/unit/test_lab_spec.rb
184
188
  has_rdoc: true
185
189
  homepage: http://github.com/atalanta/cucumber-chef
186
190
  licenses:
@@ -197,7 +201,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
201
  version: '0'
198
202
  segments:
199
203
  - 0
200
- hash: 2224216704413573753
204
+ hash: -3689892462055237010
201
205
  required_rubygems_version: !ruby/object:Gem::Requirement
202
206
  none: false
203
207
  requirements: