cucumber-chef 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -12,7 +12,6 @@ gem "cucumber-nagios", ">= 0"
12
12
  gem "rspec", ">= 0"
13
13
  gem "fog", ">= 0"
14
14
  gem "thor", ">= 0"
15
- gem "awesome_print", ">= 0"
16
15
 
17
16
  group :development do
18
17
  gem "bundler", "~> 1.0.0"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
data/bin/cucumber-chef CHANGED
@@ -23,10 +23,6 @@ GEM_DIR = Gem.default_dir
23
23
  class CucumberChef < Thor
24
24
  include Thor::Actions
25
25
 
26
- def self.source_root
27
- File.dirname(__FILE__)
28
- end
29
-
30
26
  no_tasks do
31
27
  def create_directory_structure(project_dir)
32
28
  %w{step_definitions support}.each do |dir|
@@ -35,7 +31,7 @@ class CucumberChef < Thor
35
31
  end
36
32
 
37
33
  def generate_project_skeleton(project_dir)
38
- template_dir = self.gem_root + 'lib' + 'cucumber' + 'chef' + 'templates'
34
+ template_dir = Pathname.new(__FILE__).parent.parent + 'lib' + 'cucumber' + 'chef' + 'templates'
39
35
  templates = {
40
36
  "readme.erb" => 'README',
41
37
  "example_feature.erb" => 'features/example.feature',
@@ -47,9 +43,11 @@ class CucumberChef < Thor
47
43
  project_dir + destination)
48
44
  end
49
45
  end
50
-
51
- def gem_root
52
- Pathname.new(__FILE__).parent.parent
46
+
47
+ def config
48
+ @config ||= begin
49
+ options.test? ? Cucumber::Chef::Config.test_config : Cucumber::Chef::Config.new
50
+ end
53
51
  end
54
52
 
55
53
  def error(message)
@@ -70,11 +68,6 @@ class CucumberChef < Thor
70
68
  method_option :test, :type => :boolean
71
69
  def setup
72
70
  begin
73
- if options.test?
74
- config = Cucumber::Chef::Config.test_config
75
- else
76
- config = Cucumber::Chef::Config.new
77
- end
78
71
  config.verify
79
72
  $stdout.sync
80
73
  provisioner = ::Cucumber::Chef::Provisioner.new
@@ -82,20 +75,21 @@ class CucumberChef < Thor
82
75
  sleep(10)
83
76
  provisioner.upload_cookbook(config)
84
77
  provisioner.upload_role(config)
85
- provisioner.bootstrap_node(server.dns_name, config).run
78
+ provisioner.bootstrap_node(server.dns_name, config)
86
79
  rescue ::Cucumber::Chef::Error => err
87
80
  error(err.message)
88
81
  end
82
+
89
83
  end
90
84
 
85
+ desc "connect", "Connect to a container in your test lab"
86
+ def connect
87
+ puts "Not implemented. For now, find the IP of your test lab using the info task, and connect manually."
88
+ end
89
+
91
90
  desc "displayconfig", "Display the current config from knife.rb"
92
91
  method_option :test, :type => :boolean
93
92
  def displayconfig
94
- if options.test?
95
- config = Cucumber::Chef::Config.test_config
96
- else
97
- config = Cucumber::Chef::Config.new
98
- end
99
93
  puts config.list.join("\n")
100
94
  config.verify
101
95
  rescue ::Cucumber::Chef::Error => err
@@ -105,30 +99,41 @@ class CucumberChef < Thor
105
99
  desc "info", "Display information about the current test lab"
106
100
  method_option :test, :type => :boolean
107
101
  def info
108
- if options.test?
109
- config = Cucumber::Chef::Config.test_config
110
- else
111
- config = Cucumber::Chef::Config.new
112
- end
113
102
  config.verify
114
103
  lab = Cucumber::Chef::TestLab.new(config)
115
- if lab.exists?
116
- puts lab.info
117
- else
118
- end
104
+ puts lab.info
105
+ rescue ::Cucumber::Chef::Error => err
106
+ error(err.message)
119
107
  end
120
-
121
- desc "upload", "Upload a cucumber-chef test suite to the test lab platform"
122
- def upload
123
- puts "Project uploaded to the test-lab."
108
+
109
+ desc "destroy", "Destroy running test labs"
110
+ method_option :test, :type => :boolean
111
+ def destroy
112
+ config.verify
113
+ lab = Cucumber::Chef::TestLab.new(config)
114
+ lab.destroy
115
+ end
116
+
117
+ desc "upload <project name>", "Upload a cucumber-chef test suite to the test lab platform"
118
+ def upload(project_name)
119
+ project_dir = Pathname.new(".") + "cucumber-chef" + project_name
120
+ unless File.exists?(project_dir)
121
+ raise "Project dir '#{project_dir}' does not exist."
122
+ end
123
+ config.verify
124
+ runner = Cucumber::Chef::TestRunner.new(project_dir, config)
125
+ runner.upload_project
124
126
  end
125
127
 
126
128
  desc "test", "Run a cucumber-chef test suite from a workstation."
