test-kitchen 1.7.0 → 1.7.1.dev

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 (181) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +8 -8
  3. data/.gitattributes +3 -0
  4. data/.github/ISSUE_TEMPLATE.md +55 -55
  5. data/.gitignore +28 -28
  6. data/.kitchen.ci.yml +23 -23
  7. data/.kitchen.proxy.yml +27 -27
  8. data/.rubocop.yml +3 -3
  9. data/.travis.yml +70 -70
  10. data/.yardopts +3 -3
  11. data/Berksfile +3 -3
  12. data/CHANGELOG.md +1090 -1083
  13. data/CONTRIBUTING.md +14 -14
  14. data/Gemfile +19 -19
  15. data/Gemfile.proxy_tests +4 -4
  16. data/Guardfile +42 -42
  17. data/LICENSE +15 -15
  18. data/MAINTAINERS.md +23 -23
  19. data/README.md +135 -135
  20. data/Rakefile +61 -61
  21. data/appveyor.yml +44 -44
  22. data/features/kitchen_action_commands.feature +164 -164
  23. data/features/kitchen_command.feature +16 -16
  24. data/features/kitchen_console_command.feature +34 -34
  25. data/features/kitchen_defaults.feature +38 -38
  26. data/features/kitchen_diagnose_command.feature +96 -96
  27. data/features/kitchen_driver_create_command.feature +64 -64
  28. data/features/kitchen_driver_discover_command.feature +25 -25
  29. data/features/kitchen_help_command.feature +16 -16
  30. data/features/kitchen_init_command.feature +274 -274
  31. data/features/kitchen_list_command.feature +104 -104
  32. data/features/kitchen_login_command.feature +62 -62
  33. data/features/kitchen_sink_command.feature +30 -30
  34. data/features/kitchen_test_command.feature +88 -88
  35. data/features/step_definitions/gem_steps.rb +36 -36
  36. data/features/step_definitions/git_steps.rb +5 -5
  37. data/features/step_definitions/output_steps.rb +5 -5
  38. data/features/support/env.rb +75 -75
  39. data/lib/kitchen.rb +150 -150
  40. data/lib/kitchen/base64_stream.rb +55 -55
  41. data/lib/kitchen/cli.rb +419 -419
  42. data/lib/kitchen/collection.rb +55 -55
  43. data/lib/kitchen/color.rb +65 -65
  44. data/lib/kitchen/command.rb +185 -185
  45. data/lib/kitchen/command/action.rb +45 -45
  46. data/lib/kitchen/command/console.rb +58 -58
  47. data/lib/kitchen/command/diagnose.rb +92 -92
  48. data/lib/kitchen/command/driver_discover.rb +105 -105
  49. data/lib/kitchen/command/exec.rb +41 -41
  50. data/lib/kitchen/command/list.rb +119 -119
  51. data/lib/kitchen/command/login.rb +43 -43
  52. data/lib/kitchen/command/sink.rb +54 -54
  53. data/lib/kitchen/command/test.rb +51 -51
  54. data/lib/kitchen/config.rb +322 -322
  55. data/lib/kitchen/configurable.rb +529 -529
  56. data/lib/kitchen/data_munger.rb +959 -959
  57. data/lib/kitchen/diagnostic.rb +141 -141
  58. data/lib/kitchen/driver.rb +56 -56
  59. data/lib/kitchen/driver/base.rb +134 -134
  60. data/lib/kitchen/driver/dummy.rb +108 -108
  61. data/lib/kitchen/driver/proxy.rb +72 -72
  62. data/lib/kitchen/driver/ssh_base.rb +357 -357
  63. data/lib/kitchen/errors.rb +229 -229
  64. data/lib/kitchen/generator/driver_create.rb +177 -177
  65. data/lib/kitchen/generator/init.rb +296 -296
  66. data/lib/kitchen/instance.rb +662 -662
  67. data/lib/kitchen/lazy_hash.rb +142 -142
  68. data/lib/kitchen/loader/yaml.rb +349 -349
  69. data/lib/kitchen/logger.rb +423 -423
  70. data/lib/kitchen/logging.rb +56 -56
  71. data/lib/kitchen/login_command.rb +52 -52
  72. data/lib/kitchen/metadata_chopper.rb +52 -52
  73. data/lib/kitchen/platform.rb +67 -67
  74. data/lib/kitchen/provisioner.rb +54 -54
  75. data/lib/kitchen/provisioner/base.rb +236 -236
  76. data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
  77. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
  78. data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
  79. data/lib/kitchen/provisioner/chef_apply.rb +124 -124
  80. data/lib/kitchen/provisioner/chef_base.rb +341 -341
  81. data/lib/kitchen/provisioner/chef_solo.rb +88 -88
  82. data/lib/kitchen/provisioner/chef_zero.rb +245 -245
  83. data/lib/kitchen/provisioner/dummy.rb +79 -79
  84. data/lib/kitchen/provisioner/shell.rb +138 -138
  85. data/lib/kitchen/rake_tasks.rb +63 -63
  86. data/lib/kitchen/shell_out.rb +93 -93
  87. data/lib/kitchen/ssh.rb +276 -276
  88. data/lib/kitchen/state_file.rb +120 -120
  89. data/lib/kitchen/suite.rb +51 -51
  90. data/lib/kitchen/thor_tasks.rb +66 -66
  91. data/lib/kitchen/transport.rb +54 -54
  92. data/lib/kitchen/transport/base.rb +176 -176
  93. data/lib/kitchen/transport/dummy.rb +79 -79
  94. data/lib/kitchen/transport/ssh.rb +364 -364
  95. data/lib/kitchen/transport/winrm.rb +486 -486
  96. data/lib/kitchen/util.rb +147 -147
  97. data/lib/kitchen/verifier.rb +55 -55
  98. data/lib/kitchen/verifier/base.rb +235 -235
  99. data/lib/kitchen/verifier/busser.rb +277 -277
  100. data/lib/kitchen/verifier/dummy.rb +79 -79
  101. data/lib/kitchen/verifier/shell.rb +101 -101
  102. data/lib/kitchen/version.rb +21 -21
  103. data/lib/vendor/hash_recursive_merge.rb +82 -82
  104. data/spec/kitchen/base64_stream_spec.rb +77 -77
  105. data/spec/kitchen/cli_spec.rb +56 -56
  106. data/spec/kitchen/collection_spec.rb +80 -80
  107. data/spec/kitchen/color_spec.rb +54 -54
  108. data/spec/kitchen/config_spec.rb +408 -408
  109. data/spec/kitchen/configurable_spec.rb +1095 -1095
  110. data/spec/kitchen/data_munger_spec.rb +2694 -2694
  111. data/spec/kitchen/diagnostic_spec.rb +129 -129
  112. data/spec/kitchen/driver/base_spec.rb +121 -121
  113. data/spec/kitchen/driver/dummy_spec.rb +199 -199
  114. data/spec/kitchen/driver/proxy_spec.rb +138 -138
  115. data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
  116. data/spec/kitchen/driver_spec.rb +112 -112
  117. data/spec/kitchen/errors_spec.rb +309 -309
  118. data/spec/kitchen/instance_spec.rb +1419 -1419
  119. data/spec/kitchen/lazy_hash_spec.rb +117 -117
  120. data/spec/kitchen/loader/yaml_spec.rb +774 -774
  121. data/spec/kitchen/logger_spec.rb +429 -429
  122. data/spec/kitchen/logging_spec.rb +59 -59
  123. data/spec/kitchen/login_command_spec.rb +68 -68
  124. data/spec/kitchen/metadata_chopper_spec.rb +82 -82
  125. data/spec/kitchen/platform_spec.rb +89 -89
  126. data/spec/kitchen/provisioner/base_spec.rb +386 -386
  127. data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
  128. data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
  129. data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
  130. data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
  131. data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
  132. data/spec/kitchen/provisioner/shell_spec.rb +566 -566
  133. data/spec/kitchen/provisioner_spec.rb +107 -107
  134. data/spec/kitchen/shell_out_spec.rb +150 -150
  135. data/spec/kitchen/ssh_spec.rb +693 -693
  136. data/spec/kitchen/state_file_spec.rb +129 -129
  137. data/spec/kitchen/suite_spec.rb +62 -62
  138. data/spec/kitchen/transport/base_spec.rb +89 -89
  139. data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
  140. data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
  141. data/spec/kitchen/transport_spec.rb +112 -112
  142. data/spec/kitchen/util_spec.rb +165 -165
  143. data/spec/kitchen/verifier/base_spec.rb +362 -362
  144. data/spec/kitchen/verifier/busser_spec.rb +610 -610
  145. data/spec/kitchen/verifier/dummy_spec.rb +99 -99
  146. data/spec/kitchen/verifier/shell_spec.rb +160 -160
  147. data/spec/kitchen/verifier_spec.rb +120 -120
  148. data/spec/kitchen_spec.rb +114 -114
  149. data/spec/spec_helper.rb +85 -85
  150. data/spec/support/powershell_max_size_spec.rb +40 -40
  151. data/support/busser_install_command.ps1 +14 -14
  152. data/support/busser_install_command.sh +14 -14
  153. data/support/chef-client-zero.rb +77 -77
  154. data/support/chef_base_init_command.ps1 +18 -18
  155. data/support/chef_base_init_command.sh +2 -2
  156. data/support/chef_base_install_command.ps1 +85 -85
  157. data/support/chef_base_install_command.sh +229 -229
  158. data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
  159. data/support/chef_zero_prepare_command_legacy.sh +10 -10
  160. data/support/download_helpers.sh +109 -109
  161. data/support/dummy-validation.pem +27 -27
  162. data/templates/driver/CHANGELOG.md.erb +3 -3
  163. data/templates/driver/Gemfile.erb +3 -3
  164. data/templates/driver/README.md.erb +64 -64
  165. data/templates/driver/Rakefile.erb +21 -21
  166. data/templates/driver/driver.rb.erb +23 -23
  167. data/templates/driver/gemspec.erb +29 -29
  168. data/templates/driver/gitignore.erb +17 -17
  169. data/templates/driver/license_apachev2.erb +15 -15
  170. data/templates/driver/license_lgplv3.erb +16 -16
  171. data/templates/driver/license_mit.erb +22 -22
  172. data/templates/driver/license_reserved.erb +5 -5
  173. data/templates/driver/tailor.erb +4 -4
  174. data/templates/driver/travis.yml.erb +11 -11
  175. data/templates/driver/version.rb.erb +12 -12
  176. data/templates/init/chefignore.erb +1 -1
  177. data/templates/init/kitchen.yml.erb +18 -18
  178. data/test-kitchen.gemspec +62 -62
  179. data/test/integration/default/default_spec.rb +3 -3
  180. data/testing_windows.md +37 -37
  181. metadata +5 -4
