testlab 1.4.4 → 1.5.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODBlNjc1YWRlMDE2YjI5ZDY0YWE5ZTU5M2FhMWJkYWE2Y2FlZTgwYQ==
5
+ data.tar.gz: !binary |-
6
+ YTkwZTliNWZjNDE5YzgzN2U2YTY1ZTJkZWFiZWRjNDQ4OWU1MTQ0MQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YmUxMDdhOWQ4ZmRiZjBiYWU1NDBhYzFjYjdhNDRkNTBiZmZmODljN2VmMmQ1
10
+ NWE5NTUwNDUyMjMyNjc3YjUwNmQxYjM4ZDM4NWM3ZTQ2YjRkZTA0M2ZlYWY0
11
+ NWEyY2IwYmM1MjQ3ZDA5YjhhMDc2Y2YxY2MyOGVmNzVlYTQ2M2Q=
12
+ data.tar.gz: !binary |-
13
+ MmQ4ZGUxZGQzMGFkM2MyNWZkYTliYzMzYTMyMGY4YjY4MjRhOWQxZTRhNzNk
14
+ YzE4YTc4ODliNGRjOWQzOWYyZDE1NWRkYzM2MzY5OTE1ZmZkYTUxMzk2ZjI3
15
+ NGIxNmRkNWEyNWYyMjNiZDE3YzUxY2FlODg1MDAwYzM2MGE5N2U=
@@ -26,6 +26,10 @@ When /^I destroy the lab with "([^"]*)"$/ do |app_name|
26
26
  testlab_cmd(app_name, %W(destroy))
27
27
  end
28
28
 
29
+ When /^I bounce the lab with "([^"]*)"$/ do |app_name|
30
+ testlab_cmd(app_name, %W(bounce))
31
+ end
32
+
29
33
  def testlab_cmd(app_name, *args)
30
34
  args = args.join(' ')
31
35
  step %(I run `#{app_name} --repo=#{TEST_REPO} --labfile=#{TEST_LABFILE} #{args}`)
@@ -25,6 +25,7 @@ node 'vagrant' do
25
25
 
26
26
  network 'labnet' do
27
27
  provisioners [
28
+ TestLab::Provisioner::Route,
28
29
  TestLab::Provisioner::Bind
29
30
  ]
30
31
 
@@ -38,6 +39,7 @@ node 'vagrant' do
38
39
 
39
40
  provisioners [
40
41
  TestLab::Provisioner::Resolv,
42
+ TestLab::Provisioner::Bind,
41
43
  TestLab::Provisioner::AptCacherNG,
42
44
  TestLab::Provisioner::Apt
43
45
  ]
@@ -25,6 +25,8 @@ Feature: TestLab command-line
25
25
  Then the exit status should be 0
26
26
  When I export the containers with "tl"
27
27
  Then the exit status should be 0
28
+ When I bounce the lab with "tl"
29
+ Then the exit status should be 0
28
30
 
29
31
 
30
32
  Scenario: TestLab import
@@ -34,6 +36,8 @@ Feature: TestLab command-line
34
36
  Then the exit status should be 0
35
37
  When I build the lab with "tl"
36
38
  Then the exit status should be 0
39
+ When I bounce the lab with "tl"
40
+ Then the exit status should be 0
37
41
 
38
42
 
39
43
  Scenario: TestLab clone
@@ -50,13 +54,13 @@ Feature: TestLab command-line
50
54
  Then the exit status should be 0
51
55
 
52
56
  When I build the containers with "tl"
53
- Then the exit status should be 0
57
+ Then the exit status should be 1
54
58
 
55
59
  When I bounce the containers with "tl"
56
60
  Then the exit status should be 0
57
61
 
58
62
  When I recycle the containers with "tl"
59
- Then the exit status should be 0
63
+ Then the exit status should be 1
60
64
 
61
65
  When I bounce the containers with "tl"
62
66
  Then the exit status should be 0
@@ -85,6 +89,9 @@ Feature: TestLab command-line
85
89
  When I bounce the containers with "tl"
86
90
  Then the exit status should be 0
87
91
 
92
+ When I bounce the lab with "tl"
93
+ Then the exit status should be 0
94
+
88
95
 
89
96
  Scenario: TestLab Demolish
90
97
  When I demolish the lab with "tl"
@@ -30,14 +30,10 @@ Displays the status of all containers or single/multiple containers if supplied
30
30
  EOF
