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