docker-api 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/.cane +0 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +3 -0
  4. data/README.md +215 -0
  5. data/Rakefile +16 -0
  6. data/docker-api.gemspec +27 -0
  7. data/lib/docker.rb +60 -0
  8. data/lib/docker/connection.rb +65 -0
  9. data/lib/docker/container.rb +54 -0
  10. data/lib/docker/error.rb +23 -0
  11. data/lib/docker/image.rb +73 -0
  12. data/lib/docker/model.rb +88 -0
  13. data/lib/docker/multipart.rb +30 -0
  14. data/lib/docker/version.rb +3 -0
  15. data/spec/docker/connection_spec.rb +67 -0
  16. data/spec/docker/container_spec.rb +529 -0
  17. data/spec/docker/image_spec.rb +379 -0
  18. data/spec/docker_spec.rb +58 -0
  19. data/spec/spec_helper.rb +14 -0
  20. data/spec/support/vcr.rb +11 -0
  21. data/spec/vcr/Docker/_info/returns_the_info_as_a_Hash.yml +31 -0
  22. data/spec/vcr/Docker/_version/returns_the_version_as_a_Hash.yml +31 -0
  23. data/spec/vcr/Docker_Container/_all/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +333 -0
  24. data/spec/vcr/Docker_Container/_attach/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/yields_each_chunk.yml +81 -0
  25. data/spec/vcr/Docker_Container/_changes/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/returns_the_changes_as_an_array.yml +115 -0
  26. data/spec/vcr/Docker_Container/_commit/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/creates_a_new_Image_from_the_Container_s_changes.yml +87 -0
  27. data/spec/vcr/Docker_Container/_create_/when_the_Container_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml +31 -0
  28. data/spec/vcr/Docker_Container/_export/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/yields_each_chunk.yml +97 -0
  29. data/spec/vcr/Docker_Container/_json/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/returns_the_description_as_a_Hash.yml +59 -0
  30. data/spec/vcr/Docker_Container/_kill/when_the_Container_has_been_created/when_the_HTTP_response_status_is_204/kills_the_container.yml +232 -0
  31. data/spec/vcr/Docker_Container/_restart/when_the_Container_has_been_created/when_the_HTTP_response_status_is_204/restarts_the_container.yml +201 -0
  32. data/spec/vcr/Docker_Container/_start/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/starts_the_container.yml +89 -0
  33. data/spec/vcr/Docker_Container/_stop/when_the_Container_has_been_created/when_the_HTTP_response_status_is_204/stops_the_container.yml +259 -0
  34. data/spec/vcr/Docker_Container/_wait/when_the_Container_has_been_created/when_the_HTTP_response_status_is_200/waits_for_the_command_to_finish.yml +87 -0
  35. data/spec/vcr/Docker_Image/_all/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +59 -0
  36. data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/builds_an_image.yml +45 -0
  37. data/spec/vcr/Docker_Image/_build/with_an_invalid_Dockerfile/throws_a_UnexpectedResponseError.yml +38 -0
  38. data/spec/vcr/Docker_Image/_create_/when_the_Image_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml +31 -0
  39. data/spec/vcr/Docker_Image/_history/when_the_Image_has_been_created/when_the_HTTP_response_status_is_200/returns_the_history_of_the_Image.yml +59 -0
  40. data/spec/vcr/Docker_Image/_insert/when_the_Image_has_been_created/when_the_HTTP_response_status_is_200/inserts_the_file.yml +59 -0
  41. data/spec/vcr/Docker_Image/_json/when_the_Image_has_been_created/when_the_HTTP_response_status_is_200/returns_additional_information_about_image_image.yml +60 -0
  42. data/spec/vcr/Docker_Image/_remove/when_the_Image_has_been_created/when_the_HTTP_response_status_is_204/nils_out_the_id.yml +59 -0
  43. data/spec/vcr/Docker_Image/_search/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +64 -0
  44. data/spec/vcr/Docker_Image/_tag/when_the_Image_has_been_created/when_the_HTTP_response_status_is_200/tags_the_image_with_the_repo_name.yml +59 -0
  45. metadata +281 -0