31
31
  c.command :status do |status|
32
32
  status.action do |global_options, options, args|
33
- containers = iterate_objects_by_name(options[:name], TestLab::Container).delete_if{ |container| container.node.dead? }
33
+ containers = iterate_objects_by_name(options[:name], TestLab::Container)
34
34
 
35
- if (containers.count == 0)
36
- @testlab.ui.stderr.puts("You either have no containers defined or dead nodes!".yellow)
37
- else
38
- ZTK::Report.new(:ui => @testlab.ui).list(containers, TestLab::Container::STATUS_KEYS) do |container|
39
- OpenStruct.new(container.status)
40
- end
35
+ ZTK::Report.new(:ui => @testlab.ui).list(containers, TestLab::Container::STATUS_KEYS) do |container|
36
+ OpenStruct.new(container.status)
41
37
  end
42
38
  end
43
39
  end
@@ -30,14 +30,10 @@ Displays the status of all networks or single/multiple networks if supplied via
30
30
  EOF
31
31
  c.command :status do |status|
32
32
  status.action do |global_options, options, args|
33
- networks = iterate_objects_by_name(options[:name], TestLab::Network).delete_if{ |network| network.node.dead? }
33
+ networks = iterate_objects_by_name(options[:name], TestLab::Network)
34
34
 
35
- if (networks.count == 0)
36
- @testlab.ui.stderr.puts("You either have no networks defined or dead nodes!".yellow)
37
- else
38
- ZTK::Report.new(:ui => @testlab.ui).list(networks, TestLab::Network::STATUS_KEYS) do |network|
39
- OpenStruct.new(network.status)
40
- end
35
+ ZTK::Report.new(:ui => @testlab.ui).list(networks, TestLab::Network::STATUS_KEYS) do |network|
36
+ OpenStruct.new(network.status)
41
37
  end
42
38
  end
43
39
  end
@@ -56,7 +52,6 @@ EOF
56
52
  p = TestLab::Provisioner::Route.new({}, @ui)
57
53
  p.on_network_up(network)
58
54
  @testlab.ui.stdout.puts("Added routes successfully!".green.bold)
59
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
60
55
  end
61
56
  end
62
57
  end
@@ -70,23 +65,28 @@ EOF
70
65
  p = TestLab::Provisioner::Route.new({}, @ui)
71
66
  p.on_network_down(network)
72
67
  @testlab.ui.stdout.puts("Deleted routes successfully!".red.bold)
73
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
74
68
  end
75
69
  end
76
70
  end
77
71
 
78
72
  # ROUTE SHOW
79
73
  #############
74
+
75
+ # Route show helper method because OSX sucks
76
+ def osx_network(net)
77
+ net.network.split('.').delete_if{ |o| o == '0' }.join('.')
78
+ end
79
+
80
80
  route.desc 'Show routes to lab networks'
81
81
  route.command :show do |show|
82
82
  show.action do |global_options,options,args|
83
83
  iterate_objects_by_name(options[:name], TestLab::Network) do |network|
84
- @testlab.ui.stdout.puts("TestLab routes:".green.bold)
84
+ @testlab.ui.stdout.puts("Routes for TestLab network '#{network.id}':".green.bold)
85
85
  case RUBY_PLATFORM
86
86
  when /darwin/ then
87
- @testlab.ui.stdout.puts %x(netstat -nrf inet | grep '#{network.node.ip}').strip
87
+ @testlab.ui.stdout.puts %x(netstat -nrf inet | grep '#{osx_network(network)}/#{network.cidr}').strip
88
88
  when /linux/ then
89
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
89
+ @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.network}').strip
90
90
  end
91
91
  end
92
92
  end
@@ -12,8 +12,9 @@ class TestLab
12
12
  def create
13
13
  @ui.logger.debug { "Container Create: #{self.id}" }
14
14
 
15
- (self.node.state == :running) or return false
16
- (self.state == :not_created) or return false
15
+ self.node.alive? or return false
16
+
17
+ persistent_operation_check(:create)
17
18
 
18
19
  please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
19
20
  configure
@@ -34,8 +35,7 @@ class TestLab
34
35
  def destroy
35
36
  @ui.logger.debug { "Container Destroy: #{self.id}" }
36
37
 
37
- (self.node.state == :running) or return false
38
- (self.state != :not_created) or return false
38
+ self.node.alive? or return false
39
39
 
40
40
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
41
41
  self.lxc.destroy(%(-f))
