dockerspec 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/LICENSE +1 -1
  4. data/README.md +190 -24
  5. data/Rakefile +60 -6
  6. data/TODO.md +3 -2
  7. data/lib/dockerspec.rb +1 -2
  8. data/lib/dockerspec/builder.rb +13 -6
  9. data/lib/dockerspec/builder/config_helpers.rb +8 -3
  10. data/lib/dockerspec/builder/logger/ci.rb +2 -2
  11. data/lib/dockerspec/builder/matchers.rb +32 -51
  12. data/lib/dockerspec/configuration.rb +188 -0
  13. data/lib/dockerspec/docker_exception_parser.rb +2 -2
  14. data/lib/dockerspec/engine/base.rb +156 -0
  15. data/lib/dockerspec/engine/infrataster.rb +87 -0
  16. data/lib/dockerspec/engine/specinfra.rb +130 -0
  17. data/lib/dockerspec/engine/specinfra/backend.rb +163 -0
  18. data/lib/dockerspec/{serverspec/specinfra_hack.rb → engine/specinfra/backend_hack.rb} +17 -3
  19. data/lib/dockerspec/engine_list.rb +150 -0
  20. data/lib/dockerspec/exceptions.rb +13 -0
  21. data/lib/dockerspec/helper/multiple_sources_description.rb +3 -3
  22. data/lib/dockerspec/helper/rspec_example_helpers.rb +86 -6
  23. data/lib/dockerspec/infrataster.rb +26 -0
  24. data/lib/dockerspec/rspec.rb +21 -0
  25. data/lib/dockerspec/{rspec_configuration.rb → rspec/configuration.rb} +1 -1
  26. data/lib/dockerspec/rspec/resources.rb +602 -0
  27. data/lib/dockerspec/rspec/resources/its_container.rb +110 -0
  28. data/lib/dockerspec/{rspec_settings.rb → rspec/settings.rb} +5 -1
  29. data/lib/dockerspec/runner.rb +2 -357
  30. data/lib/dockerspec/runner/base.rb +367 -0
  31. data/lib/dockerspec/runner/compose.rb +322 -0
  32. data/lib/dockerspec/runner/docker.rb +302 -0
  33. data/lib/dockerspec/runner/serverspec.rb +21 -0
  34. data/lib/dockerspec/runner/serverspec/base.rb +185 -0
  35. data/lib/dockerspec/runner/serverspec/compose.rb +106 -0
  36. data/lib/dockerspec/runner/serverspec/docker.rb +116 -0
  37. data/lib/dockerspec/runner/serverspec/rspec.rb +20 -0
  38. data/lib/dockerspec/{serverspec/rspec_settings.rb → runner/serverspec/rspec/settings.rb} +1 -1
  39. data/lib/dockerspec/serverspec.rb +12 -2
  40. data/lib/dockerspec/version.rb +1 -1
  41. data/spec/spec_helper.rb +6 -2
  42. metadata +84 -15
  43. data/lib/dockerspec/rspec_assertions.rb +0 -54
  44. data/lib/dockerspec/rspec_resources.rb +0 -203
  45. data/lib/dockerspec/serverspec/rspec_resources.rb +0 -179
  46. data/lib/dockerspec/serverspec/runner.rb +0 -305
  47. data/lib/dockerspec/serverspec/specinfra_backend.rb +0 -128
@@ -18,5 +18,4 @@
18
18
  #
19
19
 
20
20
  require 'dockerspec/version'
21
- require 'dockerspec/rspec_resources'
22
- require 'dockerspec/rspec_configuration'
21
+ require 'dockerspec/rspec'
@@ -83,7 +83,7 @@ module Dockerspec
83
83
  # `:debug` or `3` (outputs all the provided information in its raw
84
84
  # original form).
85
85
  #
86
- # @see Dockerspec::RSpecResources#docker_build
86
+ # @see Dockerspec::RSpec::Resources#docker_build
87
87
  #
88
88
  # @api public
89
89
  #
@@ -117,6 +117,8 @@ module Dockerspec
117
117
  #
118
118
  # @return [String] Docker image ID.
119
119
  #
120
+ # @raise [Dockerspec::DockerError] For underlaying docker errors.
121
+ #
120
122
  # @api public
121
123
  #
122
124
  def build
@@ -173,7 +175,7 @@ module Dockerspec
173
175
  #
174
176
  # @api private
175
177
  #
176
- alias_method :description_from_template, :description_from_file
178
+ alias description_from_template description_from_file
177
179
 
178
180
  #
179
181
  # Sets or gets the Docker image.
@@ -201,7 +203,7 @@ module Dockerspec
201
203
  # @api private
202
204
  #
203
205
  def rspec_options
