testlab 0.7.6 → 0.8.0

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.
@@ -13,6 +13,9 @@ class TestLab
13
13
  def setup
14
14
  @ui.logger.debug { "Container Setup: #{self.id} " }
15
15
 
16
+ (self.node.state != :running) and return false
17
+ (self.lxc.state == :not_created) and return false
18
+
16
19
  please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
17
20
 
18
21
  self.container_provisioners.each do |provisioner|
@@ -36,6 +39,7 @@ class TestLab
36
39
  def teardown
37
40
  @ui.logger.debug { "Container Teardown: #{self.id} " }
38
41
 
42
+ (self.node.state != :running) and return false
39
43
  (self.lxc.state == :not_created) and return false
40
44
 
41
45
  please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
@@ -60,6 +64,15 @@ class TestLab
60
64
  true
61
65
  end
62
66
 
67
+ # Demolish the container
68
+ def demolish
69
+ self.teardown
70
+ self.down
71
+ self.destroy
72
+
73
+ true
74
+ end
75
+
63
76
  # Returns all defined provisioners for this container's networks and the container iteself.
64
77
  def container_provisioners
65
78
  [self.interfaces.map(&:network).map(&:provisioners), self.provisioners].flatten.compact.uniq
@@ -20,14 +20,14 @@ class TestLab
20
20
  identities = [self.users.map(&:identity), self.node.identity].flatten.compact.uniq
21
21
 
22
22
  output = <<-EOF
23
- #{ZTK::Template.do_not_edit_notice(:message => %(TestLab "#{self.fqdn}" SSH Configuration))}
23
+ #{ZTK::Template.do_not_edit_notice(:message => %(TestLab "#{self.id}" SSH Configuration))}
24
24
  Host #{self.id}
25
25
  HostName #{self.ip}
26
26
  Port 22
27
27
  UserKnownHostsFile /dev/null
28
28
  StrictHostKeyChecking no
29
29
  PasswordAuthentication no
30
- ForwardAgent no
30
+ ForwardAgent yes
31
31
  IdentitiesOnly yes
32
32
  EOF
33
33
 
@@ -70,7 +70,7 @@ class TestLab
70
70
  # An array of symbols of the various keys in our status hash.
71
71
  #
72
72
  # @see TestLab::Container::Status
73
- STATUS_KEYS = %w(node_id id clone fqdn state distro release interfaces provisioners).map(&:to_sym)
73
+ STATUS_KEYS = %w(id node_id clone fqdn state distro release interfaces provisioners).map(&:to_sym)
74
74
 
75
75
  # Sub-Modules
76
76
  autoload :Actions, 'testlab/container/actions'
@@ -124,6 +124,8 @@ class TestLab
124
124
  @ui = TestLab.ui
125
125
 
126
126
  super(*args)
127
+
128
+ @ui.logger.info { "Container '#{self.id}' Loaded" }
127
129
  end
128
130
 
129
131
  def config_dir
@@ -22,6 +22,8 @@ class TestLab
22
22
  @ui = TestLab.ui
23
23
 
24
24
  super(*args)
25
+
26
+ @ui.logger.info { "Interface '#{self.id}' Loaded" }
25
27
  end
26
28
 
27
29
  def ip
@@ -7,7 +7,7 @@ class TestLab
7
7
  def create
8
8
  @ui.logger.debug { "Network Create: #{self.id} " }
9
9
 
10
- (self.node.state == :not_created) and return false
10
+ (self.node.state != :running) and return false
11
11
  (self.state != :not_created) and return false
12
12
 
13
13
  please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
@@ -21,7 +21,7 @@ class TestLab
21
21
  def destroy
22
22
  @ui.logger.debug { "Network Destroy: #{self.id} " }
23
23
 
24
- (self.node.state == :not_created) and return false
24
+ (self.node.state != :running) and return false
25
25
  (self.state == :not_created) and return false
26
26
 
27
27
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
@@ -7,6 +7,9 @@ class TestLab
7
7
  def setup
8
8
  @ui.logger.debug { "Network Setup: #{self.id} " }
9
9
 
10
+ (self.node.state != :running) and return false
11
+ (self.state == :not_created) and return false
12
+
10
13
  please_wait(:ui => @ui, :message => format_object_action(self, 'Setup', :green)) do
11
14
 
12
15
  self.network_provisioners.each do |provisioner|
@@ -24,6 +27,9 @@ class TestLab
24
27
  def teardown
25
28
  @ui.logger.debug { "Network Teardown: #{self.id} " }
