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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +21 -0
  3. data/LICENSE +15 -0
  4. data/Rakefile +53 -0
  5. data/bin/zl-kitchen +11 -0
  6. data/lib/kitchen/base64_stream.rb +48 -0
  7. data/lib/kitchen/chef_utils_wiring.rb +40 -0
  8. data/lib/kitchen/cli.rb +413 -0
  9. data/lib/kitchen/collection.rb +52 -0
  10. data/lib/kitchen/color.rb +63 -0
  11. data/lib/kitchen/command/action.rb +41 -0
  12. data/lib/kitchen/command/console.rb +54 -0
  13. data/lib/kitchen/command/diagnose.rb +84 -0
  14. data/lib/kitchen/command/doctor.rb +39 -0
  15. data/lib/kitchen/command/exec.rb +37 -0
  16. data/lib/kitchen/command/list.rb +148 -0
  17. data/lib/kitchen/command/login.rb +39 -0
  18. data/lib/kitchen/command/package.rb +32 -0
  19. data/lib/kitchen/command/sink.rb +50 -0
  20. data/lib/kitchen/command/test.rb +47 -0
  21. data/lib/kitchen/command.rb +207 -0
  22. data/lib/kitchen/config.rb +344 -0
  23. data/lib/kitchen/configurable.rb +616 -0
  24. data/lib/kitchen/data_munger.rb +1024 -0
  25. data/lib/kitchen/diagnostic.rb +138 -0
  26. data/lib/kitchen/driver/base.rb +133 -0
  27. data/lib/kitchen/driver/dummy.rb +105 -0
  28. data/lib/kitchen/driver/exec.rb +70 -0
  29. data/lib/kitchen/driver/proxy.rb +70 -0
  30. data/lib/kitchen/driver/ssh_base.rb +351 -0
  31. data/lib/kitchen/driver.rb +40 -0
  32. data/lib/kitchen/errors.rb +243 -0
  33. data/lib/kitchen/generator/init.rb +254 -0
  34. data/lib/kitchen/instance.rb +726 -0
  35. data/lib/kitchen/lazy_hash.rb +148 -0
  36. data/lib/kitchen/lifecycle_hook/base.rb +78 -0
  37. data/lib/kitchen/lifecycle_hook/local.rb +53 -0
  38. data/lib/kitchen/lifecycle_hook/remote.rb +39 -0
  39. data/lib/kitchen/lifecycle_hooks.rb +92 -0
  40. data/lib/kitchen/loader/yaml.rb +377 -0
  41. data/lib/kitchen/logger.rb +422 -0
  42. data/lib/kitchen/logging.rb +52 -0
  43. data/lib/kitchen/login_command.rb +49 -0
  44. data/lib/kitchen/metadata_chopper.rb +49 -0
  45. data/lib/kitchen/platform.rb +64 -0
  46. data/lib/kitchen/plugin.rb +76 -0
  47. data/lib/kitchen/plugin_base.rb +60 -0
  48. data/lib/kitchen/provisioner/base.rb +269 -0
  49. data/lib/kitchen/provisioner/chef/berkshelf.rb +116 -0
  50. data/lib/kitchen/provisioner/chef/common_sandbox.rb +350 -0
  51. data/lib/kitchen/provisioner/chef/policyfile.rb +163 -0
  52. data/lib/kitchen/provisioner/chef_apply.rb +121 -0
  53. data/lib/kitchen/provisioner/chef_base.rb +705 -0
  54. data/lib/kitchen/provisioner/chef_infra.rb +167 -0
  55. data/lib/kitchen/provisioner/chef_solo.rb +82 -0
  56. data/lib/kitchen/provisioner/chef_zero.rb +12 -0
  57. data/lib/kitchen/provisioner/dummy.rb +75 -0
  58. data/lib/kitchen/provisioner/shell.rb +157 -0
  59. data/lib/kitchen/provisioner.rb +42 -0
  60. data/lib/kitchen/rake_tasks.rb +80 -0
  61. data/lib/kitchen/shell_out.rb +90 -0
  62. data/lib/kitchen/ssh.rb +289 -0
  63. data/lib/kitchen/state_file.rb +112 -0
  64. data/lib/kitchen/suite.rb +48 -0
  65. data/lib/kitchen/thor_tasks.rb +63 -0
  66. data/lib/kitchen/transport/base.rb +236 -0
  67. data/lib/kitchen/transport/dummy.rb +78 -0
  68. data/lib/kitchen/transport/exec.rb +145 -0
  69. data/lib/kitchen/transport/ssh.rb +579 -0
  70. data/lib/kitchen/transport/winrm.rb +546 -0
  71. data/lib/kitchen/transport.rb +40 -0
  72. data/lib/kitchen/util.rb +229 -0
  73. data/lib/kitchen/verifier/base.rb +243 -0
  74. data/lib/kitchen/verifier/busser.rb +275 -0
  75. data/lib/kitchen/verifier/dummy.rb +75 -0
  76. data/lib/kitchen/verifier/shell.rb +99 -0
  77. data/lib/kitchen/verifier.rb +39 -0
  78. data/lib/kitchen/version.rb +20 -0
  79. data/lib/kitchen/which.rb +26 -0
  80. data/lib/kitchen.rb +152 -0
  81. data/lib/vendor/hash_recursive_merge.rb +79 -0
  82. data/support/busser_install_command.ps1 +14 -0
  83. data/support/busser_install_command.sh +21 -0
  84. data/support/chef-client-fail-if-update-handler.rb +15 -0
  85. data/support/chef_base_init_command.ps1 +18 -0
  86. data/support/chef_base_init_command.sh +1 -0
  87. data/support/chef_base_install_command.ps1 +85 -0
  88. data/support/chef_base_install_command.sh +229 -0
  89. data/support/download_helpers.sh +109 -0
  90. data/support/dummy-validation.pem +27 -0
  91. data/templates/driver/CHANGELOG.md.erb +3 -0
  92. data/templates/driver/Gemfile.erb +3 -0
  93. data/templates/driver/README.md.erb +64 -0
  94. data/templates/driver/Rakefile.erb +21 -0
  95. data/templates/driver/driver.rb.erb +23 -0
  96. data/templates/driver/gemspec.erb +29 -0
  97. data/templates/driver/gitignore.erb +17 -0
  98. data/templates/driver/license_apachev2.erb +15 -0
  99. data/templates/driver/license_lgplv3.erb +16 -0
  100. data/templates/driver/license_mit.erb +22 -0
  101. data/templates/driver/license_reserved.erb +5 -0
  102. data/templates/driver/tailor.erb +4 -0
  103. data/templates/driver/travis.yml.erb +11 -0
  104. data/templates/driver/version.rb.erb +12 -0
  105. data/templates/init/chefignore.erb +2 -0
  106. data/templates/init/kitchen.yml.erb +18 -0
  107. data/test-kitchen.gemspec +52 -0
  108. metadata +528 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 29d0736fe0c4a14aac48efa417d50780d2f48e216662733a3a4d526e6b6ea917
