dockerspec 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/LICENSE +1 -1
- data/README.md +190 -24
- data/Rakefile +60 -6
- data/TODO.md +3 -2
- data/lib/dockerspec.rb +1 -2
- data/lib/dockerspec/builder.rb +13 -6
- data/lib/dockerspec/builder/config_helpers.rb +8 -3
- data/lib/dockerspec/builder/logger/ci.rb +2 -2
- data/lib/dockerspec/builder/matchers.rb +32 -51
- data/lib/dockerspec/configuration.rb +188 -0
- data/lib/dockerspec/docker_exception_parser.rb +2 -2
- data/lib/dockerspec/engine/base.rb +156 -0
- data/lib/dockerspec/engine/infrataster.rb +87 -0
- data/lib/dockerspec/engine/specinfra.rb +130 -0
- data/lib/dockerspec/engine/specinfra/backend.rb +163 -0
- data/lib/dockerspec/{serverspec/specinfra_hack.rb → engine/specinfra/backend_hack.rb} +17 -3
- data/lib/dockerspec/engine_list.rb +150 -0
- data/lib/dockerspec/exceptions.rb +13 -0
- data/lib/dockerspec/helper/multiple_sources_description.rb +3 -3
- data/lib/dockerspec/helper/rspec_example_helpers.rb +86 -6
- data/lib/dockerspec/infrataster.rb +26 -0
- data/lib/dockerspec/rspec.rb +21 -0
- data/lib/dockerspec/{rspec_configuration.rb → rspec/configuration.rb} +1 -1
- data/lib/dockerspec/rspec/resources.rb +602 -0
- data/lib/dockerspec/rspec/resources/its_container.rb +110 -0
- data/lib/dockerspec/{rspec_settings.rb → rspec/settings.rb} +5 -1
- data/lib/dockerspec/runner.rb +2 -357
- data/lib/dockerspec/runner/base.rb +367 -0
- data/lib/dockerspec/runner/compose.rb +322 -0
- data/lib/dockerspec/runner/docker.rb +302 -0
- data/lib/dockerspec/runner/serverspec.rb +21 -0
- data/lib/dockerspec/runner/serverspec/base.rb +185 -0
- data/lib/dockerspec/runner/serverspec/compose.rb +106 -0
- data/lib/dockerspec/runner/serverspec/docker.rb +116 -0
- data/lib/dockerspec/runner/serverspec/rspec.rb +20 -0
- data/lib/dockerspec/{serverspec/rspec_settings.rb → runner/serverspec/rspec/settings.rb} +1 -1
- data/lib/dockerspec/serverspec.rb +12 -2
- data/lib/dockerspec/version.rb +1 -1
- data/spec/spec_helper.rb +6 -2
- metadata +84 -15
- data/lib/dockerspec/rspec_assertions.rb +0 -54
- data/lib/dockerspec/rspec_resources.rb +0 -203
- data/lib/dockerspec/serverspec/rspec_resources.rb +0 -179
- data/lib/dockerspec/serverspec/runner.rb +0 -305
- data/lib/dockerspec/serverspec/specinfra_backend.rb +0 -128
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
3
|
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
4
|
-
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2015-2016 Xabier de Zuazo
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -23,7 +23,7 @@ require 'specinfra/backend/base'
|
|
23
23
|
# Add a method to the {Specinfra::Backend::Base} singleton class to set its
|
24
24
|
# internal backend.
|
25
25
|
#
|
26
|
-
#
|
26
|
+
# This hack makes me want to poke my own eyes out :-(
|
27
27
|
#
|
28
28
|
Specinfra::Backend::Base.class_eval do
|
29
29
|
#
|
@@ -37,7 +37,21 @@ Specinfra::Backend::Base.class_eval do
|
|
37
37
|
#
|
38
38
|
def self.instance_set(instance)
|
39
39
|
return if @instance == instance
|
40
|
-
|
40
|
+
host_reset
|
41
41
|
@instance = instance
|
42
42
|
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Resets the information stored for a host.
|
46
|
+
#
|
47
|
+
# - Host inventory.
|
48
|
+
# - Detected OS.
|
49
|
+
#
|
50
|
+
# @return void
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
#
|
54
|
+
def self.host_reset
|
55
|
+
property[:host_inventory] = property[:os] = nil
|
56
|
+
end
|
43
57
|
end
|
@@ -0,0 +1,150 @@
|
|
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/configuration'
|
21
|
+
require 'dockerspec/exceptions'
|
22
|
+
|
23
|
+
module Dockerspec
|
24
|
+
#
|
25
|
+
# Manages the list of testing engines to use.
|
26
|
+
#
|
27
|
+
class EngineList
|
28
|
+
#
|
29
|
+
# A message with description on how to avoid the error when you forget
|
30
|
+
# specifying the testing engine you want to use.
|
31
|
+
#
|
32
|
+
NO_ENGINES_MESSAGE = <<-EOE
|
33
|
+
|
34
|
+
Remember to include the Test Engine you want to use.
|
35
|
+
|
36
|
+
For example, to use Serverspec:
|
37
|
+
|
38
|
+
require 'dockerspec/serverspec'
|
39
|
+
|
40
|
+
EOE
|
41
|
+
.freeze
|
42
|
+
|
43
|
+
#
|
44
|
+
# Constructs the list of engines.
|
45
|
+
#
|
46
|
+
# Initializes all the selected engines.
|
47
|
+
#
|
48
|
+
# @param runner [Dockerspec::Runner::Base] The class used to run the
|
49
|
+
# docker container.
|
50
|
+
#
|
51
|
+
# @return [Dockerspec::EngineList] The list of engines.
|
52
|
+
#
|
53
|
+
# @raise [Dockerspec::EngineError] Raises this exception when the engine
|
54
|
+
# list is empty.
|
55
|
+
#
|
56
|
+
# @api public
|
57
|
+
#
|
58
|
+
def initialize(runner)
|
59
|
+
engine_classes = Configuration.engines
|
60
|
+
@engines =
|
61
|
+
engine_classes.map { |engine_class| engine_class.new(runner) }
|
62
|
+
assert_engines!
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Setups all the engines one by one.
|
67
|
+
#
|
68
|
+
# @param args [Mixed] Arguments to pass to the `#before_running` methods.
|
69
|
+
#
|
70
|
+
# @return void
|
71
|
+
#
|
72
|
+
# @api public
|
73
|
+
#
|
74
|
+
def before_running(*args)
|
75
|
+
call_engines_method(:before_running, *args)
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Notify the engines that the container to test is selected and ready.
|
80
|
+
#
|
81
|
+
# @param args [Mixed] Arguments to pass to the `#when_container_ready`
|
82
|
+
# methods.
|
83
|
+
#
|
84
|
+
# @return void
|
85
|
+
#
|
86
|
+
# @api public
|
87
|
+
#
|
88
|
+
def when_container_ready(*args)
|
89
|
+
call_engines_method(:when_container_ready, *args)
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Saves all the engines one by one.
|
94
|
+
#
|
95
|
+
# @param args [Mixed] Arguments to pass to the `#when_running` methods.
|
96
|
+
#
|
97
|
+
# @return void
|
98
|
+
#
|
99
|
+
# @api public
|
100
|
+
#
|
101
|
+
def when_running(*args)
|
102
|
+
call_engines_method(:when_running, *args)
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Restores all the engines one by one.
|
107
|
+
#
|
108
|
+
# @param args [Mixed] Arguments to pass to the `#restore` methods.
|
109
|
+
#
|
110
|
+
# @return void
|
111
|
+
#
|
112
|
+
# @api public
|
113
|
+
#
|
114
|
+
def restore(*args)
|
115
|
+
call_engines_method(:restore, *args)
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
|
120
|
+
#
|
121
|
+
# Ensures that there has been chosen at least one engine.
|
122
|
+
#
|
123
|
+
# @return void
|
124
|
+
#
|
125
|
+
# @raise [Dockerspec::EngineError] Raises this exception when the engine
|
126
|
+
# list is empty.
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
#
|
130
|
+
def assert_engines!
|
131
|
+
return unless @engines.empty?
|
132
|
+
raise EngineError, NO_ENGINES_MESSAGE
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Runs the same method on all the engines.
|
137
|
+
#
|
138
|
+
# @param method [String, Symbol] The method to run.
|
139
|
+
#
|
140
|
+
# @param args [Mixed] Arguments to pass to the methods.
|
141
|
+
#
|
142
|
+
# @return void
|
143
|
+
#
|
144
|
+
# @api private
|
145
|
+
#
|
146
|
+
def call_engines_method(method, *args)
|
147
|
+
@engines.map { |engine| engine.send(method, *args) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -24,8 +24,21 @@ module Dockerspec
|
|
24
24
|
#
|
25
25
|
class DockerRunArgumentError < ArgumentError; end
|
26
26
|
#
|
27
|
+
# An exception message raised when there are errors related to Test Engines.
|
28
|
+
#
|
29
|
+
class EngineError < ArgumentError; end
|
30
|
+
#
|
31
|
+
# An exception message raised when there are errors related to the Runner.
|
32
|
+
#
|
33
|
+
class RunnerError < ArgumentError; end
|
34
|
+
#
|
27
35
|
# An exception message raised when there are errors running Docker or
|
28
36
|
# building Docker images.
|
29
37
|
#
|
30
38
|
class DockerError < ArgumentError; end
|
39
|
+
#
|
40
|
+
# An exception message raised when there is an error with the `its_container`
|
41
|
+
# resource.
|
42
|
+
#
|
43
|
+
class ItsContainerError < ArgumentError; end
|
31
44
|
end
|
@@ -83,14 +83,14 @@ module Dockerspec
|
|
83
83
|
# @api private
|
84
84
|
#
|
85
85
|
def description_from_docker(str)
|
86
|
-
return str unless str
|
86
|
+
return str unless str =~ /^[0-9a-f]+$/
|
87
87
|
str[0..11]
|
88
88
|
end
|
89
89
|
|
90
90
|
#
|
91
91
|
# Generates a description from Docker ID.
|
92
92
|
#
|
93
|
-
|
93
|
+
alias description_from_id description_from_docker
|
94
94
|
|
95
95
|
#
|
96
96
|
# Generates a description from string.
|
@@ -136,7 +136,7 @@ module Dockerspec
|
|
136
136
|
#
|
137
137
|
# @api private
|
138
138
|
#
|
139
|
-
|
139
|
+
alias description_from_path description_from_file
|
140
140
|
end
|
141
141
|
end
|
142
142
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
3
|
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
4
|
-
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2015-2016 Xabier de Zuazo
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -23,6 +23,36 @@ module Dockerspec
|
|
23
23
|
# Some Helper methods to work with RSpec Examples.
|
24
24
|
#
|
25
25
|
module RSpecExampleHelpers
|
26
|
+
#
|
27
|
+
# Checks if the parent RSpec example information exists in the metadata.
|
28
|
+
#
|
29
|
+
# @param metadata [Hash] RSpec metadata.
|
30
|
+
#
|
31
|
+
# @return [Boolean] Returns true if the parent metadata is available.
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
#
|
35
|
+
def self.metadata_has_parent?(metadata)
|
36
|
+
metadata.key?(:parent_example_group) || metadata.key?(:example_group)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Get the parent RSpec example metadata if available.
|
41
|
+
#
|
42
|
+
# @param metadata [Hash] RSpec metadata.
|
43
|
+
#
|
44
|
+
# @return [Hash] RSpec metadata from the parent example.
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
#
|
48
|
+
def self.metadata_parent(metadata)
|
49
|
+
if metadata.key?(:parent_example_group)
|
50
|
+
metadata[:parent_example_group]
|
51
|
+
elsif metadata.key?(:example_group)
|
52
|
+
metadata[:example_group]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
26
56
|
#
|
27
57
|
# Searches for an object in the description of the parent RSpec examples.
|
28
58
|
#
|
@@ -34,15 +64,65 @@ module Dockerspec
|
|
34
64
|
# @api public
|
35
65
|
#
|
36
66
|
def self.search_object(metadata, klass)
|
37
|
-
return
|
67
|
+
return nil if metadata.nil?
|
38
68
|
if metadata[:described_class].is_a?(klass)
|
39
69
|
metadata[:described_class]
|
40
|
-
elsif
|
41
|
-
search_object(metadata
|
42
|
-
elsif metadata.key?(:example_group)
|
43
|
-
search_object(metadata[:example_group], klass)
|
70
|
+
elsif metadata_has_parent?(metadata)
|
71
|
+
search_object(metadata_parent(metadata), klass)
|
44
72
|
end
|
45
73
|
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Searches for an object in the description of the parent RSpec examples
|
77
|
+
# that implements a specific method.
|
78
|
+
#
|
79
|
+
# @param metadata [Hash] RSpec metadata.
|
80
|
+
# @param meth [Symbol] The method name.
|
81
|
+
# @param arity [Integer] The arity of the method.
|
82
|
+
#
|
83
|
+
# @return [Array<Object>] Returns the objects list.
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
#
|
87
|
+
def self.search_objects_with(metadata, meth, arity)
|
88
|
+
o_ary = []
|
89
|
+
return o_ary if metadata.nil?
|
90
|
+
if metadata[:described_class].respond_to?(meth) &&
|
91
|
+
metadata[:described_class].method(meth).arity == arity
|
92
|
+
o_ary << metadata[:described_class]
|
93
|
+
end
|
94
|
+
return o_ary unless metadata_has_parent?(metadata)
|
95
|
+
search_objects_with(metadata_parent(metadata), meth, arity) + o_ary
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# Restores the Docker running container instance in the Specinfra
|
100
|
+
# internal reference.
|
101
|
+
#
|
102
|
+
# Gets the correct {Runner::Base} reference from the RSpec metadata.
|
103
|
+
#
|
104
|
+
# @example Restore Specinfra Backend
|
105
|
+
# RSpec.configure do |c|
|
106
|
+
# c.before(:each) do
|
107
|
+
# metadata = RSpec.current_example.metadata
|
108
|
+
# Dockerspec::Runner::Base.restore(metadata)
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# @param metadata [Hash] RSpec metadata.
|
113
|
+
#
|
114
|
+
# @return void
|
115
|
+
#
|
116
|
+
# @api public
|
117
|
+
#
|
118
|
+
# @see restore
|
119
|
+
#
|
120
|
+
def self.restore_rspec_context(metadata)
|
121
|
+
o_ary =
|
122
|
+
Helper::RSpecExampleHelpers
|
123
|
+
.search_objects_with(metadata, :restore_rspec_context, 0)
|
124
|
+
o_ary.each(&:restore_rspec_context)
|
125
|
+
end
|
46
126
|
end
|
47
127
|
end
|
48
128
|
end
|
@@ -0,0 +1,26 @@
|
|
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'
|
21
|
+
require 'dockerspec/engine/infrataster'
|
22
|
+
|
23
|
+
#
|
24
|
+
# Use Infrataster to run the tests (engine).
|
25
|
+
#
|
26
|
+
Dockerspec::Configuration.add_engine Dockerspec::Engine::Infrataster
|
@@ -0,0 +1,21 @@
|
|
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/rspec/resources'
|
21
|
+
require 'dockerspec/rspec/configuration'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#
|
3
3
|
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
4
|
-
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
|
4
|
+
# Copyright:: Copyright (c) 2015-2016 Xabier de Zuazo
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -0,0 +1,602 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
|
4
|
+
# Copyright:: Copyright (c) 2015-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/configuration'
|
21
|
+
require 'dockerspec/rspec/settings'
|
22
|
+
require 'dockerspec/builder'
|
23
|
+
require 'dockerspec/rspec/resources/its_container'
|
24
|
+
require 'dockerspec/exceptions'
|
25
|
+
|
26
|
+
module Dockerspec
|
27
|
+
#
|
28
|
+
# Some classes related to RSpec testing framework.
|
29
|
+
#
|
30
|
+
module RSpec
|
31
|
+
#
|
32
|
+
# Some resources included inside {RSpec::Core::ExampleGroup} to build and
|
33
|
+
# run Docker containers.
|
34
|
+
#
|
35
|
+
# ## Load the Test Engine You Want to Use
|
36
|
+
#
|
37
|
+
# If you want to run [Serverspec](http://serverspec.org/) tests, you need
|
38
|
+
# to require the `dockerspec/serverspec` path:
|
39
|
+
#
|
40
|
+
# ```ruby
|
41
|
+
# require 'dockerspec/serverspec'
|
42
|
+
# ```
|
43
|
+
#
|
44
|
+
# If you want to run [Infrataster](https://github.com/ryotarai/infrataster)
|
45
|
+
# tests, you need to require the `dockerspec/infrataster` path:
|
46
|
+
#
|
47
|
+
# ```ruby
|
48
|
+
# require 'dockerspec/infrataster'
|
49
|
+
# ```
|
50
|
+
#
|
51
|
+
# Of course, you can load both engines:
|
52
|
+
#
|
53
|
+
# ```ruby
|
54
|
+
# require 'dockerspec/serverspec'
|
55
|
+
# require 'dockerspec/infrataster'
|
56
|
+
# ```
|
57
|
+
#
|
58
|
+
# ## RSpec Settings
|
59
|
+
#
|
60
|
+
# * `dockerfile_path`: The dockerfile path.
|
61
|
+
# * `rm_build`: Whether to remove the build after the run.
|
62
|
+
# * `log_level`: Log level to use by default.
|
63
|
+
# * `docker_wait`: Seconds to wait before running the tests.
|
64
|
+
# * `container_name`: Docker container to test with Docker Compose.
|
65
|
+
#
|
66
|
+
# All the RSpec settings are optional.
|
67
|
+
#
|
68
|
+
# @example RSpec Settings
|
69
|
+
# RSpec.configure do |config|
|
70
|
+
# config.log_level = :silent
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
module Resources
|
74
|
+
#
|
75
|
+
# Builds a Docker image.
|
76
|
+
#
|
77
|
+
# The image can be build from a path or from a string.
|
78
|
+
#
|
79
|
+
# See the {Dockerspec::Builder::ConfigHelpers} documentation for more
|
80
|
+
# information about the available RSpec resource helpers.
|
81
|
+
#
|
82
|
+
# @example A Simple Example
|
83
|
+
# describe 'My Dockerfile' do
|
84
|
+
# describe docker_build('.') do
|
85
|
+
# it { should have_maintainer /John Doe/ }
|
86
|
+
# it { should have_cmd ['/bin/dash'] }
|
87
|
+
# it { should have_expose '80' }
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# @example A Complete Example
|
92
|
+
# describe docker_build(path: '.') do
|
93
|
+
# it { should have_maintainer 'John Doe "john.doe@example.com"' }
|
94
|
+
# it { should have_maintainer(/John Doe/) }
|
95
|
+
# it { should have_cmd %w(2 2000) }
|
96
|
+
# it { should have_label 'description' }
|
97
|
+
# it { should have_label 'description' => 'My Container' }
|
98
|
+
# it { should have_expose '80' }
|
99
|
+
# it { should have_expose(/80$/) }
|
100
|
+
# it { should have_env 'container' }
|
101
|
+
# it { should have_env 'container' => 'docker' }
|
102
|
+
# it { should have_env 'PATH' => '/tmp/bin:/sbin:/bin' }
|
103
|
+
# it { should have_entrypoint ['sleep'] }
|
104
|
+
# it { should have_volume '/volume1' }
|
105
|
+
# it { should have_volume %r{/vol.*2} }
|
106
|
+
# it { should have_user 'nobody' }
|
107
|
+
# it { should have_workdir '/opt' }
|
108
|
+
# it { should have_workdir %r{^/op} }
|
109
|
+
# it { should have_onbuild 'RUN echo onbuild' }
|
110
|
+
# it { should have_stopsignal 'SIGTERM' }
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# @example Checking the Attribute Values Using the `its` Method
|
114
|
+
# describe docker_build(path: '.') do
|
115
|
+
# its(:maintainer) { should eq 'John Doe "john.doe@example.com"' }
|
116
|
+
# its(:cmd) { should eq %w(2 2000) }
|
117
|
+
# its(:labels) { should include 'description' }
|
118
|
+
# its(:labels) { should include 'description' => 'My Container' }
|
119
|
+
# its(:exposes) { should include '80' }
|
120
|
+
# its(:env) { should include 'container' }
|
121
|
+
# its(:env) { should include 'container' => 'docker' }
|
122
|
+
# its(:entrypoint) { should eq ['sleep'] }
|
123
|
+
# its(:volumes) { should include '/volume1' }
|
124
|
+
# its(:user) { should eq 'nobody' }
|
125
|
+
# its(:workdir) { should eq '/opt' }
|
126
|
+
# its(:onbuilds) { should include 'RUN echo onbuild' }
|
127
|
+
# its(:stopsignal) { should eq 'SIGTERM' }
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# @example Checking Its Size and OS
|
131
|
+
# describe docker_build(path: '.') do
|
132
|
+
# its(:size) { should be < 20 * 2**20 } # 20M
|
133
|
+
# its(:arch) { should eq 'amd64' }
|
134
|
+
# its(:os) { should eq 'linux' }
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# @example Building from a File
|
138
|
+
# describe docker_build(path: '../dockerfiles/Dockerfile-nginx') do
|
139
|
+
# # [...]
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# @example Building from a Template
|
143
|
+
# describe docker_build(template: 'Dockerfile1.erb') do
|
144
|
+
# # [...]
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# @example Building from a Template with a Context
|
148
|
+
# describe docker_build(
|
149
|
+
# template: 'Dockerfile1.erb', context: {version: '8'}
|
150
|
+
# ) do
|
151
|
+
# it { should have_maintainer(/John Doe/) }
|
152
|
+
# it { should have_cmd %w(/bin/sh) }
|
153
|
+
# # [...]
|
154
|
+
# end
|
155
|
+
#
|
156
|
+
# @example Building from a String
|
157
|
+
# describe docker_build(string: "FROM nginx:1.9\n [...]") do
|
158
|
+
# # [...]
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# @example Building from a Docker Image ID
|
162
|
+
# describe docker_build(id: '07d362aea98d') do
|
163
|
+
# # [...]
|
164
|
+
# end
|
165
|
+
#
|
166
|
+
# @example Building from a Docker Image Name
|
167
|
+
# describe docker_build(id: 'nginx:1.9') do
|
168
|
+
# # [...]
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# @param opts [String, Hash] The `:path` or a list of options.
|
172
|
+
#
|
173
|
+
# @option opts [String] :path ('.') The directory or file that contains
|
174
|
+
# the *Dockerfile*. By default tries to read it from the
|
175
|
+
# `DOCKERFILE_PATH` environment variable and uses `'.'` if it is not
|
176
|
+
# set.
|
177
|
+
# @option opts [String] :string Use this string as *Dockerfile* instead of
|
178
|
+
# `:path`. Not set by default.
|
179
|
+
# @option opts [String] :template Use this [Erubis]
|
180
|
+
# (http://www.kuwata-lab.com/erubis/users-guide.html) template file as
|
181
|
+
# *Dockerfile*.
|
182
|
+
# @option opts [String] :id Use this Docker image ID instead of a
|
183
|
+
# *Dockerfile*.
|
184
|
+
# @option opts [Boolean] :rm Whether to remove the generated docker images
|
185
|
+
# after running the tests. By default only removes them if it is running
|
186
|
+
# on a CI machine.
|
187
|
+
# @option opts [Hash, Erubis::Context] :context ({}) Template *context*
|
188
|
+
# used when the `:template` source is used.
|
189
|
+
# @option opts [String] :tag Repository tag to be applied to the resulting
|
190
|
+
# image.
|
191
|
+
# @option opts [Fixnum, Symbol] :log_level Sets the docker library
|
192
|
+
# verbosity level. Possible values:
|
193
|
+
# `:silent` or `0` (no output),
|
194
|
+
# `:ci` or `1` (enables some outputs recommended for CI environments),
|
195
|
+
# `:info` or `2` (gives information about main build steps),
|
196
|
+
# `:debug` or `3` (outputs all the provided information in its raw
|
197
|
+
# original form).
|
198
|
+
#
|
199
|
+
# @return [Dockerspec::Builder] Builder object.
|
200
|
+
#
|
201
|
+
# @raise [Dockerspec::DockerError] For underlaying docker errors.
|
202
|
+
#
|
203
|
+
# @see Dockerspec::Builder::ConfigHelpers
|
204
|
+
#
|
205
|
+
# @api public
|
206
|
+
#
|
207
|
+
def docker_build(*opts)
|
208
|
+
builder = Dockerspec::Builder.new(*opts)
|
209
|
+
builder.build
|
210
|
+
described_image(builder.id)
|
211
|
+
builder
|
212
|
+
end
|
213
|
+
|
214
|
+
#
|
215
|
+
# Runs a docker image.
|
216
|
+
#
|
217
|
+
# See the [Serverspec Resource Types documentation]
|
218
|
+
# (http://serverspec.org/resource_types.html) to see the available
|
219
|
+
# resources.
|
220
|
+
#
|
221
|
+
# By default tries to detect the most appropriate Docker backend: native
|
222
|
+
# or LXC.
|
223
|
+
#
|
224
|
+
# @example A Basic Example to Test the HTTPd Service
|
225
|
+
# describe docker_build('.', tag: 'myapp') do
|
226
|
+
# describe docker_run('myapp') do
|
227
|
+
# describe service('httpd') do
|
228
|
+
# it { should be_enabled }
|
229
|
+
# it { should be_running }
|
230
|
+
# end
|
231
|
+
# # [...]
|
232
|
+
# end
|
233
|
+
# end
|
234
|
+
#
|
235
|
+
# @example Avoid Automatic OS Detection to Speed Up the Tests
|
236
|
+
# describe docker_build('.', tag: 'myapp') do
|
237
|
+
# describe docker_run('myapp', family: 'debian') do
|
238
|
+
# # [...]
|
239
|
+
# end
|
240
|
+
# end
|
241
|
+
#
|
242
|
+
# @example Using Hash Format
|
243
|
+
# describe docker_build('.', tag: 'myapp') do
|
244
|
+
# describe docker_run(tag: 'myapp', family: 'debian') do
|
245
|
+
# # [...]
|
246
|
+
# end
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# @example Force a Specific Docker Backend
|
250
|
+
# describe docker_build('.', tag: 'myapp') do
|
251
|
+
# describe docker_run('myapp', backend: :lxc) do
|
252
|
+
# # [...]
|
253
|
+
# end
|
254
|
+
# end
|
255
|
+
#
|
256
|
+
# @example Use a Backend Not Included by Default
|
257
|
+
# # specinfra-backend-docker_nsenter gem must be installed by hand
|
258
|
+
# require 'specinfra/backend/docker_nsenter'
|
259
|
+
# describe docker_build('.', tag: 'myapp') do
|
260
|
+
# describe docker_run('myapp', backend: :nsenter) do
|
261
|
+
# # [...]
|
262
|
+
# end
|
263
|
+
# end
|
264
|
+
#
|
265
|
+
# @example Running a Container Image Tag
|
266
|
+
# describe docker_run('debian:8') do
|
267
|
+
# # [...]
|
268
|
+
# end
|
269
|
+
#
|
270
|
+
# @example Testing `FROM` Dockerfile Instruction
|
271
|
+
# # FROM debian:8
|
272
|
+
# describe docker_run('myapp') do
|
273
|
+
# describe file('/etc/debian_version') do
|
274
|
+
# it { should be_file }
|
275
|
+
# its(:content) { should match /^8\./ }
|
276
|
+
# end
|
277
|
+
# # Another way to check it:
|
278
|
+
# describe command('lsb_release -ri') do
|
279
|
+
# its(:stdout) { should match /^Distributor ID:\s+Debian/ }
|
280
|
+
# its(:stdout) { should match /^Release:\s+8\./ }
|
281
|
+
# end
|
282
|
+
# end
|
283
|
+
#
|
284
|
+
# @example Testing `COPY` and `ADD` Dockerfile Instructions
|
285
|
+
# # COPY docker-entrypoint.sh /entrypoint.sh
|
286
|
+
# describe docker_run('myapp') do
|
287
|
+
# describe file('/entrypoint.sh') do
|
288
|
+
# it { should be_file }
|
289
|
+
# its(:content) { should match /^exec java -jar myapp\.jar/ }
|
290
|
+
# end
|
291
|
+
# end
|
292
|
+
#
|
293
|
+
# @example Testing `RUN` Dockerfile Instructions
|
294
|
+
# describe docker_run('myapp') do
|
295
|
+
# # RUN apt-get install -y wget
|
296
|
+
# describe package('wget') do
|
297
|
+
# it { should be_installed }
|
298
|
+
# end
|
299
|
+
# # RUN useradd -g myapp -d /opt/myapp myapp
|
300
|
+
# describe user('myapp') do
|
301
|
+
# it { should exist }
|
302
|
+
# it { should belong_to_group 'myapp' }
|
303
|
+
# it { should have_home_directory '/opt/myapp' }
|
304
|
+
# end
|
305
|
+
# end
|
306
|
+
#
|
307
|
+
# @example Testing with Infrataster
|
308
|
+
# require 'dockerspec/infrataster'
|
309
|
+
# describe docker_run('nginx') do
|
310
|
+
# describe server(described_container) do
|
311
|
+
# describe http('/') do
|
312
|
+
# it 'responds content including "Welcome to nginx!"' do
|
313
|
+
# expect(response.body).to include 'Welcome to nginx!'
|
314
|
+
# end
|
315
|
+
# it 'responds as "nginx" server' do
|
316
|
+
# expect(response.headers['server']).to match(/nginx/i)
|
317
|
+
# end
|
318
|
+
# end
|
319
|
+
# end
|
320
|
+
# end
|
321
|
+
#
|
322
|
+
# @param opts [String, Hash] The `:tag` or a list of options. This
|
323
|
+
# configuration options will be passed to the Testing Engines like
|
324
|
+
# Infrataster. So you can include your Infrataster server configuration
|
325
|
+
# here.
|
326
|
+
#
|
327
|
+
# @option opts [String] :tag The Docker image tag name to run.
|
328
|
+
# @option opts [String] :id The Docker container ID to use instead of
|
329
|
+
# starting a new container.
|
330
|
+
# @option opts [Boolean] :rm (calculated) Whether to remove the Docker
|
331
|
+
# container afterwards.
|
332
|
+
# @option opts [String] :path The environment `PATH` value of the
|
333
|
+
# container.
|
334
|
+
# @option opts [Hash, Array] :env Some `ENV` instructions to add to the
|
335
|
+
# container.
|
336
|
+
# @option opts [Symbol, String] :family (calculated) The OS family.
|
337
|
+
# It's automatically detected by default, but can be used to
|
338
|
+
# **speed up the tests**. Some possible values:
|
339
|
+
# `:alpine`, `:arch`, `:coreos`, `:debian`, `:gentoo`, `:nixos`,
|
340
|
+
# `:plamo`, `:poky`, `:redhat`, `:suse`.
|
341
|
+
# @option opts [Symbol] :backend (calculated) Docker backend to use:
|
342
|
+
# `:docker`, `:lxc`.
|
343
|
+
#
|
344
|
+
# @return [Dockerspec::Runner::Docker] Runner object.
|
345
|
+
#
|
346
|
+
# @raise [Dockerspec::DockerRunArgumentError] Raises this exception when
|
347
|
+
# some required fields are missing.
|
348
|
+
#
|
349
|
+
# @raise [Dockerspec::EngineError] Raises this exception when the engine
|
350
|
+
# list is empty.
|
351
|
+
#
|
352
|
+
# @raise [Dockerspec::DockerError] For underlaying docker errors.
|
353
|
+
#
|
354
|
+
# @api public
|
355
|
+
#
|
356
|
+
def docker_run(*opts)
|
357
|
+
runner = Dockerspec::Configuration.docker_runner.new(*opts)
|
358
|
+
runner.run
|
359
|
+
described_container(runner.container_name)
|
360
|
+
runner
|
361
|
+
end
|
362
|
+
|
363
|
+
#
|
364
|
+
# Runs Docker Compose.
|
365
|
+
#
|
366
|
+
# By default tries to detect the most appropriate Docker backend: native
|
367
|
+
# or LXC.
|
368
|
+
#
|
369
|
+
# @example Testing Containers from a YAML File
|
370
|
+
# describe docker_compose('docker-compose.yml', wait: 15) do
|
371
|
+
# its_container(:myapp) do
|
372
|
+
# describe process('apache2') do
|
373
|
+
# it { should be_running }
|
374
|
+
# end
|
375
|
+
# # [...]
|
376
|
+
# end
|
377
|
+
# its_container(:db) do
|
378
|
+
# describe process('mysqld') do
|
379
|
+
# it { should be_running }
|
380
|
+
# end
|
381
|
+
# # [...]
|
382
|
+
# end
|
383
|
+
# end
|
384
|
+
#
|
385
|
+
# @example Testing Only One Container from a Directory
|
386
|
+
# describe docker_compose('data/', container: :myapp, wait: 15) do
|
387
|
+
# describe process('apache2') do
|
388
|
+
# it { should be_running }
|
389
|
+
# end
|
390
|
+
# # [...]
|
391
|
+
# end
|
392
|
+
#
|
393
|
+
# @example Avoid Automatic OS Detection to Speed Up the Tests
|
394
|
+
# describe docker_compose(
|
395
|
+
# 'data/', container: :myapp, family: 'debian', wait: 15
|
396
|
+
# ) do
|
397
|
+
# describe process('apache2') do
|
398
|
+
# it { should be_running }
|
399
|
+
# end
|
400
|
+
# # [...]
|
401
|
+
# end
|
402
|
+
#
|
403
|
+
# @param opts [String, Hash] The `:file` or a list of options.
|
404
|
+
#
|
405
|
+
# @option opts [String] :file The compose YAML file or a directory
|
406
|
+
# containing the `'docker-compose.yml'` file.
|
407
|
+
# @option opts [Symbol, String] :container The name of the container to
|
408
|
+
# test. It is better to use
|
409
|
+
# {Dockerspec::RSpec::Resources#its_container} if you want to test
|
410
|
+
# multiple containers.
|
411
|
+
# @option opts [Boolean] :rm (calculated) Whether to remove the Docker
|
412
|
+
# containers afterwards.
|
413
|
+
# @option opts [Symbol, String] :family (calculated) The OS family.
|
414
|
+
# It's automatically detected by default, but can be used to
|
415
|
+
# **speed up the tests**. Some possible values:
|
416
|
+
# `:alpine`, `:arch`, `:coreos`, `:debian`, `:gentoo`, `:nixos`,
|
417
|
+
# `:plamo`, `:poky`, `:redhat`, `:suse`.
|
418
|
+
# @option opts [Symbol] :backend (calculated) Docker backend to use:
|
419
|
+
# `:docker_compose`, `:docker_compose_lxc`.
|
420
|
+
#
|
421
|
+
# @return [Dockerspec::Runner::Compose] Runner object.
|
422
|
+
#
|
423
|
+
# @raise [Dockerspec::DockerRunArgumentError] Raises this exception when
|
424
|
+
# some required fields are missing.
|
425
|
+
#
|
426
|
+
# @raise [Dockerspec::EngineError] Raises this exception when the engine
|
427
|
+
# list is empty.
|
428
|
+
#
|
429
|
+
# @raise [Dockerspec::DockerError] For underlaying docker errors.
|
430
|
+
#
|
431
|
+
# @api public
|
432
|
+
#
|
433
|
+
def docker_compose(*opts)
|
434
|
+
runner = Dockerspec::Configuration.compose_runner.new(*opts)
|
435
|
+
runner.run
|
436
|
+
end
|
437
|
+
|
438
|
+
#
|
439
|
+
# Selects the container to test inside {#docker_compose}.
|
440
|
+
#
|
441
|
+
# @example Testing Multiple Containers
|
442
|
+
# describe docker_compose('docker-compose.yml', wait: 15) do
|
443
|
+
# its_container(:myapp) do
|
444
|
+
# describe process('apache2') do
|
445
|
+
# it { should be_running }
|
446
|
+
# its(:args) { should match(/-DFOREGROUND/) }
|
447
|
+
# end
|
448
|
+
# # [...]
|
449
|
+
# end
|
450
|
+
# its_container(:db) do
|
451
|
+
# describe process('mysqld') do
|
452
|
+
# it { should be_running }
|
453
|
+
# end
|
454
|
+
# # [...]
|
455
|
+
# end
|
456
|
+
# end
|
457
|
+
#
|
458
|
+
# @example Avoid Automatic OS Detection to Speed Up the Tests
|
459
|
+
# describe docker_compose('docker-compose.yml', wait: 15) do
|
460
|
+
# its_container('myapp', family: 'centos') do
|
461
|
+
# describe process('httpd') do
|
462
|
+
# it { should be_running }
|
463
|
+
# end
|
464
|
+
# # [...]
|
465
|
+
# end
|
466
|
+
# its_container('db', family: 'debian') do
|
467
|
+
# describe process('mysqld') do
|
468
|
+
# it { should be_running }
|
469
|
+
# end
|
470
|
+
# # [...]
|
471
|
+
# end
|
472
|
+
# end
|
473
|
+
#
|
474
|
+
# @example Testing a Database with Infrataster using Docker Compose
|
475
|
+
# require 'dockerspec/infrataster'
|
476
|
+
# # After including `gem 'infrataster-plugin-mysql'` in your Gemfile:
|
477
|
+
# require 'infrataster-plugin-mysql'
|
478
|
+
# describe docker_compose('docker-compose.yml', wait: 60) do
|
479
|
+
# its_container(:db, mysql: { user: 'root', password: 'example' }) do
|
480
|
+
# describe server(described_container) do
|
481
|
+
# describe mysql_query('SHOW STATUS') do
|
482
|
+
# it 'returns positive uptime' do
|
483
|
+
# row = results.find { |r| r['Variable_name'] == 'Uptime' }
|
484
|
+
# expect(row['Value'].to_i).to be > 0
|
485
|
+
# end
|
486
|
+
# end
|
487
|
+
# end
|
488
|
+
# end
|
489
|
+
# end
|
490
|
+
#
|
491
|
+
# @param container [Symbol, String] The name of the container to test.
|
492
|
+
#
|
493
|
+
# @param opts [Hash] A list of options. This configuration options will
|
494
|
+
# be passed to the Testing Engines like Infrataster. So you can include
|
495
|
+
# your Infrataster server configuration here.
|
496
|
+
#
|
497
|
+
# @option opts [Symbol, String] :family (calculated) The OS family.
|
498
|
+
# It's automatically detected by default, but can be used to
|
499
|
+
# **speed up the tests**. Some possible values:
|
500
|
+
# `:alpine`, `:arch`, `:coreos`, `:debian`, `:gentoo`, `:nixos`,
|
501
|
+
# `:plamo`, `:poky`, `:redhat`, `:suse`.
|
502
|
+
#
|
503
|
+
# @return [Dockerspec::Runner::Compose] Runner object.
|
504
|
+
#
|
505
|
+
# @raise [Dockerspec::DockerComposeError] Raises this exception when
|
506
|
+
# you call `its_container` without calling `docker_compose`.
|
507
|
+
#
|
508
|
+
# @api public
|
509
|
+
#
|
510
|
+
def its_container(container, *opts, &block)
|
511
|
+
compose = Runner::Compose.current_instance
|
512
|
+
if compose.nil?
|
513
|
+
raise ItsContainerError, ItsContainer::NO_DOCKER_COMPOSE_MESSAGE
|
514
|
+
end
|
515
|
+
container_opts = opts[0].is_a?(Hash) ? opts[0] : {}
|
516
|
+
compose.select_container(container, container_opts)
|
517
|
+
described_container(compose.container_name)
|
518
|
+
describe(ItsContainer.new(container), *opts, &block)
|
519
|
+
end
|
520
|
+
|
521
|
+
#
|
522
|
+
# Sets or gets the latest run container name.
|
523
|
+
#
|
524
|
+
# This can be used to avoid adding a tag to the build image.
|
525
|
+
#
|
526
|
+
# @example
|
527
|
+
# describe docker_build('.') do
|
528
|
+
# describe docker_run(described_image, family: 'debian') do
|
529
|
+
# # [...]
|
530
|
+
# end
|
531
|
+
# end
|
532
|
+
#
|
533
|
+
# @param value [String] The docker image id.
|
534
|
+
#
|
535
|
+
# @return [String] The docker image id.
|
536
|
+
#
|
537
|
+
# @api public
|
538
|
+
#
|
539
|
+
def described_image(value = nil)
|
540
|
+
# rubocop:disable Style/ClassVars
|
541
|
+
@@described_image = value unless value.nil?
|
542
|
+
# rubocop:enable Style/ClassVars
|
543
|
+
@@described_image
|
544
|
+
end
|
545
|
+
|
546
|
+
#
|
547
|
+
# Sets or gets the latest run container name.
|
548
|
+
#
|
549
|
+
# Used to call the Infrataster {#server} method.
|
550
|
+
#
|
551
|
+
# @example Testing a Docker Container
|
552
|
+
# describe docker_run('myapp') do
|
553
|
+
# describe server(described_container) do
|
554
|
+
# describe http('/') do
|
555
|
+
# it 'responds content including "My App Homepage"' do
|
556
|
+
# expect(response.body).to match(/My App Homepage/i)
|
557
|
+
# end
|
558
|
+
# end
|
559
|
+
# end
|
560
|
+
# end
|
561
|
+
#
|
562
|
+
# @example Testing with Docker Compose
|
563
|
+
# describe docker_compose('docker-compose.yml', wait: 60) do
|
564
|
+
# its_container(:wordpress) do
|
565
|
+
# describe server(described_container) do
|
566
|
+
# describe http('/wp-admin/install.php') do
|
567
|
+
# it 'responds content including "Wordpress Installation"' do
|
568
|
+
# expect(response.body).to match(/WordPress .* Installation/i)
|
569
|
+
# end
|
570
|
+
# end
|
571
|
+
# end
|
572
|
+
# end
|
573
|
+
# end
|
574
|
+
#
|
575
|
+
# @param value [Symbol, String] The container name.
|
576
|
+
#
|
577
|
+
# @return [Symbol] The container name.
|
578
|
+
#
|
579
|
+
# @api public
|
580
|
+
#
|
581
|
+
def described_container(value = nil)
|
582
|
+
# rubocop:disable Style/ClassVars
|
583
|
+
@@described_container = value unless value.nil?
|
584
|
+
# rubocop:enable Style/ClassVars
|
585
|
+
@@described_container.to_sym
|
586
|
+
end
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
#
|
592
|
+
# Add the Dockerspec resources to RSpec core.
|
593
|
+
#
|
594
|
+
RSpec::Core::ExampleGroup.class_eval do
|
595
|
+
extend Dockerspec::RSpec::Resources
|
596
|
+
include Dockerspec::RSpec::Resources
|
597
|
+
end
|
598
|
+
|
599
|
+
#
|
600
|
+
# Allow using #docker_build in the outermost example
|
601
|
+
#
|
602
|
+
extend Dockerspec::RSpec::Resources
|