@@ -55,8 +55,7 @@ class TestLab
55
55
  def up
56
56
  @ui.logger.debug { "Container Up: #{self.id}" }
57
57
 
58
- (self.node.state == :running) or return false
59
- (self.state != :running) or return false
58
+ self.node.alive? or return false
60
59
 
61
60
  please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
62
61
  configure
@@ -66,19 +65,19 @@ class TestLab
66
65
  self.node.exec(%(sudo arp --verbose --delete #{interface.ip}), :ignore_exit_status => true)
67
66
  end
68
67
 
69
- if self.lxc_clone.exists?
68
+ if self.is_ephemeral?
70
69
  self.lxc_clone.start_ephemeral(clone_args)
71
70
  else
72
71
  self.lxc.start(%(--daemon))
73
72
  end
74
73
 
75
- (self.lxc.state != :running) and raise ContainerError, "The container failed to online!"
74
+ (self.state != :running) and raise ContainerError, "The container failed to online!"
76
75
 
77
76
  ZTK::TCPSocketCheck.new(:ui => @ui, :host => self.primary_interface.ip, :port => 22).wait
78
77
 
79
78
  # If we are not in ephemeral mode we should attempt to provision our
80
79
  # defined users.
81
- if !self.lxc_clone.exists?
80
+ if self.is_persistent?
82
81
  self.users.each do |user|
83
82
  user.provision
84
83
  end
@@ -101,15 +100,14 @@ class TestLab
101
100
  def down
102
101
  @ui.logger.debug { "Container Down: #{self.id}" }
103
102
 
104
- (self.node.state == :running) or return false
105
- (self.state == :running) or return false
103
+ self.node.alive? or return false
106
104
 
107
105
  please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
108
106
 
109
107
  self.lxc.stop
110
108
 
111
109
  # If we are in ephemeral mode...
112
- if self.lxc_clone.exists?
110
+ if self.is_ephemeral?
113
111
 
114
112
  # IMPORTANT NOTE:
115
113
  #
@@ -118,11 +116,10 @@ class TestLab
118
116
  #
119
117
  # If we are using a memory backed COW filesystem for the ephemeral
120
118
  # clones then it will be released when the container is stopped.
121
-
122
119
  self.persist and self.lxc.destroy(%(-f))
123
120
  end
124
121
 
125
- (self.lxc.state == :running) and raise ContainerError, "The container failed to offline!"
122
+ (self.state == :running) and raise ContainerError, "The container failed to offline!"
126
123
 
127
124
  do_provisioner_callbacks(self, :down, @ui)
128
125
  end
@@ -12,7 +12,7 @@ class TestLab
12
12
  @ui.logger.debug { "Container Ephemeral: #{self.id}" }
13
13
 
14
14
  please_wait(:ui => @ui, :message => format_object_action(self, 'Ephemeral', :yellow)) do
15
- self.to_ephemeral
15
+ is_persistent? and self.to_ephemeral
16
16
  end
17
17
 
18
18
  true
@@ -27,12 +27,49 @@ class TestLab
27
27
  @ui.logger.debug { "Container Persistent: #{self.id}" }
28
28
 
29
29
  please_wait(:ui => @ui, :message => format_object_action(self, 'Persistent', :yellow)) do
30
- self.to_static
30
+ is_ephemeral? and self.to_persistent
31
31
  end
32
32
 
33
33
  true
34
34
  end
35
35
 
36
+ # Persistent Operation Check
37
+ #
38
+ # Checks if the container is operating in ephemeral mode, and if it is
39
+ # raises an exception indicating the operation can not proceed.
40
+ #
41
+ # If the container is operating in persistent mode, no output is generated
42
+ # and true is returned indicating the operation can continue.
43
+ #
44
+ # @return [Boolean] True if the operation can continue; false otherwise.
45
+ def persistent_operation_check(action)
46
+ if is_ephemeral?
47
+ raise ContainerError, "You can not #{action} #{self.id} because it is currently in ephemeral mode!"
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ # Is Container Ephemeral?
54
+ #
55
+ # Returns true if the container is in ephemeral mode, false otherwise.
56
+ #
57
+ # @return [Boolean] Returns true if the container is ephemeral, false
58
+ # otherwise.
59
+ def is_ephemeral?
60
+ self.lxc_clone.exists?
61
+ end
62
+
63
+ # Is Container Persistent?
64
+ #
65
+ # Returns true if the container is in persistent mode, false otherwise.
66
+ #
67
+ # @return [Boolean] Returns true if the container is persistent, false
68
+ # otherwise.
69
+ def is_persistent?
70
+ !is_ephemeral?
71
+ end
72
+
36
73
  # LXC::Container object
37
74
  #
38
75
  # Returns a *LXC::Container* class instance configured for the clone of
@@ -51,8 +88,12 @@ class TestLab
51
88
  # occur.
52
89
  #
53
90
  # @return [Boolean] Returns true if successful.
54
- def to_static
55
- if self.lxc_clone.exists?
91
+ def to_persistent
92
+ if self.is_ephemeral?
93
+ self_state = self.state
94
+
95
+ configure
96
+
56
97
  self.lxc.stop
57
98
  self.lxc.destroy(%(-f))
58
99
 
@@ -60,7 +101,8 @@ class TestLab
60
101
  self.lxc_clone.clone(%W(-o #{self.lxc_clone.name} -n #{self.lxc.name}))
61
102
  self.lxc_clone.destroy(%(-f))
62
103
 
63
- build_lxc_config(self.lxc.config)
104
+ # bring our container back online if it was running before the operation
105
+ (self_state == :running) and self.up
64
106
  end
65
107
 
66
108
  true
@@ -73,7 +115,11 @@ class TestLab
73
115
  #
74
116
  # @return [Boolean] Returns true if successful.
75
117
  def to_ephemeral
76
- if (self.lxc.exists? && !self.lxc_clone.exists?)
118
+ if self.is_persistent?
119
+ self_state = self.state
120
+
121
+ configure
122
+
77
123
  self.lxc_clone.stop
78
124
  self.lxc_clone.destroy(%(-f))
79
125
 
@@ -81,10 +127,8 @@ class TestLab
81
127
  self.lxc.clone(%W(-o #{self.lxc.name} -n #{self.lxc_clone.name}))
82
128
  self.lxc.destroy(%(-f))
83
129
 
84
- build_lxc_config(self.lxc_clone.config)
85
- else
86
- self.lxc.stop
87
- self.persist and self.lxc.destroy(%(-f))
130
+ # bring our container back online if it was running before the operation
131
+ (self_state == :running) and self.up
88
132
  end
89
133
 
90
134
  true
@@ -11,7 +11,7 @@ class TestLab
11
11
  def export(compression=9, local_file=nil)
12
12
  @ui.logger.debug { "Container Export: #{self.id} " }
13
13
 
14
- (self.lxc.state == :not_created) and return false
14
+ (self.state == :not_created) and raise ContainerError, 'You must create a container before you can export it!'
15
15
 
16
16
  # Throw an exception if we are attempting to export a container in a
17
17
  # ephemeral state.
@@ -49,9 +49,7 @@ EOF
49
49
  self.node.download(remote_file, local_file)
50
50
  end
51
51
 
52
- @ui.stdout.puts
53
- @ui.stdout.puts("Your shipping container is now exported and available at '#{local_file}'!".green.bold)
54
- @ui.stdout.puts
52
+ @ui.stdout.puts(format_message("Your shipping container is now exported and available at '#{local_file}'!".green.bold))
55
53
 
56
54
  true
57
55
  end
@@ -63,7 +61,7 @@ EOF
63
61
  @ui.logger.debug { "Container Import: #{self.id} " }
64
62
 
65
63
  # Ensure we are not in ephemeral mode.
66
- self.to_static
64
+ self.persistent
67
65
 
68
66
  self.down
69
67
  self.destroy
@@ -97,9 +95,7 @@ du -sh #{self.lxc.container_root}
97
95
  EOF
98
96
  end
99
97
 
100
- @ui.stdout.puts
101
- @ui.stdout.puts("Your shipping container is now imported and available for use!".green.bold)
102
- @ui.stdout.puts
98
+ @ui.stdout.puts(format_message("Your shipping container is now imported and available for use!".green.bold))
103
99
 
104
100
  true
105
101
  end
@@ -5,16 +5,14 @@ class TestLab
5
5
 
6
6
  # Provision the container
7
7
  #
8
- # Attempts to provision the container. We first create the container,
9
- # then attempt to bring it online. Afterwards the containers provisioner
10
- # is called.
8
+ # Attempts to provision the container. Calls the containers defined
9
+ # provisioners provision methods.
11
10
  #
12
11
  # @return [Boolean] True if successful.
13
12
  def provision
14
13
  @ui.logger.debug { "Container Provision: #{self.id} " }
15
14
 
16
- (self.node.state != :running) and return false
17
- (self.state != :running) and return false
15
+ self.node.alive? or return false
18
16
 
19
17
  please_wait(:ui => @ui, :message => format_object_action(self, :provision, :green)) do
20
18
  do_provisioner_callbacks(self, :provision, @ui)
@@ -25,16 +23,16 @@ class TestLab
25
23
 
26
24
  # Deprovision the container
27
25
  #
28
- # Attempts to deprovision the container. We first call the provisioner
29
- # deprovision method defined for the container, if any. Next we attempt
30
- # to offline the container. Afterwards the container is destroy.
26
+ # Attempts to deprovision the container. Calls the containers defined
27
+ # provisioners deprovision methods.
31
28
  #
32
29
  # @return [Boolean] True if successful.
33
30
  def deprovision
34
31
  @ui.logger.debug { "Container Deprovision: #{self.id} " }
35
32
 
36
- (self.node.state != :running) and return false
37
- (self.state != :running) and return false
33
+ self.node.alive? or return false
34
+
35
+ persistent_operation_check(:deprovision)
38
36
 
39
37
  please_wait(:ui => @ui, :message => format_object_action(self, :deprovision, :red)) do
40
38
  do_provisioner_callbacks(self, :deprovision, @ui)
@@ -70,8 +70,8 @@ class TestLab
70
70
  #
71
71
  # @return [Symbol] A symbol indicating the state of the container.
72
72
  def state
73
- if self.lxc_clone.exists?
74
- self.lxc_clone.state
73
+ if self.node.dead?
74
+ :unknown
75
75
  else
76
76
  self.lxc.state
77
77
  end
@@ -82,10 +82,14 @@ class TestLab
82
82
  # What mode the container is in.
83
83
  # @return [Symbol] A symbol indicating the mode of the container.
84
84
  def mode
85
- if self.lxc_clone.exists?
86
- :ephemeral
85
+ if self.node.dead?
86
+ :unknown
87
87
  else
88
- :persistent
88
+ if self.is_ephemeral?
89
+ :ephemeral
90
+ else
91
+ :persistent
92
+ end
89
93
  end
90
94
  end
91
95
 
@@ -7,8 +7,7 @@ class TestLab
7
7
  def create
8
8
  @ui.logger.debug { "Network Create: #{self.id} " }
9
9
 
10
- (self.node.state == :running) or return false
11
- (self.state == :not_created) or return false
10
+ self.node.alive? or return false
12
11
 
13
12
  please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
14
13
  self.node.bootstrap(<<-EOF, :ignore_exit_status => true)
@@ -41,8 +40,7 @@ brctl setfd #{self.bridge} 0
41
40
  def destroy
42
41
  @ui.logger.debug { "Network Destroy: #{self.id} " }
43
42
 
44
- (self.node.state == :running) or return false
45
- (self.state != :not_created) or return false
43
+ self.node.alive? or return false
46
44
 
47
45
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
48
46
  self.node.bootstrap(<<-EOF, :ignore_exit_status => true)
@@ -61,8 +59,7 @@ brctl delbr #{self.bridge}
61
59
  def up
62
60
  @ui.logger.debug { "Network Up: #{self.id} " }
63
61
 
64
- (self.node.state == :running) or return false
65
- # (self.state != :running) or return false
62
+ self.node.alive? or return false
66
63
 
67
64
  please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
68
65
  self.node.bootstrap(<<-EOF, :ignore_exit_status => true)
@@ -80,8 +77,7 @@ ifconfig #{self.bridge} #{self.ip} netmask #{self.netmask} broadcast #{self.broa
80
77
  def down
81
78
  @ui.logger.debug { "Network Down: #{self.id} " }
82
79
 
83
- (self.node.state == :running) or return false
84
- # (self.state == :running) or return false
80
+ self.node.alive? or return false
85
81
 
86
82
  please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
87
83
  self.node.bootstrap(<<-EOF, :ignore_exit_status => true)
@@ -7,8 +7,7 @@ class TestLab
7
7
  def provision
8
8
  @ui.logger.debug { "Network Provision: #{self.id} " }
9
9
 
10
- (self.node.state != :running) and return false
11
- (self.state != :running) and return false
10
+ self.node.alive? or return false
12
11
 
13
12
  please_wait(:ui => @ui, :message => format_object_action(self, 'Provision', :green)) do
14
13
  do_provisioner_callbacks(self, :provision, @ui)
@@ -21,8 +20,7 @@ class TestLab
21
20
  def deprovision
22
21
  @ui.logger.debug { "Network Deprovision: #{self.id} " }
23
22
 
24
- (self.node.state != :running) and return false
25
- (self.state != :running) and return false
23
+ self.node.alive? or return false
26
24
 
27
25
  please_wait(:ui => @ui, :message => format_object_action(self, 'Deprovision', :red)) do
28
26
  do_provisioner_callbacks(self, :deprovision, @ui)
@@ -63,15 +63,19 @@ class TestLab
63
63
 
64
64
  # Network Bridge State
65
65
  def state
66
- exit_code = self.node.exec(%(sudo brctl show #{self.bridge} 2>&1 | grep -i 'No such device'), :ignore_exit_status => true).exit_code
67
- if (exit_code == 0)
68
- :not_created
66
+ if self.node.dead?
67
+ :unknown
69
68
  else
70
- output = self.node.exec(%(sudo ifconfig #{self.bridge} 2>&1 | grep 'MTU'), :ignore_exit_status => true).output.strip
71
- if ((output =~ /UP/) || (output =~ /RUNNING/))
72
- :running
69
+ exit_code = self.node.exec(%(sudo brctl show #{self.bridge} 2>&1 | grep -i 'No such device'), :ignore_exit_status => true).exit_code
70
+ if (exit_code == 0)
71
+ :not_created
73
72
  else
74
- :stopped
73
+ output = self.node.exec(%(sudo ifconfig #{self.bridge} 2>&1 | grep 'MTU'), :ignore_exit_status => true).output
74
+ if ((output =~ /UP/) || (output =~ /RUNNING/))
75
+ :running
76
+ else
77
+ :stopped
78
+ end
75
79
  end
76
80
  end
77
81
  end
@@ -7,8 +7,6 @@ class TestLab
7
7
  def create
8
8
  @ui.logger.debug { "Node Create: #{self.id} " }
9
9
 
10
- (self.state == :not_created) or return false
11
-
12
10
  please_wait(:ui => @ui, :message => format_object_action(self, 'Create', :green)) do
13
11
  @provider.create
14
12
 
@@ -22,8 +20,6 @@ class TestLab
22
20
  def destroy
23
21
  @ui.logger.debug { "Node Destroy: #{self.id} " }
24
22
 
25
- (self.state != :not_created) or return false
26
-
27
23
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
28
24
  @provider.destroy
29
25
 
@@ -37,8 +33,6 @@ class TestLab
37
33
  def up
38
34
  @ui.logger.debug { "Node Up: #{self.id} " }
39
35
 
40
- (self.state != :running) or return false
41
-
42
36
  please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
43
37
  @provider.up
44
38
 
@@ -52,8 +46,6 @@ class TestLab
52
46
  def down
53
47
  @ui.logger.debug { "Node Down: #{self.id} " }
54
48
 
55
- (self.state == :running) or return false
56
-
57
49
  please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
58
50
  @provider.down
59
51
 
@@ -7,8 +7,6 @@ class TestLab
7
7
  def provision
8
8
  @ui.logger.debug { "Node Provision: #{self.id} " }
9
9
 
10
- (self.state != :running) and return false
11
-
12
10
  please_wait(:ui => @ui, :message => format_object_action(self, 'Provision', :green)) do
13
11
  do_provisioner_callbacks(self, :provision, @ui)
14
12
  end
@@ -20,8 +18,6 @@ class TestLab
20
18
  def deprovision
21
19
  @ui.logger.debug { "Node Deprovision: #{self.id} " }
22
20
 
23
- (self.state != :running) and return false
24
-
25
21
  please_wait(:ui => @ui, :message => format_object_action(self, 'Deprovision', :red)) do
26
22
  do_provisioner_callbacks(self, :deprovision, @ui)
27
23
  end
@@ -29,8 +29,6 @@ class TestLab
29
29
  # A collection of all states the VM can be in
30
30
  ALL_STATES = (VALID_STATES + INVALID_STATES).flatten
31
31
 
32
- MSG_NO_LAB = %(We could not find a test lab!)
33
-
34
32
  ################################################################################
35
33
 
36
34
  def initialize(config={}, ui=nil)
@@ -50,8 +48,6 @@ class TestLab
50
48
 
51
49
  # Destroy Vagrant-controlled VM
52
50
  def destroy
53
- !self.exists? and raise VagrantError, MSG_NO_LAB
54
-
55
51
  self.alive? and self.down
56
52
  self.exists? and self.vagrant_cli("destroy", "--force", self.instance_id)
57
53
 
@@ -71,8 +67,6 @@ class TestLab
71
67
 
72
68
  # Halt Vagrant-controlled VM
73
69
  def down(*args)
74
- !self.exists? and raise VagrantError, MSG_NO_LAB
75
-
76
70
  arguments = (%W(halt #{self.instance_id}) + args).flatten.compact
77
71
 
78
72
  self.vagrant_cli(*arguments)
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "1.4.4"
4
+ VERSION = "1.5.0"
5
5
  end
6
6
  end
@@ -52,8 +52,10 @@ describe TestLab::Container do
52
52
 
53
53
  describe "#status" do
54
54
  it "should return a hash of status information about the container" do
55
+ subject.node.stub(:state) { :running }
55
56
  subject.lxc.stub(:state) { :not_created }
56
57
  subject.lxc_clone.stub(:exists?) { false }
58
+
57
59
  subject.status.should be_kind_of(Hash)
58
60
  subject.status.should_not be_empty
59
61
  end
@@ -61,7 +63,9 @@ describe TestLab::Container do
61
63
 
62
64
  describe "#state" do
63
65
  it "should return the state of the container" do
66
+ subject.node.stub(:dead?) { false }
64
67
  subject.lxc.stub(:state) { :not_created }
68
+ subject.lxc_clone.stub(:exists?) { false }
65
69
  subject.state.should == :not_created
66
70
  end
67
71
  end
@@ -166,6 +170,7 @@ describe TestLab::Container do
166
170
  subject.lxc.stub(:state) { :stopped }
167
171
  subject.lxc.stub(:destroy) { true }
168
172
  subject.lxc_clone.stub(:exists?) { false }
173
+ subject.lxc_clone.stub(:destroy) { false }
169
174
  subject.stub(:provisioners) { Array.new }
170
175
 
171
176
  subject.destroy
@@ -175,15 +180,17 @@ describe TestLab::Container do
175
180
  describe "#up" do
176
181
  it "should up the container" do
177
182
  subject.node.stub(:state) { :running }
183
+
178
184
  subject.lxc.stub(:exists?) { true }
179
185
  subject.lxc.stub(:start) { true }
180
186
  subject.lxc.stub(:wait) { true }
181
187
  subject.lxc.stub(:state) { :running }
182
188
  subject.lxc.stub(:attach)
183
- subject.stub(:provisioners) { Array.new }
184
189
 
185
190
  subject.lxc_clone.stub(:exists?) { false }
186
191
 
192
+ subject.stub(:provisioners) { Array.new }
193
+
187
194
  ZTK::TCPSocketCheck.any_instance.stub(:wait) { true }
188
195
 
189
196
  subject.up
@@ -193,10 +200,14 @@ describe TestLab::Container do
193
200
  describe "#down" do
194
201
  it "should down the container" do
195
202
  subject.node.stub(:state) { :running }
203
+
196
204
  subject.lxc.stub(:exists?) { true }
197
205
  subject.lxc.stub(:stop) { true }
198
206
  subject.lxc.stub(:wait) { true }
199
207
  subject.lxc.stub(:state) { :stopped }
208
+
209
+ subject.lxc_clone.stub(:exists?) { false }
210
+
200
211
  subject.stub(:provisioners) { Array.new }
201
212
 
202
213
  subject.down
@@ -207,8 +218,12 @@ describe TestLab::Container do
207
218
  context "with no provisioner" do
208
219
  it "should provision the container" do
209
220
  subject.node.stub(:state) { :running }
221
+
210
222
  subject.lxc.stub(:exists?) { true }
211
223
  subject.lxc.stub(:state) { :stopped }
224
+
225
+ subject.lxc_clone.stub(:exists?) { false }
226
+
212
227
  subject.stub(:provisioners) { Array.new }
213
228
 
214
229
  subject.provision
@@ -220,8 +235,12 @@ describe TestLab::Container do
220
235
  subject and (subject = TestLab::Container.first('server-shell'))
221
236
 
222
237
  subject.node.stub(:state) { :running }
238
+
223
239
  subject.lxc.stub(:exists?) { true }
224
240
  subject.lxc.stub(:state) { :stopped }
241
+
242
+ subject.lxc_clone.stub(:exists?) { false }
243
+
225
244
  subject.stub(:provisioners) { Array.new }
226
245
 
227
246
  subject.provision
@@ -233,8 +252,12 @@ describe TestLab::Container do
233
252
  context "with no provisioner" do
234
253
  it "should deprovision the container" do
235
254
  subject.node.stub(:state) { :running }
255
+
236
256
  subject.lxc.stub(:exists?) { true }
237
257
  subject.lxc.stub(:state) { :stopped }
258
+
259
+ subject.lxc_clone.stub(:exists?) { false }
260
+
238
261
  subject.stub(:provisioners) { Array.new }
239
262
 
240
263
  subject.deprovision
@@ -246,8 +269,12 @@ describe TestLab::Container do
246
269
  subject and (subject = TestLab::Container.first('server-shell'))
247
270
 
248
271
  subject.node.stub(:state) { :running }
272
+
249
273
  subject.lxc.stub(:exists?) { true }
250
274
  subject.lxc.stub(:state) { :stopped }
275
+
276
+ subject.lxc_clone.stub(:exists?) { false }
277
+
251
278
  subject.stub(:provisioners) { Array.new }
252
279
 
253
280
  subject.deprovision
data/spec/network_spec.rb CHANGED
@@ -102,6 +102,7 @@ describe TestLab::Network do
102
102
 
103
103
  describe "#state" do
104
104
  it "should return the state of the bridge" do
105
+ subject.node.stub(:dead?) { false }
105
106
  subject.node.ssh.stub(:exec) { OpenStruct.new(:output => " UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1") }
106
107
  subject.state.should == :running
107
108
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.4
5
- prerelease:
4
+ version: 1.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Zachary Patten
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-12 00:00:00.000000000 Z
11
+ date: 2013-08-14 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: gli
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: lxc
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: ztk
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: activesupport
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: bundler
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: pry
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ! '>='
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: rake
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ! '>='
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ! '>='
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: redcarpet
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ! '>='
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ! '>='
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: aruba
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -158,7 +139,6 @@ dependencies:
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: rspec
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
143
  - - ! '>='
164
144
  - !ruby/object:Gem::Version
@@ -166,7 +146,6 @@ dependencies:
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
150
  - - ! '>='
172
151
  - !ruby/object:Gem::Version
@@ -174,7 +153,6 @@ dependencies:
174
153
  - !ruby/object:Gem::Dependency
175
154
  name: yard
176
155
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
156
  requirements:
179
157
  - - ! '>='
180
158
  - !ruby/object:Gem::Version
@@ -182,7 +160,6 @@ dependencies:
182
160
  type: :development
183
161
  prerelease: false
184
162
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
163
  requirements:
187
164
  - - ! '>='
188
165
  - !ruby/object:Gem::Version
@@ -190,7 +167,6 @@ dependencies:
190
167
  - !ruby/object:Gem::Dependency
191
168
  name: coveralls
192
169
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
170
  requirements:
195
171
  - - ! '>='
196
172
  - !ruby/object:Gem::Version
@@ -198,7 +174,6 @@ dependencies:
198
174
  type: :development
199
175
  prerelease: false
200
176
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
177
  requirements:
203
178
  - - ! '>='
204
179
  - !ruby/object:Gem::Version
@@ -328,27 +303,26 @@ files:
328
303
  homepage: http://hackers.lookout.com/testlab/
329
304
  licenses:
330
305
  - Apache 2.0
306
+ metadata: {}
331
307
  post_install_message:
332
308
  rdoc_options: []
333
309
  require_paths:
334
310
  - lib
335
311
  required_ruby_version: !ruby/object:Gem::Requirement
336
- none: false
337
312
  requirements:
338
313
  - - ! '>='
339
314
  - !ruby/object:Gem::Version
340
315
  version: '0'
341
316
  required_rubygems_version: !ruby/object:Gem::Requirement
342
- none: false
343
317
  requirements:
344
318
  - - ! '>='
345
319
  - !ruby/object:Gem::Version
346
320
  version: '0'
347
321
  requirements: []
348
322
  rubyforge_project:
349
- rubygems_version: 1.8.25
323
+ rubygems_version: 2.0.6
350
324
  signing_key:
351
- specification_version: 3
325
+ specification_version: 4
352
326
  summary: A toolkit for building virtual computer labs
353
327
  test_files:
354
328
  - features/step_definitions/container_steps.rb