test-kitchen 1.3.1 → 1.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +2 -0
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +45 -0
  5. data/Rakefile +15 -0
  6. data/features/kitchen_action_commands.feature +12 -9
  7. data/features/kitchen_defaults.feature +38 -0
  8. data/features/kitchen_init_command.feature +0 -1
  9. data/features/kitchen_list_command.feature +2 -2
  10. data/features/kitchen_login_command.feature +7 -1
  11. data/features/kitchen_test_command.feature +4 -4
  12. data/lib/kitchen.rb +40 -11
  13. data/lib/kitchen/cli.rb +38 -22
  14. data/lib/kitchen/command/list.rb +5 -2
  15. data/lib/kitchen/config.rb +45 -18
  16. data/lib/kitchen/configurable.rb +137 -1
  17. data/lib/kitchen/data_munger.rb +248 -17
  18. data/lib/kitchen/driver.rb +1 -1
  19. data/lib/kitchen/driver/base.rb +1 -83
  20. data/lib/kitchen/driver/dummy.rb +0 -5
  21. data/lib/kitchen/driver/ssh_base.rb +177 -22
  22. data/lib/kitchen/instance.rb +140 -20
  23. data/lib/kitchen/logger.rb +43 -8
  24. data/lib/kitchen/login_command.rb +14 -5
  25. data/lib/kitchen/platform.rb +19 -0
  26. data/lib/kitchen/provisioner.rb +5 -3
  27. data/lib/kitchen/provisioner/base.rb +46 -48
  28. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -0
  29. data/lib/kitchen/provisioner/chef_base.rb +179 -286
  30. data/lib/kitchen/provisioner/chef_solo.rb +11 -5
  31. data/lib/kitchen/provisioner/chef_zero.rb +108 -94
  32. data/lib/kitchen/provisioner/dummy.rb +47 -0
  33. data/lib/kitchen/provisioner/shell.rb +45 -12
  34. data/lib/kitchen/rake_tasks.rb +1 -1
  35. data/lib/kitchen/ssh.rb +1 -1
  36. data/lib/kitchen/thor_tasks.rb +1 -1
  37. data/lib/kitchen/transport.rb +54 -0
  38. data/lib/kitchen/transport/base.rb +146 -0
  39. data/lib/kitchen/transport/dummy.rb +75 -0
  40. data/lib/kitchen/transport/ssh.rb +325 -0
  41. data/lib/kitchen/transport/winrm.rb +508 -0
  42. data/lib/kitchen/transport/winrm/command_executor.rb +188 -0
  43. data/lib/kitchen/transport/winrm/file_transporter.rb +454 -0
  44. data/lib/kitchen/transport/winrm/logging.rb +50 -0
  45. data/lib/kitchen/transport/winrm/template.rb +74 -0
  46. data/lib/kitchen/transport/winrm/tmp_zip.rb +187 -0
  47. data/lib/kitchen/verifier.rb +55 -0
  48. data/lib/kitchen/verifier/base.rb +191 -0
  49. data/lib/kitchen/verifier/busser.rb +266 -0
  50. data/lib/kitchen/verifier/dummy.rb +75 -0
  51. data/lib/kitchen/version.rb +1 -1
  52. data/spec/kitchen/cli_spec.rb +56 -0
  53. data/spec/kitchen/config_spec.rb +61 -20
  54. data/spec/kitchen/configurable_spec.rb +327 -1
  55. data/spec/kitchen/data_munger_spec.rb +777 -14
  56. data/spec/kitchen/driver/base_spec.rb +7 -38
  57. data/spec/kitchen/driver/dummy_spec.rb +0 -29
  58. data/spec/kitchen/driver/ssh_base_spec.rb +580 -236
  59. data/spec/kitchen/driver_spec.rb +1 -0
  60. data/spec/kitchen/instance_spec.rb +383 -83
  61. data/spec/kitchen/login_command_spec.rb +29 -10
  62. data/spec/kitchen/platform_spec.rb +58 -2
  63. data/spec/kitchen/provisioner/base_spec.rb +170 -18
  64. data/spec/kitchen/provisioner/chef_base_spec.rb +454 -104
  65. data/spec/kitchen/provisioner/chef_solo_spec.rb +307 -104
  66. data/spec/kitchen/provisioner/chef_zero_spec.rb +561 -230
  67. data/spec/kitchen/provisioner/dummy_spec.rb +91 -0
  68. data/spec/kitchen/provisioner/shell_spec.rb +158 -56
  69. data/spec/kitchen/provisioner_spec.rb +37 -0
  70. data/spec/kitchen/ssh_spec.rb +19 -19
  71. data/spec/kitchen/transport/base_spec.rb +89 -0
  72. data/spec/kitchen/transport/ssh_spec.rb +1147 -0
  73. data/spec/kitchen/transport/winrm/command_executor_spec.rb +400 -0
  74. data/spec/kitchen/transport/winrm/file_transporter_spec.rb +876 -0
  75. data/spec/kitchen/transport/winrm/logging_spec.rb +92 -0
  76. data/spec/kitchen/transport/winrm/template_spec.rb +51 -0
  77. data/spec/kitchen/transport/winrm/tmp_zip_spec.rb +132 -0
  78. data/spec/kitchen/transport/winrm_spec.rb +1069 -0
  79. data/spec/kitchen/transport_spec.rb +112 -0
  80. data/spec/kitchen/verifier/base_spec.rb +310 -0
  81. data/spec/kitchen/verifier/busser_spec.rb +540 -0
  82. data/spec/kitchen/verifier/dummy_spec.rb +91 -0
  83. data/spec/kitchen/verifier_spec.rb +120 -0
  84. data/spec/kitchen_spec.rb +7 -0
  85. data/spec/spec_helper.rb +8 -0
  86. data/spec/support/powershell_max_size_spec.rb +40 -0
  87. data/support/busser_install_command.ps1 +14 -0
  88. data/support/busser_install_command.sh +15 -0
  89. data/support/check_files.ps1.erb +48 -0
  90. data/support/chef_base_init_command.ps1 +18 -0
  91. data/support/chef_base_init_command.sh +2 -0
  92. data/support/chef_base_install_command.ps1 +76 -0
  93. data/support/chef_base_install_command.sh +137 -0
  94. data/support/chef_zero_prepare_command_legacy.ps1 +9 -0
  95. data/support/chef_zero_prepare_command_legacy.sh +10 -0
  96. data/support/decode_files.ps1.erb +61 -0
  97. data/test-kitchen.gemspec +2 -0
  98. metadata +97 -8
  99. data/lib/kitchen/busser.rb +0 -316
  100. data/spec/kitchen/busser_spec.rb +0 -490
  101. data/support/chef_helpers.sh +0 -16
