tenderloin 0.2.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.
Files changed (73) hide show
  1. data/LICENCE +21 -0
  2. data/README.md +50 -0
  3. data/Version +1 -0
  4. data/bin/loin +5 -0
  5. data/config/default.rb +26 -0
  6. data/lib/tenderloin/actions/base.rb +93 -0
  7. data/lib/tenderloin/actions/box/add.rb +22 -0
  8. data/lib/tenderloin/actions/box/destroy.rb +14 -0
  9. data/lib/tenderloin/actions/box/download.rb +63 -0
  10. data/lib/tenderloin/actions/box/unpackage.rb +46 -0
  11. data/lib/tenderloin/actions/runner.rb +138 -0
  12. data/lib/tenderloin/actions/vm/boot.rb +52 -0
  13. data/lib/tenderloin/actions/vm/destroy.rb +18 -0
  14. data/lib/tenderloin/actions/vm/halt.rb +14 -0
  15. data/lib/tenderloin/actions/vm/import.rb +32 -0
  16. data/lib/tenderloin/actions/vm/move_hard_drive.rb +53 -0
  17. data/lib/tenderloin/actions/vm/provision.rb +71 -0
  18. data/lib/tenderloin/actions/vm/reload.rb +17 -0
  19. data/lib/tenderloin/actions/vm/shared_folders.rb +47 -0
  20. data/lib/tenderloin/actions/vm/start.rb +17 -0
  21. data/lib/tenderloin/actions/vm/up.rb +55 -0
  22. data/lib/tenderloin/box.rb +143 -0
  23. data/lib/tenderloin/busy.rb +73 -0
  24. data/lib/tenderloin/cli.rb +59 -0
  25. data/lib/tenderloin/commands.rb +154 -0
  26. data/lib/tenderloin/config.rb +144 -0
  27. data/lib/tenderloin/downloaders/base.rb +13 -0
  28. data/lib/tenderloin/downloaders/file.rb +21 -0
  29. data/lib/tenderloin/downloaders/http.rb +47 -0
  30. data/lib/tenderloin/env.rb +156 -0
  31. data/lib/tenderloin/fusion_vm.rb +85 -0
  32. data/lib/tenderloin/ssh.rb +49 -0
  33. data/lib/tenderloin/util.rb +51 -0
  34. data/lib/tenderloin/vm.rb +63 -0
  35. data/lib/tenderloin/vmx_file.rb +28 -0
  36. data/lib/tenderloin.rb +14 -0
  37. data/script/tenderloin-ssh-expect.sh +23 -0
  38. data/templates/Tenderfile +8 -0
  39. data/test/tenderloin/actions/base_test.rb +32 -0
  40. data/test/tenderloin/actions/box/add_test.rb +37 -0
  41. data/test/tenderloin/actions/box/destroy_test.rb +18 -0
  42. data/test/tenderloin/actions/box/download_test.rb +118 -0
  43. data/test/tenderloin/actions/box/unpackage_test.rb +100 -0
  44. data/test/tenderloin/actions/runner_test.rb +262 -0
  45. data/test/tenderloin/actions/vm/boot_test.rb +55 -0
  46. data/test/tenderloin/actions/vm/destroy_test.rb +24 -0
  47. data/test/tenderloin/actions/vm/down_test.rb +32 -0
  48. data/test/tenderloin/actions/vm/export_test.rb +88 -0
  49. data/test/tenderloin/actions/vm/forward_ports_test.rb +50 -0
  50. data/test/tenderloin/actions/vm/halt_test.rb +27 -0
  51. data/test/tenderloin/actions/vm/import_test.rb +36 -0
  52. data/test/tenderloin/actions/vm/move_hard_drive_test.rb +108 -0
  53. data/test/tenderloin/actions/vm/package_test.rb +181 -0
  54. data/test/tenderloin/actions/vm/provision_test.rb +103 -0
  55. data/test/tenderloin/actions/vm/reload_test.rb +44 -0
  56. data/test/tenderloin/actions/vm/resume_test.rb +27 -0
  57. data/test/tenderloin/actions/vm/shared_folders_test.rb +117 -0
  58. data/test/tenderloin/actions/vm/start_test.rb +28 -0
  59. data/test/tenderloin/actions/vm/suspend_test.rb +27 -0
  60. data/test/tenderloin/actions/vm/up_test.rb +98 -0
  61. data/test/tenderloin/box_test.rb +139 -0
  62. data/test/tenderloin/busy_test.rb +83 -0
  63. data/test/tenderloin/commands_test.rb +269 -0
  64. data/test/tenderloin/config_test.rb +123 -0
  65. data/test/tenderloin/downloaders/base_test.rb +20 -0
  66. data/test/tenderloin/downloaders/file_test.rb +32 -0
  67. data/test/tenderloin/downloaders/http_test.rb +40 -0
  68. data/test/tenderloin/env_test.rb +345 -0
  69. data/test/tenderloin/ssh_test.rb +103 -0
  70. data/test/tenderloin/util_test.rb +64 -0
  71. data/test/tenderloin/vm_test.rb +89 -0
  72. data/test/test_helper.rb +92 -0
  73. metadata +241 -0
