testlab 1.4.4 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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