@@ -62,13 +62,15 @@ module Kitchen
62
62
  color_pad(instance.name),
63
63
  color_pad(instance.driver.name),
64
64
  color_pad(instance.provisioner.name),
65
+ color_pad(instance.verifier.name),
66
+ color_pad(instance.transport.name),
65
67
  format_last_action(instance.last_action)
66
68
  ]
67
69
  end
68
70
 
69
71
  # Format and color the given last action.
70
72
  #
71
- # @param [String] the last action
73
+ # @param last_action [String] the last action
72
74
  # @return [String] formated last action
73
75
  # @api private
74
76
  def format_last_action(last_action)
@@ -90,7 +92,8 @@ module Kitchen
90
92
  table = [
91
93
  [
92
94
  colorize("Instance", :green), colorize("Driver", :green),
93
- colorize("Provisioner", :green), colorize("Last Action", :green)
95
+ colorize("Provisioner", :green), colorize("Verifier", :green),
96
+ colorize("Transport", :green), colorize("Last Action", :green)
94
97
  ]
95
98
  ]
96
99
  table += Array(result).map { |i| display_instance(i) }
@@ -72,6 +72,11 @@ module Kitchen
72
72
  # @api private
73
73
  attr_accessor :log_level
74
74
 
75
+ # @return [Boolean] whether to overwrite the log file when
76
+ # Test Kitchen runs
77
+ # @api private
78
+ attr_accessor :log_overwrite
79
+
75
80
  # Creates a new configuration, representing a particular testing