204
- config = RSpec.configuration
206
+ config = ::RSpec.configuration
205
207
  {}.tap do |opts|
206
208
  opts[:path] = config.dockerfile_path if config.dockerfile_path?
207
209
  opts[:rm] = config.rm_build if config.rm_build?
@@ -313,11 +315,13 @@ module Dockerspec
313
315
  #
314
316
  # @return void
315
317
  #
318
+ # @raise [Dockerspec::DockerError] For underlaying docker errors.
319
+ #
316
320
  # @api private
317
321
  #
318
322
  def build_from_dir(dir)
319
323
  image(::Docker::Image.build_from_dir(dir, &build_block))
320
- add_respository_tag
324
+ add_repository_tag
321
325
  rescue ::Docker::Error::DockerError => e
322
326
  DockerExceptionParser.new(e)
323
327
  end
@@ -370,13 +374,16 @@ module Dockerspec
370
374
  #
371
375
  # @return void
372
376
  #
377
+ # @raise [Dockerspec::DockerError] For underlaying docker errors.
378
+ #
373
379
  # @api private
374
380
  #
375
381
  def build_from_id(id)
376
382
  @image = ::Docker::Image.get(id)
377
- add_respository_tag
383
+ add_repository_tag
378
384
  rescue ::Docker::Error::NotFoundError
379
385
  @image = ::Docker::Image.create('fromImage' => id)
386
+ add_repository_tag
380
387
  rescue ::Docker::Error::DockerError => e
381
388
  DockerExceptionParser.new(e)
382
389
  end
@@ -388,7 +395,7 @@ module Dockerspec
388
395
  #
389
396
  # @api private
390
397
  #
391
- def add_respository_tag
398
+ def add_repository_tag
392
399
  return unless @options.key?(:tag)
393
400
  repo, repo_tag = @options[:tag].split(':', 2)
394
401
  @image.tag(repo: repo, tag: repo_tag, force: true)
@@ -24,7 +24,7 @@ module Dockerspec
24
24
  #
25
25
  # **Note:** Keep in mind that not all the available Dockerfile instructions
26
26
  # can be checked in the docker image. You should use
27
- # {Dockerspec::Serverspec::RSpecResources#docker_run} to check some
27
+ # {Dockerspec::Serverspec::RSpec::Resources#docker_run} to check some
28
28
  # instructions like `FROM`, `RUN`, `ADD` and `COPY` (see the examples
29
29
  # there).
30
30
  #
@@ -72,7 +72,7 @@ module Dockerspec
72
72
  @image.json['Architecture']
73
73
  end
74
74
 
75
- alias_method :arch, :architecture
75
+ alias arch architecture
76
76
 
77
77
  #
78
78
  # Returns the image Operating System.
@@ -194,6 +194,11 @@ module Dockerspec
194
194
  # it { should have_expose '80' }
195
195
  # end
196
196
  #
197
+ # @example RSpec Example Using *Have* Matchers with Integer Valuess
198
+ # describe docker_build(path: '.') do
199
+ # it { should have_expose 80 }
200
+ # end
201
+ #
197
202
  # @example RSpec Example Using Regular Expressions
198
203
  # describe docker_build(path: '.') do
199
204
  # it { should have_expose(/80$/) }
@@ -253,7 +258,7 @@ module Dockerspec
253
258
  end
254
259
  end
255
260
 
256
- alias_method :env, :envs
261
+ alias env envs
257
262
 
258
263
  #
259
264
  # Returns the image entrypoint (`ENTRYPOINT`).
@@ -52,12 +52,12 @@ module Dockerspec
52
52
  # @api private
53
53
  #
54
54
  def print_stream(stream)
55
- if stream.match(/^Step /)
55
+ if stream =~ /^Step /
56
56
  @buffer = stream
57
57
  @skip = true
58
58
  else
59
59
  @buffer += stream
60
- @skip = false if stream.match(/^ ---> (Running in|\[Warning\]) /)
60
+ @skip = false if stream =~ /^ ---> (Running in|\[Warning\]) /
61
61
  end
62
62
  return if @skip
63
63
  @output.puts @buffer
@@ -55,78 +55,59 @@ module Dockerspec
55
55
  workdir: :string,
56
56
  onbuild: :array,
57
57
  stopsignal: :string
58
- }
58
+ }.freeze
59
59
 
60
60
  PREDICATE_TYPES.each do |name, type|
61
61
  matcher_name = "have_#{name}".to_sym
62
62
 
63
- case type
64
- when :string
65
- matcher matcher_name do |expected|
66
- match { |actual| !expected.match(actual.send(name)).nil? }
63
+ value_method = name
64
+ verb = 'be'
65
+ matcher matcher_name do |expected|
66
+ case type
67
+ when :string
68
+ verb = 'match'
67
69
 
