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
@@ -0,0 +1,156 @@
|
|
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
|
+
module Dockerspec
|
21
|
+
#
|
22
|
+
# The classes behind this namespace are Testing Engines. These are the
|
23
|
+
# frameworks used below to run the tests. For example `Specinfra` (used by
|
24
|
+
# `Serverspec`).
|
25
|
+
#
|
26
|
+
module Engine
|
27
|
+
#
|
28
|
+
# A basic class with the minimal skeleton to create a Testing Engine.
|
29
|
+
#
|
30
|
+
class Base
|
31
|
+
#
|
32
|
+
# Constructs the engine.
|
33
|
+
#
|
34
|
+
# Saves the runner and the options.
|
35
|
+
#
|
36
|
+
# @param runner [Dockerspec::Runner::Base] The class that is being used
|
37
|
+
# to run the Docker Containers.
|
38
|
+
#
|
39
|
+
# @return [Dockerspec::Engine::Base] The engine.
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
#
|
43
|
+
def initialize(runner)
|
44
|
+
@runner = runner
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Runs the engine setup just before running docker.
|
49
|
+
#
|
50
|
+
# Also run when there is a change in the testing target like changing the
|
51
|
+
# container you want to run the tests into with Docker Compose.
|
52
|
+
#
|
53
|
+
# Usually this is implemented to clean configurations from previous tests.
|
54
|
+
#
|
55
|
+
# Does nothing by default.
|
56
|
+
#
|
57
|
+
# @param args [Mixed] The passed arguments.
|
58
|
+
#
|
59
|
+
# @return void
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
#
|
63
|
+
def before_running(*args); end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Saves the engine status internally after starting the docker container.
|
67
|
+
#
|
68
|
+
# Does nothing by default.
|
69
|
+
#
|
70
|
+
# @param args [Mixed] The passed arguments.
|
71
|
+
#
|
72
|
+
# @return void
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
#
|
76
|
+
def when_running(*args); end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Runs when the container to test is ready.
|
80
|
+
#
|
81
|
+
# This is mainly used with Docker Compose to know when the container to
|
82
|
+
# test is selected.
|
83
|
+
#
|
84
|
+
# Without Docker Compose this is called just after calling
|
85
|
+
# {#when_running}.
|
86
|
+
#
|
87
|
+
# Does nothing by default.
|
88
|
+
#
|
89
|
+
# @param args [Mixed] The passed arguments.
|
90
|
+
#
|
91
|
+
# @return void
|
92
|
+
#
|
93
|
+
# @api public
|
94
|
+
#
|
95
|
+
def when_container_ready(*args); end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Restores the engine internal status after running tests on other
|
99
|
+
# containers.
|
100
|
+
#
|
101
|
+
# This is used to avoid the engine running against the last started
|
102
|
+
# container if you are testing multiple containers at the same time.
|
103
|
+
#
|
104
|
+
# Does nothing by default.
|
105
|
+
#
|
106
|
+
# @param args [Mixed] The passed arguments.
|
107
|
+
#
|
108
|
+
# @return void
|
109
|
+
#
|
110
|
+
# @api public
|
111
|
+
#
|
112
|
+
def restore(*args); end
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
#
|
117
|
+
# Gets the configuration options from the runner.
|
118
|
+
#
|
119
|
+
# @return [Hash] Options list.
|
120
|
+
#
|
121
|
+
# @api private
|
122
|
+
#
|
123
|
+
def options
|
124
|
+
@runner.options
|
125
|
+
end
|
126
|
+
|
127
|
+
#
|
128
|
+
# Gets the Container Name.
|
129
|
+
#
|
130
|
+
# @return [String, nil] Container name.
|
131
|
+
#
|
132
|
+
# @raise [Dockerspec::RunnerError] When the `#container` method is no
|
133
|
+
# implemented in the subclass or cannot select the container to test.
|
134
|
+
#
|
135
|
+
# @api private
|
136
|
+
#
|
137
|
+
def container_name
|
138
|
+
@runner.container_name
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Gets the Docker Container IP address.
|
143
|
+
#
|
144
|
+
# @return [String] IP address.
|
145
|
+
#
|
146
|
+
# @raise [Dockerspec::RunnerError] When the `#container` method is no
|
147
|
+
# implemented in the subclass or cannot select the container to test.
|
148
|
+
#
|
149
|
+
# @api private
|
150
|
+
#
|
151
|
+
def ipaddress
|
152
|
+
@runner.ipaddress
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,87 @@
|
|
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 'infrataster/rspec'
|
21
|
+
require 'dockerspec/engine/base'
|
22
|
+
require 'securerandom'
|
23
|
+
|
24
|
+
module Dockerspec
|
25
|
+
module Engine
|
26
|
+
#
|
27
|
+
# The Infrataster testing engine implementation.
|
28
|
+
#
|
29
|
+
class Infrataster < Base
|
30
|
+
include ::Infrataster::Helpers::ResourceHelper
|
31
|
+
|
32
|
+
#
|
33
|
+
# Constructs a testing engine to use Infrataster.
|
34
|
+
#
|
35
|
+
# @param runner [Dockerspec::Runner::Base] The class that is being used
|
36
|
+
# to run the Docker Containers.
|
37
|
+
#
|
38
|
+
# @return [Dockerspec::Engine::Specinfra] The engine.
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
#
|
42
|
+
def initialize(runner)
|
43
|
+
super
|
44
|
+
@definitions = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Sets up Infrataster.
|
49
|
+
#
|
50
|
+
# @return void
|
51
|
+
#
|
52
|
+
# @raise [Dockerspec::RunnerError] When the `#container` method is no
|
53
|
+
# implemented in the subclass or cannot select the container to test.
|
54
|
+
#
|
55
|
+
# @api public
|
56
|
+
#
|
57
|
+
def when_container_ready
|
58
|
+
define_server
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
#
|
64
|
+
# Defines the Infrataster server to test.
|
65
|
+
#
|
66
|
+
# It calls {Infrataster::Server.define} reading the internal IP address
|
67
|
+
# from the Docker metadata.
|
68
|
+
#
|
69
|
+
# @return void
|
70
|
+
#
|
71
|
+
# @raise [Dockerspec::RunnerError] When the `#container` method is no
|
72
|
+
# implemented in the subclass or cannot select the container to test.
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
#
|
76
|
+
def define_server
|
77
|
+
return if @definitions.key?(container_name)
|
78
|
+
::Infrataster::Server.define(
|
79
|
+
container_name.to_sym,
|
80
|
+
ipaddress,
|
81
|
+
options
|
82
|
+
)
|
83
|
+
@definitions[container_name] = ipaddress
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,130 @@
|
|
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/engine/base'
|
21
|
+
require 'dockerspec/engine/specinfra/backend'
|
22
|
+
|
23
|
+
module Dockerspec
|
24
|
+
module Engine
|
25
|
+
#
|
26
|
+
# The Specinfra (Serverspec) testing engine implementation.
|
27
|
+
#
|
28
|
+
class Specinfra < Base
|
29
|
+
#
|
30
|
+
# Constructs a testing engine to use Specinfra (used by Serverspec).
|
31
|
+
#
|
32
|
+
# @param runner [Dockerspec::Runner::Base] The class that is being used
|
33
|
+
# to run the Docker Containers.
|
34
|
+
#
|
35
|
+
# @return [Dockerspec::Engine::Specinfra] The engine.
|
36
|
+
#
|
37
|
+
# @api public
|
38
|
+
#
|
39
|
+
def initialize(runner)
|
40
|
+
super
|
41
|
+
@backend = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Sets the Specinfra configuration.
|
46
|
+
#
|
47
|
+
# - Resets the internal Specinfra backend reference.
|
48
|
+
# - Sets the chosen container name with Docker Compose.
|
49
|
+
# - Sets the `:family`.
|
50
|
+
#
|
51
|
+
# @return void
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
#
|
55
|
+
def before_running
|
56
|
+
if @backend.nil?
|
57
|
+
@backend = Backend.new(backend_name)
|
58
|
+
@backend.reset
|
59
|
+
end
|
60
|
+
setup_container_name
|
61
|
+
setup_family
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Saves the Specinfra backend reference internally to restore it later.
|
66
|
+
#
|
67
|
+
# @return void
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
#
|
71
|
+
def when_running
|
72
|
+
@backend.save
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Restores the Specinfra backend instance to point to this object's
|
77
|
+
# container.
|
78
|
+
#
|
79
|
+
# This is used to avoid Serverspec running against the previous started
|
80
|
+
# container if you are testing multiple containers at the same time.
|
81
|
+
#
|
82
|
+
# @return void
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
def restore
|
87
|
+
@backend.restore
|
88
|
+
setup_container_name
|
89
|
+
setup_family
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
#
|
95
|
+
# Gets the Specinfra backend name from the runner.
|
96
|
+
#
|
97
|
+
# @return [String] The backend name.
|
98
|
+
#
|
99
|
+
# @api private
|
100
|
+
#
|
101
|
+
def backend_name
|
102
|
+
@runner.backend_name
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Sets up the OS family.
|
107
|
+
#
|
108
|
+
# @return void
|
109
|
+
#
|
110
|
+
# @api private
|
111
|
+
#
|
112
|
+
def setup_family
|
113
|
+
return unless options.key?(:family)
|
114
|
+
::Specinfra.configuration.os(family: options[:family])
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Selects the container to test.
|
119
|
+
#
|
120
|
+
# @return void
|
121
|
+
#
|
122
|
+
# @api private
|
123
|
+
#
|
124
|
+
def setup_container_name
|
125
|
+
return unless options.key?(:container)
|
126
|
+
@backend.restore_container(options[:container])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,163 @@
|
|
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 'specinfra/backend/base'
|
21
|
+
require 'dockerspec/engine/specinfra/backend_hack'
|
22
|
+
|
23
|
+
module Dockerspec
|
24
|
+
module Engine
|
25
|
+
class Specinfra < Base
|
26
|
+
#
|
27
|
+
# A class to handle the underlying Specinfra backend.
|
28
|
+
#
|
29
|
+
# This class saves Specinfra instance in internally and then it is able
|
30
|
+
# to recover it from there and setup the running environment accordingly.
|
31
|
+
#
|
32
|
+
# This class uses a small hack in the Specinfra class to reset its
|
33
|
+
# internal singleton instance.
|
34
|
+
#
|
35
|
+
class Backend
|
36
|
+
#
|
37
|
+
# The Specinfra backend constructor.
|
38
|
+
#
|
39
|
+
# @param backend [Symbol, Specinfra::Backend::Base, Class] The backend
|
40
|
+
# can be the backend name as a symbol, a Specinfra backend object or
|
41
|
+
# a Specinfra backend class.
|
42
|
+
#
|
43
|
+
# @api public
|
44
|
+
#
|
45
|
+
def initialize(backend)
|
46
|
+
@backend = backend
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Saves the Specinfra backend instance reference internally.
|
51
|
+
#
|
52
|
+
# @return void
|
53
|
+
#
|
54
|
+
# @api public
|
55
|
+
#
|
56
|
+
def save
|
57
|
+
@saved_backend_name = ::Specinfra.configuration.backend
|
58
|
+
@saved_backend_instance = backend_instance
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Restores the Specinfra backend instance.
|
63
|
+
#
|
64
|
+
# @return void
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
#
|
68
|
+
def restore
|
69
|
+
instance_set(@saved_backend_instance)
|
70
|
+
::Specinfra.configuration.backend = @saved_backend_name
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Restores the testing context for a container.
|
75
|
+
#
|
76
|
+
# Used with Docker Compose to choose the container to test.
|
77
|
+
#
|
78
|
+
# @param container_name [String, Symbol] The name of the container.
|
79
|
+
#
|
80
|
+
# @return void
|
81
|
+
#
|
82
|
+
# @api public
|
83
|
+
#
|
84
|
+
def restore_container(container_name)
|
85
|
+
current_container_name =
|
86
|
+
::Specinfra.configuration.docker_compose_container
|
87
|
+
return if current_container_name == container_name
|
88
|
+
::Specinfra.configuration.docker_compose_container(container_name)
|
89
|
+
# TODO: Save the host family instead of always reseting it:
|
90
|
+
backend_class.host_reset
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Resets the Specinfra backend.
|
95
|
+
#
|
96
|
+
# @return void
|
97
|
+
#
|
98
|
+
# @api public
|
99
|
+
#
|
100
|
+
def reset
|
101
|
+
instance_set(nil)
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Gets the internal attribute value from the Specinfra backend object.
|
106
|
+
#
|
107
|
+
# Used mainly to get information from the running containers like their
|
108
|
+
# name or their IP address.
|
109
|
+
#
|
110
|
+
# @return [Mixed] The value of the attribute to read.
|
111
|
+
#
|
112
|
+
# @api public
|
113
|
+
#
|
114
|
+
def backend_instance_attribute(name)
|
115
|
+
backend_instance.instance_variable_get("@#{name}".to_sym)
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
|
120
|
+
#
|
121
|
+
# Sets the Specinfra backend.
|
122
|
+
#
|
123
|
+
# Used by {.load}.
|
124
|
+
#
|
125
|
+
# @param instance [Specinfra::Backend::Base] The Specinfra backend
|
126
|
+
# object.
|
127
|
+
#
|
128
|
+
# @return void
|
129
|
+
#
|
130
|
+
# @api private
|
131
|
+
#
|
132
|
+
def instance_set(instance)
|
133
|
+
backend_class.instance_set(instance)
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Returns the current Specinfra backend object.
|
138
|
+
#
|
139
|
+
# @return [Specinfra::Backend::Base] The Specinfra backend object.
|
140
|
+
#
|
141
|
+
# @api private
|
142
|
+
#
|
143
|
+
def backend_instance
|
144
|
+
backend_class.instance
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Returns the current Specinfra backend class.
|
149
|
+
#
|
150
|
+
# @return [Class] The Specinfra backend class.
|
151
|
+
#
|
152
|
+
# @api private
|
153
|
+
#
|
154
|
+
def backend_class
|
155
|
+
@backend_class ||= begin
|
156
|
+
return @backend.class if @backend.is_a?(::Specinfra::Backend::Base)
|
157
|
+
::Specinfra::Backend.const_get(@backend.to_s.to_camel_case)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|