76
81
  # configuration for a project.
77
82
  #
@@ -94,6 +99,7 @@ module Kitchen
94
99
  @loader = options.fetch(:loader) { Kitchen::Loader::YAML.new }
95
100
  @kitchen_root = options.fetch(:kitchen_root) { Dir.pwd }
96
101
  @log_level = options.fetch(:log_level) { Kitchen::DEFAULT_LOG_LEVEL }
102
+ @log_overwrite = options.fetch(:log_overwrite) { Kitchen::DEFAULT_LOG_OVERWRITE }
97
103
  @log_root = options.fetch(:log_root) { default_log_root }
98
104
  @test_base_path = options.fetch(:test_base_path) { default_test_base_path }
99
105
  end
@@ -188,7 +194,7 @@ module Kitchen
188
194
  end
189
195
 
190
196
  # Generates the immutable Test Kitchen configuration and reasonable
191
- # defaults for Drivers and Provisioners.
197
+ # defaults for Drivers, Provisioners and Transports.
192
198
  #
193
199
  # @return [Hash] a configuration Hash
194
200
  # @api private
@@ -196,25 +202,19 @@ module Kitchen
196
202
  @kitchen_config ||= {
197
203
  :defaults => {
198
204
  :driver => Driver::DEFAULT_PLUGIN,
199
- :provisioner => Provisioner::DEFAULT_PLUGIN
205
+ :provisioner => Provisioner::DEFAULT_PLUGIN,
206
+ :verifier => Verifier::DEFAULT_PLUGIN,
207
+ :transport => lambda { |_suite, platform|
208
+ platform =~ /^win/i ? "winrm" : Transport::DEFAULT_PLUGIN
209
+ }
200
210
  },
201
211
  :kitchen_root => kitchen_root,
202
212
  :test_base_path => test_base_path,
203
- :log_level => log_level
213
+ :log_level => log_level,
214
+ :log_overwrite => log_overwrite
204
215
  }
205
216
  end
206
217
 
207
- # Builds a newly configured Busser object, for a given a Suite and Platform.
208
- #
209
- # @param suite [Suite,#name] a Suite
210
- # @param platform [Platform,#name] a Platform
211
- # @return [Busser] a new Busser object
212
- # @api private
213
- def new_busser(suite, platform)
214
- bdata = data.busser_data_for(suite.name, platform.name)
215
- Busser.new(suite.name, bdata)
216
- end
217
-
218
218
  # Builds a newly configured Driver object, for a given Suite and Platform.
219
219
  #
220
220
  # @param suite [Suite,#name] a Suite
@@ -236,12 +236,13 @@ module Kitchen
236
236
  # @api private
237
237
  def new_instance(suite, platform, index)
238
238
  Instance.new(
239
- :busser => new_busser(suite, platform),
240
239
  :driver => new_driver(suite, platform),
241
- :logger => new_logger(suite, platform, index),
240
+ :logger => new_instance_logger(suite, platform, index),
242
241
  :suite => suite,
243
242
  :platform => platform,
244
243
  :provisioner => new_provisioner(suite, platform),
244
+ :transport => new_transport(suite, platform),
245
+ :verifier => new_verifier(suite, platform),
245
246
  :state_file => new_state_file(suite, platform)
246
247
  )
247
248
  end
@@ -254,13 +255,15 @@ module Kitchen
254
255
  # @param index [Integer] an index used for colorizing output
255
256
  # @return [Logger] a new Logger object
256
257
  # @api private
257
- def new_logger(suite, platform, index)
258
+ def new_instance_logger(suite, platform, index)
258
259
  name = instance_name(suite, platform)
260
+ log_location = File.join(log_root, "#{name}.log").to_s
259
261
  Logger.new(
260
262
  :stdout => STDOUT,
261
263
  :color => Color::COLORS[index % Color::COLORS.size].to_sym,
262
- :logdev => File.join(log_root, "#{name}.log"),
264
+ :logdev => log_location,
263
265
  :level => Util.to_logger_level(log_level),
266
+ :log_overwrite => log_overwrite,
264
267
  :progname => name
265
268
  )
