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,269 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
class CommandsTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
Tenderloin::Env.stubs(:load!)
|
6
|
+
|
7
|
+
@persisted_vm = mock("persisted_vm")
|
8
|
+
@persisted_vm.stubs(:execute!)
|
9
|
+
Tenderloin::Env.stubs(:persisted_vm).returns(@persisted_vm)
|
10
|
+
Tenderloin::Env.stubs(:require_persisted_vm)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "init" do
|
14
|
+
setup do
|
15
|
+
FileUtils.stubs(:cp)
|
16
|
+
@rootfile_path = File.join(Dir.pwd, Tenderloin::Env::ROOTFILE_NAME)
|
17
|
+
@template_path = File.join(PROJECT_ROOT, "templates", Tenderloin::Env::ROOTFILE_NAME)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "error and exit if a rootfile already exists" do
|
21
|
+
File.expects(:exist?).with(@rootfile_path).returns(true)
|
22
|
+
Tenderloin::Commands.expects(:error_and_exit).once
|
23
|
+
Tenderloin::Commands.init
|
24
|
+
end
|
25
|
+
|
26
|
+
should "copy the templated rootfile to the current path" do
|
27
|
+
File.expects(:exist?).with(@rootfile_path).returns(false)
|
28
|
+
FileUtils.expects(:cp).with(@template_path, @rootfile_path).once
|
29
|
+
Tenderloin::Commands.init
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "up" do
|
34
|
+
setup do
|
35
|
+
Tenderloin::Env.stubs(:persisted_vm).returns(nil)
|
36
|
+
Tenderloin::VM.stubs(:execute!)
|
37
|
+
Tenderloin::Env.stubs(:require_box)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "require load the environment" do
|
41
|
+
Tenderloin::Env.expects(:load!).once
|
42
|
+
Tenderloin::Commands.up
|
43
|
+
end
|
44
|
+
|
45
|
+
should "require a box" do
|
46
|
+
Tenderloin::Env.expects(:require_box).once
|
47
|
+
Tenderloin::Commands.up
|
48
|
+
end
|
49
|
+
|
50
|
+
should "call the up action on VM if it doesn't exist" do
|
51
|
+
Tenderloin::VM.expects(:execute!).with(Tenderloin::Actions::VM::Up).once
|
52
|
+
Tenderloin::Commands.up
|
53
|
+
end
|
54
|
+
|
55
|
+
should "call start on the persisted vm if it exists" do
|
56
|
+
Tenderloin::Env.stubs(:persisted_vm).returns(@persisted_vm)
|
57
|
+
@persisted_vm.expects(:start).once
|
58
|
+
Tenderloin::VM.expects(:execute!).never
|
59
|
+
Tenderloin::Commands.up
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "down" do
|
64
|
+
setup do
|
65
|
+
@persisted_vm.stubs(:destroy)
|
66
|
+
end
|
67
|
+
|
68
|
+
should "require a persisted VM" do
|
69
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
70
|
+
Tenderloin::Commands.down
|
71
|
+
end
|
72
|
+
|
73
|
+
should "destroy the persisted VM and the VM image" do
|
74
|
+
@persisted_vm.expects(:destroy).once
|
75
|
+
Tenderloin::Commands.down
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "reload" do
|
80
|
+
should "require a persisted VM" do
|
81
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
82
|
+
Tenderloin::Commands.reload
|
83
|
+
end
|
84
|
+
|
85
|
+
should "call the `reload` action on the VM" do
|
86
|
+
@persisted_vm.expects(:execute!).with(Tenderloin::Actions::VM::Reload).once
|
87
|
+
Tenderloin::Commands.reload
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "ssh" do
|
92
|
+
setup do
|
93
|
+
Tenderloin::SSH.stubs(:connect)
|
94
|
+
end
|
95
|
+
|
96
|
+
should "require a persisted VM" do
|
97
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
98
|
+
Tenderloin::Commands.ssh
|
99
|
+
end
|
100
|
+
|
101
|
+
should "connect to SSH" do
|
102
|
+
Tenderloin::SSH.expects(:connect).once
|
103
|
+
Tenderloin::Commands.ssh
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "halt" do
|
108
|
+
should "require a persisted VM" do
|
109
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
110
|
+
Tenderloin::Commands.halt
|
111
|
+
end
|
112
|
+
|
113
|
+
should "call the `halt` action on the VM" do
|
114
|
+
@persisted_vm.expects(:execute!).with(Tenderloin::Actions::VM::Halt).once
|
115
|
+
Tenderloin::Commands.halt
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "suspend" do
|
120
|
+
setup do
|
121
|
+
@persisted_vm.stubs(:suspend)
|
122
|
+
@persisted_vm.stubs(:saved?).returns(false)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "require a persisted VM" do
|
126
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
127
|
+
Tenderloin::Commands.suspend
|
128
|
+
end
|
129
|
+
|
130
|
+
should "suspend the VM" do
|
131
|
+
@persisted_vm.expects(:suspend).once
|
132
|
+
Tenderloin::Commands.suspend
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "resume" do
|
137
|
+
setup do
|
138
|
+
@persisted_vm.stubs(:resume)
|
139
|
+
@persisted_vm.stubs(:saved?).returns(true)
|
140
|
+
end
|
141
|
+
|
142
|
+
should "require a persisted VM" do
|
143
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
144
|
+
Tenderloin::Commands.resume
|
145
|
+
end
|
146
|
+
|
147
|
+
should "save the state of the VM" do
|
148
|
+
@persisted_vm.expects(:resume).once
|
149
|
+
Tenderloin::Commands.resume
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "package" do
|
154
|
+
setup do
|
155
|
+
@persisted_vm.stubs(:package)
|
156
|
+
@persisted_vm.stubs(:powered_off?).returns(true)
|
157
|
+
end
|
158
|
+
|
159
|
+
should "require a persisted vm" do
|
160
|
+
Tenderloin::Env.expects(:require_persisted_vm).once
|
161
|
+
Tenderloin::Commands.package
|
162
|
+
end
|
163
|
+
|
164
|
+
should "error and exit if the VM is not powered off" do
|
165
|
+
@persisted_vm.stubs(:powered_off?).returns(false)
|
166
|
+
Tenderloin::Commands.expects(:error_and_exit).once
|
167
|
+
@persisted_vm.expects(:package).never
|
168
|
+
Tenderloin::Commands.package
|
169
|
+
end
|
170
|
+
|
171
|
+
should "call package on the persisted VM" do
|
172
|
+
@persisted_vm.expects(:package).once
|
173
|
+
Tenderloin::Commands.package
|
174
|
+
end
|
175
|
+
|
176
|
+
should "pass the out path and include_files to the package method" do
|
177
|
+
out_path = mock("out_path")
|
178
|
+
include_files = mock("include_files")
|
179
|
+
@persisted_vm.expects(:package).with(out_path, include_files).once
|
180
|
+
Tenderloin::Commands.package(out_path, include_files)
|
181
|
+
end
|
182
|
+
|
183
|
+
should "default to an empty array when not include_files are specified" do
|
184
|
+
out_path = mock("out_path")
|
185
|
+
@persisted_vm.expects(:package).with(out_path, []).once
|
186
|
+
Tenderloin::Commands.package(out_path)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "box" do
|
191
|
+
setup do
|
192
|
+
Tenderloin::Commands.stubs(:box_foo)
|
193
|
+
Tenderloin::Commands.stubs(:box_add)
|
194
|
+
Tenderloin::Commands.stubs(:box_remove)
|
195
|
+
end
|
196
|
+
|
197
|
+
should "load the environment" do
|
198
|
+
Tenderloin::Env.expects(:load!).once
|
199
|
+
Tenderloin::Commands.box(["add"])
|
200
|
+
end
|
201
|
+
|
202
|
+
should "error and exit if the first argument is not 'add' or 'remove'" do
|
203
|
+
Tenderloin::Commands.expects(:error_and_exit).once
|
204
|
+
Tenderloin::Commands.box(["foo"])
|
205
|
+
end
|
206
|
+
|
207
|
+
should "not error and exit if the first argument is 'add' or 'remove'" do
|
208
|
+
commands = ["add", "remove"]
|
209
|
+
|
210
|
+
commands.each do |command|
|
211
|
+
Tenderloin::Commands.expects(:error_and_exit).never
|
212
|
+
Tenderloin::Commands.expects("box_#{command}".to_sym).once
|
213
|
+
Tenderloin::Commands.box([command])
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
should "forward any additional arguments" do
|
218
|
+
Tenderloin::Commands.expects(:box_add).with(1,2,3).once
|
219
|
+
Tenderloin::Commands.box(["add",1,2,3])
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "box list" do
|
224
|
+
setup do
|
225
|
+
@boxes = ["foo", "bar"]
|
226
|
+
|
227
|
+
Tenderloin::Box.stubs(:all).returns(@boxes)
|
228
|
+
Tenderloin::Commands.stubs(:puts)
|
229
|
+
end
|
230
|
+
|
231
|
+
should "call all on box and sort the results" do
|
232
|
+
@all = mock("all")
|
233
|
+
@all.expects(:sort).returns(@boxes)
|
234
|
+
Tenderloin::Box.expects(:all).returns(@all)
|
235
|
+
Tenderloin::Commands.box_list
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "box add" do
|
240
|
+
setup do
|
241
|
+
@name = "foo"
|
242
|
+
@path = "bar"
|
243
|
+
end
|
244
|
+
|
245
|
+
should "execute the add action with the name and path" do
|
246
|
+
Tenderloin::Box.expects(:add).with(@name, @path).once
|
247
|
+
Tenderloin::Commands.box_add(@name, @path)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context "box remove" do
|
252
|
+
setup do
|
253
|
+
@name = "foo"
|
254
|
+
end
|
255
|
+
|
256
|
+
should "error and exit if the box doesn't exist" do
|
257
|
+
Tenderloin::Box.expects(:find).returns(nil)
|
258
|
+
Tenderloin::Commands.expects(:error_and_exit).once
|
259
|
+
Tenderloin::Commands.box_remove(@name)
|
260
|
+
end
|
261
|
+
|
262
|
+
should "call destroy on the box if it exists" do
|
263
|
+
@box = mock("box")
|
264
|
+
Tenderloin::Box.expects(:find).with(@name).returns(@box)
|
265
|
+
@box.expects(:destroy).once
|
266
|
+
Tenderloin::Commands.box_remove(@name)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
class ConfigTest < Test::Unit::TestCase
|
4
|
+
context "resetting" do
|
5
|
+
setup do
|
6
|
+
Tenderloin::Config.run { |config| }
|
7
|
+
Tenderloin::Config.execute!
|
8
|
+
end
|
9
|
+
|
10
|
+
should "return the same config object typically" do
|
11
|
+
config = Tenderloin::Config.config
|
12
|
+
assert config.equal?(Tenderloin::Config.config)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "create a new object if cleared" do
|
16
|
+
config = Tenderloin::Config.config
|
17
|
+
Tenderloin::Config.reset!
|
18
|
+
assert !config.equal?(Tenderloin::Config.config)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "empty the runners" do
|
22
|
+
assert !Tenderloin::Config.config_runners.empty?
|
23
|
+
Tenderloin::Config.reset!
|
24
|
+
assert Tenderloin::Config.config_runners.empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "accessing configuration" do
|
29
|
+
setup do
|
30
|
+
Tenderloin::Config.run { |config| }
|
31
|
+
Tenderloin::Config.execute!
|
32
|
+
end
|
33
|
+
|
34
|
+
should "forward config to the class method" do
|
35
|
+
assert_equal Tenderloin.config, Tenderloin::Config.config
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "initializing" do
|
40
|
+
teardown do
|
41
|
+
Tenderloin::Config.instance_variable_set(:@config_runners, nil)
|
42
|
+
Tenderloin::Config.instance_variable_set(:@config, nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "not run the blocks right away" do
|
46
|
+
obj = mock("obj")
|
47
|
+
obj.expects(:foo).never
|
48
|
+
Tenderloin::Config.run { |config| obj.foo }
|
49
|
+
Tenderloin::Config.run { |config| obj.foo }
|
50
|
+
Tenderloin::Config.run { |config| obj.foo }
|
51
|
+
end
|
52
|
+
|
53
|
+
should "run the blocks when execute! is ran" do
|
54
|
+
obj = mock("obj")
|
55
|
+
obj.expects(:foo).times(2)
|
56
|
+
Tenderloin::Config.run { |config| obj.foo }
|
57
|
+
Tenderloin::Config.run { |config| obj.foo }
|
58
|
+
Tenderloin::Config.execute!
|
59
|
+
end
|
60
|
+
|
61
|
+
should "run the blocks with the same config object" do
|
62
|
+
Tenderloin::Config.run { |config| assert config }
|
63
|
+
Tenderloin::Config.run { |config| assert config }
|
64
|
+
Tenderloin::Config.execute!
|
65
|
+
end
|
66
|
+
|
67
|
+
should "not be loaded, initially" do
|
68
|
+
assert !Tenderloin::Config.config.loaded?
|
69
|
+
end
|
70
|
+
|
71
|
+
should "be loaded after running" do
|
72
|
+
Tenderloin::Config.run {}
|
73
|
+
Tenderloin::Config.execute!
|
74
|
+
assert Tenderloin::Config.config.loaded?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "base class" do
|
79
|
+
setup do
|
80
|
+
@base = Tenderloin::Config::Base.new
|
81
|
+
end
|
82
|
+
|
83
|
+
should "forward [] access to methods" do
|
84
|
+
@base.expects(:foo).once
|
85
|
+
@base[:foo]
|
86
|
+
end
|
87
|
+
|
88
|
+
should "return a hash of instance variables" do
|
89
|
+
data = { :foo => "bar", :bar => "baz" }
|
90
|
+
|
91
|
+
data.each do |iv, value|
|
92
|
+
@base.instance_variable_set("@#{iv}".to_sym, value)
|
93
|
+
end
|
94
|
+
|
95
|
+
result = @base.instance_variables_hash
|
96
|
+
assert_equal data.length, result.length
|
97
|
+
|
98
|
+
data.each do |iv, value|
|
99
|
+
assert_equal value, result[iv]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
should "convert instance variable hash to json" do
|
104
|
+
@json = mock("json")
|
105
|
+
@iv_hash = mock("iv_hash")
|
106
|
+
@iv_hash.expects(:to_json).once.returns(@json)
|
107
|
+
@base.expects(:instance_variables_hash).returns(@iv_hash)
|
108
|
+
assert_equal @json, @base.to_json
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "chef config" do
|
113
|
+
setup do
|
114
|
+
@config = Tenderloin::Config::ChefConfig.new
|
115
|
+
@config.json = "HEY"
|
116
|
+
end
|
117
|
+
|
118
|
+
should "not include the 'json' key in the config dump" do
|
119
|
+
result = JSON.parse(@config.to_json)
|
120
|
+
assert !result.has_key?("json")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class BaseDownloaderTest < Test::Unit::TestCase
|
4
|
+
should "include the util class so subclasses have access to it" do
|
5
|
+
assert Tenderloin::Downloaders::Base.include?(Tenderloin::Util)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "base instance" do
|
9
|
+
setup do
|
10
|
+
@base = Tenderloin::Downloaders::Base.new
|
11
|
+
end
|
12
|
+
|
13
|
+
should "implement prepare which does nothing" do
|
14
|
+
assert_nothing_raised do
|
15
|
+
assert @base.respond_to?(:download!)
|
16
|
+
@base.download!("source", "destination")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class FileDownloaderTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@downloader, @tempfile = mock_downloader(Tenderloin::Downloaders::File)
|
6
|
+
@uri = "foo.box"
|
7
|
+
end
|
8
|
+
|
9
|
+
context "downloading" do
|
10
|
+
setup do
|
11
|
+
@file = mock("file")
|
12
|
+
@file.stubs(:read)
|
13
|
+
@file.stubs(:eof?).returns(false)
|
14
|
+
@downloader.stubs(:open).yields(@file)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "open with the given uri" do
|
18
|
+
@downloader.expects(:open).with(@uri).once
|
19
|
+
@downloader.download!(@uri, @tempfile)
|
20
|
+
end
|
21
|
+
|
22
|
+
should "buffer the read from the file and write to the tempfile" do
|
23
|
+
data = mock("data")
|
24
|
+
write_seq = sequence("write_seq")
|
25
|
+
@file.stubs(:eof?).returns(false).in_sequence(write_seq)
|
26
|
+
@file.expects(:read).returns(data).in_sequence(write_seq)
|
27
|
+
@tempfile.expects(:write).with(data).in_sequence(write_seq)
|
28
|
+
@file.stubs(:eof?).returns(true).in_sequence(write_seq)
|
29
|
+
@downloader.download!(@uri, @tempfile)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class HttpDownloaderTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@downloader, @tempfile = mock_downloader(Tenderloin::Downloaders::HTTP)
|
6
|
+
@downloader.stubs(:report_progress)
|
7
|
+
@downloader.stubs(:complete_progress)
|
8
|
+
@uri = "foo.box"
|
9
|
+
end
|
10
|
+
|
11
|
+
context "downloading" do
|
12
|
+
setup do
|
13
|
+
@parsed_uri = mock("parsed")
|
14
|
+
URI.stubs(:parse).with(@uri).returns(@parsed_uri)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "parse the URI and use that parsed URI for Net::HTTP" do
|
18
|
+
URI.expects(:parse).with(@uri).returns(@parsed_uri).once
|
19
|
+
Net::HTTP.expects(:get_response).with(@parsed_uri).once
|
20
|
+
@downloader.download!(@uri, @tempfile)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "read the body of the response and place each segment into the file" do
|
24
|
+
response = mock("response")
|
25
|
+
response.stubs(:content_length)
|
26
|
+
segment = mock("segment")
|
27
|
+
segment.stubs(:length).returns(7)
|
28
|
+
|
29
|
+
Net::HTTP.stubs(:get_response).yields(response)
|
30
|
+
response.expects(:read_body).once.yields(segment)
|
31
|
+
@tempfile.expects(:write).with(segment).once
|
32
|
+
|
33
|
+
@downloader.download!(@uri, @tempfile)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "reporting progress" do
|
38
|
+
# TODO: Testing for this, probably
|
39
|
+
end
|
40
|
+
end
|