@@ -0,0 +1,379 @@
1
+ require 'spec_helper'
2
+
3
+ describe Docker::Image do
4
+ describe '#initialize' do
5
+ subject { described_class }
6
+
7
+ context 'with no argument' do
8
+ let(:image) { subject.new }
9
+
10
+ it 'sets the id to nil' do
11
+ image.id.should be_nil
12
+ end
13
+
14
+ it 'keeps the default Connection' do
15
+ image.connection.should == Docker.connection
16
+ end
17
+ end
18
+
19
+ context 'with an argument' do
20
+ let(:id) { 'a7c2ee4' }
21
+ let(:image) { subject.new(:id => id) }
22
+
23
+ it 'sets the id to the argument' do
24
+ image.id.should == id
25
+ end
26
+
27
+ it 'keeps the default Connection' do
28
+ image.connection.should == Docker.connection
29
+ end
30
+ end
31
+
32
+ context 'with two arguments' do
33
+ context 'when the second argument is not a Docker::Connection' do
34
+ let(:id) { 'abc123f' }
35
+ let(:connection) { :not_a_connection }
36
+ let(:image) { subject.new(:id => id, :connection => connection) }
37
+
38
+ it 'raises an error' do
39
+ expect { image }.to raise_error(Docker::Error::ArgumentError)
40
+ end
41
+ end
42
+
43
+ context 'when the second argument is a Docker::Connection' do
44
+ let(:id) { 'cb3f14a' }
45
+ let(:connection) { Docker::Connection.new }
46
+ let(:image) { subject.new(:id => id, :connection => connection) }
47
+
48
+ it 'initializes the Image' do
49
+ image.id.should == id
50
+ image.connection.should == connection
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#to_s' do
57
+ let(:id) { 'bf119e2' }
58
+ let(:connection) { Docker::Connection.new }
59
+ let(:expected_string) do
60
+ "Docker::Image { :id => #{id}, :connection => #{connection} }"
61
+ end
62
+ subject { described_class.new(:id => id, :connection => connection) }
63
+
64
+ its(:to_s) { should == expected_string }
65
+ end
66
+
67
+ describe '#created?' do
68
+ context 'when the id is nil' do
69
+ its(:created?) { should be_false }
70
+ end
71
+
72
+ context 'when the id is present' do
73
+ subject { described_class.new(:id => 'a732ebf') }
74
+
75
+ its(:created?) { should be_true }
76
+ end
77
+ end
78
+
79
+ describe '#create!' do
80
+ context 'when the Image has already been created' do
81
+ subject { described_class.new(:id => '5e88b2a') }
82
+
83
+ it 'raises an error' do
84
+ expect { subject.create! }
85
+ .to raise_error(Docker::Error::StateError)
86
+ end
87
+ end
88
+
89
+ context 'when the body is not a Hash' do
90
+ it 'raises an error' do
91
+ expect { subject.create!(:not_a_hash) }
92
+ .to raise_error(Docker::Error::ArgumentError)
93
+ end
94
+ end
95
+
96
+ context 'when the Image does not yet exist and the body is a Hash' do
97
+ context 'when the HTTP request does not return a 200' do
98
+ before { Excon.stub({ :method => :post }, { :status => 400 }) }
99
+ after { Excon.stubs.shift }
100
+
101
+ it 'raises an error' do
102
+ expect { subject.create! }.to raise_error(Docker::Error::ClientError)
103
+ end
104
+ end
105
+
106
+ context 'when the HTTP request returns a 200' do
107
+ it 'sets the id', :vcr do
108
+ expect { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
109
+ .to change { subject.id }
110
+ .from(nil)
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#remove' do
117
+ context 'when the Image has not been created' do
118
+ it 'raises an error' do
119
+ expect { subject.remove }.to raise_error Docker::Error::StateError
120
+ end
121
+ end
122
+
123
+ context 'when the Image has been created' do
124
+ context 'when the HTTP response status is not 204' do
125
+ before do
126
+ subject.stub(:created?).and_return(true)
127
+ Excon.stub({ :method => :delete }, { :status => 500 })
128
+ end
129
+ after { Excon.stubs.shift }
130
+
131
+ it 'raises an error' do
132
+ expect { subject.remove }
133
+ .to raise_error(Docker::Error::ServerError)
134
+ end
135
+ end
136
+
137
+ context 'when the HTTP response status is 204' do
138
+ before { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
139
+
140
+ it 'nils out the id', :vcr do
141
+ expect { subject.remove }
142
+ .to change { subject.id }
143
+ .to nil
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ describe "#insert" do
150
+ context 'when the Image has not been created' do
151
+ it 'raises an error' do
152
+ expect { subject.insert }.to raise_error Docker::Error::StateError
153
+ end
154
+ end
155
+
156
+ context 'when the Image has been created' do
157
+ context 'when the HTTP response status is not 200' do
158
+ before do
159
+ subject.stub(:created?).and_return(true)
160
+ Excon.stub({ :method => :post }, { :status => 500 })
161
+ end
162
+ after { Excon.stubs.shift }
163
+
164
+ it 'raises an error' do
165
+ expect { subject.insert }
166
+ .to raise_error(Docker::Error::ServerError)
167
+ end
168
+ end
169
+
170
+ context 'when the HTTP response status is 200' do
171
+ before { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
172
+
173
+ it 'inserts the file', :vcr do
174
+ expect { subject.insert('path' => '/', 'url' => 'lol') }
175
+ .to_not raise_error
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ describe "#push" do
182
+ context 'when the Image has not been created' do
183
+ it 'raises an error' do
184
+ expect { subject.push }.to raise_error Docker::Error::StateError
185
+ end
186
+ end
187
+
188
+ context 'when the Image has been created' do
189
+ context 'when the HTTP response status is not 200' do
190
+ before do
191
+ subject.stub(:created?).and_return(true)
192
+ Excon.stub({ :method => :post }, { :status => 500 })
193
+ end
194
+ after { Excon.stubs.shift }
195
+
196
+ it 'raises an error' do
197
+ expect { subject.push }
198
+ .to raise_error(Docker::Error::ServerError)
199
+ end
200
+ end
201
+
202
+ context 'when the HTTP response status is 200' do
203
+ it 'pushes the Image', :vcr do
204
+ pending 'I don\'t want to push the Image to the Docker Registry'
205
+ subject.create!('fromRepo' => 'base', 'fromSrc' => '-')
206
+ subject.push
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ describe "#tag" do
213
+ context 'when the Image has not been created' do
214
+ it 'raises an error' do
215
+ expect { subject.tag }.to raise_error Docker::Error::StateError
216
+ end
217
+ end
218
+
219
+ context 'when the Image has been created' do
220
+ context 'when the HTTP response status is not 200' do
221
+ before do
222
+ subject.stub(:created?).and_return(true)
223
+ Excon.stub({ :method => :post }, { :status => 500 })
224
+ end
225
+ after { Excon.stubs.shift }
226
+
227
+ it 'raises an error' do
228
+ expect { subject.tag }
229
+ .to raise_error(Docker::Error::ServerError)
230
+ end
231
+ end
232
+
233
+ context 'when the HTTP response status is 200' do
234
+ before { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
235
+
236
+ it 'tags the image with the repo name', :vcr do
237
+ expect { subject.tag(:repo => 'base2', :force => true) }
238
+ .to_not raise_error
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ describe "#json" do
245
+ context 'when the Image has not been created' do
246
+ it 'raises an error' do
247
+ expect { subject.json }.to raise_error Docker::Error::StateError
248
+ end
249
+ end
250
+
251
+ context 'when the Image has been created' do
252
+ context 'when the HTTP response status is not 200' do
253
+ before do
254
+ subject.stub(:created?).and_return(true)
255
+ Excon.stub({ :method => :get }, { :status => 500 })
256
+ end
257
+ after { Excon.stubs.shift }
258
+
259
+ it 'raises an error' do
260
+ expect { subject.json }
261
+ .to raise_error(Docker::Error::ServerError)
262
+ end
263
+ end
264
+
265
+ context 'when the HTTP response status is 200' do
266
+ let(:json) { subject.json }
267
+ before { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
268
+
269
+ it 'returns additional information about image image', :vcr do
270
+ json.should be_a Hash
271
+ json['id'].should start_with subject.id
272
+ json['comment'].should == 'Imported from -'
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ describe "#history" do
279
+ context 'when the Image has not been created' do
280
+ it 'raises an error' do
281
+ expect { subject.history }.to raise_error Docker::Error::StateError
282
+ end
283
+ end
284
+
285
+ context 'when the Image has been created' do
286
+ context 'when the HTTP response status is not 200' do
287
+ before do
288
+ subject.stub(:created?).and_return(true)
289
+ Excon.stub({ :method => :get }, { :status => 500 })
290
+ end
291
+ after { Excon.stubs.shift }
292
+
293
+ it 'raises an error' do
294
+ expect { subject.history }
295
+ .to raise_error(Docker::Error::ServerError)
296
+ end
297
+ end
298
+
299
+ context 'when the HTTP response status is 200' do
300
+ let(:history) { subject.history }
301
+ before { subject.create!('fromRepo' => 'base', 'fromSrc' => '-') }
302
+
303
+ it 'returns the history of the Image', :vcr do
304
+ history.should be_a Array
305
+ history.length.should_not be_zero
306
+ history.should be_all { |elem| elem.is_a? Hash }
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ describe '.all' do
313
+ subject { described_class }
314
+
315
+ context 'when the HTTP response is not a 200' do
316
+ before { Excon.stub({ :method => :get }, { :status => 500 }) }
317
+ after { Excon.stubs.shift }
318
+
319
+ it 'raises an error' do
320
+ expect { subject.all }
321
+ .to raise_error(Docker::Error::ServerError)
322
+ end
323
+ end
324
+
325
+ context 'when the HTTP response is a 200' do
326
+ let(:images) { subject.all(:all => true) }
327
+ before { subject.new.create!('fromRepo' => 'base', 'fromSrc' => '-') }
328
+ it 'materializes each Container into a Docker::Container', :vcr do
329
+ images.should be_all { |image|
330
+ !image.id.nil? && image.is_a?(described_class)
331
+ }
332
+ images.length.should_not be_zero
333
+ end
334
+ end
335
+ end
336
+
337
+ describe '.search' do
338
+ subject { described_class }
339
+
340
+ context 'when the HTTP response is not a 200' do
341
+ before { Excon.stub({ :method => :get }, { :status => 500 }) }
342
+ after { Excon.stubs.shift }
343
+
344
+ it 'raises an error' do
345
+ expect { subject.search }
346
+ .to raise_error(Docker::Error::ServerError)
347
+ end
348
+ end
349
+
350
+ context 'when the HTTP response is a 200' do
351
+ it 'materializes each Container into a Docker::Container', :vcr do
352
+ subject.new.create!('fromRepo' => 'base', 'fromSrc' => '-')
353
+ subject.search('term' => 'sshd').should be_all { |image|
354
+ !image.id.nil? && image.is_a?(described_class)
355
+ }
356
+ end
357
+ end
358
+ end
359
+
360
+ describe '.build' do
361
+ subject { described_class }
362
+ context 'with an invalid Dockerfile' do
363
+ it 'throws a UnexpectedResponseError', :vcr do
364
+ expect { subject.build('lololol') }
365
+ .to raise_error(Docker::Error::UnexpectedResponseError)
366
+ end
367
+ end
368
+
369
+ context 'with a valid Dockerfile', :vcr do
370
+ let(:image) { subject.build("from base\n") }
371
+
372
+ it 'builds an image' do
373
+ image.should be_a Docker::Image
374
+ image.id.should_not be_nil
375
+ image.connection.should be_a Docker::Connection
376
+ end
377
+ end
378
+ end
379
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Docker do
4
+ subject { Docker }
5
+
6
+ it { should be_a Module }
7
+ its(:options) { should == { :port => 4243 } }
8
+ its(:url) { should == 'http://localhost' }
9
+ its(:connection) { should be_a Docker::Connection }
10
+
11
+ describe '#reset_connection!' do
12
+ before { subject.connection }
13
+ it 'sets the @connection to nil' do
14
+ expect { subject.reset_connection! }
15
+ .to change { subject.instance_variable_get(:@connection) }
16
+ .to nil
17
+ end
18
+ end
19
+
20
+ [:options=, :url=].each do |method|
21
+ describe "##{method}" do
22
+ after(:all) do
23
+ subject.options = { :port => 4243 }
24
+ subject.url = 'http://localhost'
25
+ end
26
+ it 'calls #reset_connection!' do
27
+ subject.should_receive(:reset_connection!)
28
+ subject.public_send(method, {})
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#version' do
34
+ let(:version) { subject.version }
35
+ it 'returns the version as a Hash', :vcr do
36
+ version.should be_a Hash
37
+ version.keys.sort.should == %w[GoVersion Version]
38
+ end
39
+ end
40
+
41
+ describe '#info' do
42
+ let(:info) { subject.info }
43
+ let(:keys) do
44
+ ["Containers", "Debug", "Images", "MemoryLimit", "NFd", "NGoroutines"]
45
+ end
46
+
47
+ it 'returns the info as a Hash', :vcr do
48
+ info.should be_a Hash
49
+ info.keys.sort.should == keys
50
+ end
51
+ end
52
+
53
+ describe '#auth' do
54
+ it 'logs in' do
55
+ pending
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rspec'
4
+ require 'docker'
5
+
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rspec
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.color_enabled = true
12
+ config.formatter = :documentation
13
+ config.tty = true
14
+ end