266
269
  end
@@ -287,5 +290,29 @@ module Kitchen
287
290
  def new_state_file(suite, platform)
288
291
  StateFile.new(kitchen_root, instance_name(suite, platform))
289
292
  end
293
+
294
+ # Builds a newly configured Transport object, for a given Suite and
295
+ # Platform.
296
+ #
297
+ # @param suite [Suite,#name] a Suite
298
+ # @param platform [Platform,#name] a Platform
299
+ # @return [Transport] a new Transport object
300
+ # @api private
301
+ def new_transport(suite, platform)
302
+ tdata = data.transport_data_for(suite.name, platform.name)
303
+ Transport.for_plugin(tdata[:name], tdata)
304
+ end
305
+
306
+ # Builds a newly configured Verifier object, for a given a Suite and
307
+ # Platform.
308
+ #
309
+ # @param suite [Suite,#name] a Suite
310
+ # @param platform [Platform,#name] a Platform
311
+ # @return [Verifier] a new Verifier object
312
+ # @api private
313
+ def new_verifier(suite, platform)
314
+ vdata = data.verifier_data_for(suite.name, platform.name)
315
+ Verifier.for_plugin(vdata[:name], vdata)
316
+ end
290
317
  end
291
318
  end
@@ -53,6 +53,7 @@ module Kitchen
53
53
  @instance = instance
54
54
  expand_paths!
55
55
  validate_config!
56
+ load_needed_dependencies!
56
57
 
57
58
  self
58
59
  end
@@ -65,6 +66,12 @@ module Kitchen
65
66
  config[attr]
66
67
  end
67
68
 
69
+ # @return [TrueClass,FalseClass] true if `:shell_type` is `"bourne"` (or
70
+ # unset, for backwards compatability)
71
+ def bourne_shell?
72
+ ["bourne", nil].include?(instance.platform.shell_type)
73
+ end
74
+
68
75
  # Find an appropriate path to a file or directory, based on graceful
69
76
  # fallback rules or returns nil if path cannot be determined.
70
77
  #
@@ -117,6 +124,48 @@ module Kitchen
117
124
  result
118
125
  end
119
126
 
127
+ # Returns the name of this plugin, suitable for display in a CLI.
128
+ #
129
+ # @return [String] name of this plugin
130
+ def name
131
+ self.class.name.split("::").last
132
+ end
133
+
134
+ # @return [TrueClass,FalseClass] true if `:shell_type` is `"powershell"`
135
+ def powershell_shell?
136
+ ["powershell"].include?(instance.platform.shell_type)
137
+ end
138
+
139
+ # Builds a file path based on the `:os_type` (`"windows"` or `"unix"`).
140
+ #
141
+ # @return [String] joined path for instance's os_type
142
+ def remote_path_join(*parts)
143
+ path = File.join(*parts)
144
+ windows_os? ? path.gsub("/", "\\") : path.gsub("\\", "/")
145
+ end
146
+
147
+ # @return [TrueClass,FalseClass] true if `:os_type` is `"unix"` (or
148
+ # unset, for backwards compatibility)
149
+ def unix_os?
150
+ ["unix", nil].include?(instance.platform.os_type)
151
+ end
152
+
153
+ # Performs whatever tests that may be required to ensure that this plugin
154
+ # will be able to function in the current environment. This may involve
155
+ # checking for the presence of certain directories, software installed,
156
+ # etc.
157
+ #
158
+ # @raise [UserError] if the plugin will not be able to perform or if a
159
+ # documented dependency is missing from the system
160
+ def verify_dependencies
161
+ # this method may be left unimplemented if that is applicable
162
+ end
163
+
164
+ # @return [TrueClass,FalseClass] true if `:os_type` is `"windows"`
165
+ def windows_os?
166
+ ["windows"].include?(instance.platform.os_type)
167
+ end
168
+
120
169
  private
