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.
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
@@ -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