4
+ data.tar.gz: cd4485fb111391400af85845b9927a19a745b496411059d4f00eae9ab9ddcc1b
5
+ SHA512:
6
+ metadata.gz: 03c21555b0be1dd75b89d4cf1f7d63eea0dafefb29fd1bb9af8c7d6da575a449575adba2b067e654fb8e8d9d654503d4b930046f27456ed3fe92c8375a26ea02
7
+ data.tar.gz: a57aa49fcce002ef96be611b0ae70e4f284419d4c5da38609179f40a2fe207b2ee177dd104c3bf4dff2999fb01d8d638c62f99be08745e76169100bf0b3fc1ef
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem"s dependencies in test-kitchen.gemspec
4
+ gemspec
5
+
6
+ group :integration do
7
+ gem "berkshelf"
8
+ gem "kitchen-inspec"
9
+ gem "kitchen-dokken"
10
+ gem "kitchen-vagrant"
11
+ end
12
+
13
+ group :debug do
14
+ gem "pry", "~>0.12"
15
+ gem "pry-byebug"
16
+ gem "pry-stack_explorer"
17
+ end
18
+
19
+ group :chefstyle do
20
+ gem "chefstyle", "2.0.9"
21
+ end
data/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Author:: Fletcher Nichol (<fnichol@nichol.ca>)
2
+
3
+ Copyright 2012 Fletcher Nichol
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/testtask"
4
+ Rake::TestTask.new(:unit) do |t|
5
+ t.libs.push "lib"
6
+ t.test_files = FileList["spec/**/*_spec.rb"]
7
+ t.verbose = true
8
+ end
9
+
10
+ begin
11
+ require "cucumber"
12
+ require "cucumber/rake/task"
13
+ Cucumber::Rake::Task.new(:features) do |t|
14
+ t.cucumber_opts = ["features", "-x", "--format progress", "--no-color", "--tags 'not @ignore'"]
15
+ end
16
+ rescue LoadError
17
+ puts "cucumber is not available. (sudo) gem install cucumber to run tests."
18
+ end
19
+
20
+ desc "Run all test suites"
21
+ task test: %i{unit features}
22
+
23
+ desc "Display LOC stats"
24
+ task :stats do
25
+ puts "\n## Production Code Stats"
26
+ sh "countloc -r lib/kitchen lib/kitchen.rb"
27
+ puts "\n## Test Code Stats"
28
+ sh "countloc -r spec features"
29
+ end
30
+
31
+ begin
32
+ require "chefstyle"
33
+ require "rubocop/rake_task"
34
+ RuboCop::RakeTask.new(:style) do |task|
35
+ task.options += ["--display-cop-names", "--no-color"]
36
+ end
37
+ rescue LoadError
38
+ puts "chefstyle is not available. (sudo) gem install chefstyle to do style checking."
39
+ end
40
+
41
+ desc "Run all quality tasks"
42
+ task quality: %i{style stats}
43
+
44
+ task default: %i{test quality}
45
+
46
+ namespace :docs do
47
+ desc "Deploy docs"
48
+ task :deploy do
49
+ sh "cd docs && hugo"
50
+ sh "aws --profile chef-cd s3 sync docs/public s3://test-kitchen-legacy.cd.chef.co --delete --acl public-read"
51
+ sh "aws --profile chef-cd cloudfront create-invalidation --distribution-id EQD8MRW086SRT --paths '/*'"
52
+ end
53
+ end
data/bin/zl-kitchen ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # Trap interrupts to quit cleanly. See
3
+ # https://twitter.com/mitchellh/status/283014103189053442
4
+ Signal.trap("INT") { exit 1 }
5
+
6
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), %w{.. lib})
7
+ require "rubygems" unless defined?(Gem)
8
+ require "kitchen/cli"
9
+ require "kitchen/errors"
10
+
11
+ Kitchen.with_friendly_errors { Kitchen::CLI.start }
@@ -0,0 +1,48 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ #
4
+ # Copyright (C) 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
+ module Kitchen
19
+ # Base64 encoder/decoder that operates on IO objects so as to minimize
20
+ # memory allocations on large payloads.
21
+ #
22
+ # @author Fletcher Nichol <fnichol@nichol.ca>
23
+ module Base64Stream
24
+ # Encodes an input stream into a Base64 output stream. The input and ouput
25
+ # objects must be opened IO resources. In other words, opening and closing
26
+ # the resources are not the responsibilty of this method.
27
+ #
28
+ # @param io_in [#read] input stream
29
+ # @param io_out [#write] output stream
30
+ def self.strict_encode(io_in, io_out)
31
+ buffer = ""
32
+ io_out.write([buffer].pack("m0")) while io_in.read(3 * 1000, buffer)
33
+ buffer = nil # rubocop:disable Lint/UselessAssignment
34
+ end
35
+
36
+ # Decodes a Base64 input stream into an output stream. The input and ouput
37
+ # objects must be opened IO resources. In other words, opening and closing
38
+ # the resources are not the responsibilty of this method.
39
+ #
40
+ # @param io_in [#read] input stream
41
+ # @param io_out [#write] output stream
42
+ def self.strict_decode(io_in, io_out)
43
+ buffer = ""
44
+ io_out.write(buffer.unpack("m0").first) while io_in.read(3 * 1000, buffer)
45
+ buffer = nil # rubocop:disable Lint/UselessAssignment
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,40 @@
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
+
19
+ module Kitchen
20
+ # Common Dependency Injection wiring for ChefUtils-related modules
21
+ module ChefUtilsWiring
22
+ private
23
+
24
+ def __config
25
+ # this would need to be some kind of Chef::Config looking thing, which probably requires
26
+ # a translation object from t-k config to Chef::Config layout if that ever becomes necessary.
27
+ # this ISNT the t-k config.
28
+ {}
29
+ end
30
+
31
+ def __log
32
+ @logger
33
+ end
34
+
35
+ def __transport_connection
36
+ # this could be wired up to train at some point, but need to be careful because about local vs. remote
37
+ # uses of helpers with test-kitchen, right now we're using it for local.
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,413 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ #
4
+ # Copyright (C) 2012, 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
+ # CI tests fail without an explicit unconditional require of Thor
19
+ require "thor" # rubocop:disable Chef/Ruby/UnlessDefinedRequire
20
+
21
+ require_relative "../kitchen"
22
+ require_relative "generator/init"
23
+
24
+ module Kitchen
25
+ # The command line runner for Kitchen.
26
+ #
27
+ # @author Fletcher Nichol <fnichol@nichol.ca>
28
+ class CLI < Thor
29
+ # Common module to load and invoke a CLI-implementation agnostic command.
30
+ module PerformCommand
31
+ # Perform a CLI subcommand.
32
+ #
33
+ # @param task [String] action to take, usually corresponding to the
34
+ # subcommand name
35
+ # @param command [String] command class to create and invoke]
36
+ # @param args [Array] remainder arguments from processed ARGV
37
+ # (default: `nil`)
38
+ # @param additional_options [Hash] additional configuration needed to
39
+ # set up the command class (default: `{}`)
40
+ def perform(task, command, args = nil, additional_options = {})
41
+ require "kitchen/command/#{command}"
42
+
43
+ command_options = {
44
+ action: task,
45
+ help: -> { help(task) },
46
+ config: @config,
47
+ shell: shell,
48
+ }.merge(additional_options)
49
+
50
+ str_const = Thor::Util.camel_case(command)
51
+ klass = ::Kitchen::Command.const_get(str_const)
52
+ klass.new(args, options, command_options).call
53
+ end
54
+ end
55
+
56
+ include Logging
57
+ include PerformCommand
58
+
59
+ # The maximum number of concurrent instances that can run--which is a bit
60
+ # high
61
+ MAX_CONCURRENCY = 9999
62
+
63
+ attr_reader :config
64
+
65
+ # Constructs a new instance.
66
+ def initialize(*args)
67
+ super
68
+ $stdout.sync = true
69
+ @loader = Kitchen::Loader::YAML.new(
70
+ project_config: ENV["KITCHEN_YAML"] || ENV["KITCHEN_YML"],
71
+ local_config: ENV["KITCHEN_LOCAL_YAML"] || ENV["KITCHEN_LOCAL_YML"],
72
+ global_config: ENV["KITCHEN_GLOBAL_YAML"] || ENV["KITCHEN_GLOBAL_YML"]
73
+ )
74
+ @config = Kitchen::Config.new(
75
+ loader: @loader
76
+ )
77
+ @config.log_level = Kitchen.env_log unless Kitchen.env_log.nil?
78
+ @config.log_overwrite = Kitchen.env_log_overwrite unless Kitchen.env_log_overwrite.nil?
79
+ end
80
+
81
+ # Sets the logging method_options
82
+ # @api private
83
+ def self.log_options
84
+ method_option :log_level,
85
+ aliases: "-l",
86
+ desc: "Set the log level (debug, info, warn, error, fatal)"
87
+ method_option :log_overwrite,
88
+ desc: "Set to false to prevent log overwriting each time Test Kitchen runs",
89
+ type: :boolean
90
+ method_option :color,
91
+ type: :boolean,
92
+ lazy_default: $stdout.tty?,
93
+ desc: "Toggle color output for STDOUT logger"
94
+ end
95
+
96
+ # Sets the test_base_path method_options
97
+ # @api private
98
+ def self.test_base_path
99
+ method_option :test_base_path,
100
+ aliases: "-t",
101
+ desc: "Set the base path of the tests"
102
+ end
103
+
104
+ desc "list [INSTANCE|REGEXP|all]", "Lists one or more instances"
105
+ method_option :bare,
106
+ aliases: "-b",
107
+ type: :boolean,
108
+ desc: "List the name of each instance only, one per line"
109
+ method_option :json,
110
+ aliases: "-j",
111
+ type: :boolean,
112
+ desc: "Print data as JSON"
113
+ method_option :debug,
114
+ aliases: "-d",
115
+ type: :boolean,
116
+ desc: "[Deprecated] Please use `kitchen diagnose'"
117
+ log_options
118
+ def list(*args)
119
+ update_config!
120
+ perform("list", "list", args)
121
+ end
122
+ map status: :list
123
+
124
+ desc "diagnose [INSTANCE|REGEXP|all]", "Show computed diagnostic configuration"
125
+ method_option :loader,
126
+ type: :boolean,
127
+ desc: "Include data loader diagnostics"
128
+ method_option :plugins,
129
+ type: :boolean,
130
+ desc: "Include plugin diagnostics"
131
+ method_option :instances,
132
+ type: :boolean,
133
+ default: true,
134
+ desc: "Include instances diagnostics"
135
+ method_option :all,
136
+ type: :boolean,
137
+ desc: "Include all diagnostics"
138
+ log_options
139
+ test_base_path
140
+ def diagnose(*args)
141
+ update_config!
142
+ perform("diagnose", "diagnose", args, loader: @loader)
143
+ end
144
+
145
+ {
146
+ create: "Change instance state to create. " \
147
+ "Start one or more instances",
148
+ converge: "Change instance state to converge. " \
149
+ "Use a provisioner to configure one or more instances",
150
+ setup: "Change instance state to setup. " \
151
+ "Prepare to run automated tests. " \
152
+ "Install busser and related gems on one or more instances",
153
+ verify: "Change instance state to verify. " \
154
+ "Run automated tests on one or more instances",
155
+ destroy: "Change instance state to destroy. " \
156
+ "Delete all information for one or more instances",
157
+ }.each do |action, short_desc|
158
+ desc(
159
+ "#{action} [INSTANCE|REGEXP|all]",
160
+ short_desc
161
+ )
162
+ long_desc <<-DESC
163
+ The instance states are in order: destroy, create, converge, setup, verify, destroy.
164
+ Change one or more instances from the current state to the #{action} state. Actions for all
165
+ intermediate states will be executed. See https://kitchen.ci/ for further explanation.
166
+ DESC
167
+ method_option :concurrency,
168
+ aliases: "-c",
169
+ type: :numeric,
170
+ lazy_default: MAX_CONCURRENCY,
171
+ desc: <<-DESC.gsub(/^\s+/, "").tr("\n", " ")
172
+ Run a #{action} against all matching instances concurrently. Only N
173
+ instances will run at the same time if a number is given.
174
+ DESC
175
+ method_option :parallel,
176
+ aliases: "-p",
177
+ type: :boolean,
178
+ desc: <<-DESC.gsub(/^\s+/, "").tr("\n", " ")
179
+ [Future DEPRECATION, use --concurrency]
180
+ Run a #{action} against all matching instances concurrently.
181
+ DESC
182
+ if action == :converge || action == :verify
183
+ method_option :debug,
184
+ aliases: "-D",
185
+ type: :boolean,
186
+ default: false,
187
+ desc: "Run the #{action} with debugging enabled."
188
+ end
189
+ method_option :fail_fast,
190
+ aliases: "-f",
191
+ type: :boolean,
192
+ desc: "Fail immediately when errors occur in concurrency mode"
193
+
194
+ test_base_path
195
+ log_options
196
+ define_method(action) do |*args|
197
+ update_config!
198
+ perform(action, "action", args)
199
+ end
200
+ end
201
+
202
+ desc "test [INSTANCE|REGEXP|all]",
203
+ "Test (destroy, create, converge, setup, verify and destroy) one or more instances"
204
+ long_desc <<-DESC
205
+ The instance states are in order: destroy, create, converge, setup, verify, destroy.
206
+ Test changes the state of one or more instances to destroyed, then executes
207
+ the actions for each state up to destroy. At any sign of failure, executing the
208
+ actions stops and the instance is left in the last successful execution state.
209
+
210
+ There are 3 post-verify modes for instance cleanup, triggered with
211
+ the `--destroy' flag:
212
+
213
+ * passing: instances passing verify will be destroyed afterwards.\n
214
+ * always: instances will always be destroyed afterwards.\n
215
+ * never: instances will never be destroyed afterwards.
216
+ DESC
217
+ method_option :concurrency,
218
+ aliases: "-c",
219
+ type: :numeric,
220
+ lazy_default: MAX_CONCURRENCY,
221
+ desc: <<-DESC.gsub(/^\s+/, "").tr("\n", " ")
222
+ Run a test against all matching instances concurrently. Only N
223
+ instances will run at the same time if a number is given.
224
+ DESC
225
+ method_option :parallel,
226
+ aliases: "-p",
227
+ type: :boolean,
228
+ desc: <<-DESC.gsub(/^\s+/, "").tr("\n", " ")
229
+ [Future DEPRECATION, use --concurrency]
230
+ Run a test against all matching instances concurrently.
231
+ DESC
232
+ method_option :destroy,
233
+ aliases: "-d",
234
+ default: "passing",
235
+ desc: "Destroy strategy to use after testing (passing, always, never)."
236
+ method_option :auto_init,
237
+ type: :boolean,
238
+ default: false,
239
+ desc: "Invoke init command if .kitchen.yml is missing"
240
+ method_option :debug,
241
+ aliases: "-D",
242
+ type: :boolean,
243
+ default: false,
244
+ desc: "Run the converge and verify with debugging enabled."
245
+ test_base_path
246
+ log_options
247
+ def test(*args)
248
+ update_config!
249
+ ensure_initialized
250
+ perform("test", "test", args)
251
+ end
252
+
253
+ desc "login INSTANCE|REGEXP", "Log in to one instance"
254
+ log_options
255
+ def login(*args)
256
+ update_config!
257
+ perform("login", "login", args)
258
+ end
259
+
260
+ desc "package INSTANCE|REGEXP", "package an instance"
261
+ log_options
262
+ def package(*args)
263
+ update_config!
264
+ perform("package", "package", args)
265
+ end
266
+
267
+ desc "doctor INSTANCE|REGEXP", "Check for common system problems"
268
+ log_options
269
+ method_option :all,
270
+ aliases: "-a",
271
+ desc: "Check all instances"
272
+ def doctor(*args)
273
+ update_config!
274
+ perform("doctor", "doctor", args)
275
+ end
276
+
277
+ desc "exec INSTANCE|REGEXP -c REMOTE_COMMAND",
278
+ "Execute command on one or more instance"
279
+ method_option :command,
280
+ aliases: "-c",
281
+ desc: "execute via ssh"
282
+ log_options
283
+ def exec(*args)
284
+ update_config!
285
+ perform("exec", "exec", args)
286
+ end
287
+
288
+ desc "version", "Print Test Kitchen's version information"
289
+ def version
290
+ puts "Test Kitchen version #{Kitchen::VERSION}"
291
+ end
292
+ map %w{-v --version} => :version
293
+
294
+ desc "sink", "Show the Kitchen sink!", hide: true
295
+ def sink
296
+ perform("sink", "sink")
297
+ end
298
+
299
+ desc "console", "Test Kitchen Console!"
300
+ def console
301
+ perform("console", "console")
302
+ end
303
+
304
+ register Kitchen::Generator::Init, "init",
305
+ "init", "Adds some configuration to your cookbook so Kitchen can rock"
306
+ long_desc <<-D, for: "init"
307
+ Init will add Test Kitchen support to an existing project for
308
+ convergence integration testing. A default kitchen.yml file (which is
309
+ intended to be customized) is created in the project's root directory
310
+ and one or more gems will be added to the project's Gemfile.
311
+ D
312
+ tasks["init"].options = Kitchen::Generator::Init.class_options
313
+
314
+ class << self
315
+ private
316
+
317
+ # Ensure the any failing commands exit non-zero.
318
+ #
319
+ # @return [true] you die always on failure
320
+ # @api private
321
+ def exit_on_failure?
322
+ true
323
+ end
324
+ end
325
+
326
+ private
327
+
328
+ # @return [Logger] the common logger
329
+ # @api private
330
+ def logger
331
+ Kitchen.logger
332
+ end
333
+
334
+ # Update and finalize options for logging, concurrency, and other concerns.
335
+ #
336
+ # @api private
337
+ def update_config!
338
+ @config.log_level = log_level if log_level
339
+
340
+ unless options[:log_overwrite].nil?
341
+ @config.log_overwrite = options[:log_overwrite]
342
+ end
343
+ @config.colorize = options[:color] unless options[:color].nil?
344
+
345
+ if options[:test_base_path]
346
+ # ensure we have an absolute path
347
+ @config.test_base_path = File.absolute_path(options[:test_base_path])
348
+ end
349
+
350
+ @config.debug = options[:debug]
351
+
352
+ # Now that we have required configs, lets create our file logger
353
+ Kitchen.logger = Kitchen.default_file_logger(
354
+ log_level,
355
+ options[:log_overwrite]
356
+ )
357
+
358
+ update_parallel!
359
+ end
360
+
361
+ # Validate the log level from the config / CLI options, defaulting
362
+ # to :info if the supplied level is empty or invalid
363
+ #
364
+ # @api private
365
+ def log_level
366
+ return unless options[:log_level]
367
+ return @log_level if @log_level
368
+
369
+ level = options[:log_level].downcase.to_sym
370
+ unless valid_log_level?(level)
371
+ level = :info
372
+ banner "WARNING - invalid log level specified: " \
373
+ "\"#{options[:log_level]}\" - reverting to :info log level."
374
+ end
375
+
376
+ @log_level = level
377
+ end
378
+
379
+ # Check to whether a provided log level is valid
380
+ #
381
+ # @api private
382
+ def valid_log_level?(level)
383
+ !Util.to_logger_level(level).nil?
384
+ end
385
+
386
+ # Set parallel concurrency options for Thor
387
+ #
388
+ # @api private
389
+ def update_parallel!
390
+ if options[:parallel]
391
+ # warn here in a future release when option is used
392
+ @options = Thor::CoreExt::HashWithIndifferentAccess.new(options.to_hash)
393
+ if options[:parallel] && !options[:concurrency]
394
+ options[:concurrency] = MAX_CONCURRENCY
395
+ end
396
+ options.delete(:parallel)
397
+ options.freeze
398
+ end
399
+ end
400
+
401
+ # If auto_init option is active, invoke the init generator.
402
+ #
403
+ # @api private
404
+ def ensure_initialized
405
+ yaml = ENV["KITCHEN_YAML"] || ENV["KITCHEN_YML"] || ".kitchen.yml"
406
+
407
+ if options[:auto_init] && !File.exist?(yaml)
408
+ banner "Invoking init as '#{yaml}' file is missing"
409
+ invoke "init"
410
+ end
411
+ end
412
+ end
413
+ end
@@ -0,0 +1,52 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ #
4
+ # Copyright (C) 2012, 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 "delegate"
19
+
20
+ module Kitchen
21
+ # Delegate class which adds the ability to find single and multiple
22
+ # objects by their #name in an Array. Hey, it's better than monkey-patching
23
+ # Array, right?
24
+ #
25
+ # @author Fletcher Nichol <fnichol@nichol.ca>
26
+ class Collection < SimpleDelegator
27
+ # Returns a single object by its name, or nil if none are found.
28
+ #
29
+ # @param name [String] name of object
30
+ # @return [Object] first match by name, or nil if none are found
31
+ def get(name)
32
+ __getobj__.find { |i| i.name == name }
33
+ end
34
+
35
+ # Returns a Collection of all objects whose #name is matched by the
36
+ # regular expression.
37
+ #
38
+ # @param regexp [Regexp] a regular expression pattern
39
+ # @return [Kitchen::Config::Collection<Object>] a new collection of
40
+ # matched objects
41
+ def get_all(regexp)
42
+ Kitchen::Collection.new(__getobj__.select { |i| i.name =~ regexp })
43
+ end
44
+
45
+ # Returns an Array of names from the collection as strings.
46
+ #
47
+ # @return [Array<String>] array of name strings
48
+ def as_names
49
+ __getobj__.map(&:name)
50
+ end
51
+ end
52
+ end