121
170
 
122
171
  # @return [LzayHash] a configuration hash
@@ -148,7 +197,71 @@ module Kitchen
148
197
  expanded_paths.each do |key, should_expand|
149
198
  next if !should_expand || config[key].nil?
150
199
 
151
- config[key] = File.expand_path(config[key], root_path)
200
+ config[key] = if config[key].is_a?(Array)
201
+ config[key].map { |path| File.expand_path(path, root_path) }
202
+ else
203
+ File.expand_path(config[key], root_path)
204
+ end
205
+ end
206
+ end
207
+
208
+ # Loads any required third party Ruby libraries or runs any shell out
209
+ # commands to prepare the plugin. This method will be called in the
210
+ # context of the main thread of execution and so does not necessarily
211
+ # have to be thread safe.
212
+ #
213
+ # **Note:** any subclasses overriding this method would be well advised
214
+ # to call super when overriding this method, for example:
215
+ #
216
+ # @example overriding `#load_needed_dependencies!`
217
+ #
218
+ # class MyProvisioner < Kitchen::Provisioner::Base
219
+ # def load_needed_dependencies!
220
+ # super
221
+ # # any further work
222
+ # end
223
+ # end
224
+ #
225
+ # @raise [ClientError] if any library loading fails or any of the
226
+ # dependency requirements cannot be satisfied
227
+ # @api private
228
+ def load_needed_dependencies!
229
+ # this method may be left unimplemented if that is applicable
230
+ end
231
+
232
+ # @return [Logger] the instance's logger or Test Kitchen's common logger
233
+ # otherwise
234
+ # @api private
235
+ def logger
236
+ instance ? instance.logger : Kitchen.logger
237
+ end
238
+
239
+ # Builds a shell environment variable assignment string for the
240
+ # required shell type.
241
+ #
242
+ # @param name [String] variable name
243
+ # @param value [String] variable value
244
+ # @return [String] shell variable assignment
245
+ # @api private
246
+ def shell_env_var(name, value)
247
+ if powershell_shell?
248
+ shell_var("env:#{name}", value)
249
+ else
250
+ "#{shell_var(name, value)}; export #{name}"
251
+ end
252
+ end
253
+
254
+ # Builds a shell variable assignment string for the required shell type.
255
+ #
256
+ # @param name [String] variable name
257
+ # @param value [String] variable value
258
+ # @return [String] shell variable assignment
259
+ # @api private
260
+ def shell_var(name, value)
261
+ if powershell_shell?
262
+ %{$#{name} = "#{value}"}
263
+ else
264
+ %{#{name}="#{value}"}
152
265
  end
153
266
  end
154
267
 
@@ -164,6 +277,29 @@ module Kitchen
164
277
  end
165
278
  end
166
279
 
280
+ # Wraps a body of shell code with common context appropriate for the type
281
+ # of shell.
282
+ #
283
+ # @param code [String] the shell code to be wrapped
284
+ # @return [String] wrapped shell code
285
+ # @api private
286
+ def wrap_shell_code(code)
287
+ env = []
288
+ if config[:http_proxy]
289
+ env << shell_env_var("http_proxy", config[:http_proxy])
290
+ env << shell_env_var("HTTP_PROXY", config[:http_proxy])
291
+ end
292
+ if config[:https_proxy]
293
+ env << shell_env_var("https_proxy", config[:https_proxy])
294
+ env << shell_env_var("HTTPS_PROXY", config[:https_proxy])
295
+ end
296
+ if powershell_shell?
297
+ env.join("\n").concat("\n").concat(code)
298
+ else
299
+ Util.wrap_command(env.join("\n").concat("\n").concat(code))
300
+ end
301
+ end
302
+
167
303
  # Class methods which will be mixed in on inclusion of Configurable module.
168
304
  module ClassMethods
169
305
 
@@ -44,24 +44,11 @@ module Kitchen
44
44
  convert_legacy_driver_format!
45
45
  convert_legacy_chef_paths_format!
46
46
  convert_legacy_require_chef_omnibus_format!
47
+ convert_legacy_busser_format!
48
+ convert_legacy_driver_http_proxy_format!
47
49
  move_chef_data_to_provisioner!
48
50
  end
49
51
 
50
- # Generate a new Hash of configuration data that can be used to construct
51
- # a new Busser object.
52
- #
53
- # @param suite [String] a suite name
54
- # @param platform [String] a platform name
55
- # @return [Hash] a new configuration Hash that can be used to construct a
56
- # new Busser
57
- def busser_data_for(suite, platform)
58
- merged_data_for(:busser, suite, platform, :version).tap do |bdata|
59
- set_kitchen_config_at!(bdata, :kitchen_root)
60
- set_kitchen_config_at!(bdata, :test_base_path)
61
- set_kitchen_config_at!(bdata, :log_level)
62
- end
63
- end
64
-
65
52
  # Generate a new Hash of configuration data that can be used to construct
66
53
  # a new Driver object.
67
54
  #
@@ -107,6 +94,36 @@ module Kitchen
107
94
  data.fetch(:suites, [])
108
95
  end
109
96
 
97
+ # Generate a new Hash of configuration data that can be used to construct
98
+ # a new Transport object.
99
+ #
100
+ # @param suite [String] a suite name
101
+ # @param platform [String] a platform name
102
+ # @return [Hash] a new configuration Hash that can be used to construct a
103
+ # new Transport
104
+ def transport_data_for(suite, platform)
105
+ merged_data_for(:transport, suite, platform).tap do |tdata|
106
+ set_kitchen_config_at!(tdata, :kitchen_root)
107
+ set_kitchen_config_at!(tdata, :test_base_path)
108
+ set_kitchen_config_at!(tdata, :log_level)
109
+ end
110
+ end
111
+
112
+ # Generate a new Hash of configuration data that can be used to construct
113
+ # a new Verifier object.
114
+ #
115
+ # @param suite [String] a suite name
116
+ # @param platform [String] a platform name
117
+ # @return [Hash] a new configuration Hash that can be used to construct a
118
+ # new Verifier
119
+ def verifier_data_for(suite, platform)
120
+ merged_data_for(:verifier, suite, platform).tap do |vdata|
121
+ set_kitchen_config_at!(vdata, :kitchen_root)
122
+ set_kitchen_config_at!(vdata, :test_base_path)
123
+ set_kitchen_config_at!(vdata, :log_level)
124
+ end
125
+ end
126
+
110
127
  private
111
128
 
112
129
  # @return [Hash] the user data hash
@@ -125,6 +142,93 @@ module Kitchen
125
142
  end
126
143
  end
127
144
 
145
+ # Destructively moves old-style `:busser` configuration hashes into the
146
+ # correct `:verifier` hash.
147
+ #
148
+ # This method converts the following:
149
+ #
150
+ # {
151
+ # :busser => { :one => "two" },
152
+ #
153
+ # :platforms => [
154
+ # {
155
+ # :name => "ubuntu-12.04",
156
+ # :busser => "bar"
157
+ # }
158
+ # ],
159
+ #
160
+ # :suites => [
161
+ # {
162
+ # :name => "alpha",
163
+ # :busser => { :three => "four" }
164
+ # }
165
+ # ]
166
+ # }
167
+ #
168
+ # into the following:
169
+ #
170
+ # {
171
+ # :verifier => {
172
+ # :name => "busser",
173
+ # :one => "two"
174
+ # }
175
+ #
176
+ # :platforms => [
177
+ # {
178
+ # :name => "ubuntu-12.04",
179
+ # :verifier => {
180
+ # :name => "busser",
181
+ # :version => "bar
182
+ # }
183
+ # }
184
+ # ],
185
+ #
186
+ # :suites => [
187
+ # {
188
+ # :name => "alpha",
189
+ # :verifier => {
190
+ # :name => "busser",
191
+ # :three => "four"
192
+ # }
193
+ # }
194
+ # ]
195
+ # }
196
+ #
197
+ # @deprecated The following configuration hashes should no longer be
198
+ # created in a `:platform`, `:suite`, or common location:
199
+ # `:busser`. Use a `:verifier` hash block in their place.
200
+ # @api private
201
+ def convert_legacy_busser_format!
202
+ convert_legacy_busser_format_at!(data)
203
+ data.fetch(:platforms, []).each do |platform|
204
+ convert_legacy_busser_format_at!(platform)
205
+ end
206
+ data.fetch(:suites, []).each do |suite|
207
+ convert_legacy_busser_format_at!(suite)
208
+ end
209
+ end
210
+
211
+ # Destructively moves old-style `:busser` configuration hashes into the
212
+ # correct `:verifier` hashes. This method has no knowledge of suites,
213
+ # platforms, or the like, just a vanilla hash.
214
+ #
215
+ # @param root [Hash] a hash to use as the root of the conversion
216
+ # @deprecated The following configuration hashses should no longer be
217
+ # created in a Test Kitchen hash: `:busser`. Use a `:verifier` hash
218
+ # block in their place.
219
+ # @api private
220
+ def convert_legacy_busser_format_at!(root)
221
+ if root.key?(:busser)
222
+ bdata = root.delete(:busser)
223
+ bdata = { :version => bdata } if bdata.is_a?(String)
224
+ bdata[:name] = "busser" if bdata[:name].nil?
225
+
226
+ vdata = root.fetch(:verifier, Hash.new)
227
+ vdata = { :name => vdata } if vdata.is_a?(String)
228
+ root[:verifier] = bdata.rmerge(vdata)
229
+ end
230
+ end
231
+
128
232
  # Destructively moves Chef-related paths out of a suite hash and into the
129
233
  # suite's provisioner sub-hash.
130
234
  #
@@ -273,6 +377,130 @@ module Kitchen
273
377
  end
274
378
  end
275
379
 
380
+ # Copies `:http_proxy` and `:https_proxy` values in a driver hash into the
381
+ # provisioner and verifier hashes. For backwards compatibility with legacy
382
+ # Drivers (those inheriting directly from `SSHBase`), the original
383
+ # values are maintained in the driver hash.
384
+ #
385
+ # This method converts the following:
386
+ #
387
+ # {
388
+ # :driver => {
389
+ # :http_proxy => "http://proxy",
390
+ # :https_proxy => "https://proxy"
391
+ # },
392
+ #
393
+ # :platforms => [
394
+ # {
395
+ # :name => "ubuntu-12.04",
396
+ # :driver => {
397
+ # :http_proxy => "foo"
398
+ # }
399
+ # }
400
+ # ],
401
+ #
402
+ # :suites => [
403
+ # {
404
+ # :name => "alpha",
405
+ # :driver => {
406
+ # :https_proxy => "bar"
407
+ # }
408
+ # }
409
+ # ]
410
+ # }
411
+ #
412
+ # into the following:
413
+ #
414
+ # {
415
+ # :driver => {
416
+ # :http_proxy => "http://proxy",
417
+ # :https_proxy => "https://proxy"
418
+ # },
419
+ #
420
+ # :provisioner => {
421
+ # :http_proxy => "http://proxy",
422
+ # :https_proxy => "https://proxy"
423
+ # },
424
+ #
425
+ # :verifier => {
426
+ # :http_proxy => "http://proxy",
427
+ # :https_proxy => "https://proxy"
428
+ # },
429
+ #
430
+ # :platforms => [
431
+ # {
432
+ # :name => "ubuntu-12.04",
433
+ # :driver => {
434
+ # :http_proxy => "foo"
435
+ # },
436
+ # :provisioner => {
437
+ # :http_proxy => "foo"
438
+ # },
439
+ # :verifier => {
440
+ # :http_proxy => "foo"
441
+ # }
442
+ # }
443
+ # ],
444
+ #
445
+ # :suites => [
446
+ # {
447
+ # :name => "alpha",
448
+ # :driver => {
449
+ # :https_proxy => "bar"
450
+ # },
451
+ # :provisioner => {
452
+ # :https_proxy => "bar"
453
+ # },
454
+ # :verifier => {
455
+ # :https_proxy => "bar"
456
+ # }
457
+ # }
458
+ # ]
459
+ # }
460
+ #
461
+ # @deprecated The `:http_proxy` and `:https_proxy` should no longer be
462
+ # used in driver blocks, they should be added to the provisioner and
463
+ # verifier blocks so that they can be independantly configured.
464
+ # Provisioners and Verifiers are responsible for HTTP proxying and no
465
+ # longer are Drivers responsible for this.
466
+ # @api private
467
+ def convert_legacy_driver_http_proxy_format!
468
+ convert_legacy_driver_http_proxy_format_at!(data)
469
+ data.fetch(:platforms, []).each do |platform|
470
+ convert_legacy_driver_http_proxy_format_at!(platform)
471
+ end
472
+ data.fetch(:suites, []).each do |suite|
473
+ convert_legacy_driver_http_proxy_format_at!(suite)
474
+ end
475
+ end
476
+
477
+ # Copies `:http_proxy` and `:https_proxy` values in a driver hash into
478
+ # the provisioner and verifier hashes. This method has no knowledge of
479
+ # suites, platforms, or the like, just a vanilla hash.
480
+ #
481
+ # @param root [Hash] a hash to use as the root of the conversion
482
+ # @deprecated The `:http_proxy` and `:https_proxy` should no longer be
483
+ # used in driver blocks, they should be added to the provisioner and
484
+ # verifier blocks so that they can be independantly configured.
485
+ # Provisioners and Verifiers are responsible for HTTP proxying and no
486
+ # longer are Drivers responsible for this.
487
+ # @api private
488
+ def convert_legacy_driver_http_proxy_format_at!(root)
489
+ ddata = root.fetch(:driver, Hash.new)
490
+
491
+ [:http_proxy, :https_proxy].each do |key|
492
+ next unless ddata.is_a?(Hash) && ddata.key?(key)
493
+
494
+ pdata = root.fetch(:provisioner, Hash.new)
495
+ pdata = { :name => pdata } if pdata.is_a?(String)
496
+ root[:provisioner] = { key => ddata.fetch(key) }.rmerge(pdata)
497
+
498
+ vdata = root.fetch(:verifier, Hash.new)
499
+ vdata = { :name => vdata } if vdata.is_a?(String)
500
+ root[:verifier] = { key => ddata.fetch(key) }.rmerge(vdata)
501
+ end
502
+ end
503
+
276
504
  # Destructively moves a `:require_chef_omnibus` key/value pair from a
277
505
  # `:driver` hash block to a `:provisioner` hash block.
278
506
  #
@@ -386,7 +614,7 @@ module Kitchen
386
614
  # @return [Hash] a new merged Hash
387
615
  # @api private
388
616
  def merged_data_for(key, suite, platform, default_key = :name)
389
- ddata = normalized_default_data(key, default_key)
617
+ ddata = normalized_default_data(key, default_key, suite, platform)
390
618
  cdata = normalized_common_data(key, default_key)
391
619
  pdata = normalized_platform_data(key, default_key, platform)
392
620
  sdata = normalized_suite_data(key, default_key, suite)
@@ -563,11 +791,14 @@ module Kitchen
563
791
  # @param key [Symbol] the value to normalize
564
792
  # @param default_key [Symbol] the implicit default key if a String value
565
793
  # is given
794
+ # @param suite [String] name of a suite
795
+ # @param platform [String] name of a platform
566
796
  # @return [Hash] a shallow Hash copy of the original if not modified, or a
567
797
  # new Hash otherwise
568
798
  # @api private
569
- def normalized_default_data(key, default_key)
799
+ def normalized_default_data(key, default_key, suite, platform)
570
800
  ddata = kitchen_config.fetch(:defaults, Hash.new).fetch(key, Hash.new).dup
801
+ ddata = { default_key => ddata.call(suite, platform) } if ddata.is_a?(Proc)
571
802
  ddata = { default_key => ddata } if ddata.is_a?(String)
572
803
  ddata
573
804
  end