docker-api 1.28.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,89 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Docker::Event do
4
- describe "#to_s" do
5
- subject { described_class.new(status, id, from, time) }
6
-
7
- let(:status) { "start" }
8
- let(:id) { "398c9f77b5d2" }
9
- let(:from) { "debian:wheezy" }
10
- let(:time) { 1381956164 }
11
-
12
- let(:expected_string) {
13
- "Docker::Event { :status => #{status}, :id => #{id}, "\
14
- ":from => #{from}, :time => #{time.to_s} }"
15
- }
16
-
17
- it "equals the expected string" do
18
- expect(subject.to_s).to eq(expected_string)
19
- end
20
- end
21
-
22
- describe ".stream" do
23
- let(:container) { Docker::Image.create('fromImage' => 'debian:wheezy').run('bash') }
24
- it 'receives at least 4 events' do
25
- expect(Docker::Event)
26
- .to receive(:new_event)
27
- .at_least(4).times
28
- .and_call_original
29
-
30
- stream_thread = Thread.new do
31
- Docker::Event.stream do |event|
32
- puts "#{event}"
33
- end
34
- end
35
-
36
- stream_thread.join(0.1)
37
- container.wait
38
- stream_thread.join(10)
39
- stream_thread.kill
40
-
41
- container.remove
42
- end
43
- end
44
-
45
- describe ".since" do
46
- let(:time) { Time.now.to_i + 1 }
47
- let(:container) { Docker::Image.create('fromImage' => 'debian:wheezy').run('bash') }
48
-
49
- it 'receives at least 4 events' do
50
- expect(Docker::Event)
51
- .to receive(:new_event)
52
- .at_least(4).times
53
- .and_call_original
54
-
55
- stream_thread = Thread.new do
56
- Docker::Event.since(time) do |event|
57
- puts "#{event}"
58
- end
59
- end
60
-
61
- stream_thread.join(0.1)
62
- container.wait
63
- stream_thread.join(10)
64
- stream_thread.kill
65
-
66
- container.remove
67
- end
68
- end
69
-
70
- describe ".new_event" do
71
- subject { Docker::Event.new_event(response_body, nil, nil) }
72
- let(:status) { "start" }
73
- let(:id) { "398c9f77b5d2" }
74
- let(:from) { "debian:wheezy" }
75
- let(:time) { 1381956164 }
76
- let(:response_body) {
77
- "{\"status\":\"#{status}\",\"id\":\"#{id}\""\
78
- ",\"from\":\"#{from}\",\"time\":#{time}}"
79
- }
80
-
81
- it "returns a Docker::Event" do
82
- expect(subject).to be_kind_of(Docker::Event)
83
- expect(subject.status).to eq(status)
84
- expect(subject.id).to eq(id)
85
- expect(subject.from).to eq(from)
86
- expect(subject.time).to eq(time)
87
- end
88
- end
89
- end
@@ -1,181 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Docker::Exec do
4
- let(:container) {
5
- Docker::Container.create(
6
- 'Cmd' => %w(sleep 300),
7
- 'Image' => 'debian:wheezy'
8
- ).start!
9
- }
10
-
11
- describe '#to_s' do
12
- subject {
13
- described_class.send(:new, Docker.connection, 'id' => rand(10000).to_s)
14
- }
15
-
16
- let(:id) { 'bf119e2' }
17
- let(:connection) { Docker.connection }
18
- let(:expected_string) {
19
- "Docker::Exec { :id => #{id}, :connection => #{connection} }"
20
- }
21
- before do
22
- {
23
- :@id => id,
24
- :@connection => connection
25
- }.each { |k, v| subject.instance_variable_set(k, v) }
26
- end
27
-
28
- its(:to_s) { should == expected_string }
29
- end
30
-
31
- describe '.create' do
32
- subject { described_class }
33
-
34
- context 'when the HTTP request returns a 201' do
35
- let(:options) do
36
- {
37
- 'AttachStdin' => false,
38
- 'AttachStdout' => false,
39
- 'AttachStderr' => false,
40
- 'Tty' => false,
41
- 'Cmd' => [
42
- 'date'
43
- ],
44
- 'Container' => container.id
45
- }
46
- end
47
- let(:process) { subject.create(options) }
48
- after { container.kill!.remove }
49
-
50
- it 'sets the id' do
51
- expect(process).to be_a Docker::Exec
52
- expect(process.id).to_not be_nil
53
- expect(process.connection).to_not be_nil
54
- end
55
- end
56
-
57
- context 'when the parent container does not exist' do
58
- before do
59
- Docker.options = { :mock => true }
60
- Excon.stub({ :method => :post }, { :status => 404 })
61
- end
62
- after do
63
- Excon.stubs.shift
64
- Docker.options = {}
65
- end
66
-
67
- it 'raises an error' do
68
- expect { subject.create }.to raise_error(Docker::Error::NotFoundError)
69
- end
70
- end
71
- end
72
-
73
- describe '#json' do
74
- subject {
75
- described_class.create(
76
- 'Container' => container.id,
77
- 'Detach' => true,
78
- 'Cmd' => %w[true]
79
- )
80
- }
81
-
82
- let(:description) { subject.json }
83
- before { subject.start! }
84
- after { container.kill!.remove }
85
-
86
- it 'returns the description as a Hash' do
87
- expect(description).to be_a Hash
88
- expect(description['ID']).to start_with(subject.id)
89
- end
90
- end
91
-
92
- describe '#start!' do
93
- context 'when the exec instance does not exist' do
94
- subject do
95
- described_class.send(:new, Docker.connection, 'id' => rand(10000).to_s)
96
- end
97
-
98
- it 'raises an error' do
99
- expect { subject.start! }.to raise_error(Docker::Error::NotFoundError)
100
- end
101
- end
102
-
103
- context 'when :detach is set to false' do
104
- subject {
105
- described_class.create(
106
- 'Container' => container.id,
107
- 'AttachStdout' => true,
108
- 'Cmd' => ['bash','-c','sleep 2; echo hello']
109
- )
110
- }
111
- after { container.kill!.remove }
112
-
113
- it 'returns the stdout and stderr messages' do
114
- expect(subject.start!).to eq([["hello\n"],[],0])
115
- end
116
-
117
- context 'block is passed' do
118
- it 'attaches to the stream' do
119
- chunk = nil
120
- result = subject.start! do |stream, c|
121
- chunk ||= c
122
- end
123
- expect(chunk).to eq("hello\n")
124
- expect(result).to eq([["hello\n"], [], 0])
125
- end
126
- end
127
- end
128
-
129
- context 'when :detach is set to true' do
130
- subject {
131
- described_class.create('Container' => container.id, 'Cmd' => %w[date])
132
- }
133
- after { container.kill!.remove }
134
-
135
- it 'returns empty stdout/stderr messages with exitcode' do
136
- expect(subject.start!(:detach => true).length).to eq(3)
137
- end
138
- end
139
-
140
- context 'when :wait set long time value' do
141
- subject {
142
- described_class.create(
143
- 'Container' => container.id,
144
- 'AttachStdout' => true,
145
- 'Cmd' => %w[true]
146
- )
147
- }
148
- after { container.kill!.remove }
149
-
150
- it 'returns empty stdout and stderr messages with exitcode' do
151
- expect(subject.start!(:wait => 100)).to eq([[], [], 0])
152
- end
153
- end
154
-
155
- context 'when :wait set short time value' do
156
- subject {
157
- described_class.create(
158
- 'Container' => container.id,
159
- 'AttachStdout' => true,
160
- 'Cmd' => ['bash', '-c', 'sleep 2; echo hello']
161
- )
162
- }
163
- after { container.kill!.remove }
164
-
165
- it 'raises an error' do
166
- expect { subject.start!(:wait => 1) }.to raise_error(Docker::Error::TimeoutError)
167
- end
168
- end
169
-
170
- context 'when the HTTP request returns a 201' do
171
- subject {
172
- described_class.create('Container' => container.id, 'Cmd' => ['date'])
173
- }
174
- after { container.kill!.remove }
175
-
176
- it 'starts the exec instance' do
177
- expect { subject.start! }.not_to raise_error
178
- end
179
- end
180
- end
181
- end
@@ -1,695 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Docker::Image do
4
- describe '#to_s' do
5
- subject { described_class.new(Docker.connection, info) }
6
-
7
- let(:id) { 'bf119e2' }
8
- let(:connection) { Docker.connection }
9
-
10
- let(:info) do
11
- {"id" => "bf119e2", "Repository" => "debian", "Tag" => "wheezy",
12
- "Created" => 1364102658, "Size" => 24653, "VirtualSize" => 180116135}
13
- end
14
-
15
- let(:expected_string) do
16
- "Docker::Image { :id => #{id}, :info => #{info.inspect}, "\
17
- ":connection => #{connection} }"
18
- end
19
-
20
- its(:to_s) { should == expected_string }
21
- end
22
-
23
- describe '#remove' do
24
-
25
- context 'when no name is given' do
26
- let(:id) { subject.id }
27
- subject { described_class.create('fromImage' => 'busybox:latest') }
28
- after { described_class.create('fromImage' => 'busybox:latest') }
29
-
30
- it 'removes the Image' do
31
- subject.remove(:force => true)
32
- expect(Docker::Image.all.map(&:id)).to_not include(id)
33
- end
34
- end
35
-
36
- context 'when a valid tag is given' do
37
- it 'untags the Image'
38
- end
39
-
40
- context 'when an invalid tag is given' do
41
- it 'raises an error'
42
- end
43
- end
44
-
45
- describe '#insert_local' do
46
- include_context "local paths"
47
-
48
- subject { described_class.create('fromImage' => 'debian:wheezy') }
49
-
50
- let(:rm) { false }
51
- let(:new_image) {
52
- opts = {'localPath' => file, 'outputPath' => '/'}
53
- opts[:rm] = true if rm
54
- subject.insert_local(opts)
55
- }
56
-
57
- context 'when the local file does not exist' do
58
- let(:file) { '/lol/not/a/file' }
59
-
60
- it 'raises an error' do
61
- expect { new_image }.to raise_error(Docker::Error::ArgumentError)
62
- end
63
- end
64
-
65
- context 'when the local file does exist' do
66
- let(:file) { File.join(project_dir, 'Gemfile') }
67
- let(:gemfile) { File.read('Gemfile') }
68
- let(:container) { new_image.run('cat /Gemfile').tap(&:wait) }
69
- after do
70
- container.remove
71
- new_image.remove
72
- end
73
-
74
- it 'creates a new Image that has that file' do
75
- output = container.streaming_logs(stdout: true)
76
- expect(output).to eq(gemfile)
77
- end
78
- end
79
-
80
- context 'when a direcory is passed' do
81
- let(:new_image) {
82
- subject.insert_local(
83
- 'localPath' => File.join(project_dir, 'lib'),
84
- 'outputPath' => '/lib'
85
- )
86
- }
87
- let(:container) { new_image.run('ls -a /lib/docker') }
88
- let(:response) { container.tap(&:wait).streaming_logs(stdout: true) }
89
- after do
90
- container.tap(&:wait).remove
91
- new_image.remove
92
- end
93
-
94
- it 'inserts the directory' do
95
- expect(response.split("\n").sort).to eq(Dir.entries('lib/docker').sort)
96
- end
97
- end
98
-
99
- context 'when there are multiple files passed' do
100
- let(:file) {
101
- [File.join(project_dir, 'Gemfile'), File.join(project_dir, 'LICENSE')]
102
- }
103
- let(:gemfile) { File.read('Gemfile') }
104
- let(:license) { File.read('LICENSE') }
105
- let(:container) { new_image.run('cat /Gemfile /LICENSE') }
106
- let(:response) {
107
- container.tap(&:wait).streaming_logs(stdout: true)
108
- }
109
- after do
110
- container.remove
111
- new_image.remove
112
- end
113
-
114
- it 'creates a new Image that has each file' do
115
- expect(response).to eq("#{gemfile}#{license}")
116
- end
117
- end
118
-
119
- context 'when removing intermediate containers' do
120
- let(:rm) { true }
121
- let(:file) { File.join(project_dir, 'Gemfile') }
122
- after(:each) { new_image.remove }
123
-
124
- it 'leave no intermediate containers' do
125
- expect { new_image }.to change {
126
- Docker::Container.all(:all => true).count
127
- }.by 0
128
- end
129
-
130
- it 'creates a new image' do
131
- expect{new_image}.to change{Docker::Image.all.count}.by 1
132
- end
133
- end
134
- end
135
-
136
- describe '#push' do
137
- let(:credentials) {
138
- {
139
- 'username' => ENV['DOCKER_API_USER'],
140
- 'password' => ENV['DOCKER_API_PASS'],
141
- 'serveraddress' => 'https://index.docker.io/v1',
142
- 'email' => ENV['DOCKER_API_EMAIL']
143
- }
144
- }
145
- let(:repo_tag) { "#{ENV['DOCKER_API_USER']}/true" }
146
- let(:image) {
147
- described_class.build("FROM tianon/true\n", "t" => repo_tag).refresh!
148
- }
149
- after { image.remove(:name => repo_tag, :noprune => true) }
150
-
151
- it 'pushes the Image' do
152
- image.push(credentials)
153
- end
154
-
155
- it 'streams output from push' do
156
- expect { |b| image.push(credentials, &b) }
157
- .to yield_control.at_least(1)
158
- end
159
-
160
- context 'when a tag is specified' do
161
- it 'pushes that specific tag'
162
- end
163
-
164
- context 'when the image was retrived by get' do
165
- let(:image) {
166
- described_class.build("FROM tianon/true\n", "t" => repo_tag).refresh!
167
- described_class.get(repo_tag)
168
- }
169
-
170
- context 'when no tag is specified' do
171
- it 'looks up the first repo tag' do
172
- expect { image.push }.to_not raise_error
173
- end
174
- end
175
- end
176
-
177
- context 'when there are no credentials' do
178
- let(:credentials) { nil }
179
- let(:repo_tag) { "localhost:5000/true" }
180
-
181
- it 'still pushes' do
182
- expect { image.push }.to_not raise_error
183
- end
184
- end
185
- end
186
-
187
- describe '#tag' do
188
- subject { described_class.create('fromImage' => 'debian:wheezy') }
189
- after { subject.remove(:name => 'teh:latest', :noprune => true) }
190
-
191
- it 'tags the image with the repo name' do
192
- subject.tag(:repo => :teh, :force => true)
193
- expect(subject.info['RepoTags']).to include 'teh:latest'
194
- end
195
- end
196
-
197
- describe '#json' do
198
- subject { described_class.create('fromImage' => 'debian:wheezy') }
199
- let(:json) { subject.json }
200
-
201
- it 'returns additional information about image image' do
202
- expect(json).to be_a Hash
203
- expect(json.length).to_not be_zero
204
- end
205
- end
206
-
207
- describe '#history' do
208
- subject { described_class.create('fromImage' => 'debian:wheezy') }
209
- let(:history) { subject.history }
210
-
211
- it 'returns the history of the Image' do
212
- expect(history).to be_a Array
213
- expect(history.length).to_not be_zero
214
- expect(history).to be_all { |elem| elem.is_a? Hash }
215
- end
216
- end
217
-
218
- describe '#run' do
219
- subject { described_class.create('fromImage' => 'debian:wheezy') }
220
- let(:container) { subject.run(cmd).tap(&:wait) }
221
- let(:output) { container.streaming_logs(stdout: true) }
222
-
223
- context 'when the argument is a String' do
224
- let(:cmd) { 'ls /lib64/' }
225
- after { container.remove }
226
-
227
- it 'splits the String by spaces and creates a new Container' do
228
- expect(output).to eq("ld-linux-x86-64.so.2\n")
229
- end
230
- end
231
-
232
- context 'when the argument is an Array' do
233
- let(:cmd) { %w[which pwd] }
234
- after { container.remove }
235
-
236
- it 'creates a new Container' do
237
- expect(output).to eq("/bin/pwd\n")
238
- end
239
- end
240
-
241
- context 'when the argument is nil' do
242
- let(:cmd) { nil }
243
- context 'no command configured in image' do
244
- subject { described_class.create('fromImage' => 'swipely/base') }
245
- it 'should raise an error if no command is specified' do
246
- expect {container}.to raise_error(Docker::Error::ServerError,
247
- "No command specified.")
248
- end
249
- end
250
-
251
- context "command configured in image" do
252
- let(:cmd) { 'pwd' }
253
- after { container.remove }
254
-
255
- it 'should normally show result if image has Cmd configured' do
256
- expect(output).to eql "/\n"
257
- end
258
- end
259
- end
260
- end
261
-
262
- describe '#save' do
263
- let(:image) { Docker::Image.get('busybox') }
264
-
265
- it 'calls the class method' do
266
- expect(Docker::Image).to receive(:save)
267
- .with(image.id, 'busybox.tar', anything)
268
- image.save('busybox.tar')
269
- end
270
- end
271
-
272
- describe '#save_stream' do
273
- let(:image) { Docker::Image.get('busybox') }
274
- let(:block) { proc { |chunk| puts chunk } }
275
-
276
- it 'calls the class method' do
277
- expect(Docker::Image).to receive(:save_stream)
278
- .with(image.id, instance_of(Hash), instance_of(Docker::Connection))
279
- image.save_stream(:chunk_size => 1024 * 1024, &block)
280
- end
281
- end
282
-
283
- describe '#refresh!' do
284
- let(:image) { Docker::Image.create('fromImage' => 'debian:wheezy') }
285
-
286
- it 'updates the @info hash' do
287
- size = image.info.size
288
- image.refresh!
289
- expect(image.info.size).to be > size
290
- end
291
-
292
- context 'with an explicit connection' do
293
- let(:connection) { Docker::Connection.new(Docker.url, Docker.options) }
294
- let(:image) {
295
- Docker::Image.create({'fromImage' => 'debian:wheezy'}, nil, connection)
296
- }
297
-
298
- it 'updates using the provided connection' do
299
- image.refresh!
300
- end
301
- end
302
- end
303
-
304
- describe '.load' do
305
- include_context "local paths"
306
- let(:file) { File.join(project_dir, 'spec', 'fixtures', 'load.tar') }
307
-
308
- context 'when the argument is a String' do
309
- it 'loads tianon/true image from the file system' do
310
- result = Docker::Image.load(file)
311
- expect(result).to eq("")
312
- end
313
- end
314
-
315
- context 'when the argument is an IO' do
316
- let(:io) { File.open(file) }
317
-
318
- after { io.close }
319
-
320
- it 'loads tinan/true image from the IO' do
321
- result = Docker::Image.load(io)
322
- expect(result).to eq("")
323
- end
324
- end
325
- end
326
-
327
- describe '.create' do
328
- subject { described_class }
329
-
330
- context 'when the Image does not yet exist and the body is a Hash' do
331
- let(:image) { subject.create('fromImage' => 'swipely/base') }
332
- let(:creds) {
333
- {
334
- :username => ENV['DOCKER_API_USER'],
335
- :password => ENV['DOCKER_API_PASS'],
336
- :email => ENV['DOCKER_API_EMAIL']
337
- }
338
- }
339
-
340
- before do
341
- Docker::Image.create('fromImage' => 'swipely/base').remove
342
- end
343
- after { Docker::Image.create('fromImage' => 'swipely/base') }
344
-
345
- it 'sets the id and sends Docker.creds' do
346
- allow(Docker).to receive(:creds).and_return(creds)
347
- expect(image).to be_a Docker::Image
348
- expect(image.id).to match(/\A(sha256:)?[a-fA-F0-9]+\Z/)
349
- expect(image.id).to_not include('base')
350
- expect(image.id).to_not be_nil
351
- expect(image.id).to_not be_empty
352
- end
353
- end
354
-
355
- context 'with a block capturing create output' do
356
- let(:create_output) { "" }
357
- let(:block) { Proc.new { |chunk| create_output << chunk } }
358
-
359
- before do
360
- Docker.creds = nil
361
- subject.create('fromImage' => 'tianon/true').remove
362
- end
363
-
364
- it 'calls the block and passes build output' do
365
- subject.create('fromImage' => 'tianon/true', &block)
366
- expect(create_output).to match(/Pulling.*tianon\/true/)
367
- end
368
- end
369
- end
370
-
371
- describe '.get' do
372
- subject { described_class }
373
- let(:image) { subject.get(image_name) }
374
-
375
- context 'when the image does exist' do
376
- let(:image_name) { 'debian:wheezy' }
377
-
378
- it 'returns the new image' do
379
- expect(image).to be_a Docker::Image
380
- end
381
- end
382
-
383
- context 'when the image does not exist' do
384
- let(:image_name) { 'abcdefghijkl' }
385
-
386
- before do
387
- Docker.options = { :mock => true }
388
- Excon.stub({ :method => :get }, { :status => 404 })
389
- end
390
-
391
- after do
392
- Docker.options = {}
393
- Excon.stubs.shift
394
- end
395
-
396
- it 'raises a not found error' do
397
- expect { image }.to raise_error(Docker::Error::NotFoundError)
398
- end
399
- end
400
- end
401
-
402
- describe '.save' do
403
- include_context "local paths"
404
-
405
- context 'when a filename is specified' do
406
- let(:file) { "#{project_dir}/scratch.tar" }
407
- after { FileUtils.remove(file) }
408
-
409
- it 'exports tarball of image to specified file' do
410
- Docker::Image.save('swipely/base', file)
411
- expect(File.exist?(file)).to eq true
412
- expect(File.read(file)).to_not be_nil
413
- end
414
- end
415
-
416
- context 'when no filename is specified' do
417
- it 'returns raw binary data as string' do
418
- raw = Docker::Image.save('swipely/base')
419
- expect(raw).to_not be_nil
420
- end
421
- end
422
- end
423
-
424
- describe '.save_stream' do
425
- let(:image) { 'busybox:latest' }
426
- let(:non_streamed) do
427
- Docker.connection.get(
428
- '/images/get',
429
- 'names' => URI.encode(image)
430
- )
431
- end
432
- let(:streamed) { '' }
433
- let(:tar_files) do
434
- proc do |string|
435
- Gem::Package::TarReader
436
- .new(StringIO.new(string, 'rb'))
437
- .map(&:full_name)
438
- .sort
439
- end
440
- end
441
-
442
- it 'yields each chunk of the image' do
443
- Docker::Image.save_stream(image) { |chunk| streamed << chunk }
444
- expect(tar_files.call(streamed)).to eq(tar_files.call(non_streamed))
445
- end
446
- end
447
-
448
- describe '.exist?' do
449
- subject { described_class }
450
- let(:exists) { subject.exist?(image_name) }
451
-
452
- context 'when the image does exist' do
453
- let(:image_name) { 'debian:wheezy' }
454
-
455
- it 'returns true' do
456
- expect(exists).to eq(true)
457
- end
458
- end
459
-
460
- context 'when the image does not exist' do
461
- let(:image_name) { 'abcdefghijkl' }
462
-
463
- before do
464
- Docker.options = { :mock => true }
465
- Excon.stub({ :method => :get }, { :status => 404 })
466
- end
467
-
468
- after do
469
- Docker.options = {}
470
- Excon.stubs.shift
471
- end
472
-
473
- it 'return false' do
474
- expect(exists).to eq(false)
475
- end
476
- end
477
- end
478
-
479
- describe '.import' do
480
- include_context "local paths"
481
-
482
- subject { described_class }
483
-
484
- context 'when the file does not exist' do
485
- let(:file) { '/lol/not/a/file' }
486
-
487
- it 'raises an error' do
488
- expect { subject.import(file) }
489
- .to raise_error(Docker::Error::IOError)
490
- end
491
- end
492
-
493
- context 'when the file does exist' do
494
- let(:file) { File.join(project_dir, 'spec', 'fixtures', 'export.tar') }
495
- let(:import) { subject.import(file) }
496
- after { import.remove(:noprune => true) }
497
-
498
- it 'creates the Image' do
499
- expect(import).to be_a Docker::Image
500
- expect(import.id).to_not be_nil
501
- end
502
- end
503
-
504
- context 'when the argument is a URI' do
505
- context 'when the URI is invalid' do
506
- it 'raises an error' do
507
- expect { subject.import('http://google.com') }
508
- .to raise_error(Docker::Error::IOError)
509
- end
510
- end
511
-
512
- context 'when the URI is valid' do
513
- let(:uri) { 'http://swipely-pub.s3.amazonaws.com/tianon_true.tar' }
514
- let(:import) { subject.import(uri) }
515
- after { import.remove(:noprune => true) }
516
-
517
- it 'returns an Image' do
518
- expect(import).to be_a Docker::Image
519
- expect(import.id).to_not be_nil
520
- end
521
- end
522
- end
523
- end
524
-
525
- describe '.all' do
526
- subject { described_class }
527
-
528
- let(:images) { subject.all(:all => true) }
529
- before { subject.create('fromImage' => 'debian:wheezy') }
530
-
531
- it 'materializes each Image into a Docker::Image' do
532
- images.each do |image|
533
- expect(image).to_not be_nil
534
-
535
- expect(image).to be_a(described_class)
536
-
537
- expect(image.id).to_not be_nil
538
-
539
- %w(Created Size VirtualSize).each do |key|
540
- expect(image.info).to have_key(key)
541
- end
542
- end
543
-
544
- expect(images.length).to_not be_zero
545
- end
546
- end
547
-
548
- describe '.search' do
549
- subject { described_class }
550
-
551
- it 'materializes each Image into a Docker::Image' do
552
- expect(subject.search('term' => 'sshd')).to be_all { |image|
553
- !image.id.nil? && image.is_a?(described_class)
554
- }
555
- end
556
- end
557
-
558
- describe '.build' do
559
- subject { described_class }
560
- context 'with an invalid Dockerfile' do
561
- it 'throws a UnexpectedResponseError' do
562
- expect { subject.build('lololol') }
563
- .to raise_error(Docker::Error::UnexpectedResponseError)
564
- end
565
- end
566
-
567
- context 'with a valid Dockerfile' do
568
- context 'without query parameters' do
569
- let(:image) { subject.build("FROM debian:wheezy\n") }
570
-
571
- it 'builds an image' do
572
- expect(image).to be_a Docker::Image
573
- expect(image.id).to_not be_nil
574
- expect(image.connection).to be_a Docker::Connection
575
- end
576
- end
577
-
578
- context 'with specifying a repo in the query parameters' do
579
- let(:image) {
580
- subject.build(
581
- "FROM debian:wheezy\nRUN true\n",
582
- "t" => "#{ENV['DOCKER_API_USER']}/debian:true"
583
- )
584
- }
585
- after { image.remove(:noprune => true) }
586
-
587
- it 'builds an image and tags it' do
588
- expect(image).to be_a Docker::Image
589
- expect(image.id).to_not be_nil
590
- expect(image.connection).to be_a Docker::Connection
591
- image.refresh!
592
- expect(image.info["RepoTags"]).to eq(
593
- ["#{ENV['DOCKER_API_USER']}/debian:true"]
594
- )
595
- end
596
- end
597
-
598
- context 'with a block capturing build output' do
599
- let(:build_output) { "" }
600
- let(:block) { Proc.new { |chunk| build_output << chunk } }
601
- let!(:image) { subject.build("FROM debian:wheezy\n", &block) }
602
-
603
- it 'calls the block and passes build output' do
604
- expect(build_output).to match(/Step \d : FROM debian:wheezy/)
605
- end
606
- end
607
- end
608
- end
609
-
610
- describe '.build_from_dir' do
611
- subject { described_class }
612
-
613
- context 'with a valid Dockerfile' do
614
- let(:dir) {
615
- File.join(File.dirname(__FILE__), '..', 'fixtures', 'build_from_dir')
616
- }
617
- let(:docker_file) { File.new("#{dir}/Dockerfile") }
618
- let(:image) { subject.build_from_dir(dir, opts, &block) }
619
- let(:opts) { {} }
620
- let(:block) { Proc.new {} }
621
- let(:container) do
622
- Docker::Container.create(
623
- 'Image' => image.id,
624
- 'Cmd' => %w[cat /Dockerfile]
625
- ).tap(&:start).tap(&:wait)
626
- end
627
- let(:output) { container.streaming_logs(stdout: true) }
628
-
629
- after(:each) do
630
- container.remove
631
- image.remove(:noprune => true)
632
- end
633
-
634
- context 'with no query parameters' do
635
- it 'builds the image' do
636
- expect(output).to eq(docker_file.read)
637
- end
638
- end
639
-
640
- context 'with specifying a repo in the query parameters' do
641
- let(:opts) { { "t" => "#{ENV['DOCKER_API_USER']}/debian:from_dir" } }
642
- it 'builds the image and tags it' do
643
- expect(output).to eq(docker_file.read)
644
- image.refresh!
645
- expect(image.info["RepoTags"]).to eq(
646
- ["#{ENV['DOCKER_API_USER']}/debian:from_dir"]
647
- )
648
- end
649
- end
650
-
651
- context 'with a block capturing build output' do
652
- let(:build_output) { "" }
653
- let(:block) { Proc.new { |chunk| build_output << chunk } }
654
-
655
- it 'calls the block and passes build output' do
656
- image # Create the image variable, which is lazy-loaded by Rspec
657
- expect(build_output).to match(/Step \d : FROM debian:wheezy/)
658
- end
659
-
660
- context 'uses a cached version the second time' do
661
- let(:build_output_two) { "" }
662
- let(:block_two) { Proc.new { |chunk| build_output_two << chunk } }
663
- let(:image_two) { subject.build_from_dir(dir, opts, &block_two) }
664
-
665
- it 'calls the block and passes build output' do
666
- image # Create the image variable, which is lazy-loaded by Rspec
667
- expect(build_output).to match(/Step \d : FROM debian:wheezy/)
668
- expect(build_output).to_not match(/Using cache/)
669
-
670
- image_two # Create the image_two variable, which is lazy-loaded by Rspec
671
- expect(build_output_two).to match(/Using cache/)
672
- end
673
- end
674
- end
675
-
676
- context 'with credentials passed' do
677
- let(:creds) {
678
- {
679
- :username => ENV['DOCKER_API_USER'],
680
- :password => ENV['DOCKER_API_PASS'],
681
- :email => ENV['DOCKER_API_EMAIL'],
682
- :serveraddress => 'https://index.docker.io/v1'
683
- }
684
- }
685
-
686
- before { Docker.creds = creds }
687
- after { Docker.creds = nil }
688
-
689
- it 'sends X-Registry-Config header' do
690
- expect(image.info[:headers].keys).to include('X-Registry-Config')
691
- end
692
- end
693
- end
694
- end
695
- end