26
29
 
30
+ (self.node.state != :running) and return false
31
+ (self.state == :not_created) and return false
32
+
27
33
  please_wait(:ui => @ui, :message => format_object_action(self, 'Teardown', :red)) do
28
34
 
29
35
  self.network_provisioners.each do |provisioner|
@@ -46,6 +52,15 @@ class TestLab
46
52
  true
47
53
  end
48
54
 
55
+ # Demolish the network
56
+ def demolish
57
+ self.teardown
58
+ self.down
59
+ self.destroy
60
+
61
+ true
62
+ end
63
+
49
64
  # Returns all defined provisioners for this network's containers and the network iteself.
50
65
  def network_provisioners
51
66
  [self.provisioners, self.interfaces.map(&:container).map(&:provisioners)].flatten.compact.uniq
@@ -48,7 +48,7 @@ class TestLab
48
48
  :not_created
49
49
  else
50
50
  output = self.node.ssh.exec(%(sudo ifconfig #{self.bridge} 2>&1 | grep 'MTU'), :silence => true, :ignore_exit_status => true).output.strip
51
- if ((output =~ /UP/) && (output =~ /RUNNING/))
51
+ if ((output =~ /UP/) || (output =~ /RUNNING/))
52
52
  :running
53
53
  else
54
54
  :stopped
@@ -7,7 +7,7 @@ class TestLab
7
7
  #
8
8
  # @author Zachary Patten <zachary AT jovelabs DOT com>
9
9
  class Network < ZTK::DSL::Base
10
- STATUS_KEYS = %w(node_id id state interface network netmask broadcast provisioners).map(&:to_sym)
10
+ STATUS_KEYS = %w(id node_id state interface network netmask broadcast provisioners).map(&:to_sym)
11
11
 
12
12
  # Sub-Modules
13
13
  autoload :Actions, 'testlab/network/actions'
@@ -40,6 +40,8 @@ class TestLab
40
40
  @ui = TestLab.ui
41
41
 
42
42
  super(*args)
43
+
44
+ @ui.logger.info { "Network '#{self.id}' Loaded" }
43
45
  end
44
46
 
45
47
  end
@@ -54,6 +54,15 @@ class TestLab
54
54
  true
55
55
  end
56
56
 
57
+ # Demolish the node
58
+ def demolish
59
+ self.teardown
60
+ self.down
61
+ self.destroy
62
+
63
+ true
64
+ end
65
+
57
66
  # Returns all defined provisioners for this node and it's networks and containers.
58
67
  def all_provisioners
59
68
  [self.provisioners, self.networks.map(&:provisioners), self.containers.map(&:provisioners)].flatten.compact.uniq
data/lib/testlab/node.rb CHANGED
@@ -48,6 +48,8 @@ class TestLab
48
48
  @provider = self.provider.new(self.config, @ui)
49
49
 
50
50
  raise NodeError, "You must specify a provider class!" if self.provider.nil?
51
+
52
+ @ui.logger.info { "Node '#{self.id}' Loaded" }
51
53
  end
52
54
 
53
55
  def config_dir
data/lib/testlab/user.rb CHANGED
@@ -30,6 +30,8 @@ class TestLab
30
30
  @ui = TestLab.ui
31
31
 
32
32
  super(*args)
33
+
34
+ @ui.logger.info { "User '#{self.id}' Loaded" }
33
35
  end
34
36
 
35
37
  end
@@ -0,0 +1,83 @@
1
+ class TestLab
2
+ module Utility
3
+
4
+ # GLI Module
5
+ #
6
+ # @author Zachary Patten <zachary AT jovelabs DOT com>
7
+ module GLI
8
+ require 'ztk'
9
+
10
+ LAB_ACTION_ORDER = %W(create destroy up down setup teardown build demolish).map(&:to_sym)
11
+
12
+ LAB_ACTIONS = {
13
+ :create => ["Construct %s", "Attempts to create the <%= @component %>."],
14
+ :destroy => ["Destruct %s", "Attempts to destroy the <%= @component %>."],
15
+ :up => ["On-line %s", "Attempts to online the <%= @component %>."],
16
+ :down => ["Off-line %s", "Attempts to offline the <%= @component %>."],
17
+ :setup => ["Provision %s", "Attempts to provision the <%= @component %>."],
18
+ :teardown => ["De-provision %s", "Attempts to deprovision the <%= @component %>."],
19
+ :build => ["Build %s", <<-EOF],
20
+ Attempts to build the <%= @component %>. TestLab will attempt to create, online and provision the <%= @component %>.
21
+
22
+ The <%= @component %> are taken through the following states:
23
+
24
+ Create -> Up -> Setup
25
+ EOF
26
+ :demolish => ["Demolish %s", <<-EOF]
27
+ Attempts to demolish the <%= @component %>. TestLab will attempt to deprovision, offline and destroy the <%= @component %>.
28
+
29
+ The <%= @component %> are taken through the following states:
30
+
31
+ Teardown -> Down -> Destroy
32
+ EOF
33
+ }
34
+
35
+ def build_lab_commands(component, klass, &block)
36
+ desc %(Manage lab #{component}s)
37
+ command component do |c|
38
+ c.desc %(Optional #{component} ID or comma separated list of #{component} IDs)
39
+ c.arg_name %(#{component}[,#{component},...])
40
+ c.flag [:n, :name]
41
+
42
+ LAB_ACTION_ORDER.each do |lab_action|
43
+ action_desc = LAB_ACTIONS[lab_action]
44
+ c.desc(action_desc.first % "#{component}s")
45
+ c.long_desc(ZTK::Template.string(action_desc.last, {:component => "#{component}s"}))
46
+
47
+ c.command lab_action do |la|
48
+ la.action do |global_options, options, args|
49
+ iterate_objects_by_name(options[:name], klass) do |object|
50
+ object.send(lab_action)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ !block.nil? and block.call(c)
57
+ end
58
+ end
59
+
60
+ def iterate_objects_by_name(name, klass, &block)
61
+ objects = Array.new
62
+ klass_name = klass.to_s.split('::').last.downcase
63
+
64
+ if name.nil?
65
+ objects = klass.all
66
+ else
67
+ names = name.split(',')
68
+ objects = klass.find(names)
69
+ end
70
+
71
+ (objects.nil? || (objects.count == 0)) and raise TestLab::TestLabError, "We could not find any of the #{klass_name}s you supplied!"
72
+
73
+ objects.each do |object|
74
+ !block.nil? and block.call(object)
75
+ end
76
+
77
+ objects
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
@@ -16,76 +16,81 @@ class TestLab
16
16
  end
17
17
 
18
18
  def log_page_break(max_key_length, char='-')
19
+ (max_key_length > 80) and (max_key_length = 80)
19
20
  (char * max_key_length)
20
21
  end
21
22
 
22
- def log_details(testlab)
23
+ def log_config(testlab)
23
24
  {
24
- "hostname" => "%s (%s)" % [Socket.gethostname.inspect, TestLab.hostname.inspect],
25
- "program" => $0.to_s.inspect,
26
25
  "config_dir" => testlab.config_dir.inspect,
27
26
  "repo_dir" => testlab.repo_dir.inspect,
28
27
  "labfile_path" => testlab.labfile_path.inspect,
29
28
  "logdev" => testlab.ui.logger.logdev.inspect,
30
29
  "version" => TestLab::VERSION.inspect,
31
- "argv" => ARGV.inspect
32
30
  }
33
31
  end
34
32
 
35
- def log_ruby
33
+ def log_details(testlab)
34
+ {
35
+ "hostname" => "%s (%s)" % [Socket.gethostname.inspect, TestLab.hostname.inspect],
36
+ "program" => $0.to_s.inspect,
37
+ "argv" => ARGV.join(' ').inspect,
38
+ "timezone" => Time.now.zone.inspect
39
+ }
40
+ end
41
+
42
+ def log_ruby(testlab)
36
43
  dependencies = {
37
44
  "ruby_version" => RUBY_VERSION.inspect,
38
45
  "ruby_patchlevel" => RUBY_PATCHLEVEL.inspect,
39
46
  "ruby_platform" => RUBY_PLATFORM.inspect
40
47
  }
41
48
 
42
- defined?(RUBY_ENGINE) and dependencies.merge!("ruby_engine" => RUBY_ENGINE)
49
+ defined?(RUBY_ENGINE) and dependencies.merge!("ruby_engine" => RUBY_ENGINE)
50
+ defined?(RUBY_DESCRIPTION) and dependencies.merge!("ruby_description" => RUBY_DESCRIPTION)
51
+ defined?(RUBY_RELEASE_DATE) and dependencies.merge!("ruby_release_date" => RUBY_RELEASE_DATE)
43
52
 
44
53
  dependencies
45
54
  end
46
55
 
47
- def log_dependencies
48
- @command = ZTK::Command.new(:silence => true, :ignore_exit_status => true)
49
-
56
+ def log_gem_dependencies(testlab)
50
57
  {
51
58
  "gli_version" => ::GLI::VERSION.inspect,
52
59
  "lxc_version" => ::LXC::VERSION.inspect,
53
60
  "ztk_version" => ::ZTK::VERSION.inspect,
54
- "activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect,
61
+ "activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect
62
+ }
63
+ end
64
+
65
+ def log_external_dependencies(testlab)
66
+ @command = ZTK::Command.new(:silence => true, :ignore_exit_status => true)
67
+
68
+ {
55
69
  "vagrant_version" => @command.exec(%(/usr/bin/env vagrant --version)).output.strip.inspect,
56
- "virtualbox_version" => @command.exec(%(/usr/bin/env vboxmanage --version)).output.strip.inspect
70
+ "virtualbox_version" => @command.exec(%(/usr/bin/env vboxmanage --version)).output.strip.inspect,
71
+ "lxc_version" => @command.exec(%(/usr/bin/env lxc-version)).output.strip.inspect
57
72
  }
58
73
  end
59
74
 
60
75
  def log_header(testlab)
61
76
  log_lines = Array.new
62
77
 
63
- details_hash = log_details(testlab)
64
- ruby_hash = log_ruby
65
- dependencies_hash = log_dependencies
78
+ log_methods = [:log_details, :log_config, :log_ruby, :log_gem_dependencies, :log_external_dependencies]
79
+ log_hashes = log_methods.collect{ |log_method| self.send(log_method, testlab) }
66
80
 
67
- max_key_length = [details_hash.keys, ruby_hash.keys, dependencies_hash.keys].flatten.compact.map(&:length).max + 2
68
- max_value_length = [details_hash.values, ruby_hash.values, dependencies_hash.values].flatten.compact.map(&:length).max + 2
81
+ max_key_length = log_hashes.collect{ |log_hash| log_hash.keys }.flatten.compact.map(&:length).max + 2
82
+ max_value_length = log_hashes.collect{ |log_hash| log_hash.values }.flatten.compact.map(&:length).max + 2
69
83
 
70
84
  max_length = (max_key_length + max_value_length + 2)
71
85
 
72
86
  log_lines << log_page_break(max_length, '=')
73
- details_hash.sort.each do |key, value|
74
- log_lines << log_key_value(key, value, max_key_length)
87
+ log_hashes.each do |log_hash|
88
+ log_hash.sort.each do |key, value|
89
+ log_lines << log_key_value(key, value, max_key_length)
90
+ end
91
+ log_lines << log_page_break(max_length, '=')
75
92
  end
76
93
 
77
- log_lines << log_page_break(max_length)
78
- ruby_hash.sort.each do |key, value|
79
- log_lines << log_key_value(key, value, max_key_length)
80
- end
81
-
82
- log_lines << log_page_break(max_length)
83
- dependencies_hash.sort.each do |key, value|
84
- log_lines << log_key_value(key, value, max_key_length)
85
- end
86
-
87
- log_lines << log_page_break(max_length, '=')
88
-
89
94
  log_lines.flatten.compact
90
95
  end
91
96
 
@@ -11,10 +11,12 @@ class TestLab
11
11
  # @author Zachary Patten <zachary AT jovelabs DOT com>
12
12
  module Utility
13
13
  autoload :CIDR, 'testlab/utility/cidr'
14
+ autoload :GLI, 'testlab/utility/gli'
14
15
  autoload :Logger, 'testlab/utility/logger'
15
16
  autoload :Misc, 'testlab/utility/misc'
16
17
 
17
18
  extend TestLab::Utility::CIDR
19
+ extend TestLab::Utility::GLI
18
20
  extend TestLab::Utility::Logger
19
21
  extend TestLab::Utility::Misc
20
22
 
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "0.7.6"
4
+ VERSION = "0.8.0"
5
5
  end
6
6
  end
data/lib/testlab.rb CHANGED
@@ -17,53 +17,85 @@ require 'testlab/monkeys'
17
17
  # to accomplish this.
18
18
  #
19
19
  # @example Sample Labfile:
20
- # shell_provision_script = <<-EOF
21
- # set -x
22
- # apt-get -y update
23
- # apt-get -y install dnsutils
24
- # EOF
20
+ # node 'vagrant' do
25
21
  #
26
- # config Hash[
27
- # :domain => "default.zone",
28
- # :repo => File.join(ENV['HOME'], "code", "personal", "testlab-repo")
29
- # ]
30
- #
31
- # node :localhost do
32
- # components %w(resolv bind)
33
- # route true
22
+ # provider TestLab::Provider::Vagrant
23
+ # provisioners [
24
+ # TestLab::Provisioner::Raring,
25
+ # TestLab::Provisioner::Bind
26
+ # ]
34
27
  #
35
- # provider TestLab::Provider::Vagrant
36
- # config Hash[
28
+ # config ({
37
29
  # :vagrant => {
38
- # :id => "mytestlab-#{ENV['USER']}".downcase,
39
- # :ip => "192.168.13.37",
40
- # :user => "vagrant",
41
- # :port => 22,
42
- # :cpus => 8,
43
- # :memory => 16384,
44
- # :box => 'raring64'
30
+ # :id => "chef-rubygem-#{TestLab.hostname}".downcase,
31
+ # :cpus => ZTK::Parallel::MAX_FORKS.div(2), # use half of the available processors
32
+ # :memory => ZTK::Parallel::MAX_MEMORY.div(3).div(1024 * 1024), # use a third of available RAM
33
+ # :box => 'raring64',
34
+ # :box_url => 'https://dl.dropboxusercontent.com/u/22904185/boxes/raring64.box',
35
+ # :file => File.dirname(__FILE__)
36
+ # },
37
+ # :bind => {
38
+ # :domain => "default.zone"
45
39
  # }
46
- # ]
40
+ # })
47
41
  #
48
- # network :east do
49
- # address '10.10.0.1/16'
50
- # bridge :br0
42
+ # network 'labnet' do
43
+ # provisioners [TestLab::Provisioner::Route]
44
+ # address '10.10.0.1/16'
45
+ # bridge :br0
51
46
  # end
52
47
  #
53
- # container "server-east-1" do
54
- # domain "east.zone"
48
+ # container "chef-server" do
49
+ # distro "ubuntu"
50
+ # release "precise"
51
+ #
52
+ # provisioners [
53
+ # TestLab::Provisioner::Resolv,
54
+ # TestLab::Provisioner::AptCacherNG,
55
+ # TestLab::Provisioner::Apt,
56
+ # TestLab::Provisioner::Chef::RubyGemServer
57
+ # ]
58
+ #
59
+ # user 'deployer' do
60
+ # password 'deployer'
61
+ # identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
62
+ # public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
63
+ # uid 2600
64
+ # gid 2600
65
+ # end
66
+ #
67
+ # interface do
68
+ # network_id 'labnet'
69
+ # name :eth0
70
+ # address '10.10.0.254/16'
71
+ # mac '00:00:5e:63:b5:9f'
72
+ # end
73
+ # end
55
74
  #
75
+ # container "chef-client" do
56
76
  # distro "ubuntu"
57
77
  # release "precise"
58
78
  #
59
- # provisioner TestLab::Provisioner::Shell
60
- # config Hash[:setup => shell_provision_script]
79
+ # provisioners [
80
+ # TestLab::Provisioner::Resolv,
81
+ # TestLab::Provisioner::AptCacherNG,
82
+ # TestLab::Provisioner::Apt,
83
+ # TestLab::Provisioner::Chef::RubyGemClient
84
+ # ]
85
+ #
86
+ # user 'deployer' do
87
+ # password 'deployer'
88
+ # identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
89
+ # public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
90
+ # uid 2600
91
+ # gid 2600
92
+ # end
61
93
  #
62
94
  # interface do
63
- # name :eth0
64
- # network_id :east
65
- # address '10.10.0.254/16'
66
- # mac '00:00:5e:b7:e5:15'
95
+ # network_id 'labnet'
96
+ # name :eth0
97
+ # address '10.10.0.20/16'
98
+ # mac '00:00:5e:b7:e5:15'
67
99
  # end
68
100
  # end
69
101
  #
@@ -78,8 +110,8 @@ require 'testlab/monkeys'
78
110
  # @example We can control things via code easily as well:
79
111
  # testlab.create # creates the lab
80
112
  # testlab.up # ensures the lab is up and running
81
- # testlab.setup # setup the lab, creating all networks and containers
82
- # testlab.teardown # teardown the lab, destroy all networks and containers
113
+ # testlab.build # build the lab, creating all networks and containers
114
+ # testlab.demolish # demolish the lab, destroy all networks and containers
83
115
  #
84
116
  # @author Zachary Patten <zachary AT jovelabs DOT com>
85
117
  class TestLab
@@ -115,11 +147,16 @@ class TestLab
115
147
 
116
148
  labfile_path = (options[:labfile_path] || File.join(@repo_dir, 'Labfile'))
117
149
  @labfile_path = File.expand_path(ZTK::Locator.find(labfile_path))
150
+ end
118
151
 
152
+ # Boot TestLab
153
+ #
154
+ # Change to the defined repository directory and load the *Labfile*.
155
+ #
156
+ # @return [Boolean] True if successful.
157
+ def boot
119
158
  @labfile = TestLab::Labfile.load(labfile_path)
120
159
  @labfile.testlab = self
121
-
122
- Dir.chdir(@repo_dir)
123
160
  end
124
161
 
125
162
  # Test Lab Nodes
@@ -186,6 +223,30 @@ class TestLab
186
223
  !alive?
187
224
  end
188
225
 
226
+ # Test Lab Create
227
+ #
228
+ # Attempts to create our lab topology. This calls the create method on all of
229
+ # our nodes.
230
+ #
231
+ # @return [Boolean] True if successful.
232
+ def create
233
+ method_proxy(:create)
234
+
235
+ true
236
+ end
237
+
238
+ # Test Lab Destroy
239
+ #
240
+ # Attempts to destroy our lab topology. This calls the destroy method on all of
241
+ # our nodes.
242
+ #
243
+ # @return [Boolean] True if successful.
244
+ def destroy
245
+ reverse_method_proxy(:destroy)
246
+
247
+ true
248
+ end
249
+
189
250
  # Test Lab Up
190
251
  #
191
252
  # Attempts to up our lab topology. This calls the up method on all of
@@ -246,6 +307,18 @@ class TestLab
246
307
  true
247
308
  end
248
309
 
310
+ # Test Lab Demolish
311
+ #
312
+ # Attempts to demolish our lab topology. This calls various methods on
313
+ # all of our nodes, networks and containers.
314
+ #
315
+ # @return [Boolean] True if successful.
316
+ def demolish
317
+ reverse_method_proxy(:demolish)
318
+
319
+ true
320
+ end
321
+
249
322
  # Node Method Proxy
250
323
  #
251
324
  # Iterates all of the lab nodes, sending the supplied method name and arguments
@@ -195,6 +195,7 @@ describe TestLab::Container do
195
195
  describe "#setup" do
196
196
  context "with no provisioner" do
197
197
  it "should setup the container" do
198
+ subject.node.stub(:state) { :running }
198
199
  subject.lxc.stub(:exists?) { true }
199
200
  subject.lxc.stub(:state) { :stopped }
200
201
  subject.provisioners = Array.new
@@ -207,6 +208,7 @@ describe TestLab::Container do
207
208
  it "should setup the container" do
208
209
  subject = TestLab::Container.first('server-shell')
209
210
 
211
+ subject.node.stub(:state) { :running }
210
212
  subject.lxc.stub(:exists?) { true }
211
213
  subject.lxc.stub(:state) { :stopped }
212
214
  subject.provisioners = Array.new
@@ -219,6 +221,7 @@ describe TestLab::Container do
219
221
  describe "#teardown" do
220
222
  context "with no provisioner" do
221
223
  it "should teardown the container" do
224
+ subject.node.stub(:state) { :running }
222
225
  subject.lxc.stub(:exists?) { true }
223
226
  subject.lxc.stub(:state) { :stopped }
224
227
  subject.provisioners = Array.new
@@ -231,6 +234,7 @@ describe TestLab::Container do
231
234
  it "should teardown the container" do
232
235
  subject = TestLab::Container.first('server-shell')
233
236
 
237
+ subject.node.stub(:state) { :running }
234
238
  subject.lxc.stub(:exists?) { true }
235
239
  subject.lxc.stub(:state) { :stopped }
236
240
  subject.provisioners = Array.new
data/spec/network_spec.rb CHANGED
@@ -144,6 +144,8 @@ describe TestLab::Network do
144
144
 
145
145
  describe "#setup" do
146
146
  it "should create and online the network" do
147
+ subject.node.stub(:state) { :running }
148
+ subject.stub(:state) { :running }
147
149
  subject.stub(:create) { true }
148
150
  subject.stub(:up) { true }
149
151
 
@@ -153,6 +155,8 @@ describe TestLab::Network do
153
155
 
154
156
  describe "#teardown" do
155
157
  it "should create and online the network" do
158
+ subject.node.stub(:state) { :running }
159
+ subject.stub(:state) { :running }
156
160
  subject.stub(:down) { true }
157
161
  subject.stub(:destroy) { true }
158
162