testlab 1.9.2 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -11,5 +11,9 @@ before_install: sudo ./spec/support/install-lxc.sh
11
11
 
12
12
  notifications:
13
13
  email:
14
- - testlab-ci@lookout.com
15
- irc: "irc.freenode.net#jovelabs"
14
+ recipients:
15
+ - testlab-ci@lookout.com
16
+ on_success: always
17
+ on_failure: always
18
+ irc:
19
+ - "irc.freenode.net#jovelabs"
data/Gemfile CHANGED
@@ -7,4 +7,8 @@ if (RUBY_VERSION < "1.9.3")
7
7
  gem "redcarpet", "< 3.0.0"
8
8
  end
9
9
 
10
+ if (RUBY_VERSION < "1.9.2")
11
+ gem "mime-types", "< 2.0"
12
+ end
13
+
10
14
  gemspec
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/testlab.png)](http://badge.fury.io/rb/testlab)
2
2
  [![Dependency Status](https://gemnasium.com/zpatten/testlab.png)](https://gemnasium.com/zpatten/testlab)
3
3
  [![Build Status](https://secure.travis-ci.org/lookout/testlab.png)](http://travis-ci.org/lookout/testlab)
4
- [![Coverage Status](https://coveralls.io/repos/zpatten/testlab/badge.png?branch=master)](https://coveralls.io/r/zpatten/testlab)
4
+ [![Coverage Status](https://coveralls.io/repos/lookout/testlab/badge.png?branch=master)](https://coveralls.io/r/lookout/testlab)
5
5
  [![Code Climate](https://codeclimate.com/github/zpatten/testlab.png)](https://codeclimate.com/github/zpatten/testlab)
6
6
 
7
7
  # A Quick Note on Versioning
@@ -10,25 +10,31 @@ I attempt to keep TestLab in line with Semantic Versioning when incrementing ver
10
10
 
11
11
  * http://semver.org/
12
12
 
13
- # TestLab
13
+ # What is TestLab?
14
14
 
15
- A toolkit for building virtual computer labs.
15
+ Simply put; a toolkit for building virtual computer labs.
16
16
 
17
- What is TestLab? TestLab lets you iterate virtual infrastructure quickly. Using a `Labfile` you can define how you want your virtual infrastructure laid out. You can define multiple network segments and containers (i.e. boxen). TestLab will then build and demolish this virtual infrastructure as you have dictated in the `Labfile`.
17
+ TestLab lets you iterate virtual infrastructure quickly. Using a `Labfile` you can define how you want your virtual infrastructure laid out. You can define multiple network segments and containers (i.e. boxen). TestLab will then build and demolish this virtual infrastructure as you have dictated in the `Labfile`.
18
+
19
+ TestLab also allows you to template objects, meaning less congestion in your `Labfile`.
18
20
 
19
21
  TestLab can also import and export containers, making it easy to share them. TestLab supports the latest LXC versions, allowing for ephemeral cloning operations, furthering your ability to iterate quickly. TestLab can be used for many other applications, including infrastructure unit and integration testing, allowing for vastly more complex configurations and more effective resource sharing than traditional VM solutions.
20
22
 
21
23
  TestLab can be run via the command-line or can be interfaced with directly via Ruby code.
22
24
 
25
+ # What is a Labfile?
26
+
27
+ A `Labfile` defines what your lab will look like using the TestLab DSL.
28
+
23
29
  # Using TestLab Interactively
24
30
 
25
- $ tl
31
+ $ tl help
26
32
  NAME
27
33
  tl - TestLab - A toolkit for building virtual computer labs
28
34
 
29
35
  TestLab is based around the abstraction of three main components: nodes, networks and containers. Nodes represent a system
30
- (bare-metal or virtualized) that hosts containers. Networks repesent a Linux bridge on a node. Containers simply represent a
31
- Linux Container (LXC) running on its parent node which is typically connected to a network on the node.
36
+ (bare-metal or virtualized) that hosts containers. Networks represent a Linux bridge on a node. Containers simply represent a Linux
37
+ Container (LXC) running on its parent node which is typically connected to a network on the node.
32
38
 
33
39
  In addition to the core component abstractions, TestLab shares a series of core tasks that are universal across all of the
34
40
  components. These are create and destroy, up and down, provision and deprovision. Several other core tasks, such as build,
@@ -36,11 +42,11 @@ TestLab can be run via the command-line or can be interfaced with directly via R
36
42
 
37
43
  You can execute almost all of the tasks against the entire lab, or individual lab components.
38
44
 
39
- When building a lab from scratch, you will typically run 'tl build'. To breakdown your lab, destroying all the components, you
40
- will typically run 'tl demolish'. If you want to re-build the lab you can run 'tl recycle' which will run the demolish task
41
- followed by the build task against all the lab components. If you want to power-cycle the entire lab you can run 'tl bounce'
42
- which will run the down task followed by the up task against all the lab components. Again these tasks can be run against the
43
- lab as a whole or individual components.
45
+ When building a lab from scratch, you will typically run 'tl build'. To breakdown your lab, destroying all the components, you will
46
+ typically run 'tl demolish'. If you want to re-build the lab you can run 'tl recycle' which will run the demolish task followed by
47
+ the build task against all the lab components. If you want to power-cycle the entire lab you can run 'tl bounce' which will run the
48
+ down task followed by the up task against all the lab components. Again these tasks can be run against the lab as a whole or
49
+ individual components.
44
50
 
45
51
  You can view the status of the entire lab using 'tl status', or view the status of individual components using 'tl node status',
46
52
  'tl network status' or 'tl container status'.
@@ -52,11 +58,11 @@ TestLab can be run via the command-line or can be interfaced with directly via R
52
58
  tl [global options] command [command options] [arguments...]
53
59
 
54
60
  VERSION
55
- 1.1.0
61
+ 1.9.2
56
62
 
57
63
  GLOBAL OPTIONS
58
64
  -l, --labfile=path/to/file - Path to Labfile: ${REPO}/Labfile (default: none)
59
- -r, --repo=path/to/directory - Path to Repository directory: ${PWD} (default: /home/zpatten/code/chef-repo)
65
+ -r, --repo=path/to/directory - Path to Repository directory: ${PWD} (default: /home/zpatten/Dropbox/code/lookout/chef-repo)
60
66
  -c, --config=path/to/directory - Path to Configuration directory: ${REPO}/.testlab-$(hostname -s) (default: none)
61
67
  --version - Display the program version
62
68
  -v, --[no-]verbose - Show verbose output
@@ -270,6 +276,10 @@ You can access all the nodes for example:
270
276
 
271
277
  For more information see the TestLab Documentation, `testlab-repo`, command-line binary and it never hurts to look at the TestLab source itself.
272
278
 
279
+ You can also check out the `tl-knife` command-line binary for another example of using TestLab in a programmatic fashion:
280
+
281
+ * https://github.com/zpatten/testlab/blob/master/bin/tl-knife
282
+
273
283
  # REQUIREMENTS
274
284
 
275
285
  * Latest VirtualBox Package
data/bin/tl CHANGED
@@ -22,7 +22,6 @@ require 'gli'
22
22
  require 'testlab'
23
23
 
24
24
  include GLI::App
25
- include TestLab::Utility::GLI
26
25
  include TestLab::Utility::Misc
27
26
 
28
27
  version TestLab::VERSION
@@ -31,7 +30,7 @@ program_desc %(TestLab - A toolkit for building virtual computer labs)
31
30
  program_long_desc <<-EOF
32
31
  TestLab is based around the abstraction of three main components: nodes,
33
32
  networks and containers. Nodes represent a system (bare-metal or virtualized)
34
- that hosts containers. Networks repesent a Linux bridge on a node. Containers
33
+ that hosts containers. Networks represent a Linux bridge on a node. Containers
35
34
  simply represent a Linux Container (LXC) running on its parent node which is
36
35
  typically connected to a network on the node.
37
36
 
@@ -67,7 +66,13 @@ default_command :help
67
66
 
68
67
  preserve_argv true
69
68
 
70
- commands_from 'commands'
69
+ require 'commands/support'
70
+ require 'commands/testlab'
71
+ require 'commands/node'
72
+ require 'commands/network'
73
+ require 'commands/container'
74
+
75
+ # commands_from 'commands'
71
76
 
72
77
  desc 'Show verbose output'
73
78
  default_value false
@@ -0,0 +1,85 @@
1
+ require 'ztk'
2
+
3
+ LAB_ACTION_ORDER = %W(build demolish recycle bounce create destroy up down provision deprovision).map(&:to_sym)
4
+
5
+ LAB_ACTIONS = {
6
+ :create => ["Initialize %s", "Attempts to create the <%= @component %>."],
7
+ :destroy => ["Terminate %s", "Attempts to destroy the <%= @component %>."],
8
+ :up => ["On-line %s", "Attempts to online the <%= @component %>."],
9
+ :down => ["Off-line %s", "Attempts to offline the <%= @component %>."],
10
+ :provision => ["Provision %s", "Attempts to provision the <%= @component %>."],
11
+ :deprovision => ["De-provision %s", "Attempts to deprovision the <%= @component %>."],
12
+ :bounce => ["Bounce %s (down->up)", <<-EOF],
13
+ Attempts to bounce the <%= @component %>. TestLab will attempt to offline, then online the <%= @component %>.
14
+
15
+ The <%= @component %> are taken through the following states:
16
+
17
+ Current -> Down -> Up
18
+ EOF
19
+ :recycle => ["Recycle %s (demolish->build)", <<-EOF],
20
+ Attempts to recycle the <%= @component %>. TestLab will attempt to demolish, then build the <%= @component %>.
21
+
22
+ The <%= @component %> are taken through the following states:
23
+
24
+ Current -> Demolish -> Build
25
+ EOF
26
+ :build => ["Build %s (create->up->provision)", <<-EOF],
27
+ Attempts to build the <%= @component %>. TestLab will attempt to create, online and provision the <%= @component %>.
28
+
29
+ The <%= @component %> are taken through the following states:
30
+
31
+ Current -> Create -> Up -> Provision
32
+ EOF
33
+ :demolish => ["Demolish %s (deprovision->down->destroy)", <<-EOF]
34
+ Attempts to demolish the <%= @component %>. TestLab will attempt to deprovision, offline and destroy the <%= @component %>.
35
+
36
+ The <%= @component %> are taken through the following states:
37
+
38
+ Current -> Deprovision -> Down -> Destroy
39
+ EOF
40
+ }
41
+
42
+ def build_lab_commands(component, klass, &block)
43
+ desc %(Manage lab #{component}s)
44
+ command component do |c|
45
+ c.desc %(Optional #{component} ID or comma separated list of #{component} IDs)
46
+ c.arg_name %(#{component}[,#{component},...])
47
+ c.flag [:n, :name]
48
+
49
+ LAB_ACTION_ORDER.each do |lab_action|
50
+ action_desc = LAB_ACTIONS[lab_action]
51
+ c.desc(action_desc.first % "#{component}s")
52
+ c.long_desc(ZTK::Template.string(action_desc.last, {:component => "#{component}s"}))
53
+
54
+ c.command lab_action do |la|
55
+ la.action do |global_options, options, args|
56
+ iterate_objects_by_name(options[:name], klass) do |object|
57
+ object.send(lab_action)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ !block.nil? and block.call(c)
64
+ end
65
+ end
66
+
67
+ def iterate_objects_by_name(name, klass, &block)
68
+ objects = Array.new
69
+ klass_name = klass.to_s.split('::').last.downcase
70
+
71
+ if name.nil?
72
+ objects = klass.all.select{ |object| (!object.template rescue true) }
73
+ else
74
+ names = name.split(',')
75
+ objects = klass.find(names).select{ |object| (!object.template rescue true) }
76
+ end
77
+
78
+ (objects.nil? || (objects.count == 0)) and raise TestLab::TestLabError, "We could not find any of the #{klass_name}s you supplied!"
79
+
80
+ objects.each do |object|
81
+ !block.nil? and block.call(object)
82
+ end
83
+
84
+ objects
85
+ end
@@ -82,7 +82,6 @@ class TestLab
82
82
  autoload :Interface, 'testlab/container/interface'
83
83
  autoload :IO, 'testlab/container/io'
84
84
  autoload :LXC, 'testlab/container/lxc'
85
- autoload :MethodMissing, 'testlab/container/method_missing'
86
85
  autoload :Provision, 'testlab/container/provision'
87
86
  autoload :SSH, 'testlab/container/ssh'
88
87
  autoload :Status, 'testlab/container/status'
@@ -95,7 +94,6 @@ class TestLab
95
94
  include TestLab::Container::Interface
96
95
  include TestLab::Container::IO
97
96
  include TestLab::Container::LXC
98
- include TestLab::Container::MethodMissing
99
97
  include TestLab::Container::Provision
100
98
  include TestLab::Container::SSH
101
99
  include TestLab::Container::Status
@@ -27,22 +27,42 @@ class TestLab
27
27
  else
28
28
  @ui.logger.debug { "Labfile Version: #{version}" }
29
29
  version_arguments = version.split
30
- @ui.logger.debug { version_arguments.inspect }
30
+ @ui.logger.debug { "version_arguments=#{version_arguments.inspect}" }
31
31
 
32
32
  if version_arguments.count == 1
33
- if (TestLab::VERSION != version_arguments.first)
34
- raise LabfileError, "This Labfile is not compatible with this version of TestLab! (#{version})"
35
- end
33
+ compare_versions(TestLab::VERSION, version_arguments.first)
36
34
  elsif version_arguments.count == 2
37
- if !TestLab::VERSION.send(version_arguments.first, version_arguments.last)
38
- raise LabfileError, "This Labfile is not compatible with this version of TestLab! (#{version})"
39
- end
35
+ compare_versions(TestLab::VERSION, version_arguments.last, version_arguments.first)
40
36
  else
41
- raise LabfileError, 'Invalid version!'
37
+ raise LabfileError, 'Invalid Labfile version attribute!'
42
38
  end
43
39
  end
44
40
  end
45
41
 
42
+ def compare_versions(version_one, version_two, comparison_operator=nil)
43
+ v1_splat = version_one.split('.')
44
+ v2_splat = version_two.split('.')
45
+
46
+ max_length = [v1_splat.map(&:length).max, v2_splat.map(&:length).max].max
47
+
48
+ v1 = v1_splat.collect{ |element| "%0#{max_length}d" % element.to_i }.join('.')
49
+ v2 = v2_splat.collect{ |element| "%0#{max_length}d" % element.to_i }.join('.')
50
+
51
+ @ui.logger.debug { "v1=#{v1.inspect}" }
52
+ @ui.logger.debug { "v2=#{v2.inspect}" }
53
+ @ui.logger.debug { "max_length=#{max_length.inspect}" }
54
+
55
+ if comparison_operator.nil?
56
+ invalid_version if v1 != v2
57
+ else
58
+ invalid_version if !v1.send(comparison_operator.to_sym, v2)
59
+ end
60
+ end
61
+
62
+ def invalid_version
63
+ raise LabfileError, "This Labfile is not compatible with this version of TestLab! (#{self.version})"
64
+ end
65
+
46
66
  def config_dir
47
67
  self.testlab.config_dir
48
68
  end
@@ -15,9 +15,11 @@ class TestLab
15
15
  @ui = (ui || TestLab.ui)
16
16
 
17
17
  @config[:apt] ||= Hash.new
18
- @config[:apt][:install] ||= Array.new
19
- @config[:apt][:remove] ||= Array.new
20
- @config[:apt][:purge] ||= Array.new
18
+ @config[:apt][:install] ||= Array.new
19
+ @config[:apt][:remove] ||= Array.new
20
+ @config[:apt][:purge] ||= Array.new
21
+ @config[:apt][:sources] ||= Array.new
22
+ @config[:apt][:multiarch] ||= true
21
23
 
22
24
  @ui.logger.debug { "config(#{@config.inspect})" }
23
25
  end
@@ -3,7 +3,20 @@ set -e
3
3
 
4
4
  export DEBIAN_FRONTEND="noninteractive"
5
5
 
6
+ <% if !@apt[:multiarch].nil? && (@apt[:multiarch] == false) -%>
7
+ rm -fv /etc/dpkg/dpkg.cfg.d/multiarch || true
8
+ <% end -%>
9
+
10
+ apt-get -y update
11
+ apt-get -y install apt-transport-https
12
+
13
+ <% if !@apt[:sources].nil? && @apt[:sources].count > 0 -%>
14
+ rm -fv /etc/apt/sources.list || true
15
+ <% @apt[:sources].flatten.compact.each do |source| -%>
16
+ echo '<%= source %>' | tee -a /etc/apt/sources.list
17
+ <% end -%>
6
18
  apt-get -y update
19
+ <% end -%>
7
20
 
8
21
  <% if !@apt[:install].nil? -%>
9
22
  <% @apt[:install].flatten.compact.each do |package| -%>
@@ -11,12 +11,10 @@ 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'
15
14
  autoload :Logger, 'testlab/utility/logger'
16
15
  autoload :Misc, 'testlab/utility/misc'
17
16
 
18
17
  extend TestLab::Utility::CIDR
19
- extend TestLab::Utility::GLI
20
18
  extend TestLab::Utility::Logger
21
19
  extend TestLab::Utility::Misc
22
20
 
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "1.9.2"
4
+ VERSION = "1.10.0"
5
5
  end
6
6
  end
@@ -23,10 +23,11 @@ describe TestLab::Container do
23
23
 
24
24
  subject {
25
25
  @logger = ZTK::Logger.new('/tmp/test.log')
26
- @ui = ZTK::UI.new(:stdout => StringIO.new, :stderr => StringIO.new, :logger => @logger)
27
- @testlab = TestLab.new(:repo_dir => REPO_DIR, :labfile_path => LABFILE_PATH, :ui => @ui)
26
+ @ui = ui_helper(:logger => @logger)
27
+ @testlab = testlab_helper(:ui => @ui)
28
28
  @testlab.boot
29
- @testlab.containers.first
29
+
30
+ TestLab::Container.first('master')
30
31
  }
31
32
 
32
33
  describe "class" do
@@ -51,44 +52,123 @@ describe TestLab::Container do
51
52
 
52
53
  describe "methods" do
53
54
 
54
- describe "#status" do
55
- it "should return a hash of status information about the container" do
56
- subject.node.stub(:dead?) { false }
57
- subject.node.stub(:state) { :running }
58
- subject.lxc.stub(:state) { :not_created }
59
- subject.lxc.stub(:memory_usage) { 0 }
60
- subject.lxc.stub(:cpu_usage) { 0 }
61
- subject.lxc_clone.stub(:exists?) { false }
55
+ { :ephemeral => true, :persistent => false }.each do |tag, mode|
56
+ context tag do
62
57
 
63
- subject.status.should be_kind_of(Hash)
64
- subject.status.should_not be_empty
65
- end
66
- end
58
+ before(:each) do
59
+ subject.node.stub(:dead?) { false }
60
+ subject.node.stub(:alive?) { true }
61
+ subject.node.stub(:state) { :running }
62
+
63
+ subject.lxc_clone.stub(:exists?) { mode }
64
+ end
65
+
66
+ describe "#status" do
67
+ it "should return a hash of status information about the container" do
68
+ subject.lxc.stub(:state) { :not_created }
69
+ subject.lxc.stub(:memory_usage) { 0 }
70
+ subject.lxc.stub(:cpu_usage) { 0 }
71
+
72
+ subject.status.should be_kind_of(Hash)
73
+ subject.status.should_not be_empty
74
+ end
75
+ end
76
+
77
+ describe "#state" do
78
+ it "should return the state of the container" do
79
+ subject.node.stub(:dead?) { false }
80
+ subject.node.stub(:alive?) { true }
81
+ subject.node.stub(:state) { :running }
82
+
83
+ subject.state.should == :not_created
84
+ end
85
+ end
86
+
87
+ describe "#ephemeral" do
88
+ it "should attempt to convert to a ephemeral container" do
89
+ subject.ephemeral
90
+ end
91
+ end
92
+
93
+ describe "#persistent" do
94
+ it "should attempt to convert to a persistent container" do
95
+ subject.persistent
96
+ end
97
+ end
98
+
99
+ # describe "#export" do
100
+ # it "should attempt to export the container" do
101
+ # case tag
102
+ # when :ephemeral
103
+ # lambda { subject.export }.should raise_error TestLab::ContainerError
104
+ # when :persistent
105
+ # subject.stub(:down) { true }
106
+ # # subject.stub(:destroy) { true }
107
+ # # subject.stub(:create) { true }
108
+ # # subject.stub(:up) { true }
109
+
110
+ # subject.lxc.config.stub(:save) { true }
111
+ # subject.lxc.stub(:state) { :running }
112
+
113
+ # subject.lxc.stub(:start) { true }
114
+ # subject.lxc.stub(:stop) { true }
115
+ # subject.lxc.stub(:create) { true }
116
+ # subject.lxc.stub(:destroy) { true }
117
+
118
+ # subject.lxc.stub(:attach) { "" }
119
+ # subject.lxc.stub(:exec) { OpenStruct.new(:exit_code => 0) }
120
+
121
+ # subject.export
122
+ # end
123
+ # end
124
+ # end
125
+
126
+ describe "#copy" do
127
+ it "should attempt to copy the container" do
128
+ case tag
129
+ when :ephemeral
130
+ lambda { subject.copy("master") }.should raise_error TestLab::ContainerError
131
+ when :persistent
132
+ subject.copy("master")
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "#up" do
138
+ it "should up the container" do
139
+ subject.lxc.config.stub(:save) { true }
140
+ subject.lxc.stub(:state) { :running }
141
+ subject.lxc.stub(:start) { true }
142
+ subject.lxc.stub(:attach) { "" }
143
+ subject.lxc.stub(:exec) { OpenStruct.new(:exit_code => 0) }
144
+
145
+ subject.node.stub(:arch) { "x86_64" }
146
+ subject.node.stub(:exec) { OpenStruct.new(:exit_code => 1) }
147
+
148
+ subject.stub(:provisioners) { Array.new }
149
+
150
+ subject.up
151
+ end
152
+ end
67
153
 
68
- describe "#state" do
69
- it "should return the state of the container" do
70
- subject.node.stub(:dead?) { false }
71
- subject.lxc.stub(:state) { :not_created }
72
- subject.lxc_clone.stub(:exists?) { false }
73
- subject.state.should == :not_created
74
154
  end
75
155
  end
76
156
 
77
157
  describe "#fqdn" do
78
158
  it "should return the FQDN for the container" do
79
- subject.fqdn.should == "server-dual-nic.default.zone"
159
+ subject.fqdn.should == "master.default.zone"
80
160
  end
81
161
  end
82
162
 
83
163
  describe "#ip" do
84
164
  it "should return the IP address of the containers primary interface" do
85
- subject.ip.should == "192.168.0.254"
165
+ subject.ip.should == "100.64.0.10"
86
166
  end
87
167
  end
88
168
 
89
169
  describe "#cidr" do
90
170
  it "should return the CIDR of the containers primary interface" do
91
- subject.cidr.should == 16
171
+ subject.cidr.should == 24
92
172
  end
93
173
  end
94
174
 
@@ -96,7 +176,7 @@ describe TestLab::Container do
96
176
  it "should return a BIND PTR record for the containers primary interface" do
97
177
  subject.ptr.should be_kind_of(String)
98
178
  subject.ptr.should_not be_empty
99
- subject.ptr.should == "254.0"
179
+ subject.ptr.should == "10"
100
180
  end
101
181
  end
102
182
 
@@ -114,6 +194,22 @@ describe TestLab::Container do
114
194
  end
115
195
  end
116
196
 
197
+ describe "#console" do
198
+ it "should attempt to open an LXC console via a node SSH console" do
199
+ subject.node.ssh.stub(:console)
200
+
201
+ subject.console
202
+ end
203
+ end
204
+
205
+ describe "#ssh_config" do
206
+ it "should return a text blob with our SSH configuration" do
207
+ subject.ssh_config.should_not be_nil
208
+ subject.ssh_config.should_not be_empty
209
+ subject.ssh_config.should be_kind_of(String)
210
+ end
211
+ end
212
+
117
213
  describe "#exists?" do
118
214
  it "should return false for a non-existant container" do
119
215
  subject.lxc.stub(:exists?) { false }
@@ -175,47 +271,60 @@ describe TestLab::Container do
175
271
  end
176
272
  end
177
273
 
178
- describe "#up" do
179
- it "should up the container" do
274
+ describe "#down" do
275
+ it "should down the container" do
180
276
  subject.node.stub(:dead?) { false }
181
277
  subject.node.stub(:alive?) { true }
182
278
  subject.node.stub(:state) { :running }
183
- subject.node.stub(:arch) { "x86_64" }
184
- subject.node.stub(:exec) { }
185
279
 
186
280
  subject.lxc.stub(:exists?) { true }
187
- subject.lxc.stub(:start) { true }
281
+ subject.lxc.stub(:stop) { true }
188
282
  subject.lxc.stub(:wait) { true }
189
- subject.lxc.stub(:state) { :running }
283
+ subject.lxc.stub(:state) { :stopped }
190
284
 
191
285
  subject.lxc_clone.stub(:exists?) { false }
192
286
 
193
- subject.stub(:exec) { }
194
- subject.stub(:configure) { }
195
287
  subject.stub(:provisioners) { Array.new }
196
288
 
197
- ZTK::TCPSocketCheck.any_instance.stub(:wait) { true }
289
+ subject.down
290
+ end
291
+ end
292
+
293
+ describe "#build" do
294
+ it "should build the container" do
295
+ subject.stub(:create) { true }
296
+ subject.stub(:up) { true }
297
+ subject.stub(:provision) { true }
198
298
 
199
- subject.up
299
+ subject.build.should == true
200
300
  end
201
301
  end
202
302
 
203
- describe "#down" do
204
- it "should down the container" do
205
- subject.node.stub(:dead?) { false }
206
- subject.node.stub(:alive?) { true }
207
- subject.node.stub(:state) { :running }
303
+ describe "#demolish" do
304
+ it "should demolish the container" do
305
+ subject.stub(:destroy) { true }
306
+ subject.stub(:down) { true }
307
+ subject.stub(:deprovision) { true }
208
308
 
209
- subject.lxc.stub(:exists?) { true }
210
- subject.lxc.stub(:stop) { true }
211
- subject.lxc.stub(:wait) { true }
212
- subject.lxc.stub(:state) { :stopped }
309
+ subject.demolish.should == true
310
+ end
311
+ end
213
312
 
214
- subject.lxc_clone.stub(:exists?) { false }
313
+ describe "#recycle" do
314
+ it "should recycle the container" do
315
+ subject.stub(:demolish) { true }
316
+ subject.stub(:build) { true }
215
317
 
216
- subject.stub(:provisioners) { Array.new }
318
+ subject.recycle.should == true
319
+ end
320
+ end
217
321
 
218
- subject.down
322
+ describe "#bounce" do
323
+ it "should bounce the container" do
324
+ subject.stub(:down) { true }
325
+ subject.stub(:up) { true }
326
+
327
+ subject.bounce.should == true
219
328
  end
220
329
  end
221
330