127
- def test
128
- puts "Running test..."
129
- puts
130
- puts "Test results will appear here."
129
+ def test(project_name)
130
+ project_dir = Pathname.new(".") + "cucumber-chef" + project_name
131
+ unless File.exists?(project_dir)
132
+ raise "Project dir '#{project_dir}' does not exist."
133
+ end
134
+ config.verify
135
+ runner = Cucumber::Chef::TestRunner.new(project_dir, config)
136
+ runner.run
131
137
  end
132
138
  end
133
-
134
139
  CucumberChef.start
@@ -144,15 +144,16 @@ EOF
144
144
  rm $image/etc/resolv.conf
145
145
  cp /etc/resolv.conf $image/etc/resolv.conf
146
146
  cp /etc/lxc/install-chef.sh $image/tmp/install-chef.sh
147
- chroot $image /bin/sh -c "/usr/bin/apt-get update && /usr/bin/apt-get --assume-yes --allow-unauthenticated install strace ruby1.9.1p180"
147
+ chroot $image /bin/sh -c "/usr/bin/apt-get update && /usr/bin/apt-get --assume-yes --allow-unauthenticated install ruby1.9.1p180"
148
148
  mkdir -p $image/$HOME
149
- chroot $image /bin/sh -c "strace /usr/local/bin/gem install chef --no-ri --no-rdoc 2>&1" 2>&1 >> /tmp/data
149
+ chroot $image /bin/sh -c "/usr/local/bin/gem install ohai --no-ri --no-rdoc"
150
+ chroot $image /bin/sh -c "/usr/local/bin/gem install chef --no-ri --no-rdoc"
150
151
  return $?
151
152
  }
152
153
 
153
154
  download_ubuntu()
154
155
  {
155
- packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,wget,gpgv,gnupg
156
+ packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,dhcp3-client,ssh,lsb-release,wget,gpgv,gnupg
156
157
 
157
158
  cache=$1
158
159
  arch=$2
@@ -38,13 +38,14 @@ cookbook_file "/var/lib/lxc/controller/rootfs/etc/chef/first-boot.json" do
38
38
  source "controller-first-boot"
39
39
  end
40
40
 
41
+ controllers = search(:node, 'name:cucumber-chef-controller')
41
42
  execute 'chroot /var/lib/lxc/controller/rootfs /bin/bash -c "chef-client -j /etc/chef/first-boot.json > /dev/null 2>&1"' do
42
43
  action :run
43
- # TODO: Make idempotent perhaps with a node search
44
+ not_if { controllers.length > 0 }
44
45
  end
45
46
 
46
47
  execute 'lxc-start -d -n controller' do
47
- status = %x[lxc-info -n #{name} 2>&1]
48
+ status = %x[lxc-info -n controller 2>&1]
48
49
  not_if {status.include?("RUNNING")}
49
50
  end
50
51
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cucumber-chef}
8
- s.version = "0.5.0"
8
+ s.version = "0.5.1"
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-09}
12
+ s.date = %q{2011-06-14}
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}
@@ -61,6 +61,7 @@ Gem::Specification.new do |s|
61
61
  "lib/cucumber/chef.rb",
62
62
  "lib/cucumber/chef/config.rb",
63
63
  "lib/cucumber/chef/handy.rb",
64
+ "lib/cucumber/chef/provisioner.rb",
64
65
  "lib/cucumber/chef/templates/controller.erb",
65
66
  "lib/cucumber/chef/templates/env.rb",
66
67
  "lib/cucumber/chef/templates/example_feature.erb",
@@ -68,11 +69,14 @@ Gem::Specification.new do |s|
68
69
  "lib/cucumber/chef/templates/readme.erb",
69
70
  "lib/cucumber/chef/templates/ubuntu10.04-gems.erb",
70
71
  "lib/cucumber/chef/test_lab.rb",
72
+ "lib/cucumber/chef/test_runner.rb",
71
73
  "lib/cucumber/chef/version.rb",
72
74
  "lib/cucumber/ec2_server_create.rb",
73
75
  "spec/unit/config_spec.rb",
74
76
  "spec/unit/cucumber_chef_spec.rb",
75
- "spec/unit/test_lab_spec.rb"
77
+ "spec/unit/provisioner_spec.rb",
78
+ "spec/unit/test_lab_spec.rb",
79
+ "spec/unit/test_runner_spec.rb"
76
80
  ]
