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.
- data/LICENCE +21 -0
- data/README.md +50 -0
- data/Version +1 -0
- data/bin/loin +5 -0
- data/config/default.rb +26 -0
- data/lib/tenderloin/actions/base.rb +93 -0
- data/lib/tenderloin/actions/box/add.rb +22 -0
- data/lib/tenderloin/actions/box/destroy.rb +14 -0
- data/lib/tenderloin/actions/box/download.rb +63 -0
- data/lib/tenderloin/actions/box/unpackage.rb +46 -0
- data/lib/tenderloin/actions/runner.rb +138 -0
- data/lib/tenderloin/actions/vm/boot.rb +52 -0
- data/lib/tenderloin/actions/vm/destroy.rb +18 -0
- data/lib/tenderloin/actions/vm/halt.rb +14 -0
- data/lib/tenderloin/actions/vm/import.rb +32 -0
- data/lib/tenderloin/actions/vm/move_hard_drive.rb +53 -0
- data/lib/tenderloin/actions/vm/provision.rb +71 -0
- data/lib/tenderloin/actions/vm/reload.rb +17 -0
- data/lib/tenderloin/actions/vm/shared_folders.rb +47 -0
- data/lib/tenderloin/actions/vm/start.rb +17 -0
- data/lib/tenderloin/actions/vm/up.rb +55 -0
- data/lib/tenderloin/box.rb +143 -0
- data/lib/tenderloin/busy.rb +73 -0
- data/lib/tenderloin/cli.rb +59 -0
- data/lib/tenderloin/commands.rb +154 -0
- data/lib/tenderloin/config.rb +144 -0
- data/lib/tenderloin/downloaders/base.rb +13 -0
- data/lib/tenderloin/downloaders/file.rb +21 -0
- data/lib/tenderloin/downloaders/http.rb +47 -0
- data/lib/tenderloin/env.rb +156 -0
- data/lib/tenderloin/fusion_vm.rb +85 -0
- data/lib/tenderloin/ssh.rb +49 -0
- data/lib/tenderloin/util.rb +51 -0
- data/lib/tenderloin/vm.rb +63 -0
- data/lib/tenderloin/vmx_file.rb +28 -0
- data/lib/tenderloin.rb +14 -0
- data/script/tenderloin-ssh-expect.sh +23 -0
- data/templates/Tenderfile +8 -0
- data/test/tenderloin/actions/base_test.rb +32 -0
- data/test/tenderloin/actions/box/add_test.rb +37 -0
- data/test/tenderloin/actions/box/destroy_test.rb +18 -0
- data/test/tenderloin/actions/box/download_test.rb +118 -0
- data/test/tenderloin/actions/box/unpackage_test.rb +100 -0
- data/test/tenderloin/actions/runner_test.rb +262 -0
- data/test/tenderloin/actions/vm/boot_test.rb +55 -0
- data/test/tenderloin/actions/vm/destroy_test.rb +24 -0
- data/test/tenderloin/actions/vm/down_test.rb +32 -0
- data/test/tenderloin/actions/vm/export_test.rb +88 -0
- data/test/tenderloin/actions/vm/forward_ports_test.rb +50 -0
- data/test/tenderloin/actions/vm/halt_test.rb +27 -0
- data/test/tenderloin/actions/vm/import_test.rb +36 -0
- data/test/tenderloin/actions/vm/move_hard_drive_test.rb +108 -0
- data/test/tenderloin/actions/vm/package_test.rb +181 -0
- data/test/tenderloin/actions/vm/provision_test.rb +103 -0
- data/test/tenderloin/actions/vm/reload_test.rb +44 -0
- data/test/tenderloin/actions/vm/resume_test.rb +27 -0
- data/test/tenderloin/actions/vm/shared_folders_test.rb +117 -0
- data/test/tenderloin/actions/vm/start_test.rb +28 -0
- data/test/tenderloin/actions/vm/suspend_test.rb +27 -0
- data/test/tenderloin/actions/vm/up_test.rb +98 -0
- data/test/tenderloin/box_test.rb +139 -0
- data/test/tenderloin/busy_test.rb +83 -0
- data/test/tenderloin/commands_test.rb +269 -0
- data/test/tenderloin/config_test.rb +123 -0
- data/test/tenderloin/downloaders/base_test.rb +20 -0
- data/test/tenderloin/downloaders/file_test.rb +32 -0
- data/test/tenderloin/downloaders/http_test.rb +40 -0
- data/test/tenderloin/env_test.rb +345 -0
- data/test/tenderloin/ssh_test.rb +103 -0
- data/test/tenderloin/util_test.rb +64 -0
- data/test/tenderloin/vm_test.rb +89 -0
- data/test/test_helper.rb +92 -0
- 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
|
data/test/test_helper.rb
ADDED
@@ -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
|