@@ -0,0 +1,345 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class EnvTest < Test::Unit::TestCase
4
+ def mock_persisted_vm(returnvalue="foovm")
5
+ filemock = mock("filemock")
6
+ filemock.expects(:read).returns("foo")
7
+ Tenderloin::VM.expects(:find).with("foo").returns(returnvalue)
8
+ File.expects(:open).with(Tenderloin::Env.dotfile_path).once.yields(filemock)
9
+ File.expects(:file?).with(Tenderloin::Env.dotfile_path).once.returns(true)
10
+ Tenderloin::Env.load_vm!
11
+ end
12
+
13
+ setup do
14
+ mock_config
15
+ Tenderloin::Box.stubs(:find).returns("foo")
16
+ end
17
+
18
+ context "requiring a VM" do
19
+ setup do
20
+ Tenderloin::Env.stubs(:require_root_path)
21
+ Tenderloin::Env.stubs(:error_and_exit)
22
+ end
23
+
24
+ should "require root path" do
25
+ Tenderloin::Env.expects(:require_root_path).once
26
+ Tenderloin::Env.require_persisted_vm
27
+ end
28
+
29
+ should "error and exit if no persisted VM was found" do
30
+ assert_nil Tenderloin::Env.persisted_vm
31
+ Tenderloin::Env.expects(:error_and_exit).once
32
+ Tenderloin::Env.require_persisted_vm
33
+ end
34
+
35
+ should "return and continue if persisted VM is found" do
36
+ mock_persisted_vm
37
+ Tenderloin::Env.expects(:error_and_exit).never
38
+ Tenderloin::Env.require_persisted_vm
39
+ end
40
+ end
41
+
42
+ context "loading home directory" do
43
+ setup do
44
+ @home_dir = File.expand_path(Tenderloin.config.tenderloin.home)
45
+
46
+ File.stubs(:directory?).returns(true)
47
+ FileUtils.stubs(:mkdir_p)
48
+ end
49
+
50
+ should "create each directory if it doesn't exist" do
51
+ create_seq = sequence("create_seq")
52
+ File.stubs(:directory?).returns(false)
53
+ Tenderloin::Env::HOME_SUBDIRS.each do |subdir|
54
+ FileUtils.expects(:mkdir_p).with(File.join(@home_dir, subdir)).in_sequence(create_seq)
55
+ end
56
+
57
+ Tenderloin::Env.load_home_directory!
58
+ end
59
+
60
+ should "not create directories if they exist" do
61
+ File.stubs(:directory?).returns(true)
62
+ FileUtils.expects(:mkdir_p).never
63
+ Tenderloin::Env.load_home_directory!
64
+ end
65
+ end
66
+
67
+ context "loading config" do
68
+ setup do
69
+ @root_path = "/foo"
70
+ Tenderloin::Env.stubs(:root_path).returns(@root_path)
71
+ Tenderloin::Env.stubs(:box).returns(nil)
72
+ File.stubs(:exist?).returns(false)
73
+ Tenderloin::Config.stubs(:execute!)
74
+ Tenderloin::Config.stubs(:reset!)
75
+ end
76
+
77
+ should "reset the configuration object" do
78
+ Tenderloin::Config.expects(:reset!).once
79
+ Tenderloin::Env.load_config!
80
+ end
81
+
82
+ should "load from the project root" do
83
+ File.expects(:exist?).with(File.join(PROJECT_ROOT, "config", "default.rb")).once
84
+ Tenderloin::Env.load_config!
85
+ end
86
+
87
+ should "load from the root path" do
88
+ File.expects(:exist?).with(File.join(@root_path, Tenderloin::Env::ROOTFILE_NAME)).once
89
+ Tenderloin::Env.load_config!
90
+ end
91
+
92
+ should "not load from the root path if nil" do
93
+ Tenderloin::Env.stubs(:root_path).returns(nil)
94
+ File.expects(:exist?).with(File.join(@root_path, Tenderloin::Env::ROOTFILE_NAME)).never
95
+ Tenderloin::Env.load_config!
96
+ end
97
+
98
+ should "not load from the box directory if it is nil" do
99
+ Tenderloin::Env.expects(:box).once.returns(nil)
100
+ Tenderloin::Env.load_config!
101
+ end
102
+
103
+ should "load from the box directory if it is not nil" do
104
+ dir = "foo"
105
+ box = mock("box")
106
+ box.stubs(:directory).returns(dir)
107
+ Tenderloin::Env.expects(:box).twice.returns(box)
108
+ File.expects(:exist?).with(File.join(dir, Tenderloin::Env::ROOTFILE_NAME)).once
109
+ Tenderloin::Env.load_config!
110
+ end
111
+
112
+ should "load the files only if exist? returns true" do
113
+ File.expects(:exist?).once.returns(true)
114
+ Tenderloin::Env.expects(:load).once
115
+ Tenderloin::Env.load_config!
116
+ end
117
+
118
+ should "not load the files if exist? returns false" do
119
+ Tenderloin::Env.expects(:load).never
120
+ Tenderloin::Env.load_config!
121
+ end
122
+
123
+ should "execute after loading" do
124
+ File.expects(:exist?).once.returns(true)
125
+ Tenderloin::Env.expects(:load).once
126
+ Tenderloin::Config.expects(:execute!).once
127
+ Tenderloin::Env.load_config!
128
+ end
129
+ end
130
+
131
+ context "initial load" do
132
+ test "load! should load the config and set the persisted_uid" do
133
+ Tenderloin::Env.expects(:load_config!).once
134
+ Tenderloin::Env.expects(:load_vm!).once
135
+ Tenderloin::Env.expects(:load_root_path!).once
136
+ Tenderloin::Env.expects(:load_home_directory!).once
137
+ Tenderloin::Env.expects(:load_box!).once
138
+ Tenderloin::Env.load!
139
+ end
140
+ end
141
+
142
+ context "persisting the VM into a file" do
143
+ setup do
144
+ mock_config
145
+ end
146
+
147
+ test "should save it to the dotfile path" do
148
+ vm = mock("vm")
149
+ vm.stubs(:uuid).returns("foo")
150
+
151
+ filemock = mock("filemock")
152
+ filemock.expects(:write).with(vm.uuid)
153
+ File.expects(:open).with(Tenderloin::Env.dotfile_path, 'w+').once.yields(filemock)
154
+ Tenderloin::Env.persist_vm(vm)
155
+ end
156
+ end
157
+
158
+ context "loading the UUID out from the persisted file" do
159
+ setup do
160
+ File.stubs(:file?).returns(true)
161
+ end
162
+
163
+ should "loading of the uuid from the dotfile" do
164
+ mock_persisted_vm
165
+ assert_equal 'foovm', Tenderloin::Env.persisted_vm
166
+ end
167
+
168
+ should "do nothing if the root path is nil" do
169
+ File.expects(:open).never
170
+ Tenderloin::Env.stubs(:root_path).returns(nil)
171
+ Tenderloin::Env.load_vm!
172
+ end
173
+
174
+ should "do nothing if dotfile is not a file" do
175
+ File.expects(:file?).returns(false)
176
+ File.expects(:open).never
177
+ Tenderloin::Env.load_vm!
178
+ end
179
+
180
+ should "uuid should be nil if dotfile didn't exist" do
181
+ File.expects(:open).raises(Errno::ENOENT)
182
+ Tenderloin::Env.load_vm!
183
+ assert_nil Tenderloin::Env.persisted_vm
184
+ end
185
+
186
+ should "should build up the dotfile out of the root path and the dotfile name" do
187
+ assert_equal File.join(Tenderloin::Env.root_path, Tenderloin.config.tenderloin.dotfile_name), Tenderloin::Env.dotfile_path
188
+ end
189
+ end
190
+
191
+ context "loading the root path" do
192
+ should "default the path to the pwd if nil" do
193
+ @path = mock("path")
194
+ @path.stubs(:to_s).returns("/")
195
+ Pathname.expects(:new).with(Dir.pwd).returns(@path)
196
+ Tenderloin::Env.load_root_path!(nil)
197
+ end
198
+
199
+ should "not default the path to pwd if its not nil" do
200
+ @path = mock("path")
201
+ @path.stubs(:to_s).returns("/")
202
+ Pathname.expects(:new).never
203
+ Tenderloin::Env.load_root_path!(@path)
204
+ end
205
+
206
+ should "should walk the parent directories looking for rootfile" do
207
+ paths = [
208
+ Pathname.new("/foo/bar/baz"),
209
+ Pathname.new("/foo/bar"),
210
+ Pathname.new("/foo")
211
+ ]
212
+
213
+ search_seq = sequence("search_seq")
214
+ paths.each do |path|
215
+ File.expects(:exist?).with("#{path}/#{Tenderloin::Env::ROOTFILE_NAME}").returns(false).in_sequence(search_seq)
216
+ end
217
+
218
+ assert !Tenderloin::Env.load_root_path!(paths.first)
219
+ end
220
+
221
+ should "return false if not found" do
222
+ path = Pathname.new("/")
223
+ assert !Tenderloin::Env.load_root_path!(path)
224
+ end
225
+
226
+ should "return false if not found on windows-style root" do
227
+ path = Pathname.new("C:.")
228
+ assert !Tenderloin::Env.load_root_path!(path)
229
+ end
230
+
231
+ should "should set the path for the rootfile" do
232
+ path = "/foo"
233
+ File.expects(:exist?).with("#{path}/#{Tenderloin::Env::ROOTFILE_NAME}").returns(true)
234
+
235
+ assert Tenderloin::Env.load_root_path!(Pathname.new(path))
236
+ assert_equal path, Tenderloin::Env.root_path
237
+ end
238
+ end
239
+
240
+ context "home directory paths" do
241
+ should "return the expanded config for `home_path`" do
242
+ assert_equal File.expand_path(Tenderloin.config.tenderloin.home), Tenderloin::Env.home_path
243
+ end
244
+
245
+ should "return the home_path joined with tmp for a tmp path" do
246
+ @home_path = "foo"
247
+ Tenderloin::Env.stubs(:home_path).returns(@home_path)
248
+ assert_equal File.join(@home_path, "tmp"), Tenderloin::Env.tmp_path
249
+ end
250
+
251
+ should "return the boxes path" do
252
+ @home_path = "foo"
253
+ Tenderloin::Env.stubs(:home_path).returns(@home_path)
254
+ assert_equal File.join(@home_path, "boxes"), Tenderloin::Env.boxes_path
255
+ end
256
+ end
257
+
258
+ context "loading box" do
259
+ setup do
260
+ @box = mock("box")
261
+
262
+ Tenderloin::Env.stubs(:load_config!)
263
+ Tenderloin::Env.stubs(:root_path).returns("foo")
264
+ end
265
+
266
+ should "do nothing if the root path is nil" do
267
+ Tenderloin::Box.expects(:find).never
268
+ Tenderloin::Env.stubs(:root_path).returns(nil)
269
+ Tenderloin::Env.load_vm!
270
+ end
271
+
272
+ should "not load the box if its not set" do
273
+ mock_config do |config|
274
+ config.vm.box = nil
275
+ end
276
+
277
+ Tenderloin::Box.expects(:find).never
278
+ Tenderloin::Env.load_box!
279
+ end
280
+
281
+ should "set the box to what is found by the Box class" do
282
+ Tenderloin::Box.expects(:find).with(Tenderloin.config.vm.box).once.returns(@box)
283
+ Tenderloin::Env.load_box!
284
+ assert @box.equal?(Tenderloin::Env.box)
285
+ end
286
+
287
+ should "load the config if a box is loaded" do
288
+ Tenderloin::Env.expects(:load_config!).once
289
+ Tenderloin::Box.expects(:find).returns(@box)
290
+ Tenderloin::Env.load_box!
291
+ end
292
+ end
293
+
294
+ context "requiring boxes" do
295
+ setup do
296
+ Tenderloin::Env.stubs(:require_root_path)
297
+ Tenderloin::Env.stubs(:error_and_exit)
298
+ end
299
+
300
+ should "require root path" do
301
+ Tenderloin::Env.expects(:require_root_path).once
302
+ Tenderloin::Env.require_box
303
+ end
304
+
305
+ should "error and exit if no box is found" do
306
+ mock_config do |config|
307
+ config.vm.box = nil
308
+ end
309
+
310
+ Tenderloin::Env.expects(:box).returns(nil)
311
+ Tenderloin::Env.expects(:error_and_exit).once.with() do |msg|
312
+ assert msg =~ /no base box was specified/i
313
+ true
314
+ end
315
+ Tenderloin::Env.require_box
316
+ end
317
+
318
+ should "error and exit if box is specified but doesn't exist" do
319
+ mock_config do |config|
320
+ config.vm.box = "foo"
321
+ end
322
+
323
+ Tenderloin::Env.expects(:box).returns(nil)
324
+ Tenderloin::Env.expects(:error_and_exit).once.with() do |msg|
325
+ assert msg =~ /does not exist/i
326
+ true
327
+ end
328
+ Tenderloin::Env.require_box
329
+ end
330
+ end
331
+
332
+ context "requiring root_path" do
333
+ should "error and exit if no root_path is set" do
334
+ Tenderloin::Env.expects(:root_path).returns(nil)
335
+ Tenderloin::Env.expects(:error_and_exit).once
336
+ Tenderloin::Env.require_root_path
337
+ end
338
+
339
+ should "not error and exit if root_path is set" do
340
+ Tenderloin::Env.expects(:root_path).returns("foo")
341
+ Tenderloin::Env.expects(:error_and_exit).never
342
+ Tenderloin::Env.require_root_path
343
+ end
344
+ end
345
+ end
@@ -0,0 +1,103 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class SshTest < Test::Unit::TestCase
4
+ setup do
5
+ mock_config
6
+ end
7
+
8
+ context "connecting to SSH" do
9
+ setup do
10
+ @script = Tenderloin::SSH::SCRIPT
11
+ end
12
+
13
+ test "should call exec with defaults when no options are supplied" do
14
+ ssh = Tenderloin.config.ssh
15
+ Kernel.expects(:exec).with("#{@script} #{ssh[:username]} #{ssh[:password]} #{ssh[:host]} #{Tenderloin::SSH.port}")
16
+ Tenderloin::SSH.connect
17
+ end
18
+
19
+ test "should call exec with supplied params" do
20
+ args = {:username => 'bar', :password => 'baz', :host => 'bak', :port => 'bag'}
21
+ Kernel.expects(:exec).with("#{@script} #{args[:username]} #{args[:password]} #{args[:host]} #{args[:port]}")
22
+ Tenderloin::SSH.connect(args)
23
+ end
24
+ end
25
+
26
+ context "executing ssh commands" do
27
+ should "call net::ssh.start with the proper names" do
28
+ Net::SSH.expects(:start).once.with() do |host, username, opts|
29
+ assert_equal Tenderloin.config.ssh.host, host
30
+ assert_equal Tenderloin.config.ssh.username, username
31
+ assert_equal Tenderloin::SSH.port, opts[:port]
32
+ assert_equal Tenderloin.config.ssh.password, opts[:password]
33
+ true
34
+ end
35
+ Tenderloin::SSH.execute
36
+ end
37
+
38
+ should "use custom host if set" do
39
+ Tenderloin.config.ssh.host = "foo"
40
+ Net::SSH.expects(:start).with(Tenderloin.config.ssh.host, Tenderloin.config.ssh.username, anything).once
41
+ Tenderloin::SSH.execute
42
+ end
43
+ end
44
+
45
+ context "SCPing files to the remote host" do
46
+ should "use Tenderloin::SSH execute to setup an SCP connection and upload" do
47
+ scp = mock("scp")
48
+ ssh = mock("ssh")
49
+ scp.expects(:upload!).with("foo", "bar").once
50
+ Net::SCP.expects(:new).with(ssh).returns(scp).once
51
+ Tenderloin::SSH.expects(:execute).yields(ssh).once
52
+ Tenderloin::SSH.upload!("foo", "bar")
53
+ end
54
+ end
55
+
56
+ context "checking if host is up" do
57
+ setup do
58
+ mock_config
59
+ end
60
+
61
+ should "return true if SSH connection works" do
62
+ Net::SSH.expects(:start).yields("success")
63
+ assert Tenderloin::SSH.up?
64
+ end
65
+
66
+ should "return false if SSH connection times out" do
67
+ Net::SSH.expects(:start)
68
+ assert !Tenderloin::SSH.up?
69
+ end
70
+
71
+ should "allow the thread the configured timeout time" do
72
+ @thread = mock("thread")
73
+ @thread.stubs(:[])
74
+ Thread.expects(:new).returns(@thread)
75
+ @thread.expects(:join).with(Tenderloin.config.ssh.timeout).once
76
+ Tenderloin::SSH.up?
77
+ end
78
+
79
+ should "return false if the connection is refused" do
80
+ Net::SSH.expects(:start).raises(Errno::ECONNREFUSED)
81
+ assert_nothing_raised {
82
+ assert !Tenderloin::SSH.up?
83
+ }
84
+ end
85
+
86
+ should "return false if the connection is dropped" do
87
+ Net::SSH.expects(:start).raises(Net::SSH::Disconnect)
88
+ assert_nothing_raised {
89
+ assert !Tenderloin::SSH.up?
90
+ }
91
+ end
92
+ end
93
+
94
+ context "getting the ssh port" do
95
+ should "return the configured port by default" do
96
+ assert_equal Tenderloin.config.vm.forwarded_ports[Tenderloin.config.ssh.forwarded_port_key][:hostport], Tenderloin::SSH.port
97
+ end
98
+
99
+ should "return the port given in options if it exists" do
100
+ assert_equal "47", Tenderloin::SSH.port({ :port => "47" })
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class UtilTest < Test::Unit::TestCase
4
+ class RegUtil
5
+ extend Tenderloin::Util
6
+ end
7
+
8
+ context "erroring" do
9
+ # TODO: Any way to stub Kernel.exit? Can't test nicely
10
+ # otherwise
11
+ end
12
+
13
+ context "logger" do
14
+ class OtherUtil
15
+ extend Tenderloin::Util
16
+ end
17
+
18
+ setup do
19
+ @config = Tenderloin::Config::Top.new
20
+ @config.stubs(:loaded?).returns(true)
21
+ @config.tenderloin.log_output = STDOUT
22
+ Tenderloin::Config.stubs(:config).returns(@config)
23
+ Tenderloin::Logger.reset_logger!
24
+ end
25
+
26
+ teardown do
27
+ Tenderloin::Logger.reset_logger!
28
+ end
29
+
30
+ should "return a logger to nil if config is not loaded" do
31
+ @config.expects(:loaded?).returns(false)
32
+ logger = RegUtil.logger
33
+ assert_nil logger.instance_variable_get(:@logdev)
34
+ end
35
+
36
+ should "return a logger using the configured output" do
37
+ logger = RegUtil.logger
38
+ logdev = logger.instance_variable_get(:@logdev)
39
+ assert logger
40
+ assert !logdev.nil?
41
+ assert_equal STDOUT, logdev.dev
42
+ end
43
+
44
+ should "only instantiate a logger once" do
45
+ Tenderloin::Logger.expects(:new).once.returns("GOOD")
46
+ RegUtil.logger
47
+ RegUtil.logger
48
+ end
49
+
50
+ should "be able to reset the logger" do
51
+ Tenderloin::Logger.expects(:new).twice
52
+ RegUtil.logger
53
+ Tenderloin::Logger.reset_logger!
54
+ RegUtil.logger
55
+ end
56
+
57
+ should "return the same logger across classes" do
58
+ logger = RegUtil.logger
59
+ other = OtherUtil.logger
60
+
61
+ assert logger.equal?(other)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,89 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class VMTest < Test::Unit::TestCase
4
+ setup do
5
+ @mock_vm = mock("vm")
6
+ mock_config
7
+
8
+ @persisted_vm = mock("persisted_vm")
9
+ Tenderloin::Env.stubs(:persisted_vm).returns(@persisted_vm)
10
+
11
+ Net::SSH.stubs(:start)
12
+ end
13
+
14
+ context "being an action runner" do
15
+ should "be an action runner" do
16
+ vm = Tenderloin::VM.new
17
+ assert vm.is_a?(Tenderloin::Actions::Runner)
18
+ end
19
+ end
20
+
21
+ context "finding a VM" do
22
+ should "return nil if the VM is not found" do
23
+ VirtualBox::VM.expects(:find).returns(nil)
24
+ assert_nil Tenderloin::VM.find("foo")
25
+ end
26
+
27
+ should "return a Tenderloin::VM object for that VM otherwise" do
28
+ VirtualBox::VM.expects(:find).with("foo").returns("bar")
29
+ result = Tenderloin::VM.find("foo")
30
+ assert result.is_a?(Tenderloin::VM)
31
+ assert_equal "bar", result.vm
32
+ end
33
+ end
34
+
35
+ context "tenderloin VM instance" do
36
+ setup do
37
+ @vm = Tenderloin::VM.new(@mock_vm)
38
+ end
39
+
40
+ context "packaging" do
41
+ should "queue up the actions and execute" do
42
+ out_path = mock("out_path")
43
+ action_seq = sequence("actions")
44
+ @vm.expects(:add_action).with(Tenderloin::Actions::VM::Export).once.in_sequence(action_seq)
45
+ @vm.expects(:add_action).with(Tenderloin::Actions::VM::Package, out_path, []).once.in_sequence(action_seq)
46
+ @vm.expects(:execute!).in_sequence(action_seq)
47
+ @vm.package(out_path)
48
+ end
49
+ end
50
+
51
+ context "destroying" do
52
+ should "execute the down action" do
53
+ @vm.expects(:execute!).with(Tenderloin::Actions::VM::Down).once
54
+ @vm.destroy
55
+ end
56
+ end
57
+
58
+ context "suspending" do
59
+ should "execute the suspend action" do
60
+ @vm.expects(:execute!).with(Tenderloin::Actions::VM::Suspend).once
61
+ @vm.suspend
62
+ end
63
+ end
64
+
65
+ context "resuming" do
66
+ should "execute the resume action" do
67
+ @vm.expects(:execute!).with(Tenderloin::Actions::VM::Resume).once
68
+ @vm.resume
69
+ end
70
+ end
71
+
72
+ context "starting" do
73
+ setup do
74
+ @mock_vm.stubs(:running?).returns(false)
75
+ end
76
+
77
+ should "not do anything if the VM is already running" do
78
+ @mock_vm.stubs(:running?).returns(true)
79
+ @vm.expects(:execute!).never
80
+ @vm.start
81
+ end
82
+
83
+ should "execute the start action" do
84
+ @vm.expects(:execute!).once.with(Tenderloin::Actions::VM::Start)
85
+ @vm.start
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,92 @@
1
+ begin
2
+ require File.expand_path('../.bundle/environment', __FILE__)
3
+ rescue LoadError
4
+ # Fallback on doing the resolve at runtime.
5
+ require "rubygems"
6
+ require "bundler"
7
+ Bundler.setup
8
+ end
9
+
10
+ # ruby-debug, not necessary, but useful if we have it
11
+ begin
12
+ require 'ruby-debug'
13
+ rescue LoadError; end
14
+
15
+
16
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'tenderloin')
17
+ require 'contest'
18
+ require 'mocha'
19
+
20
+ class Test::Unit::TestCase
21
+ # Clears the previous config and sets up the new config
22
+ def mock_config
23
+ Tenderloin::Config.instance_variable_set(:@config_runners, nil)
24
+ Tenderloin::Config.instance_variable_set(:@config, nil)
25
+
26
+ Tenderloin::Config.run do |config|
27
+ config.tenderloin.dotfile_name = ".hobo"
28
+
29
+ config.ssh.username = "foo"
30
+ config.ssh.password = "bar"
31
+ config.ssh.host = "baz"
32
+ config.ssh.forwarded_port_key = "ssh"
33
+ config.ssh.max_tries = 10
34
+ config.ssh.timeout = 10
35
+
36
+ config.vm.box = "foo"
37
+ config.vm.box_ovf = "box.ovf"
38
+ config.vm.base_mac = "42"
39
+ config.vm.project_directory = "/hobo"
40
+ config.vm.disk_image_format = 'VMDK'
41
+ config.vm.forward_port("ssh", 22, 2222)
42
+
43
+ config.package.name = 'tenderloin'
44
+ config.package.extension = '.box'
45
+
46
+ config.chef.cookbooks_path = "cookbooks"
47
+ config.chef.provisioning_path = "/tmp/hobo-chef"
48
+ config.chef.json = {
49
+ :recipes => ["hobo_main"]
50
+ }
51
+
52
+ config.tenderloin.home = '~/.home'
53
+ end
54
+
55
+ if block_given?
56
+ Tenderloin::Config.run do |config|
57
+ yield config
58
+ end
59
+ end
60
+
61
+ if block_given?
62
+ Tenderloin::Config.run do |config|
63
+ yield config
64
+ end
65
+ end
66
+
67
+ Tenderloin::Config.execute!
68
+ end
69
+
70
+ # Sets up the mocks and instantiates an action for testing
71
+ def mock_action(action_klass, *args)
72
+ vm = mock("vboxvm")
73
+ mock_vm = mock("vm")
74
+ action = action_klass.new(mock_vm, *args)
75
+
76
+ mock_vm.stubs(:vm).returns(vm)
77
+ mock_vm.stubs(:vm=)
78
+ mock_vm.stubs(:invoke_callback)
79
+ mock_vm.stubs(:invoke_around_callback).yields
80
+ mock_vm.stubs(:actions).returns([action])
81
+
82
+ [mock_vm, vm, action]
83
+ end
84
+
85
+ # Sets up the mocks and stubs for a downloader
86
+ def mock_downloader(downloader_klass)
87
+ tempfile = mock("tempfile")
88
+ tempfile.stubs(:write)
89
+
90
+ [downloader_klass.new, tempfile]
91
+ end
92
+ end