77
81
  s.homepage = %q{http://github.com/atalanta/cucumber-chef}
78
82
  s.licenses = ["MIT"]
@@ -90,7 +94,6 @@ Gem::Specification.new do |s|
90
94
  s.add_runtime_dependency(%q<rspec>, [">= 0"])
91
95
  s.add_runtime_dependency(%q<fog>, [">= 0"])
92
96
  s.add_runtime_dependency(%q<thor>, [">= 0"])
93
- s.add_runtime_dependency(%q<awesome_print>, [">= 0"])
94
97
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
95
98
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
96
99
  s.add_development_dependency(%q<rcov>, [">= 0"])
@@ -101,7 +104,6 @@ Gem::Specification.new do |s|
101
104
  s.add_dependency(%q<rspec>, [">= 0"])
102
105
  s.add_dependency(%q<fog>, [">= 0"])
103
106
  s.add_dependency(%q<thor>, [">= 0"])
104
- s.add_dependency(%q<awesome_print>, [">= 0"])
105
107
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
106
108
  s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
107
109
  s.add_dependency(%q<rcov>, [">= 0"])
@@ -113,7 +115,6 @@ Gem::Specification.new do |s|
113
115
  s.add_dependency(%q<rspec>, [">= 0"])
114
116
  s.add_dependency(%q<fog>, [">= 0"])
115
117
  s.add_dependency(%q<thor>, [">= 0"])
116
- s.add_dependency(%q<awesome_print>, [">= 0"])
117
118
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
118
119
  s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
119
120
  s.add_dependency(%q<rcov>, [">= 0"])
data/lib/cucumber/chef.rb CHANGED
@@ -6,6 +6,7 @@ require 'chef/knife/core/bootstrap_context'
6
6
  require 'chef/knife/ssh'
7
7
  require 'socket'
8
8
  require 'net/ssh/multi'
9
+ require 'net/scp'
9
10
  require "fog"
10
11
  require 'readline'
11
12
  require 'stringio'
@@ -15,78 +16,9 @@ module Cucumber
15
16
  class Error < StandardError ; end
16
17
 
17
18
  autoload :Config, "cucumber/chef/config"
19
+ autoload :Provisioner, "cucumber/chef/provisioner"
18
20
  autoload :TestLab, "cucumber/chef/test_lab"
19
-
20
- class ProvisionerError < Error ; end
21
- class Provisioner
22
- def initialize
23
- @cookbook_path = File.join(File.dirname(__FILE__), "../../cookbooks/cucumber-chef")
24
- end
25
-
26
- def config
27
- Config.new.config
28
- end
29
-
30
- def bootstrap_node(dns_name, config)
31
- template_file = File.join(File.dirname(__FILE__),
32
- "chef/templates/ubuntu10.04-gems.erb")
33
- bootstrap = ::Chef::Knife::Bootstrap.new
34
- @stdout, @stderr, @stdout = StringIO.new, StringIO.new, StringIO.new
35
- ui = ::Chef::Knife::UI.new(@stdout, @stderr, @stdout, bootstrap.config)
36
- bootstrap.ui = ui
37
- bootstrap.name_args = [dns_name]
38
- bootstrap.config[:run_list] = "role[test_lab_test]"
39
- bootstrap.config[:ssh_user] = "ubuntu"
40
- bootstrap.config[:identity_file] = config[:knife][:identity_file]
41
- bootstrap.config[:chef_node_name] = "cucumber-chef-test-lab"
42
- bootstrap.config[:use_sudo] = true
43
- bootstrap.config[:template_file] = template_file
44
- bootstrap.config[:validation_client_name] = config["validation_client_name"]
45
- bootstrap.config[:validation_key] = config["validation_key"]
46
- bootstrap.config[:chef_server_url] = config["chef_server_url"]
47
- bootstrap
48
- end
49
-
50
- def build_controller(dns_name, config)
51
- template_file = File.join(File.dirname(__FILE__),
52
- "chef/templates/controller.erb")
53
- bootstrap = ::Chef::Knife::Bootstrap.new
54
- @stdout, @stderr, @stdout = StringIO.new, StringIO.new, StringIO.new
55
- ui = ::Chef::Knife::UI.new(@stdout, @stderr, @stdout, bootstrap.config)
56
- bootstrap.ui = ui
57
- bootstrap.name_args = [dns_name]
58
- bootstrap.config[:ssh_user] = "ubuntu"
59
- bootstrap.config[:identity_file] = config[:knife][:identity_file]
60
- bootstrap.config[:chef_node_name] = "cucumber-chef-controller"
61
- bootstrap.config[:use_sudo] = true
62
- bootstrap.config[:template_file] = template_file
63
- bootstrap.config[:validation_client_name] = config["validation_client_name"]
64
- bootstrap.config[:validation_key] = config["validation_key"]
65
- bootstrap.config[:chef_server_url] = config["chef_server_url"]
66
- bootstrap
67
- end
68
-
69
- def upload_cookbook(config)
70
- version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(@cookbook_path)
71
- version_loader.load_cookbooks
72
- uploader = ::Chef::CookbookUploader.new(version_loader.cookbook_version,
73
- @cookbook_path)
74
- uploader.upload_cookbook
75
- end
76
-
77
- def upload_role(config)
78
- role_path = File.join(@cookbook_path, "roles")
79
- ::Chef::Config[:role_path] = role_path
80
- role = ::Chef::Role.from_disk("test_lab_test")
81
- role.save
82
- role = ::Chef::Role.from_disk("controller")
83
- role.save
84
- end
85
-
86
- def build_test_lab(config, output)
87
- TestLab.new(config).build(output)
88
- end
89
- end
21
+ autoload :TestRunner, "cucumber/chef/test_runner"
90
22
  end
91
23
  end
92
24
 
@@ -10,10 +10,10 @@ module Cucumber
10
10
  config[:mode] = "user"
11
11
  end
12
12
 
13
- def self.test_config
14
- config = self.new
15
- config[:mode] = "test"
16
- config
13
+
14
+
15
+ def self.mode
16
+ config.test_mode? ? 'test' : 'user'
17
17
  end
18
18
 
19
19
  def [](key)
@@ -40,6 +40,16 @@ module Cucumber
40
40
  @config
41
41
  end
42
42
 
43
+ def test_config
44
+ config = self.new
45
+ config[:mode] = "test"
46
+ config
47
+ end
48
+
49
+ def test_mode?
50
+ config[:mode] == "test"
51
+ end
52
+
43
53
  def list
44
54
  values = []
45
55
  KEYS.each do |key|
@@ -0,0 +1,92 @@
1
+ require "digest"
2
+
3
+ module Cucumber
4
+ module Chef
5
+ class ProvisionerError < Error ; end
6
+
7
+ class Provisioner
8
+ def initialize
9
+ @cookbook_path = File.join(File.dirname(__FILE__), "../../../cookbooks/cucumber-chef")
10
+ end
11
+
12
+ def bootstrap_node(dns_name, config)
13
+ template_file = File.join(File.dirname(__FILE__), "templates/ubuntu10.04-gems.erb")
14
+ bootstrap = ::Chef::Knife::Bootstrap.new
15
+ @stdout, @stderr, @stdout = StringIO.new, StringIO.new, StringIO.new
16
+ ui = ::Chef::Knife::UI.new(@stdout, @stderr, @stdout, bootstrap.config)
17
+ bootstrap.ui = ui
18
+ nodename = chef_node_name(config)
19
+ bootstrap.name_args = [dns_name]
20
+ bootstrap.config[:run_list] = "role[test_lab_test]"
21
+ bootstrap.config[:ssh_user] = "ubuntu"
22
+ bootstrap.config[:identity_file] = config[:knife][:identity_file]
23
+ bootstrap.config[:chef_node_name] = nodename
24
+ bootstrap.config[:use_sudo] = true
25
+ bootstrap.config[:template_file] = template_file
26
+ bootstrap.config[:validation_client_name] = config["validation_client_name"]
27
+ bootstrap.config[:validation_key] = config["validation_key"]
28
+ bootstrap.config[:chef_server_url] = config["chef_server_url"]
29
+ bootstrap
30
+ bootstrap.run
31
+ tag_node(config)
32
+ end
33
+
34
+ def build_controller(dns_name, config)
35
+ template_file = File.join(File.dirname(__FILE__), "templates/controller.erb")
36
+ bootstrap = ::Chef::Knife::Bootstrap.new
37
+ @stdout, @stderr, @stdout = StringIO.new, StringIO.new, StringIO.new
38
+ ui = ::Chef::Knife::UI.new(@stdout, @stderr, @stdout, bootstrap.config)
39
+ bootstrap.ui = ui
40
+ bootstrap.name_args = [dns_name]
41
+ bootstrap.config[:ssh_user] = "ubuntu"
42
+ bootstrap.config[:identity_file] = config[:knife][:identity_file]
43
+ bootstrap.config[:chef_node_name] = "cucumber-chef-controller"
44
+ bootstrap.config[:use_sudo] = true
45
+ bootstrap.config[:template_file] = template_file
46
+ bootstrap.config[:validation_client_name] = config["validation_client_name"]
47
+ bootstrap.config[:validation_key] = config["validation_key"]
48
+ bootstrap.config[:chef_server_url] = config["chef_server_url"]
49
+
50
+ end
51
+
52
+ def upload_cookbook(config)
53
+ version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(@cookbook_path)
54
+ version_loader.load_cookbooks
55
+ uploader = ::Chef::CookbookUploader.new(version_loader.cookbook_version,
56
+ @cookbook_path)
57
+ uploader.upload_cookbook
58
+ end
59
+
60
+ def upload_role(config)
61
+ role_path = File.join(@cookbook_path, "roles")
62
+ ::Chef::Config[:role_path] = role_path
63
+ role = ::Chef::Role.from_disk("test_lab_test")
64
+ role.save
65
+ role = ::Chef::Role.from_disk("controller")
66
+ role.save
67
+ end
68
+
69
+ def build_test_lab(config, output)
70
+ TestLab.new(config).build(output)
71
+ end
72
+
73
+ def tag_node(config)
74
+ node = ::Chef::Node.load(chef_node_name)
75
+ node.tags << (config.test_mode? ? 'test' : 'user')
76
+ node.save
77
+ end
78
+
79
+ private
80
+
81
+ def chef_node_name(config=nil)
82
+ @node_name ||= begin
83
+ if config.test_mode?
84
+ "cucumber-chef-#{Digest::SHA1.hexdigest(Time.now.to_s)[0..7]}"
85
+ else
86
+ "cucumber-chef-test-lab"
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -1,10 +1,8 @@
1
1
  Welcome to the <%= @project %> suite of cucumber-chef tests
2
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$
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 behaviour, expressing them as cucumer scenarios.
4
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 %>
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 run the tests with:
8
6
 
9
7
  Then run your tests with:
10
8
 
@@ -14,15 +12,3 @@ For an example feature, take a look at ./<%= @project %>/features/example.featur
14
12
 
15
13
  For an example step definition, look at ./<%= @project %>/features/example.feature
16
14
 
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
-
@@ -10,7 +10,6 @@ module Cucumber
10
10
  :aws_access_key_id => @config[:knife][:aws_access_key_id],
11
11
  :aws_secret_access_key => @config[:knife][:aws_secret_access_key],
12
12
  :region => @config[:knife][:region])