68
- failure_message do |actual|
69
- "expected `#{name.upcase}` to match `#{expected.inspect}`, "\
70
- "got `#{actual.send(name)}`"
71
- end
70
+ match { |actual| !expected.match(actual.send(value_method)).nil? }
71
+ when :json
72
+ verb = 'be'
72
73
 
73
- failure_message_when_negated do |actual|
74
- "expected `#{name.upcase}` not to match `#{expected.inspect}`, "\
75
- "got `#{actual.send(name)}`"
76
- end
77
- end
78
- when :json
79
- matcher matcher_name do |expected|
80
74
  include MatcherHelpers
81
75
 
82
- match { |actual| maybe_json?(actual.send(name), expected) }
76
+ match { |actual| maybe_json?(actual.send(value_method), expected) }
77
+ when :array
78
+ value_method = "#{name}s"
79
+ verb = 'include'
83
80
 
84
- failure_message do |actual|
85
- "expected `#{name.upcase}` to be `#{expected.inspect}`, "\
86
- "got `#{actual.send(name)}`"
81
+ # Allow ports to be passed as integer:
82
+ if matcher_name == :have_expose && expected.is_a?(Numeric)
83
+ expected = expected.to_s
87
84
  end
88
85
 
89
- failure_message_when_negated do |actual|
90
- "expected `#{name.upcase}` not to be `#{expected.inspect}`, "\
91
- "got `#{actual.send(name)}`"
92
- end
93
- end
94
- when :array
95
- matcher matcher_name do |expected|
96
- match { |actual| !actual.send("#{name}s").grep(expected).empty? }
97
-
98
- failure_message do |actual|
99
- "expected `#{name.upcase}` to include `#{expected.inspect}`, "\
100
- "got `#{actual.send("#{name}s").inspect}`"
101
- end
86
+ match { |actual| !actual.send(value_method).grep(expected).empty? }
87
+ when :hash
88
+ value_method = "#{name}s"
89
+ verb = 'contain'
102
90
 
103
- failure_message_when_negated do |actual|
104
- "expected `#{name.upcase}` not to include "\
105
- "`#{expected.inspect}`, got `#{actual.send("#{name}s").inspect}`"
106
- end
107
- end
108
- when :hash
109
- matcher matcher_name do |expected|
110
91
  include MatcherHelpers
111
92
 
112
93
  match do |actual|
113
- actual = actual.send("#{name}s")
94
+ actual = actual.send(value_method)
114
95
  break sub_hash?(actual, expected) if expected.is_a?(Hash)
115
96
  !actual.keys.grep(expected).empty?
116
97
  end
98
+ end # case type
117
99
 
118
- failure_message do |actual|
119
- "expected `#{name.upcase}` to contain `#{expected.inspect}`, "\
120
- "got `#{actual.send("#{name}s")}`"
121
- end
100
+ failure_message do |actual|
101
+ "expected `#{name.upcase}` to #{verb} `#{expected.inspect}`, "\
102
+ "got `#{actual.send(value_method).inspect}`"
103
+ end
122
104
 
123
- failure_message_when_negated do |actual|
124
- "expected `#{name.upcase}` not to contain "\
125
- "`#{expected.inspect}`, got `#{actual.send("#{name}s")}`"
126
- end
105
+ failure_message_when_negated do |actual|
106
+ "expected `#{name.upcase}` not to #{verb} "\
107
+ "`#{expected.inspect}`, got `#{actual.send(value_method).inspect}`"
127
108
  end
128
- end
129
- end
109
+ end # matcher
110
+ end # PREDICATE_TYPES each
130
111
  end
131
112
  end
132
113
  end
