test-kitchen-rsync 3.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +21 -0
- data/LICENSE +15 -0
- data/Rakefile +53 -0
- data/bin/zl-kitchen +11 -0
- data/lib/kitchen/base64_stream.rb +48 -0
- data/lib/kitchen/chef_utils_wiring.rb +40 -0
- data/lib/kitchen/cli.rb +413 -0
- data/lib/kitchen/collection.rb +52 -0
- data/lib/kitchen/color.rb +63 -0
- data/lib/kitchen/command/action.rb +41 -0
- data/lib/kitchen/command/console.rb +54 -0
- data/lib/kitchen/command/diagnose.rb +84 -0
- data/lib/kitchen/command/doctor.rb +39 -0
- data/lib/kitchen/command/exec.rb +37 -0
- data/lib/kitchen/command/list.rb +148 -0
- data/lib/kitchen/command/login.rb +39 -0
- data/lib/kitchen/command/package.rb +32 -0
- data/lib/kitchen/command/sink.rb +50 -0
- data/lib/kitchen/command/test.rb +47 -0
- data/lib/kitchen/command.rb +207 -0
- data/lib/kitchen/config.rb +344 -0
- data/lib/kitchen/configurable.rb +616 -0
- data/lib/kitchen/data_munger.rb +1024 -0
- data/lib/kitchen/diagnostic.rb +138 -0
- data/lib/kitchen/driver/base.rb +133 -0
- data/lib/kitchen/driver/dummy.rb +105 -0
- data/lib/kitchen/driver/exec.rb +70 -0
- data/lib/kitchen/driver/proxy.rb +70 -0
- data/lib/kitchen/driver/ssh_base.rb +351 -0
- data/lib/kitchen/driver.rb +40 -0
- data/lib/kitchen/errors.rb +243 -0
- data/lib/kitchen/generator/init.rb +254 -0
- data/lib/kitchen/instance.rb +726 -0
- data/lib/kitchen/lazy_hash.rb +148 -0
- data/lib/kitchen/lifecycle_hook/base.rb +78 -0
- data/lib/kitchen/lifecycle_hook/local.rb +53 -0
- data/lib/kitchen/lifecycle_hook/remote.rb +39 -0
- data/lib/kitchen/lifecycle_hooks.rb +92 -0
- data/lib/kitchen/loader/yaml.rb +377 -0
- data/lib/kitchen/logger.rb +422 -0
- data/lib/kitchen/logging.rb +52 -0
- data/lib/kitchen/login_command.rb +49 -0
- data/lib/kitchen/metadata_chopper.rb +49 -0
- data/lib/kitchen/platform.rb +64 -0
- data/lib/kitchen/plugin.rb +76 -0
- data/lib/kitchen/plugin_base.rb +60 -0
- data/lib/kitchen/provisioner/base.rb +269 -0
- data/lib/kitchen/provisioner/chef/berkshelf.rb +116 -0
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +350 -0
- data/lib/kitchen/provisioner/chef/policyfile.rb +163 -0
- data/lib/kitchen/provisioner/chef_apply.rb +121 -0
- data/lib/kitchen/provisioner/chef_base.rb +705 -0
- data/lib/kitchen/provisioner/chef_infra.rb +167 -0
- data/lib/kitchen/provisioner/chef_solo.rb +82 -0
- data/lib/kitchen/provisioner/chef_zero.rb +12 -0
- data/lib/kitchen/provisioner/dummy.rb +75 -0
- data/lib/kitchen/provisioner/shell.rb +157 -0
- data/lib/kitchen/provisioner.rb +42 -0
- data/lib/kitchen/rake_tasks.rb +80 -0
- data/lib/kitchen/shell_out.rb +90 -0
- data/lib/kitchen/ssh.rb +289 -0
- data/lib/kitchen/state_file.rb +112 -0
- data/lib/kitchen/suite.rb +48 -0
- data/lib/kitchen/thor_tasks.rb +63 -0
- data/lib/kitchen/transport/base.rb +236 -0
- data/lib/kitchen/transport/dummy.rb +78 -0
- data/lib/kitchen/transport/exec.rb +145 -0
- data/lib/kitchen/transport/ssh.rb +579 -0
- data/lib/kitchen/transport/winrm.rb +546 -0
- data/lib/kitchen/transport.rb +40 -0
- data/lib/kitchen/util.rb +229 -0
- data/lib/kitchen/verifier/base.rb +243 -0
- data/lib/kitchen/verifier/busser.rb +275 -0
- data/lib/kitchen/verifier/dummy.rb +75 -0
- data/lib/kitchen/verifier/shell.rb +99 -0
- data/lib/kitchen/verifier.rb +39 -0
- data/lib/kitchen/version.rb +20 -0
- data/lib/kitchen/which.rb +26 -0
- data/lib/kitchen.rb +152 -0
- data/lib/vendor/hash_recursive_merge.rb +79 -0
- data/support/busser_install_command.ps1 +14 -0
- data/support/busser_install_command.sh +21 -0
- data/support/chef-client-fail-if-update-handler.rb +15 -0
- data/support/chef_base_init_command.ps1 +18 -0
- data/support/chef_base_init_command.sh +1 -0
- data/support/chef_base_install_command.ps1 +85 -0
- data/support/chef_base_install_command.sh +229 -0
- data/support/download_helpers.sh +109 -0
- data/support/dummy-validation.pem +27 -0
- data/templates/driver/CHANGELOG.md.erb +3 -0
- data/templates/driver/Gemfile.erb +3 -0
- data/templates/driver/README.md.erb +64 -0
- data/templates/driver/Rakefile.erb +21 -0
- data/templates/driver/driver.rb.erb +23 -0
- data/templates/driver/gemspec.erb +29 -0
- data/templates/driver/gitignore.erb +17 -0
- data/templates/driver/license_apachev2.erb +15 -0
- data/templates/driver/license_lgplv3.erb +16 -0
- data/templates/driver/license_mit.erb +22 -0
- data/templates/driver/license_reserved.erb +5 -0
- data/templates/driver/tailor.erb +4 -0
- data/templates/driver/travis.yml.erb +11 -0
- data/templates/driver/version.rb.erb +12 -0
- data/templates/init/chefignore.erb +2 -0
- data/templates/init/kitchen.yml.erb +18 -0
- data/test-kitchen.gemspec +52 -0
- metadata +528 -0
@@ -0,0 +1,275 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012, 2013, Fletcher Nichol
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require "base64" unless defined?(Base64)
|
19
|
+
require "digest" unless defined?(Digest)
|
20
|
+
|
21
|
+
require_relative "base"
|
22
|
+
|
23
|
+
module Kitchen
|
24
|
+
module Verifier
|
25
|
+
# Command string generator to interface with Busser. The commands that are
|
26
|
+
# generated are safe to pass to an SSH command or as an unix command
|
27
|
+
# argument (escaped in single quotes).
|
28
|
+
#
|
29
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
30
|
+
class Busser < Kitchen::Verifier::Base
|
31
|
+
kitchen_verifier_api_version 1
|
32
|
+
|
33
|
+
plugin_version Kitchen::VERSION
|
34
|
+
|
35
|
+
default_config :busser_bin do |verifier|
|
36
|
+
verifier
|
37
|
+
.remote_path_join(%W{#{verifier[:root_path]} bin busser})
|
38
|
+
.tap { |path| path.concat(".bat") if verifier.windows_os? }
|
39
|
+
end
|
40
|
+
|
41
|
+
default_config :ruby_bindir do |verifier|
|
42
|
+
if verifier.windows_os?
|
43
|
+
'$env:systemdrive\\opscode\\chef\\embedded\\bin'
|
44
|
+
else
|
45
|
+
verifier.remote_path_join(%W{#{verifier[:chef_omnibus_root]} embedded bin})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
default_config :version, "busser"
|
50
|
+
|
51
|
+
expand_path_for :test_base_path
|
52
|
+
|
53
|
+
# Creates a new Busser object using the provided configuration data
|
54
|
+
# which will be merged with any default configuration.
|
55
|
+
#
|
56
|
+
# @param config [Hash] provided driver configuration
|
57
|
+
def initialize(config = {})
|
58
|
+
init_config(config)
|
59
|
+
end
|
60
|
+
|
61
|
+
# (see Base#create_sandbox)
|
62
|
+
def create_sandbox
|
63
|
+
super
|
64
|
+
prepare_helpers
|
65
|
+
prepare_suites
|
66
|
+
end
|
67
|
+
|
68
|
+
# (see Base#init_command)
|
69
|
+
def init_command
|
70
|
+
return if local_suite_files.empty?
|
71
|
+
|
72
|
+
cmd = sudo(config[:busser_bin]).dup
|
73
|
+
.tap { |str| str.insert(0, "& ") if powershell_shell? }
|
74
|
+
|
75
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
76
|
+
#{busser_env}
|
77
|
+
|
78
|
+
#{cmd} suite cleanup
|
79
|
+
CMD
|
80
|
+
end
|
81
|
+
|
82
|
+
# (see Base#install_command)
|
83
|
+
def install_command
|
84
|
+
return if local_suite_files.empty?
|
85
|
+
|
86
|
+
vars = install_command_vars
|
87
|
+
|
88
|
+
prefix_command(shell_code_from_file(vars, "busser_install_command"))
|
89
|
+
end
|
90
|
+
|
91
|
+
# (see Base#run_command)
|
92
|
+
def run_command
|
93
|
+
return if local_suite_files.empty?
|
94
|
+
|
95
|
+
cmd = sudo(config[:busser_bin]).dup
|
96
|
+
.tap { |str| str.insert(0, "& ") if powershell_shell? }
|
97
|
+
|
98
|
+
prefix_command(wrap_shell_code(Util.outdent!(<<-CMD)))
|
99
|
+
#{busser_env}
|
100
|
+
|
101
|
+
#{cmd} test #{plugins.join(" ").gsub!("busser-", "")}
|
102
|
+
CMD
|
103
|
+
end
|
104
|
+
|
105
|
+
# Legacy method stub for `#setup_cmd` which calls `#install_command`.
|
106
|
+
#
|
107
|
+
# @return [String] command string
|
108
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
109
|
+
# removed, this method will no longer be available. Use
|
110
|
+
# `#install_command` in its place.
|
111
|
+
define_method(:setup_cmd) { install_command }
|
112
|
+
|
113
|
+
# Legacy method stub for `#run_cmd` which calls `#run_command`.
|
114
|
+
#
|
115
|
+
# @return [String] command string
|
116
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
117
|
+
# removed, this method will no longer be available. Use
|
118
|
+
# `#run_command` in its place.
|
119
|
+
define_method(:run_cmd) { run_command }
|
120
|
+
|
121
|
+
# Legacy method stub for `#sync_cmd`.
|
122
|
+
#
|
123
|
+
# @deprecated When backwards compatibility for old Busser methods is
|
124
|
+
# removed, this method will no longer be available. Use
|
125
|
+
# `transport#upload` to transfer test files in its place.
|
126
|
+
def sync_cmd
|
127
|
+
warn("Legacy call to #sync_cmd cannot be preserved, meaning that " \
|
128
|
+
"test files will not be uploaded. " \
|
129
|
+
"Code that calls #sync_cmd can now use the transport#upload " \
|
130
|
+
"method to transfer files.")
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Returns a command string that sets appropriate environment variables for
|
136
|
+
# busser commands.
|
137
|
+
#
|
138
|
+
# @return [String] command string
|
139
|
+
# @api private
|
140
|
+
def busser_env
|
141
|
+
root = config[:root_path]
|
142
|
+
gem_home = gem_path = remote_path_join(root, "gems")
|
143
|
+
gem_cache = remote_path_join(gem_home, "cache")
|
144
|
+
|
145
|
+
[
|
146
|
+
shell_env_var("BUSSER_ROOT", root),
|
147
|
+
shell_env_var("GEM_HOME", gem_home),
|
148
|
+
shell_env_var("GEM_PATH", gem_path),
|
149
|
+
shell_env_var("GEM_CACHE", gem_cache),
|
150
|
+
].join("\n")
|
151
|
+
.tap { |str| str.insert(0, reload_ps1_path) if windows_os? }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Determines whether or not a local workstation file exists under a
|
155
|
+
# Chef-related directory.
|
156
|
+
#
|
157
|
+
# @return [truthy,falsey] whether or not a given file is some kind of
|
158
|
+
# Chef-related file
|
159
|
+
# @api private
|
160
|
+
def chef_data_dir?(base, file)
|
161
|
+
file =~ %r{^#{base}/(data|data_bags|environments|nodes|roles)/}
|
162
|
+
end
|
163
|
+
|
164
|
+
# Returns arguments to a `gem install` command, suitable to install the
|
165
|
+
# Busser gem.
|
166
|
+
#
|
167
|
+
# @return [String] arguments string
|
168
|
+
# @api private
|
169
|
+
def gem_install_args
|
170
|
+
gem, version = config[:version].split("@")
|
171
|
+
if /^\d+\.\d+\.\d+/.match?(gem)
|
172
|
+
version = gem
|
173
|
+
gem = "busser"
|
174
|
+
end
|
175
|
+
|
176
|
+
root = config[:root_path]
|
177
|
+
gem_bin = remote_path_join(root, "bin")
|
178
|
+
|
179
|
+
# We don't want the gems to be installed in the home directory,
|
180
|
+
# this will force the bindir and the gem install location both
|
181
|
+
# to be under /tmp/verifier
|
182
|
+
args = gem
|
183
|
+
args += " --version #{version}" if version
|
184
|
+
args += " --no-document --no-format-executable -n #{gem_bin}"
|
185
|
+
args += " --no-user-install"
|
186
|
+
args
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns an Array of common helper filenames currently residing on the
|
190
|
+
# local workstation.
|
191
|
+
#
|
192
|
+
# @return [Array<String>] array of helper files
|
193
|
+
# @api private
|
194
|
+
def helper_files
|
195
|
+
glob = File.join("helpers", "*/**/*")
|
196
|
+
Util.safe_glob(config[:test_base_path], glob).reject { |f| File.directory?(f) }
|
197
|
+
end
|
198
|
+
|
199
|
+
def install_command_vars
|
200
|
+
ruby = remote_path_join(config[:ruby_bindir], "ruby")
|
201
|
+
.tap { |path| path.concat(".exe") if windows_os? }
|
202
|
+
gem = remote_path_join(config[:ruby_bindir], "gem")
|
203
|
+
|
204
|
+
[
|
205
|
+
busser_env,
|
206
|
+
shell_var("ruby", ruby),
|
207
|
+
shell_var("gem", gem),
|
208
|
+
shell_var("version", config[:version]),
|
209
|
+
shell_var("gem_install_args", gem_install_args),
|
210
|
+
shell_var("busser", sudo(config[:busser_bin])),
|
211
|
+
shell_var("plugins", plugins.join(" ")),
|
212
|
+
].join("\n")
|
213
|
+
end
|
214
|
+
|
215
|
+
# Returns an Array of test suite filenames for the related suite currently
|
216
|
+
# residing on the local workstation. Any special provisioner-specific
|
217
|
+
# directories (such as a Chef roles/ directory) are excluded.
|
218
|
+
#
|
219
|
+
# @return [Array<String>] array of suite files
|
220
|
+
# @api private
|
221
|
+
def local_suite_files
|
222
|
+
base = File.join(config[:test_base_path], config[:suite_name])
|
223
|
+
Util.safe_glob(base, "*/**/*").reject do |f|
|
224
|
+
chef_data_dir?(base, f) || File.directory?(f)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Returns a uniquely sorted Array of Busser plugin gems that need to
|
229
|
+
# be installed for the related suite.
|
230
|
+
#
|
231
|
+
# @return [Array<String>] a lexically sorted, unique item array of Busser
|
232
|
+
# plugin gem names
|
233
|
+
# @api private
|
234
|
+
def plugins
|
235
|
+
non_suite_dirs = %w{data data_bags environments nodes roles}
|
236
|
+
Util.list_directory(File.join(config[:test_base_path], config[:suite_name])).reject do |d|
|
237
|
+
!File.directory?(d) || non_suite_dirs.include?(File.basename(d))
|
238
|
+
end.map { |d| "busser-#{File.basename(d)}" }.sort.uniq
|
239
|
+
end
|
240
|
+
|
241
|
+
# Copies all common testing helper files into the suites directory in
|
242
|
+
# the sandbox.
|
243
|
+
#
|
244
|
+
# @api private
|
245
|
+
def prepare_helpers
|
246
|
+
base = File.join(config[:test_base_path], "helpers")
|
247
|
+
|
248
|
+
helper_files.each do |src|
|
249
|
+
dest = File.join(sandbox_suites_dir, src.sub("#{base}/", ""))
|
250
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
251
|
+
FileUtils.cp(src, dest, preserve: true)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# Copies all test suite files into the suites directory in the sandbox.
|
256
|
+
#
|
257
|
+
# @api private
|
258
|
+
def prepare_suites
|
259
|
+
base = File.join(config[:test_base_path], config[:suite_name])
|
260
|
+
|
261
|
+
local_suite_files.each do |src|
|
262
|
+
dest = File.join(sandbox_suites_dir, src.sub("#{base}/", ""))
|
263
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
264
|
+
FileUtils.cp(src, dest, preserve: true)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# @return [String] path to suites directory under sandbox path
|
269
|
+
# @api private
|
270
|
+
def sandbox_suites_dir
|
271
|
+
File.join(sandbox_path, "suites")
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2015, Fletcher Nichol
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require_relative "base"
|
19
|
+
|
20
|
+
module Kitchen
|
21
|
+
module Verifier
|
22
|
+
# Dummy verifier for Kitchen. This verifier does nothing but report what
|
23
|
+
# would happen if this verifier did anything of consequence. As a result
|
24
|
+
# it may be a useful verifier to use when debugging or developing new
|
25
|
+
# features or plugins.
|
26
|
+
#
|
27
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
28
|
+
class Dummy < Kitchen::Verifier::Base
|
29
|
+
kitchen_verifier_api_version 1
|
30
|
+
|
31
|
+
plugin_version Kitchen::VERSION
|
32
|
+
|
33
|
+
default_config :sleep, 0
|
34
|
+
default_config :random_failure, false
|
35
|
+
|
36
|
+
# (see Base#call)
|
37
|
+
def call(state)
|
38
|
+
info("[#{name}] Verify on instance=#{instance} with state=#{state}")
|
39
|
+
sleep_if_set
|
40
|
+
failure_if_set
|
41
|
+
debug("[#{name}] Verify completed (#{config[:sleep]}s).")
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Sleep for a period of time, if a value is set in the config.
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def sleep_if_set
|
50
|
+
sleep(config[:sleep].to_f) if config[:sleep].to_f > 0.0
|
51
|
+
end
|
52
|
+
|
53
|
+
# Simulate a failure in an action, if set in the config.
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
def failure_if_set
|
57
|
+
if config[:fail]
|
58
|
+
debug("Failure for Verifier #{name}.")
|
59
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
60
|
+
elsif config[:random_failure] && randomly_fail?
|
61
|
+
debug("Random failure for Verifier #{name}.")
|
62
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Determine whether or not to randomly fail.
|
67
|
+
#
|
68
|
+
# @return [true, false]
|
69
|
+
# @api private
|
70
|
+
def randomly_fail?
|
71
|
+
[true, false].sample
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#
|
2
|
+
# Author:: SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2015, HiganWorks LLC
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require_relative "base"
|
19
|
+
|
20
|
+
module Kitchen
|
21
|
+
module Verifier
|
22
|
+
# Shell verifier for Kitchen. This verifier just execute shell command from local.
|
23
|
+
#
|
24
|
+
# @author SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
|
25
|
+
class Shell < Kitchen::Verifier::Base
|
26
|
+
require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
|
27
|
+
|
28
|
+
kitchen_verifier_api_version 1
|
29
|
+
|
30
|
+
plugin_version Kitchen::VERSION
|
31
|
+
|
32
|
+
default_config :sleep, 0
|
33
|
+
default_config :command, "true"
|
34
|
+
default_config :shellout_opts, {}
|
35
|
+
default_config :live_stream, $stdout
|
36
|
+
default_config :remote_exec, false
|
37
|
+
|
38
|
+
# (see Base#call)
|
39
|
+
def call(state)
|
40
|
+
info("[#{name}] Verify on instance #{instance.name} with state=#{state}")
|
41
|
+
sleep_if_set
|
42
|
+
merge_state_to_env(state)
|
43
|
+
if config[:remote_exec]
|
44
|
+
instance.transport.connection(state) do |conn|
|
45
|
+
conn.execute(config[:command])
|
46
|
+
end
|
47
|
+
else
|
48
|
+
shellout
|
49
|
+
end
|
50
|
+
debug("[#{name}] Verify completed.")
|
51
|
+
end
|
52
|
+
|
53
|
+
# for legacy drivers.
|
54
|
+
def run_command
|
55
|
+
if config[:remote_exec]
|
56
|
+
config[:command]
|
57
|
+
else
|
58
|
+
shellout
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# Sleep for a period of time, if a value is set in the config.
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
def sleep_if_set
|
69
|
+
config[:sleep].to_i.times do
|
70
|
+
info(".")
|
71
|
+
sleep 1
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def shellout
|
76
|
+
cmd = Mixlib::ShellOut.new(config[:command], config[:shellout_opts])
|
77
|
+
cmd.live_stream = config[:live_stream]
|
78
|
+
cmd.run_command
|
79
|
+
begin
|
80
|
+
cmd.error!
|
81
|
+
rescue Mixlib::ShellOut::ShellCommandFailed
|
82
|
+
raise ActionFailed, "Action #verify failed for #{instance.to_str}."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def merge_state_to_env(state)
|
87
|
+
env_state = { environment: {} }
|
88
|
+
env_state[:environment]["KITCHEN_INSTANCE"] = instance.name
|
89
|
+
env_state[:environment]["KITCHEN_PLATFORM"] = instance.platform.name
|
90
|
+
env_state[:environment]["KITCHEN_SUITE"] = instance.suite.name
|
91
|
+
env_state[:environment]["KITCHEN_USERNAME"] = instance.transport[:username] if instance.respond_to?(:transport)
|
92
|
+
state.each_pair do |key, value|
|
93
|
+
env_state[:environment]["KITCHEN_" + key.to_s.upcase] = value.to_s
|
94
|
+
end
|
95
|
+
config[:shellout_opts].merge!(env_state)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2015, Fletcher Nichol
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require_relative "plugin"
|
19
|
+
|
20
|
+
module Kitchen
|
21
|
+
# A verifier is responsible for running tests post-converge to confirm that
|
22
|
+
# the instance is in a known/consistent state.
|
23
|
+
#
|
24
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
25
|
+
module Verifier
|
26
|
+
# Default verifier to use
|
27
|
+
DEFAULT_PLUGIN = "busser".freeze
|
28
|
+
|
29
|
+
# Returns an instance of a verifier given a plugin type string.
|
30
|
+
#
|
31
|
+
# @param plugin [String] a verifier plugin type, to be constantized
|
32
|
+
# @param config [Hash] a configuration hash to initialize the verifier
|
33
|
+
# @return [Verifier::Base] a verifier instance
|
34
|
+
# @raise [ClientError] if a verifier instance could not be created
|
35
|
+
def self.for_plugin(plugin, config)
|
36
|
+
Kitchen::Plugin.load(self, plugin, config)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012, 2013, Fletcher Nichol
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
module Kitchen
|
19
|
+
VERSION = "3.0.0-1".freeze
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require "chef-utils/dsl/which" unless defined?(ChefUtils::DSL::Which)
|
19
|
+
require_relative "chef_utils_wiring" unless defined?(Kitchen::ChefUtilsWiring)
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Which
|
23
|
+
include ChefUtils::DSL::Which
|
24
|
+
include ChefUtilsWiring
|
25
|
+
end
|
26
|
+
end
|
data/lib/kitchen.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012, 2013, 2014 Fletcher Nichol
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require "pathname" unless defined?(Pathname)
|
19
|
+
require_relative "kitchen/errors"
|
20
|
+
require_relative "kitchen/logger"
|
21
|
+
require_relative "kitchen/logging"
|
22
|
+
require_relative "kitchen/shell_out"
|
23
|
+
require_relative "kitchen/configurable"
|
24
|
+
require_relative "kitchen/util"
|
25
|
+
|
26
|
+
require_relative "kitchen/provisioner"
|
27
|
+
require_relative "kitchen/provisioner/base"
|
28
|
+
require_relative "kitchen/color"
|
29
|
+
require_relative "kitchen/collection"
|
30
|
+
require_relative "kitchen/config"
|
31
|
+
require_relative "kitchen/data_munger"
|
32
|
+
require_relative "kitchen/driver"
|
33
|
+
require_relative "kitchen/driver/base"
|
34
|
+
require_relative "kitchen/driver/ssh_base"
|
35
|
+
require_relative "kitchen/driver/proxy"
|
36
|
+
require_relative "kitchen/instance"
|
37
|
+
require_relative "kitchen/lifecycle_hooks"
|
38
|
+
require_relative "kitchen/transport"
|
39
|
+
require_relative "kitchen/transport/base"
|
40
|
+
require_relative "kitchen/loader/yaml"
|
41
|
+
require_relative "kitchen/metadata_chopper"
|
42
|
+
require_relative "kitchen/platform"
|
43
|
+
require_relative "kitchen/state_file"
|
44
|
+
require_relative "kitchen/ssh"
|
45
|
+
require_relative "kitchen/suite"
|
46
|
+
require_relative "kitchen/verifier"
|
47
|
+
require_relative "kitchen/verifier/base"
|
48
|
+
require_relative "kitchen/version"
|
49
|
+
|
50
|
+
# Test Kitchen base module.
|
51
|
+
#
|
52
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
53
|
+
module Kitchen
|
54
|
+
class << self
|
55
|
+
# @return [Logger] the common Kitchen logger
|
56
|
+
attr_accessor :logger
|
57
|
+
|
58
|
+
# @return [Mutex] a common mutex for global coordination
|
59
|
+
attr_accessor :mutex
|
60
|
+
|
61
|
+
# @return [Mutex] a mutex used for Dir.chdir coordination
|
62
|
+
attr_accessor :mutex_chdir
|
63
|
+
|
64
|
+
# Returns the root path of the Kitchen gem source code.
|
65
|
+
#
|
66
|
+
# @return [Pathname] root path of gem
|
67
|
+
def source_root
|
68
|
+
@source_root ||= Pathname.new(File.expand_path("..", __dir__))
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns a default logger which emits on standard output.
|
72
|
+
#
|
73
|
+
# @return [Logger] a logger
|
74
|
+
def default_logger
|
75
|
+
Logger.new(stdout: $stdout, level: Util.to_logger_level(env_log))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns a default file logger which emits on standard output and to a
|
79
|
+
# log file.
|
80
|
+
#
|
81
|
+
# @param [Symbol] level logging level
|
82
|
+
# @param [Boolean] log_overwrite logging level
|
83
|
+
# @return [Logger] a logger
|
84
|
+
def default_file_logger(level = nil, log_overwrite = nil)
|
85
|
+
level ||= env_log
|
86
|
+
log_overwrite = log_overwrite.nil? ? env_log_overwrite : log_overwrite
|
87
|
+
log_location = File.expand_path(File.join(DEFAULT_LOG_DIR, "kitchen.log"))
|
88
|
+
log_location = log_location.to_s
|
89
|
+
|
90
|
+
Logger.new(
|
91
|
+
stdout: $stdout,
|
92
|
+
logdev: log_location,
|
93
|
+
level: Util.to_logger_level(level),
|
94
|
+
log_overwrite: log_overwrite
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns whether or not standard output is associated with a terminal
|
99
|
+
# device (tty).
|
100
|
+
#
|
101
|
+
# @return [true,false] is there a tty?
|
102
|
+
def tty?
|
103
|
+
$stdout.tty?
|
104
|
+
end
|
105
|
+
|
106
|
+
# Determine the default log level from an environment variable, if it is
|
107
|
+
# set.
|
108
|
+
#
|
109
|
+
# @return [Symbol,nil] a log level or nil if not set
|
110
|
+
# @api private
|
111
|
+
def env_log
|
112
|
+
ENV["KITCHEN_LOG"] && ENV["KITCHEN_LOG"].downcase.to_sym
|
113
|
+
end
|
114
|
+
|
115
|
+
# Determine the log overwriting logic from an environment variable,
|
116
|
+
# if it is set.
|
117
|
+
#
|
118
|
+
# @return [Boolean,nil]
|
119
|
+
# @api private
|
120
|
+
def env_log_overwrite
|
121
|
+
case ENV["KITCHEN_LOG_OVERWRITE"] && ENV["KITCHEN_LOG_OVERWRITE"].downcase
|
122
|
+
when nil, ""
|
123
|
+
nil
|
124
|
+
when "false", "f", "no"
|
125
|
+
false
|
126
|
+
else
|
127
|
+
true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Default log level verbosity
|
133
|
+
DEFAULT_LOG_LEVEL = :info
|
134
|
+
|
135
|
+
# Overwrite the log file when Test Kitchen runs
|
136
|
+
DEFAULT_LOG_OVERWRITE = true
|
137
|
+
|
138
|
+
# Default base directory for integration tests, fixtures, etc.
|
139
|
+
DEFAULT_TEST_DIR = "test/integration".freeze
|
140
|
+
|
141
|
+
# Default base directory for instance and common log files
|
142
|
+
DEFAULT_LOG_DIR = ".kitchen/logs".freeze
|
143
|
+
end
|
144
|
+
|
145
|
+
# Initialize the base logger
|
146
|
+
Kitchen.logger = Kitchen.default_logger
|
147
|
+
|
148
|
+
# Setup a collection of instance crash exceptions for error reporting
|
149
|
+
Kitchen.mutex = Mutex.new
|
150
|
+
|
151
|
+
# Initialize the mutex for Dir.chdir coordination
|
152
|
+
Kitchen.mutex_chdir = Mutex.new
|