13
- @mode = @config[:mode]
14
13
  end
15
14
 
16
15
  def build(output)
@@ -38,20 +37,41 @@ module Cucumber
38
37
  end
39
38
 
40
39
  def destroy
41
- @connection.servers.each do |s|
42
- s.destroy if s.tags['cucumber-chef'] == @mode && s.state == 'running'
40
+ running_labs.each do |server|
41
+ #server.destroy
42
+ puts server.public_ip_address
43
+ end
44
+ nodes.each do |node|
45
+ # node.destroy
46
+ puts node[:ec2][:public_ipv4]
43
47
  end
44
48
  end
45
49
 
46
50
  def exists?
47
- running_labs_count > 0
51
+ running_labs.size > 0
48
52
  end
49
53
 
50
54
  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
+ "#{node.name}: #{node[:ec2][:public_ipv4]}"
56
+ end
57
+
58
+ def public_hostname
59
+ node.cloud.public_hostname
60
+ end
61
+
62
+ def node
63
+ @node ||= begin
64
+ search = ::Chef::Search::Query.new
65
+ mode = @config[:mode]
66
+ query = "roles:test_lab_test AND tags:#{mode}"
67
+ nodes, offset, total = search.search("node", URI.escape(query))
68
+ nodes.compact.first
69
+ end
70
+ end
71
+
72
+ def running_labs
73
+ @connection.servers.select do |s|
74
+ s.tags['cucumber-chef'] == @config[:mode] && s.state == 'running'
55
75
  end
