docker-api 1.28.0 → 2.0.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.
@@ -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