data/lib/kitchen/util.rb CHANGED
@@ -1,147 +1,147 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2012, 2013, 2014, Fletcher Nichol
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
- module Kitchen
20
-
21
- # Stateless utility methods used in different contexts. Essentially a mini
22
- # PassiveSupport library.
23
- #
24
- # @author Fletcher Nichol <fnichol@nichol.ca>
25
- module Util
26
-
27
- # Returns the standard library Logger level constants for a given symbol
28
- # representation.
29
- #
30
- # @param symbol [Symbol] symbol representation of a logger level (:debug,
31
- # :info, :warn, :error, :fatal)
32
- # @return [Integer] Logger::Severity constant value or nil if input is not
33
- # valid
34
- def self.to_logger_level(symbol)
35
- return nil unless [:debug, :info, :warn, :error, :fatal].include?(symbol)
36
-
37
- Logger.const_get(symbol.to_s.upcase)
38
- end
39
-
40
- # Returns the symbol represenation of a logging levels for a given
41
- # standard library Logger::Severity constant.
42
- #
43
- # @param const [Integer] Logger::Severity constant value for a logging
44
- # level (Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR,
45
- # Logger::FATAL)
46
- # @return [Symbol] symbol representation of the logging level
47
- def self.from_logger_level(const)
48
- case const
49
- when Logger::DEBUG then :debug
50
- when Logger::INFO then :info
51
- when Logger::WARN then :warn
52
- when Logger::ERROR then :error
53
- else :fatal
54
- end
55
- end
56
-
57
- # Returns a new Hash with all key values coerced to symbols. All keys
58
- # within a Hash are coerced by calling #to_sym and hashes within arrays
59
- # and other hashes are traversed.
60
- #
61
- # @param obj [Object] the hash to be processed. While intended for
62
- # hashes, this method safely processes arbitrary objects
63
- # @return [Object] a converted hash with all keys as symbols
64
- def self.symbolized_hash(obj)
65
- if obj.is_a?(Hash)
66
- obj.inject({}) { |h, (k, v)| h[k.to_sym] = symbolized_hash(v); h }
67
- elsif obj.is_a?(Array)
68
- obj.inject([]) { |a, e| a << symbolized_hash(e); a }
69
- else
70
- obj
71
- end
72
- end
73
-
74
- # Returns a new Hash with all key values coerced to strings. All keys
75
- # within a Hash are coerced by calling #to_s and hashes with arrays
76
- # and other hashes are traversed.
77
- #
78
- # @param obj [Object] the hash to be processed. While intended for
79
- # hashes, this method safely processes arbitrary objects
80
- # @return [Object] a converted hash with all keys as strings
81
- def self.stringified_hash(obj)
82
- if obj.is_a?(Hash)
83
- obj.inject({}) { |h, (k, v)| h[k.to_s] = stringified_hash(v); h }
84
- elsif obj.is_a?(Array)
85
- obj.inject([]) { |a, e| a << stringified_hash(e); a }
86
- else
87
- obj
88
- end
89
- end
90
-
91
- # Returns a formatted string representing a duration in seconds.
92
- #
93
- # @param total [Integer] the total number of seconds
94
- # @return [String] a formatted string of the form (XmYY.00s)
95
- def self.duration(total)
96
- total = 0 if total.nil?
97
- minutes = (total / 60).to_i
98
- seconds = (total - (minutes * 60))
99
- format("(%dm%.2fs)", minutes, seconds)
100
- end
101
-
102
- # Generates a command (or series of commands) wrapped so that it can be
103
- # invoked on a remote instance or locally.
104
- #
105
- # This method uses the Bourne shell (/bin/sh) to maximize the chance of
106
- # cross platform portability on Unixlike systems.
107
- #
108
- # @param [String] the command
109
- # @return [String] a wrapped command string
110
- def self.wrap_command(cmd)
111
- cmd = "false" if cmd.nil?
112
- cmd = "true" if cmd.to_s.empty?
113
- cmd = cmd.sub(/\n\Z/, "") if cmd =~ /\n\Z/
114
-
115
- "sh -c '\n#{cmd}\n'"
116
- end
117
-
118
- # Modifes the given string to strip leading whitespace on each line, the
119
- # amount which is calculated by using the first line of text.
120
- #
121
- # @example
122
- #
123
- # string = <<-STRING
124
- # a
125
- # b
126
- # c
127
- # STRING
128
- # Util.outdent!(string) # => "a\n b\nc\n"
129
- #
130
- # @param string [String] the string that will be modified
131
- # @return [String] the modified string
132
- def self.outdent!(string)
133
- string.gsub!(/^ {#{string.index(/[^ ]/)}}/, "")
134
- end
135
-
136
- # Returns a set of Bourne Shell (AKA /bin/sh) compatible helper
137
- # functions. This function is usually called inline in a string that
138
- # will be executed remotely on a test instance.
139
- #
140
- # @return [String] a string representation of useful helper functions
141
- def self.shell_helpers
142
- IO.read(File.join(
143
- File.dirname(__FILE__), %w[.. .. support download_helpers.sh]
144
- ))
145
- end
146
- end
147
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2012, 2013, 2014, Fletcher Nichol
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
+ module Kitchen
20
+
21
+ # Stateless utility methods used in different contexts. Essentially a mini
22
+ # PassiveSupport library.
23
+ #
24
+ # @author Fletcher Nichol <fnichol@nichol.ca>
25
+ module Util
26
+
27
+ # Returns the standard library Logger level constants for a given symbol
28
+ # representation.
29
+ #
30
+ # @param symbol [Symbol] symbol representation of a logger level (:debug,
31
+ # :info, :warn, :error, :fatal)
32
+ # @return [Integer] Logger::Severity constant value or nil if input is not
33
+ # valid
34
+ def self.to_logger_level(symbol)
35
+ return nil unless [:debug, :info, :warn, :error, :fatal].include?(symbol)
36
+
37
+ Logger.const_get(symbol.to_s.upcase)
38
+ end
39
+
40
+ # Returns the symbol represenation of a logging levels for a given
41
+ # standard library Logger::Severity constant.
42
+ #
43
+ # @param const [Integer] Logger::Severity constant value for a logging
44
+ # level (Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR,
45
+ # Logger::FATAL)
46
+ # @return [Symbol] symbol representation of the logging level
47
+ def self.from_logger_level(const)
48
+ case const
49
+ when Logger::DEBUG then :debug
50
+ when Logger::INFO then :info
51
+ when Logger::WARN then :warn
52
+ when Logger::ERROR then :error
53
+ else :fatal
54
+ end
55
+ end
56
+
57
+ # Returns a new Hash with all key values coerced to symbols. All keys
58
+ # within a Hash are coerced by calling #to_sym and hashes within arrays
59
+ # and other hashes are traversed.
60
+ #
61
+ # @param obj [Object] the hash to be processed. While intended for
62
+ # hashes, this method safely processes arbitrary objects
63
+ # @return [Object] a converted hash with all keys as symbols
64
+ def self.symbolized_hash(obj)
65
+ if obj.is_a?(Hash)
66
+ obj.inject({}) { |h, (k, v)| h[k.to_sym] = symbolized_hash(v); h }
67
+ elsif obj.is_a?(Array)
68
+ obj.inject([]) { |a, e| a << symbolized_hash(e); a }
69
+ else
70
+ obj
71
+ end
72
+ end
73
+
74
+ # Returns a new Hash with all key values coerced to strings. All keys
75
+ # within a Hash are coerced by calling #to_s and hashes with arrays
76
+ # and other hashes are traversed.
77
+ #
78
+ # @param obj [Object] the hash to be processed. While intended for
79
+ # hashes, this method safely processes arbitrary objects
80
+ # @return [Object] a converted hash with all keys as strings
81
+ def self.stringified_hash(obj)
82
+ if obj.is_a?(Hash)
83
+ obj.inject({}) { |h, (k, v)| h[k.to_s] = stringified_hash(v); h }
84
+ elsif obj.is_a?(Array)
85
+ obj.inject([]) { |a, e| a << stringified_hash(e); a }
86
+ else
87
+ obj
88
+ end
89
+ end
90
+
91
+ # Returns a formatted string representing a duration in seconds.
92
+ #
93
+ # @param total [Integer] the total number of seconds
94
+ # @return [String] a formatted string of the form (XmYY.00s)
95
+ def self.duration(total)
96
+ total = 0 if total.nil?
97
+ minutes = (total / 60).to_i
98
+ seconds = (total - (minutes * 60))
99
+ format("(%dm%.2fs)", minutes, seconds)
100
+ end
101
+
102
+ # Generates a command (or series of commands) wrapped so that it can be
103
+ # invoked on a remote instance or locally.
104
+ #
105
+ # This method uses the Bourne shell (/bin/sh) to maximize the chance of
106
+ # cross platform portability on Unixlike systems.
107
+ #
108
+ # @param [String] the command
109
+ # @return [String] a wrapped command string
110
+ def self.wrap_command(cmd)
111
+ cmd = "false" if cmd.nil?
112
+ cmd = "true" if cmd.to_s.empty?
113
+ cmd = cmd.sub(/\n\Z/, "") if cmd =~ /\n\Z/
114
+
115
+ "sh -c '\n#{cmd}\n'"
116
+ end
117
+
118
+ # Modifes the given string to strip leading whitespace on each line, the
119
+ # amount which is calculated by using the first line of text.
120
+ #
121
+ # @example
122
+ #
123
+ # string = <<-STRING
124
+ # a
125
+ # b
126
+ # c
127
+ # STRING
128
+ # Util.outdent!(string) # => "a\n b\nc\n"
129
+ #
130
+ # @param string [String] the string that will be modified
131
+ # @return [String] the modified string
132
+ def self.outdent!(string)
133
+ string.gsub!(/^ {#{string.index(/[^ ]/)}}/, "")
134
+ end
135
+
136
+ # Returns a set of Bourne Shell (AKA /bin/sh) compatible helper
137
+ # functions. This function is usually called inline in a string that
138
+ # will be executed remotely on a test instance.
139
+ #
140
+ # @return [String] a string representation of useful helper functions
141
+ def self.shell_helpers
142
+ IO.read(File.join(
143
+ File.dirname(__FILE__), %w[.. .. support download_helpers.sh]
144
+ ))
145
+ end
146
+ end
147
+ end
@@ -1,55 +1,55 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2015, Fletcher Nichol
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
- require "thor/util"
20
-
21
- require "kitchen/errors"
22
-
23
- module Kitchen
24
-
25
- # A verifier is responsible for running tests post-converge to confirm that
26
- # the instance is in a known/consistent state.
27
- #
28
- # @author Fletcher Nichol <fnichol@nichol.ca>
29
- module Verifier
30
-
31
- # Default verifier to use
32
- DEFAULT_PLUGIN = "busser".freeze
33
-
34
- # Returns an instance of a verifier given a plugin type string.
35
- #
36
- # @param plugin [String] a verifier plugin type, to be constantized
37
- # @param config [Hash] a configuration hash to initialize the verifier
38
- # @return [Verifier::Base] a verifier instance
39
- # @raise [ClientError] if a verifier instance could not be created
40
- def self.for_plugin(plugin, config)
41
- first_load = require("kitchen/verifier/#{plugin}")
42
-
43
- str_const = Thor::Util.camel_case(plugin)
44
- klass = const_get(str_const)
45
- object = klass.new(config)
46
- object.verify_dependencies if first_load
47
- object
48
- rescue LoadError, NameError
49
- raise ClientError,
50
- "Could not load the '#{plugin}' verifier from the load path." \
51
- " Please ensure that your transport is installed as a gem or" \
52
- " included in your Gemfile if using Bundler."
53
- end
54
- end
55
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, Fletcher Nichol
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
+ require "thor/util"
20
+
21
+ require "kitchen/errors"
22
+
23
+ module Kitchen
24
+
25
+ # A verifier is responsible for running tests post-converge to confirm that
26
+ # the instance is in a known/consistent state.
27
+ #
28
+ # @author Fletcher Nichol <fnichol@nichol.ca>
29
+ module Verifier
30
+
31
+ # Default verifier to use
32
+ DEFAULT_PLUGIN = "busser".freeze
33
+
34
+ # Returns an instance of a verifier given a plugin type string.
35
+ #
36
+ # @param plugin [String] a verifier plugin type, to be constantized
37
+ # @param config [Hash] a configuration hash to initialize the verifier
38
+ # @return [Verifier::Base] a verifier instance
39
+ # @raise [ClientError] if a verifier instance could not be created
40
+ def self.for_plugin(plugin, config)
41
+ first_load = require("kitchen/verifier/#{plugin}")
42
+
43
+ str_const = Thor::Util.camel_case(plugin)
44
+ klass = const_get(str_const)
45
+ object = klass.new(config)
46
+ object.verify_dependencies if first_load
47
+ object
48
+ rescue LoadError, NameError
49
+ raise ClientError,
50
+ "Could not load the '#{plugin}' verifier from the load path." \
51
+ " Please ensure that your transport is installed as a gem or" \
52
+ " included in your Gemfile if using Bundler."
53
+ end
54
+ end
55
+ end
@@ -1,235 +1,235 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2015, Fletcher Nichol
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
- require "kitchen/errors"
20
- require "kitchen/configurable"
21
- require "kitchen/logging"
22
-
23
- module Kitchen
24
-
25
- module Verifier
26
-
27
- # Base class for a verifier.
28
- #
29
- # @author Fletcher Nichol <fnichol@nichol.ca>
30
- class Base
31
-
32
- include Configurable
33
- include Logging
34
-
35
- default_config :http_proxy, nil
36
- default_config :https_proxy, nil
37
- default_config :ftp_proxy, nil
38
-
39
- default_config :root_path do |verifier|
40
- verifier.windows_os? ? "$env:TEMP\\verifier" : "/tmp/verifier"
41
- end
42
-
43
- default_config :sudo do |verifier|
44
- verifier.windows_os? ? nil : true
45
- end
46
-
47
- default_config :chef_omnibus_root, "/opt/chef"
48
-
49
- default_config :sudo_command do |verifier|
50
- verifier.windows_os? ? nil : "sudo -E"
51
- end
52
-
53
- default_config :command_prefix, nil
54
-
55
- default_config(:suite_name) { |busser| busser.instance.suite.name }
56
-
57
- # Creates a new Verifier object using the provided configuration data
58
- # which will be merged with any default configuration.
59
- #
60
- # @param config [Hash] provided verifier configuration
61
- def initialize(config = {})
62
- init_config(config)
63
- end
64
-
65
- # Runs the verifier on the instance.
66
- #
67
- # @param state [Hash] mutable instance state
68
- # @raise [ActionFailed] if the action could not be completed
69
- def call(state)
70
- create_sandbox
71
- sandbox_dirs = Dir.glob(File.join(sandbox_path, "*"))
72
-
73
- instance.transport.connection(state) do |conn|
74
- conn.execute(install_command)
75
- conn.execute(init_command)
76
- info("Transferring files to #{instance.to_str}")
77
- conn.upload(sandbox_dirs, config[:root_path])
78
- debug("Transfer complete")
79
- conn.execute(prepare_command)
80
- conn.execute(run_command)
81
- end
82
- rescue Kitchen::Transport::TransportFailed => ex
83
- raise ActionFailed, ex.message
84
- ensure
85
- cleanup_sandbox
86
- end
87
-
88
- # Deletes the sandbox path. Without calling this method, the sandbox path
89
- # will persist after the process terminates. In other words, cleanup is
90
- # explicit. This method is safe to call multiple times.
91
- def cleanup_sandbox
92
- return if sandbox_path.nil?
93
-
94
- debug("Cleaning up local sandbox in #{sandbox_path}")
95
- FileUtils.rmtree(sandbox_path)
96
- end
97
-
98
- # Creates a temporary directory on the local workstation into which
99
- # verifier related files and directories can be copied or created. The
100
- # contents of this directory will be copied over to the instance before
101
- # invoking the verifier's run command. After this method completes, it
102
- # is expected that the contents of the sandbox is complete and ready for
103
- # copy to the remote instance.
104
- #
105
- # **Note:** any subclasses would be well advised to call super first when
106
- # overriding this method, for example:
107
- #
108
- # @example overriding `#create_sandbox`
109
- #
110
- # class MyVerifier < Kitchen::Verifier::Base
111
- # def create_sandbox
112
- # super
113
- # # any further file copies, preparations, etc.
114
- # end
115
- # end
116
- def create_sandbox
117
- @sandbox_path = Dir.mktmpdir("#{instance.name}-sandbox-")
118
- File.chmod(0755, sandbox_path)
119
- info("Preparing files for transfer")
120
- debug("Creating local sandbox in #{sandbox_path}")
121
- end
122
-
123
- # Generates a command string which will install and configure the
124
- # verifier software on an instance. If no work is required, then `nil`
125
- # will be returned.
126
- #
127
- # @return [String] a command string
128
- def install_command
129
- end
130
-
131
- # Generates a command string which will perform any data initialization
132
- # or configuration required after the verifier software is installed
133
- # but before the sandbox has been transferred to the instance. If no work
134
- # is required, then `nil` will be returned.
135
- #
136
- # @return [String] a command string
137
- def init_command
138
- end
139
-
140
- # Generates a command string which will perform any commands or
141
- # configuration required just before the main verifier run command but
142
- # after the sandbox has been transferred to the instance. If no work is
143
- # required, then `nil` will be returned.
144
- #
145
- # @return [String] a command string
146
- def prepare_command
147
- end
148
-
149
- # Generates a command string which will invoke the main verifier
150
- # command on the prepared instance. If no work is required, then `nil`
151
- # will be returned.
152
- #
153
- # @return [String] a command string
154
- def run_command
155
- end
156
-
157
- # Returns the absolute path to the sandbox directory or raises an
158
- # exception if `#create_sandbox` has not yet been called.
159
- #
160
- # @return [String] the absolute path to the sandbox directory
161
- # @raise [ClientError] if the sandbox directory has no yet been created
162
- # by calling `#create_sandbox`
163
- def sandbox_path
164
- @sandbox_path || (raise ClientError, "Sandbox directory has not yet " \
165
- "been created. Please run #{self.class}#create_sandox before " \
166
- "trying to access the path.")
167
- end
168
-
169
- # Sets the API version for this verifier. If the verifier does not set
170
- # this value, then `nil` will be used and reported.
171
- #
172
- # Sets the API version for this verifier
173
- #
174
- # @example setting an API version
175
- #
176
- # module Kitchen
177
- # module Verifier
178
- # class NewVerifier < Kitchen::Verifier::Base
179
- #
180
- # kitchen_verifier_api_version 2
181
- #
182
- # end
183
- # end
184
- # end
185
- #
186
- # @param version [Integer,String] a version number
187
- #
188
- def self.kitchen_verifier_api_version(version)
189
- @api_version = version
190
- end
191
-
192
- private
193
-
194
- # Builds a complete command given a variables String preamble and a file
195
- # containing shell code.
196
- #
197
- # @param vars [String] shell variables, as a String
198
- # @param file [String] file basename (without extension) containing
199
- # shell code
200
- # @return [String] command
201
- # @api private
202
- def shell_code_from_file(vars, file)
203
- src_file = File.join(
204
- File.dirname(__FILE__),
205
- %w[.. .. .. support],
206
- file + (powershell_shell? ? ".ps1" : ".sh")
207
- )
208
-
209
- wrap_shell_code([vars, "", IO.read(src_file)].join("\n"))
210
- end
211
-
212
- # Conditionally prefixes a command with a sudo command.
213
- #
214
- # @param command [String] command to be prefixed
215
- # @return [String] the command, conditionaly prefixed with sudo
216
- # @api private
217
- def sudo(script)
218
- config[:sudo] ? "#{config[:sudo_command]} #{script}" : script
219
- end
220
-
221
- # Conditionally prefixes a command with a command prefix.
222
- # This should generally be done after a command has been
223
- # conditionally prefixed by #sudo as certain platforms, such as
224
- # Cisco Nexus, require all commands to be run with a prefix to
225
- # obtain outbound network access.
226
- #
227
- # @param command [String] command to be prefixed
228
- # @return [String] the command, conditionally prefixed with the configured prefix
229
- # @api private
230
- def prefix_command(script)
231
- config[:command_prefix] ? "#{config[:command_prefix]} #{script}" : script
232
- end
233
- end
234
- end
235
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, Fletcher Nichol
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
+ require "kitchen/errors"
20
+ require "kitchen/configurable"
21
+ require "kitchen/logging"
22
+
23
+ module Kitchen
24
+
25
+ module Verifier
26
+
27
+ # Base class for a verifier.
28
+ #
29
+ # @author Fletcher Nichol <fnichol@nichol.ca>
30
+ class Base
31
+
32
+ include Configurable
33
+ include Logging
34
+
35
+ default_config :http_proxy, nil
36
+ default_config :https_proxy, nil
37
+ default_config :ftp_proxy, nil
38
+
39
+ default_config :root_path do |verifier|
40
+ verifier.windows_os? ? "$env:TEMP\\verifier" : "/tmp/verifier"
41
+ end
42
+
43
+ default_config :sudo do |verifier|
44
+ verifier.windows_os? ? nil : true
45
+ end
46
+
47
+ default_config :chef_omnibus_root, "/opt/chef"
48
+
49
+ default_config :sudo_command do |verifier|
50
+ verifier.windows_os? ? nil : "sudo -E"
51
+ end
52
+
53
+ default_config :command_prefix, nil
54
+
55
+ default_config(:suite_name) { |busser| busser.instance.suite.name }
56
+
57
+ # Creates a new Verifier object using the provided configuration data
58
+ # which will be merged with any default configuration.
59
+ #
60
+ # @param config [Hash] provided verifier configuration
61
+ def initialize(config = {})
62
+ init_config(config)
63
+ end
64
+
65
+ # Runs the verifier on the instance.
66
+ #
67
+ # @param state [Hash] mutable instance state
68
+ # @raise [ActionFailed] if the action could not be completed
69
+ def call(state)
70
+ create_sandbox
71
+ sandbox_dirs = Dir.glob(File.join(sandbox_path, "*"))
72
+
73
+ instance.transport.connection(state) do |conn|
74
+ conn.execute(install_command)
75
+ conn.execute(init_command)
76
+ info("Transferring files to #{instance.to_str}")
77
+ conn.upload(sandbox_dirs, config[:root_path])
78
+ debug("Transfer complete")
79
+ conn.execute(prepare_command)
80
+ conn.execute(run_command)
81
+ end
82
+ rescue Kitchen::Transport::TransportFailed => ex
83
+ raise ActionFailed, ex.message
84
+ ensure
85
+ cleanup_sandbox
86
+ end
87
+
88
+ # Deletes the sandbox path. Without calling this method, the sandbox path
89
+ # will persist after the process terminates. In other words, cleanup is
90
+ # explicit. This method is safe to call multiple times.
91
+ def cleanup_sandbox
92
+ return if sandbox_path.nil?
93
+
94
+ debug("Cleaning up local sandbox in #{sandbox_path}")
95
+ FileUtils.rmtree(sandbox_path)
96
+ end
97
+
98
+ # Creates a temporary directory on the local workstation into which
99
+ # verifier related files and directories can be copied or created. The
100
+ # contents of this directory will be copied over to the instance before
101
+ # invoking the verifier's run command. After this method completes, it
102
+ # is expected that the contents of the sandbox is complete and ready for
103
+ # copy to the remote instance.
104
+ #
105
+ # **Note:** any subclasses would be well advised to call super first when
106
+ # overriding this method, for example:
107
+ #
108
+ # @example overriding `#create_sandbox`
109
+ #
110
+ # class MyVerifier < Kitchen::Verifier::Base
111
+ # def create_sandbox
112
+ # super
113
+ # # any further file copies, preparations, etc.
114
+ # end
115
+ # end
116
+ def create_sandbox
117
+ @sandbox_path = Dir.mktmpdir("#{instance.name}-sandbox-")
118
+ File.chmod(0755, sandbox_path)
119
+ info("Preparing files for transfer")
120
+ debug("Creating local sandbox in #{sandbox_path}")
121
+ end
122
+
123
+ # Generates a command string which will install and configure the
124
+ # verifier software on an instance. If no work is required, then `nil`
125
+ # will be returned.
126
+ #
127
+ # @return [String] a command string
128
+ def install_command
129
+ end
130
+
131
+ # Generates a command string which will perform any data initialization
132
+ # or configuration required after the verifier software is installed
133
+ # but before the sandbox has been transferred to the instance. If no work
134
+ # is required, then `nil` will be returned.
135
+ #
136
+ # @return [String] a command string
137
+ def init_command
138
+ end
139
+
140
+ # Generates a command string which will perform any commands or
141
+ # configuration required just before the main verifier run command but
142
+ # after the sandbox has been transferred to the instance. If no work is
143
+ # required, then `nil` will be returned.
144
+ #
145
+ # @return [String] a command string
146
+ def prepare_command
147
+ end
148
+
149
+ # Generates a command string which will invoke the main verifier
150
+ # command on the prepared instance. If no work is required, then `nil`
151
+ # will be returned.
152
+ #
153
+ # @return [String] a command string
154
+ def run_command
155
+ end
156
+
157
+ # Returns the absolute path to the sandbox directory or raises an
158
+ # exception if `#create_sandbox` has not yet been called.
159
+ #
160
+ # @return [String] the absolute path to the sandbox directory
161
+ # @raise [ClientError] if the sandbox directory has no yet been created
162
+ # by calling `#create_sandbox`
163
+ def sandbox_path
164
+ @sandbox_path || (raise ClientError, "Sandbox directory has not yet " \
165
+ "been created. Please run #{self.class}#create_sandox before " \
166
+ "trying to access the path.")
167
+ end
168
+
169
+ # Sets the API version for this verifier. If the verifier does not set
170
+ # this value, then `nil` will be used and reported.
171
+ #
172
+ # Sets the API version for this verifier
173
+ #
174
+ # @example setting an API version
175
+ #
176
+ # module Kitchen
177
+ # module Verifier
178
+ # class NewVerifier < Kitchen::Verifier::Base
179
+ #
180
+ # kitchen_verifier_api_version 2
181
+ #
182
+ # end
183
+ # end
184
+ # end
185
+ #
186
+ # @param version [Integer,String] a version number
187
+ #
188
+ def self.kitchen_verifier_api_version(version)
189
+ @api_version = version
190
+ end
191
+
192
+ private
193
+
194
+ # Builds a complete command given a variables String preamble and a file
195
+ # containing shell code.
196
+ #
197
+ # @param vars [String] shell variables, as a String
198
+ # @param file [String] file basename (without extension) containing
199
+ # shell code
200
+ # @return [String] command
201
+ # @api private
202
+ def shell_code_from_file(vars, file)
203
+ src_file = File.join(
204
+ File.dirname(__FILE__),
205
+ %w[.. .. .. support],
206
+ file + (powershell_shell? ? ".ps1" : ".sh")
207
+ )
208
+
209
+ wrap_shell_code([vars, "", IO.read(src_file)].join("\n"))
210
+ end
211
+
212
+ # Conditionally prefixes a command with a sudo command.
213
+ #
214
+ # @param command [String] command to be prefixed
215
+ # @return [String] the command, conditionaly prefixed with sudo
216
+ # @api private
217
+ def sudo(script)
218
+ config[:sudo] ? "#{config[:sudo_command]} #{script}" : script
219
+ end
220
+
221
+ # Conditionally prefixes a command with a command prefix.
222
+ # This should generally be done after a command has been
223
+ # conditionally prefixed by #sudo as certain platforms, such as
224
+ # Cisco Nexus, require all commands to be run with a prefix to
225
+ # obtain outbound network access.
226
+ #
227
+ # @param command [String] command to be prefixed
228
+ # @return [String] the command, conditionally prefixed with the configured prefix
229
+ # @api private
230
+ def prefix_command(script)
231
+ config[:command_prefix] ? "#{config[:command_prefix]} #{script}" : script
232
+ end
233
+ end
234
+ end
235
+ end