56
76
  end
57
77
 
@@ -60,15 +80,9 @@ module Cucumber
60
80
  tag = @connection.tags.new
61
81
  tag.resource_id = @server.id
62
82
  tag.key = "cucumber-chef"
63
- tag.value = @mode
83
+ tag.value = @config[:mode]
64
84
  tag.save
65
85
  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
86
  end
73
87
  end
74
88
  end
@@ -0,0 +1,32 @@
1
+ module Cucumber
2
+ module Chef
3
+ class TestRunnerError < Error ; end
4
+
5
+ class TestRunner
6
+
7
+ require 'cucumber/chef/test_lab'
8
+
9
+ def initialize(project_dir, config)
10
+ @project_dir = project_dir
11
+ @config = config
12
+ end
13
+
14
+ def run
15
+ upload_project
16
+ @project_path = File.join('/home/ubuntu', File.basename(@project_dir), 'features')
17
+ connection = Net::SSH.start(@hostname, 'ubuntu', :keys => @key) do |ssh|
18
+ @output = ssh.exec!("sudo cucumber #{@project_path}")
19
+ end
20
+ puts @output
21
+ end
22
+
23
+ def upload_project
24
+ lab = Cucumber::Chef::TestLab.new(@config)
25
+ @hostname = lab.public_hostname
26
+ @key = File.expand_path(@config[:knife][:identity_file])
27
+ %x[scp -r -i #{@key} #{@project_dir} ubuntu@#{@hostname}: 2>/dev/null]
28
+ puts "Cucumber-chef project: #{File.basename(@project_dir)} sucessfully uploaded to the test lab."
29
+ end
30
+ end
31
+ end
32
+ end
@@ -103,6 +103,14 @@ describe Cucumber::Chef::Config do
103
103
  config = Cucumber::Chef::Config.test_config
104
104
  config[:mode].should == "test"
105
105
  end
106
+
107
+ it "should know it is in test mode" do
108
+ Cucumber::Chef::Config.test_config.test_mode?.should be
109
+ end
110
+
111
+ it "should know it is not in test_mode" do
112
+ Cucumber::Chef::Config.new.test_mode?.should_not be
113
+ end
106
114
  end
107
115
  end
108
116
 
@@ -2,126 +2,3 @@ require "rubygems"
2
2
  require "bundler/setup"
3
3
  require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
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::Provisioner do
24
- before(:all) do
25
- @config = subject.config
26
- @config[:mode] = "test"
27
- end
28
-
29
- describe "upload_cookbook" do
30
- before(:each) do
31
- begin
32
- cookbook_path = File.expand_path("cookbooks/cucumber-chef")
33
- version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(cookbook_path)
34
- version_loader.load_cookbooks
35
- version = version_loader.cookbook_version
36
- version.destroy
37
- rescue Net::HTTPServerException => err
38
- end
39
- end
40
-
41
- it "should upload the cucumber-chef cookbook" do
42
- subject.upload_cookbook(@config)
43
- ::Chef::CookbookVersion.list["cucumber-chef"].should be
44
- end
45
- end
46
-
47
- describe "upload_role" do
48
- before(:each) do
49
- begin
50
- role_path = File.expand_path("cookbooks/cucumber-chef/roles")
51
- ::Chef::Config[:role_path] = role_path
52
- role = ::Chef::Role.from_disk("test_lab_test")
53
- role.destroy
54
- rescue Net::HTTPServerException => err
55
- end
56
- end
57
-
58
- it "should upload the test_lab role" do
59
- subject.upload_role(@config)
60
- ::Chef::Role.list["test_lab_test"].should be
61
- end
62
- end
63
-
64
- describe "bootstrap_node" do
65
- before(:each) do
66
- server = subject.build_test_lab(@config, StringIO.new)
67
- @dns_name = server.dns_name
68
- puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
69
- puts "Got ssh..."
70
- sleep(10)
71
- subject.upload_cookbook(@config)
72
- subject.upload_role(@config)
73
- end
74
-
75
- after(:each) do
76
- config = @config[:knife]
77
- connection = Fog::Compute.new(:provider => 'AWS',
78
- :aws_access_key_id => config[:aws_access_key_id],
79
- :aws_secret_access_key => config[:aws_secret_access_key],
80
- :region => config[:region])
81
- connection.servers.each do |s|
82
- s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
83
- end
84
- end
85
-
86
- it "should set up platform as a chef client and apply test-lab role" do
87
- bootstrapper = subject.bootstrap_node(@dns_name, @config)
88
- bootstrapper.run
89
- # DEBUG: puts bootstrapper.ui.stdout.string
90
- node = ::Chef::Node.load("cucumber-chef-test-lab")
91
- node.run_list.to_s.should match(/role\[test_lab_test\]/)
92
- end
93
- end
94
-
95
- describe "build_controller" do
96
-
97
- before(:each) do
98
- server = subject.build_test_lab(@config, StringIO.new)
99
- @dns_name = server.dns_name
100
- puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
101
- puts "Got ssh..."
102
- sleep(10)
103
- subject.upload_cookbook(@config)
104
- subject.upload_role(@config)
105
- subject.bootstrap_node(@dns_name, @config).run
106
- end
107
-
108
- after(:each) do
109
- config = @config[:knife]
110
- connection = Fog::Compute.new(:provider => 'AWS',
111
- :aws_access_key_id => config[:aws_access_key_id],
112
- :aws_secret_access_key => config[:aws_secret_access_key],
113
- :region => config[:region])
114
- connection.servers.each do |s|
115
- s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
116
- end
117
- end
118
-
119
- it "should build a cucumber-chef controller" do
120
- controller_builder = subject.build_controller(@dns_name, @config)
121
- controller_builder.run
122
- puts controller_builder.ui.stdout.string
123
- end
124
-
125
- end
126
-
127
- end
@@ -0,0 +1,120 @@
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::Provisioner do
24
+ before(:all) do
25
+ @config = Cucumber::Chef::Config.test_config
26
+ end
27
+
28
+ describe "upload_cookbook" do
29
+ before(:each) do
30
+ begin
31
+ cookbook_path = File.expand_path("cookbooks/cucumber-chef")
32
+ version_loader = ::Chef::Cookbook::CookbookVersionLoader.new(cookbook_path)
33
+ version_loader.load_cookbooks
34
+ version = version_loader.cookbook_version
35
+ version.destroy
36
+ rescue Net::HTTPServerException => err
37
+ end
38
+ end
39
+
40
+ it "should upload the cucumber-chef cookbook" do
41
+ subject.upload_cookbook(@config)
42
+ ::Chef::CookbookVersion.list["cucumber-chef"].should be
43
+ end
44
+ end
45
+
46
+ describe "upload_role" do
47
+ before(:each) do
48
+ begin
49
+ role_path = File.expand_path("cookbooks/cucumber-chef/roles")
50
+ ::Chef::Config[:role_path] = role_path
51
+ role = ::Chef::Role.from_disk("test_lab_test")
52
+ role.destroy
53
+ rescue Net::HTTPServerException => err
54
+ end
55
+ end
56
+
57
+ it "should upload the test_lab role" do
58
+ subject.upload_role(@config)
59
+ ::Chef::Role.list["test_lab_test"].should be
60
+ end
61
+ end
62
+
63
+ describe "bootstrap_node" do
64
+ before(:each) do
65
+ @test_lab = Cucumber::Chef::TestLab.new(@config)
66
+ @test_lab.destroy
67
+ server = subject.build_test_lab(@config, StringIO.new)
68
+ @dns_name = server.dns_name
69
+ puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
70
+ puts "Got ssh..."
71
+ sleep(10)
72
+ subject.upload_cookbook(@config)
73
+ subject.upload_role(@config)
74
+ end
75
+
76
+ after(:each) do
77
+ @test_lab.destroy
78
+ end
79
+
80
+ it "should assign a random name to the node" do
81
+ bootstrapper = subject.bootstrap_node(@dns_name, @config)
82
+ bootstrapper.run
83
+ @test_lab.nodes.detect do |node|
84
+ node.name.match /^cucumber-chef-[0-9a-f]{8}$/
85
+ end.should be
86
+ end
87
+ end
88
+
89
+ describe "build_controller" do
90
+
91
+ before(:each) do
92
+ server = subject.build_test_lab(@config, StringIO.new)
93
+ @dns_name = server.dns_name
94
+ puts "Hanging around..." until tcp_test_ssh(server.public_ip_address)
95
+ puts "Got ssh..."
96
+ sleep(10)
97
+ subject.upload_cookbook(@config)
98
+ subject.upload_role(@config)
99
+ subject.bootstrap_node(@dns_name, @config).run
100
+ end
101
+
102
+ after(:each) do
103
+ config = @config[:knife]
104
+ connection = Fog::Compute.new(:provider => 'AWS',
105
+ :aws_access_key_id => config[:aws_access_key_id],
106
+ :aws_secret_access_key => config[:aws_secret_access_key],
107
+ :region => config[:region])
108
+ connection.servers.each do |s|
109
+ s.destroy if s.tags['cucumber-chef'] == 'test' && s.state == 'running'
110
+ end
111
+ end
112
+
113
+ it "should build a cucumber-chef controller" do
114
+ controller_builder = subject.build_controller(@dns_name, @config)
115
+ controller_builder.run
116
+ puts controller_builder.ui.stdout.string
117
+ end
118
+
119
+ end
120
+ end
@@ -4,8 +4,7 @@ require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
4
 
5
5
  describe Cucumber::Chef::TestLab do
6
6
  before(:all) do
7
- @config = Cucumber::Chef::Config.new.config
8
- @config[:mode] = "test"
7
+ @config = Cucumber::Chef::Config.test_config
9
8
  end
10
9
 
11
10
  subject { Cucumber::Chef::TestLab.new(@config) }
@@ -54,7 +53,7 @@ describe Cucumber::Chef::TestLab do
54
53
  after(:each) { subject.destroy }
55
54
 
56
55
  it "should report its public ip address", :slow => true do
57
- subject.info.should == @public_ip_address
56
+ subject.info.should match(/#{@public_ip_address}/)
58
57
  end
59
58
  end
60
59
  end
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require File.join(File.dirname(__FILE__), "../../lib/cucumber-chef")
4
+
5
+ describe Cucumber::Chef::TestRunner do
6
+ before(:all) do
7
+ @config = Cucumber::Chef::Config.test_config
8
+ end
9
+ end
10
+
metadata CHANGED
@@ -1,136 +1,127 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: cucumber-chef
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.0
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.5.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Stephen Nelson-Smith
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-09 00:00:00.000000000 +00:00
12
+
13
+ date: 2011-06-14 00:00:00 +01:00
13
14
  default_executable: cucumber-chef
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
16
17
  name: chef
17
- requirement: &24043900 !ruby/object:Gem::Requirement
18
+ requirement: &id001 !ruby/object:Gem::Requirement
18
19
  none: false
19
- requirements:
20
- - - ! '>='
21
- - !ruby/object:Gem::Version
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
22
23
  version: 0.10.0
23
24
  type: :runtime
24
25
  prerelease: false
25
- version_requirements: *24043900
26
- - !ruby/object:Gem::Dependency
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
27
28
  name: cucumber
28
- requirement: &24043420 !ruby/object:Gem::Requirement
29
+ requirement: &id002 !ruby/object:Gem::Requirement
29
30
  none: false
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
34
35
  type: :runtime
35
36
  prerelease: false
36
- version_requirements: *24043420
37
- - !ruby/object:Gem::Dependency
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
38
39
  name: cucumber-nagios
39
- requirement: &24042940 !ruby/object:Gem::Requirement
40
+ requirement: &id003 !ruby/object:Gem::Requirement
40
41
  none: false
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
44
- version: '0'
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
45
46
  type: :runtime
46
47
  prerelease: false
47
- version_requirements: *24042940
48
- - !ruby/object:Gem::Dependency
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
49
50
  name: rspec
50
- requirement: &24042460 !ruby/object:Gem::Requirement
51
+ requirement: &id004 !ruby/object:Gem::Requirement
51
52
  none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
56
57
  type: :runtime
57
58
  prerelease: false
58
- version_requirements: *24042460
59
- - !ruby/object:Gem::Dependency
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
60
61
  name: fog
61
- requirement: &24041980 !ruby/object:Gem::Requirement
62
+ requirement: &id005 !ruby/object:Gem::Requirement
62
63
  none: false
63
- requirements:
64
- - - ! '>='
65
- - !ruby/object:Gem::Version
66
- version: '0'
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
67
68
  type: :runtime
68
69
  prerelease: false
69
- version_requirements: *24041980
70
- - !ruby/object:Gem::Dependency
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
71
72
  name: thor
72
- requirement: &24041500 !ruby/object:Gem::Requirement
73
+ requirement: &id006 !ruby/object:Gem::Requirement
73
74
  none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
78
79
  type: :runtime
79
80
  prerelease: false
80
- version_requirements: *24041500
81
- - !ruby/object:Gem::Dependency
82
- name: awesome_print
83
- requirement: &24041020 !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ! '>='
87
- - !ruby/object:Gem::Version
88
- version: '0'
89
- type: :runtime
90
- prerelease: false
91
- version_requirements: *24041020
92
- - !ruby/object:Gem::Dependency
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
93
83
  name: bundler
94
- requirement: &24061420 !ruby/object:Gem::Requirement
84
+ requirement: &id007 !ruby/object:Gem::Requirement
95
85
  none: false
96
- requirements:
86
+ requirements:
97
87
  - - ~>
98
- - !ruby/object:Gem::Version
88
+ - !ruby/object:Gem::Version
99
89
  version: 1.0.0
100
90
  type: :development
101
91
  prerelease: false
102
- version_requirements: *24061420
103
- - !ruby/object:Gem::Dependency
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
104
94
  name: jeweler
105
- requirement: &24060940 !ruby/object:Gem::Requirement
95
+ requirement: &id008 !ruby/object:Gem::Requirement
106
96
  none: false
107
- requirements:
97
+ requirements:
108
98
  - - ~>
109
- - !ruby/object:Gem::Version
99
+ - !ruby/object:Gem::Version
110
100
  version: 1.6.2
111
101
  type: :development
112
102
  prerelease: false
113
- version_requirements: *24060940
114
- - !ruby/object:Gem::Dependency
103
+ version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
115
105
  name: rcov
116
- requirement: &24060460 !ruby/object:Gem::Requirement
106
+ requirement: &id009 !ruby/object:Gem::Requirement
117
107
  none: false
118
- requirements:
119
- - - ! '>='
120
- - !ruby/object:Gem::Version
121
- version: '0'
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
122
112
  type: :development
123
113
  prerelease: false
124
- version_requirements: *24060460
114
+ version_requirements: *id009
125
115
  description: Framework for behaviour-drive infrastructure development.
126
116
  email: stephen@atalanta-systems.com
127
- executables:
117
+ executables:
128
118
  - cucumber-chef
129
119
  extensions: []
130
- extra_rdoc_files:
120
+
121
+ extra_rdoc_files:
131
122
  - LICENSE
132
123
  - README.md
133
- files:
124
+ files:
134
125
  - .document
135
126
  - .gitignore
136
127
  - Gemfile
@@ -173,6 +164,7 @@ files:
173
164
  - lib/cucumber/chef.rb
174
165
  - lib/cucumber/chef/config.rb
175
166
  - lib/cucumber/chef/handy.rb
167
+ - lib/cucumber/chef/provisioner.rb
176
168
  - lib/cucumber/chef/templates/controller.erb
177
169
  - lib/cucumber/chef/templates/env.rb
178
170
  - lib/cucumber/chef/templates/example_feature.erb
@@ -180,38 +172,44 @@ files:
180
172
  - lib/cucumber/chef/templates/readme.erb
181
173
  - lib/cucumber/chef/templates/ubuntu10.04-gems.erb
182
174
  - lib/cucumber/chef/test_lab.rb
175
+ - lib/cucumber/chef/test_runner.rb
183
176
  - lib/cucumber/chef/version.rb
184
177
  - lib/cucumber/ec2_server_create.rb
185
178
  - spec/unit/config_spec.rb
186
179
  - spec/unit/cucumber_chef_spec.rb
180
+ - spec/unit/provisioner_spec.rb
187
181
  - spec/unit/test_lab_spec.rb
182
+ - spec/unit/test_runner_spec.rb
188
183
  has_rdoc: true
189
184
  homepage: http://github.com/atalanta/cucumber-chef
190
- licenses:
185
+ licenses:
191
186
  - MIT
192
187
  post_install_message:
193
188
  rdoc_options: []
194
- require_paths:
189
+
190
+ require_paths:
195
191
  - lib
196
- required_ruby_version: !ruby/object:Gem::Requirement
192
+ required_ruby_version: !ruby/object:Gem::Requirement
197
193
  none: false
198
- requirements:
199
- - - ! '>='
200
- - !ruby/object:Gem::Version
201
- version: '0'
202
- segments:
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ hash: 4460646559625670767
198
+ segments:
203
199
  - 0
204
- hash: -3689892462055237010
205
- required_rubygems_version: !ruby/object:Gem::Requirement
200
+ version: "0"
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
202
  none: false
207
- requirements:
208
- - - ! '>='
209
- - !ruby/object:Gem::Version
210
- version: '0'
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: "0"
211
207
  requirements: []
208
+
212
209
  rubyforge_project:
213
210
  rubygems_version: 1.6.2
214
211
  signing_key:
215
212
  specification_version: 3
216
213
  summary: Tests Chef-built infrastructure
217
214
  test_files: []
215
+