@@ -0,0 +1,188 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author:: Xabier de Zuazo (<xabier@zuazo.org>)
4
+ # Copyright:: Copyright (c) 2016 Xabier de Zuazo
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'dockerspec/runner/docker'
21
+ require 'dockerspec/runner/compose'
22
+
23
+ module Dockerspec
24
+ #
25
+ # Saves internal configuration for {Dockerspec}.
26
+ #
27
+ # - The test engines to Run: Specinfra, ...
28
+ # - The internal library used to run Docker.
29
+ #
30
+ class Configuration
31
+ #
32
+ # The {Dockerspec::Runner} class used to run Docker.
33
+ #
34
+ # @return [Class] The {Dockerspec::Runner::Base} class.
35
+ #
36
+ attr_accessor :docker_runner
37
+
38
+ #
39
+ # The {Dockerspec::Runner::Compose} class used to run Docker Compose.
40
+ #
41
+ # @return [Class] The {Dockerspec::Runner::Compose} class.
42
+ #
43
+ attr_accessor :compose_runner
44
+
45
+ #
46
+ # A list of test engines used to run the tests.
47
+ #
48
+ # @return [Array<Class>] A list of {Dockerspec::Engine::Base} classes.
49
+ #
50
+ attr_reader :engines
51
+
52
+ class << self
53
+ #
54
+ # Adds a class to use as engine to run the tests.
55
+ #
56
+ # @example
57
+ # Dockerspec.Configuration.add_engine Dockerspec::Engine::Specinfra
58
+ #
59
+ # @param engine [Class] A {Dockerspec::Engine::Base} subclass.
60
+ #
61
+ # @return void
62
+ #
63
+ # @api public
64
+ #
65
+ def add_engine(engine)
66
+ instance.add_engine(engine)
67
+ end
68
+
69
+ #
70
+ # Gets the engine classes used to run the tests.
71
+ #
72
+ # @return [Array<Class>] A list of {Dockerspec::Engine::Base} subclasses.
73
+ #
74
+ # @api public
75
+ #
76
+ def engines
77
+ instance.engines
78
+ end
79
+
80
+ #
81
+ # Sets the class used to create and start Docker Containers.
82
+ #
83
+ # @example
84
+ # Dockerspec.Configuration.docker_runner = Dockerspec::Runner::Docker
85
+ #
86
+ # @param runner [Class] A {Dockerspec::Runner::Base} subclass.
87
+ #
88
+ # @return void
89
+ #
90
+ # @api public
91
+ #
92
+ def docker_runner=(runner)
93
+ instance.docker_runner = runner
94
+ end
95
+
96
+ #
97
+ # Gets the class used to create and start Docker Containers.
98
+ #
99
+ # @return [Class] A {Dockerspec::Runner::Base} subclass.
100
+ #
101
+ # @api public
102
+ #
103
+ def docker_runner
104
+ instance.docker_runner
105
+ end
106
+
107
+ #
108
+ # Sets the class used to start Docker Compose.
109
+ #
110
+ # @example
111
+ # Dockerspec.Configuration.compose_runner = Dockerspec::Runner::Compose
112
+ #
113
+ # @param runner [Class] A {Dockerspec::Runner::Compose::Base} subclass.
114
+ #
115
+ # @return void
116
+ #
117
+ # @api public
118
+ #
119
+ def compose_runner=(runner)
120
+ instance.compose_runner = runner
121
+ end
122
+
123
+ #
124
+ # Gets the class used to start Docker Compose.
125
+ #
126
+ # @return [Class] A {Dockerspec::Runner::Compose::Base} subclass.
127
+ #
128
+ # @api public
129
+ #
130
+ def compose_runner
131
+ instance.compose_runner
132
+ end
133
+
134
+ #
135
+ # Resets the internal Configuration singleton object.
136
+ #
137
+ # @return void
138
+ #
139
+ # @api public
140
+ #
141
+ def reset
142
+ @instance = nil
143
+ end
144
+
145
+ protected
146
+
147
+ #
148
+ # Creates the Configuration singleton instance.
149
+ #
150
+ # @return void
151
+ #
152
+ # @api private
153
+ #
154
+ def instance
155
+ @instance ||= new
156
+ end
157
+ end
158
+
159
+ #
160
+ # Adds a class to use as engine to run the tests.
161
+ #
162
+ # @param engine [Class] A {Dockerspec::Engine::Base} subclass.
163
+ #
164
+ # @return void
165
+ #
166
+ # @api private
167
+ #
168
+ def add_engine(engine)
169
+ @engines << engine
170
+ @engines.uniq!
171
+ end
172
+
173
+ protected
174
+
175
+ #
176
+ # Constructs a configuration object.
177
+ #
178
+ # @return [Dockerspec::Configuretion] The configuration object.
179
+ #
180
+ # @api private
181
+ #
182
+ def initialize
183
+ @docker_runner = Runner::Docker
184
+ @compose_runner = Runner::Compose
185
+ @engines = []
186
+ end
187
+ end
188
+ end
@@ -45,7 +45,7 @@ module Dockerspec
45
45
  def initialize(e)
46
46
  e_ary = parse_exception(e)
47
47
  raise_docker_error_exception(e_ary)
48
- fail e
48
+ raise e
49
49
  end
50
50
 
51
51
  protected
@@ -153,7 +153,7 @@ module Dockerspec
153
153
  output = parse_streams(e_ary)
154
154
  error_msg = parse_error_detail(e_ary)
155
155
  return if error_msg.nil?
156
- fail DockerError, generate_error_message(error_msg, output)
156
+ raise DockerError, generate_error_message(error_msg, output)
157
157
  end
158
158
  end
159
159
  end