test-kitchen 4.1.0 → 4.1.2

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Rakefile +10 -0
  4. data/lib/kitchen/cli.rb +60 -5
  5. data/lib/kitchen/color.rb +7 -0
  6. data/lib/kitchen/command/action.rb +1 -1
  7. data/lib/kitchen/command/diagnose.rb +1 -1
  8. data/lib/kitchen/command/login.rb +1 -1
  9. data/lib/kitchen/command/logs.rb +4 -0
  10. data/lib/kitchen/command/package.rb +1 -1
  11. data/lib/kitchen/command.rb +25 -2
  12. data/lib/kitchen/config.rb +5 -5
  13. data/lib/kitchen/configurable.rb +17 -4
  14. data/lib/kitchen/data_munger.rb +19 -0
  15. data/lib/kitchen/driver/base.rb +3 -3
  16. data/lib/kitchen/driver/dummy.rb +9 -3
  17. data/lib/kitchen/errors.rb +7 -1
  18. data/lib/kitchen/generator/init.rb +4 -0
  19. data/lib/kitchen/instance.rb +27 -12
  20. data/lib/kitchen/lazy_hash.rb +2 -2
  21. data/lib/kitchen/lifecycle_hook/base.rb +14 -4
  22. data/lib/kitchen/lifecycle_hook/local.rb +2 -0
  23. data/lib/kitchen/lifecycle_hook/remote.rb +3 -1
  24. data/lib/kitchen/loader/yaml.rb +8 -4
  25. data/lib/kitchen/logger.rb +142 -8
  26. data/lib/kitchen/logging.rb +1 -1
  27. data/lib/kitchen/login_command.rb +3 -0
  28. data/lib/kitchen/metadata_chopper.rb +8 -1
  29. data/lib/kitchen/platform_filter.rb +4 -4
  30. data/lib/kitchen/plugin.rb +4 -1
  31. data/lib/kitchen/plugin_base.rb +5 -0
  32. data/lib/kitchen/provisioner/base.rb +5 -5
  33. data/lib/kitchen/provisioner/dummy.rb +1 -1
  34. data/lib/kitchen/provisioner/external.rb +22 -0
  35. data/lib/kitchen/provisioner.rb +1 -1
  36. data/lib/kitchen/state_file.rb +1 -1
  37. data/lib/kitchen/suite.rb +1 -1
  38. data/lib/kitchen/transport/base.rb +1 -1
  39. data/lib/kitchen/transport/dummy.rb +21 -3
  40. data/lib/kitchen/transport/exec.rb +1 -1
  41. data/lib/kitchen/transport/ssh.rb +13 -6
  42. data/lib/kitchen/transport/winrm.rb +12 -6
  43. data/lib/kitchen/util.rb +12 -4
  44. data/lib/kitchen/verifier/base.rb +5 -5
  45. data/lib/kitchen/verifier/busser.rb +1 -1
  46. data/lib/kitchen/verifier/shell.rb +1 -1
  47. data/lib/kitchen/version.rb +4 -1
  48. data/lib/kitchen/which.rb +2 -0
  49. data/lib/kitchen.rb +2 -2
  50. data/lib/vendor/hash_recursive_merge.rb +5 -0
  51. data/templates/driver/README.md.erb +1 -1
  52. data/test-kitchen.gemspec +2 -2
  53. metadata +2 -2
@@ -18,7 +18,7 @@
18
18
  require "benchmark" unless defined?(Benchmark)
19
19
  require "fileutils" unless defined?(FileUtils)
20
20
  require "securerandom" unless defined?(SecureRandom)
21
- require "time" unless defined?(Time)
21
+ require "time" unless defined?(Time.zone_offset)
22
22
 
23
23
  module Kitchen
24
24
  # An instance of a suite running on a platform. A created instance may be a
@@ -60,7 +60,7 @@ module Kitchen
60
60
  # @return [LifecycleHooks] lifecycle hooks manager object
61
61
  attr_accessor :lifecycle_hooks
62
62
 
63
- # @return [Provisioner::Base] provisioner object which will the setup
63
+ # @return [Provisioner::Base] provisioner object which will provide the setup
64
64
  # and invocation instructions for configuration management and other
65
65
  # automation tools
66
66
  attr_accessor :provisioner
@@ -83,9 +83,10 @@ module Kitchen
83
83
  # @option options [Platform] :platform the platform (**Required**)
84
84
  # @option options [Driver::Base] :driver the driver (**Required**)
85
85
  # @option options [Provisioner::Base] :provisioner the provisioner
86
+ # (**Required**)
86
87
  # @option options [Transport::Base] :transport the transport
87
88
  # (**Required**)
88
- # @option options [Verifier] :verifier the verifier logger (**Required**)
89
+ # @option options [Verifier] :verifier the verifier (**Required**)
89
90
  # @option options [Logger] :logger the instance logger
90
91
  # (default: Kitchen.logger)
91
92
  # @option options [StateFile] :state_file the state file object to use
@@ -343,10 +344,10 @@ module Kitchen
343
344
  # @api private
344
345
  attr_reader :state_file
345
346
 
346
- # Validate the initial internal state of this object and raising an
347
+ # Validate the initial internal state of this object, raising an
347
348
  # exception if any preconditions are not met.
348
349
  #
349
- # @param options[Hash] options hash passed into the constructor
350
+ # @param options [Hash] options hash passed into the constructor
350
351
  # @raise [ClientError] if any validations fail
351
352
  # @api private
352
353
  def validate_options(options)
@@ -375,7 +376,7 @@ module Kitchen
375
376
  end
376
377
 
377
378
  # Perform any final configuration or preparation needed for the driver
378
- # object carry out its duties.
379
+ # object to carry out its duties.
379
380
  #
380
381
  # @api private
381
382
  def setup_driver
@@ -384,7 +385,7 @@ module Kitchen
384
385
  end
385
386
 
386
387
  # Perform any final configuration or preparation needed for the lifecycle hooks
387
- # object carry out its duties.
388
+ # object to carry out its duties.
388
389
  #
389
390
  # @api private
390
391
  def setup_lifecycle_hooks
@@ -392,7 +393,7 @@ module Kitchen
392
393
  end
393
394
 
394
395
  # Perform any final configuration or preparation needed for the provisioner
395
- # object carry out its duties.
396
+ # object to carry out its duties.
396
397
  #
397
398
  # @api private
398
399
  def setup_provisioner
@@ -401,7 +402,7 @@ module Kitchen
401
402
  end
402
403
 
403
404
  # Perform any final configuration or preparation needed for the transport
404
- # object carry out its duties.
405
+ # object to carry out its duties.
405
406
  #
406
407
  # @api private
407
408
  def setup_transport
@@ -410,7 +411,7 @@ module Kitchen
410
411
  end
411
412
 
412
413
  # Perform any final configuration or preparation needed for the verifier
413
- # object carry out its duties.
414
+ # object to carry out its duties.
414
415
  #
415
416
  # @api private
416
417
  def setup_verifier
@@ -653,6 +654,16 @@ module Kitchen
653
654
  @state_file = state_file
654
655
  end
655
656
 
657
+ # Runs one instance action, wrapping it in structured logging metadata
658
+ # and benchmarking, and serializing it when the action is registered as
659
+ # non-concurrent.
660
+ #
661
+ # @param what [Symbol] the action to run
662
+ # @yield the action body, given the current state hash
663
+ # @return [void]
664
+ # @raise [ActionFailed] if the state file could not be read or the action
665
+ # did not complete
666
+ # @api private
656
667
  def call(what, &block)
657
668
  state = nil
658
669
  begin
@@ -774,12 +785,16 @@ module Kitchen
774
785
  end
775
786
  end
776
787
 
788
+ # The instance state lifecycle, ordered from least to most converged.
789
+ #
790
+ # @return [Array<Symbol>] ordered state names
791
+ # @api private
777
792
  TRANSITIONS = %i{destroy create converge setup verify}.freeze
778
793
 
779
- # Determines the index of a state in the state lifecycle vector. Woah.
794
+ # Determines the index of a state in the state lifecycle vector. Whoa.
780
795
  #
781
796
  # @param transition [Symbol,#to_sym] a state
782
- # @param [Integer] the index position
797
+ # @return [Integer] the index position
783
798
  # @api private
784
799
  def self.index(transition)
785
800
  if transition.nil?
@@ -77,7 +77,7 @@ module Kitchen
77
77
 
78
78
  # Returns a rendered value from the hash for the given key. If the key
79
79
  # can't be found, there are several options: With no other arguments, it
80
- # will raise an KeyError exception; if default is given, then that will be
80
+ # will raise a KeyError exception; if default is given, then that will be
81
81
  # returned; if the optional code block is specified, then that will be run
82
82
  # and its result returned.
83
83
  #
@@ -115,7 +115,7 @@ module Kitchen
115
115
 
116
116
  # If no block provided, returns an enumerator over the keys and
117
117
  # rendered values in the underlying object. If a block is
118
- # provided, calls the block once for each [key, rendered_value]
118
+ # provided, calls the block once for each `[key, rendered_value]`
119
119
  # pair in the underlying object.
120
120
  #
121
121
  # @return [Enumerator, Array]
@@ -1,15 +1,22 @@
1
1
  require_relative "../platform_filter"
2
2
 
3
3
  module Kitchen
4
+ # Namespace for the lifecycle hook implementations that run user-defined
5
+ # commands around instance actions.
4
6
  class LifecycleHook
7
+ # Base class for a lifecycle hook implementation.
8
+ #
9
+ # A hook is bound to a single phase (for example `pre_create`) and decides,
10
+ # via `#should_run?`, whether it applies to the instance's platform before
11
+ # `#run` carries out the command.
5
12
  class Base
6
13
  # @return [Kitchen::LifecycleHooks]
7
14
  attr_reader :lifecycle_hooks
8
15
 
9
- # return [String]
16
+ # @return [String] the lifecycle phase this hook is bound to
10
17
  attr_reader :phase
11
18
 
12
- # return [Hash]
19
+ # @return [Hash] the raw hook configuration
13
20
  attr_reader :hook
14
21
 
15
22
  # @param lifecycle_hooks [Kitchen::LifecycleHooks]
@@ -21,7 +28,10 @@ module Kitchen
21
28
  @hook = hook
22
29
  end
23
30
 
24
- # return [void]
31
+ # Carries out the hook's command. Subclasses must implement this.
32
+ #
33
+ # @return [void]
34
+ # @raise [NotImplementedError] unless overridden by a subclass
25
35
  def run
26
36
  raise NotImplementedError
27
37
  end
@@ -37,7 +47,7 @@ module Kitchen
37
47
  end
38
48
  end
39
49
 
40
- # @return [Logger] the lifecycle hooks's logger
50
+ # @return [Logger] the lifecycle hook's logger
41
51
  # otherwise
42
52
  # @api private
43
53
  def logger
@@ -4,6 +4,8 @@ require_relative "../logging"
4
4
 
5
5
  module Kitchen
6
6
  class LifecycleHook
7
+ # A lifecycle hook that runs a command on the workstation running Test
8
+ # Kitchen, with the instance's details exported as environment variables.
7
9
  class Local < Base
8
10
  include ShellOut
9
11
  include Logging
@@ -3,6 +3,8 @@ require_relative "../errors"
3
3
 
4
4
  module Kitchen
5
5
  class LifecycleHook
6
+ # A lifecycle hook that runs a command on the instance itself, over the
7
+ # instance's configured transport.
6
8
  class Remote < Base
7
9
  # Execute a specific remote command hook.
8
10
  #
@@ -33,7 +35,7 @@ module Kitchen
33
35
 
34
36
  private
35
37
 
36
- # return [String]
38
+ # @return [String] the command to run on the instance
37
39
  def command
38
40
  hook.fetch(:remote)
39
41
  end
@@ -21,6 +21,10 @@ require "psych" unless defined?(Psych)
21
21
  require "yaml" unless defined?(YAML)
22
22
 
23
23
  module Kitchen
24
+ # Namespace for configuration loaders, which turn on-disk configuration
25
+ # into the raw data hash Test Kitchen operates on.
26
+ #
27
+ # @author Fletcher Nichol <fnichol@nichol.ca>
24
28
  module Loader
25
29
  # YAML file loader for Test Kitchen configuration. This class is
26
30
  # responsible for parsing the main YAML file and the local YAML if it
@@ -57,7 +61,7 @@ module Kitchen
57
61
  end
58
62
 
59
63
  # Reads, parses, and merges YAML configuration files and returns a Hash
60
- # of tne merged data.
64
+ # of the merged data.
61
65
  #
62
66
  # @return [Hash] merged configuration data
63
67
  def read
@@ -99,7 +103,7 @@ module Kitchen
99
103
  # @api private
100
104
  attr_reader :global_config_file
101
105
 
102
- # Performed a prioritized recursive merge of several source Hashes and
106
+ # Performs a prioritized recursive merge of several source Hashes and
103
107
  # returns a new merged Hash. There are 3 sources of configuration data:
104
108
  #
105
109
  # 1. local config
@@ -178,7 +182,7 @@ module Kitchen
178
182
  # Reads a file and returns its contents as a string.
179
183
  #
180
184
  # @param file [String] a path to a file
181
- # @return [String] the files contents, or an empty string if the file
185
+ # @return [String] the file's contents, or an empty string if the file
182
186
  # does not exist
183
187
  # @api private
184
188
  def read_file(file)
@@ -208,7 +212,7 @@ module Kitchen
208
212
  File.join(Dir.pwd, "kitchen.yml")
209
213
  end
210
214
 
211
- # The absolute path to an hidden Kitchen config YAML file.
215
+ # The absolute path to a hidden Kitchen config YAML file.
212
216
  def dot_kitchen_yml
213
217
  File.join(Dir.pwd, ".kitchen.yml")
214
218
  end
@@ -18,11 +18,11 @@
18
18
  require "fileutils" unless defined?(FileUtils)
19
19
  require "json" unless defined?(JSON)
20
20
  require "logger" unless defined?(Logger)
21
- require "time" unless defined?(Time)
21
+ require "time" unless defined?(Time.zone_offset)
22
22
 
23
23
  module Kitchen
24
24
  # Logging implementation for Kitchen. By default the console/stdout output
25
- # will be displayed differently than the file log output. Therefor, this
25
+ # will be displayed differently than the file log output. Therefore, this
26
26
  # class wraps multiple loggers that conform to the stdlib `Logger` class
27
27
  # behavior.
28
28
  #
@@ -49,11 +49,11 @@ module Kitchen
49
49
  # Constructs a new logger.
50
50
  #
51
51
  # @param options [Hash] configuration for a new logger
52
- # @option options [Symbol] :color color to use when when outputting
52
+ # @option options [Symbol] :color color to use when outputting
53
53
  # messages
54
54
  # @option options [Integer] :level the logging severity threshold
55
55
  # (default: `Kitchen::DEFAULT_LOG_LEVEL`)
56
- # @option options [Boolean] whether to overwrite the log
56
+ # @option options [Boolean] :log_overwrite whether to overwrite the log
57
57
  # when Test Kitchen runs. Only applies if the :logdev is a String.
58
58
  # (default: `Kitchen::DEFAULT_LOG_OVERWRITE`)
59
59
  # @option options [String,IO] :logdev filepath String or IO object to be
@@ -111,61 +111,72 @@ module Kitchen
111
111
  private
112
112
 
113
113
  # @api private
114
- # @!macro delegate_to_first_logger
115
- # @method $1()
116
114
  def delegate_to_first_logger(meth)
117
115
  define_method(meth) { |*args, &block| @sink_set.first(meth, *args, &block) }
118
116
  end
119
117
 
120
118
  # @api private
121
- # @!macro delegate_to_all_loggers
122
- # @method $1()
123
119
  def delegate_to_all_loggers(meth)
124
120
  define_method(meth) { |*args, &block| @sink_set.all(meth, *args, &block) }
125
121
  end
126
122
  end
127
123
 
124
+ # @!method level
128
125
  # @return [Integer] the logging severity threshold
129
126
  # @see http://is.gd/Okuy5p
130
127
  delegate_to_first_logger :level
131
128
 
129
+ # @!method level=(level)
132
130
  # Sets the logging severity threshold.
133
131
  #
134
132
  # @param level [Integer] the logging severity threshold
135
133
  # @see http://is.gd/H1VBFH
136
134
  delegate_to_all_loggers :level=
137
135
 
136
+ # @!method progname
138
137
  # @return [String] program name to include in log messages
139
138
  # @see http://is.gd/5uHGK0
140
139
  delegate_to_first_logger :progname
141
140
 
141
+ # @!method progname=(progname)
142
142
  # Sets the program name to include in log messages.
143
143
  #
144
144
  # @param progname [String] the program name to include in log messages
145
145
  # @see http://is.gd/f2U5Xj
146
146
  delegate_to_all_loggers :progname=
147
147
 
148
+ # @!method datetime_format
148
149
  # @return [String] the date format being used
149
150
  # @see http://is.gd/btmFWJ
150
151
  delegate_to_first_logger :datetime_format
151
152
 
153
+ # @!method datetime_format=(format)
152
154
  # Sets the date format being used.
153
155
  #
154
156
  # @param format [String] the date format
155
157
  # @see http://is.gd/M36ml8
156
158
  delegate_to_all_loggers :datetime_format=
157
159
 
160
+ # @!method add(severity, message = nil, progname = nil, &block)
158
161
  # Log a message if the given severity is high enough.
159
162
  #
163
+ # @param severity [Integer] a stdlib Logger severity constant
164
+ # @param message [#to_s, nil] the message to log; when nil the block's
165
+ # value is used, falling back to +progname+
166
+ # @param progname [#to_s, nil] used as the message when both +message+ and
167
+ # a block are absent
168
+ # @yield evaluates to the message to log
160
169
  # @see http://is.gd/5opBW0
161
170
  delegate_to_all_loggers :add
162
171
 
172
+ # @!method <<(message)
163
173
  # Dump one or more messages to info.
164
174
  #
165
175
  # @param message [#to_s] the message to log
166
176
  # @see http://is.gd/BCp5KV
167
177
  delegate_to_all_loggers :<<
168
178
 
179
+ # @!method banner(message_or_progname = nil, &block)
169
180
  # Log a message with severity of banner (high level).
170
181
  #
171
182
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -179,6 +190,7 @@ module Kitchen
179
190
  # @see http://is.gd/pYUCYU
180
191
  delegate_to_all_loggers :banner
181
192
 
193
+ # @!method debug(message_or_progname = nil, &block)
182
194
  # Log a message with severity of debug.
183
195
  #
184
196
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -192,11 +204,13 @@ module Kitchen
192
204
  # @see http://is.gd/Re97Zp
193
205
  delegate_to_all_loggers :debug
194
206
 
207
+ # @!method debug?
195
208
  # @return [true,false] whether or not the current severity level
196
209
  # allows for the printing of debug messages
197
210
  # @see http://is.gd/Iq08xB
198
211
  delegate_to_first_logger :debug?
199
212
 
213
+ # @!method info(message_or_progname = nil, &block)
200
214
  # Log a message with severity of info.
201
215
  #
202
216
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -210,11 +224,13 @@ module Kitchen
210
224
  # @see http://is.gd/pYUCYU
211
225
  delegate_to_all_loggers :info
212
226
 
227
+ # @!method info?
213
228
  # @return [true,false] whether or not the current severity level
214
229
  # allows for the printing of info messages
215
230
  # @see http://is.gd/lBtJkT
216
231
  delegate_to_first_logger :info?
217
232
 
233
+ # @!method error(message_or_progname = nil, &block)
218
234
  # Log a message with severity of error.
219
235
  #
220
236
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -228,11 +244,13 @@ module Kitchen
228
244
  # @see http://is.gd/mLwYMl
229
245
  delegate_to_all_loggers :error
230
246
 
247
+ # @!method error?
231
248
  # @return [true,false] whether or not the current severity level
232
249
  # allows for the printing of error messages
233
250
  # @see http://is.gd/QY19JL
234
251
  delegate_to_first_logger :error?
235
252
 
253
+ # @!method warn(message_or_progname = nil, &block)
236
254
  # Log a message with severity of warn.
237
255
  #
238
256
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -246,11 +264,13 @@ module Kitchen
246
264
  # @see http://is.gd/PX9AIS
247
265
  delegate_to_all_loggers :warn
248
266
 
267
+ # @!method warn?
249
268
  # @return [true,false] whether or not the current severity level
250
269
  # allows for the printing of warn messages
251
270
  # @see http://is.gd/Gdr4lD
252
271
  delegate_to_first_logger :warn?
253
272
 
273
+ # @!method fatal(message_or_progname = nil, &block)
254
274
  # Log a message with severity of fatal.
255
275
  #
256
276
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -264,11 +284,13 @@ module Kitchen
264
284
  # @see http://is.gd/5ElFPK
265
285
  delegate_to_all_loggers :fatal
266
286
 
287
+ # @!method fatal?
267
288
  # @return [true,false] whether or not the current severity level
268
289
  # allows for the printing of fatal messages
269
290
  # @see http://is.gd/7PgwRl
270
291
  delegate_to_first_logger :fatal?
271
292
 
293
+ # @!method unknown(message_or_progname = nil, &block)
272
294
  # Log a message with severity of unknown.
273
295
  #
274
296
  # @param message_or_progname [#to_s] the message to log. In the block
@@ -282,6 +304,7 @@ module Kitchen
282
304
  # @see http://is.gd/Y4hqpf
283
305
  delegate_to_all_loggers :unknown
284
306
 
307
+ # @!method close
285
308
  # Close the logging devices.
286
309
  #
287
310
  # @see http://is.gd/b13cVn
@@ -341,10 +364,26 @@ module Kitchen
341
364
  @loggers = loggers
342
365
  end
343
366
 
367
+ # Invokes a method on the first configured sink only.
368
+ #
369
+ # @param meth [Symbol] the method to invoke
370
+ # @param args [Array] arguments to forward to the sink
371
+ # @yield an optional block forwarded to the sink
372
+ # @return [Object] the first sink's return value
373
+ # @api private
344
374
  def first(meth, *args, &block)
345
375
  @loggers.first.public_send(meth, *args, &block)
346
376
  end
347
377
 
378
+ # Invokes a method on every configured sink. A given block is memoized so
379
+ # that an expensive message block is evaluated at most once, no matter how
380
+ # many sinks consume it.
381
+ #
382
+ # @param meth [Symbol] the method to invoke
383
+ # @param args [Array] arguments to forward to each sink
384
+ # @yield an optional block forwarded to each sink
385
+ # @return [Object] the last sink's return value
386
+ # @api private
348
387
  def all(meth, *args, &block)
349
388
  result = nil
350
389
  block = memoized_block(block) if block
@@ -449,6 +488,13 @@ module Kitchen
449
488
  @line_handler = line_handler
450
489
  end
451
490
 
491
+ # Appends a chunk of stream output to the buffer, emitting each complete
492
+ # newline-terminated line to the line handler.
493
+ #
494
+ # @param msg [String] a chunk of stream output, which may contain zero or
495
+ # more complete lines
496
+ # @return [void]
497
+ # @api private
452
498
  def <<(msg)
453
499
  @buffer += msg
454
500
  flush_lines
@@ -470,6 +516,12 @@ module Kitchen
470
516
  @logger = logger
471
517
  end
472
518
 
519
+ # Routes an already-prefixed stream line to the logger call matching its
520
+ # prefix, stripping the prefix before logging.
521
+ #
522
+ # @param line [String] a single line of prefixed stream output
523
+ # @return [void]
524
+ # @api private
473
525
  def format(line)
474
526
  case line
475
527
  when /^-----> / then log_line(:banner, line.gsub(/^[ >-]{6} /, ""))
@@ -540,6 +592,11 @@ module Kitchen
540
592
  class StructuredLogdevLogger
541
593
  include ::Logger::Severity
542
594
 
595
+ # Maps stdlib Logger severity constants to their lowercase string names
596
+ # as they appear in emitted JSON events.
597
+ #
598
+ # @return [Hash{Integer => String}] severity constant to name mapping
599
+ # @api private
543
600
  SEVERITY_NAMES = {
544
601
  DEBUG => "debug",
545
602
  INFO => "info",
@@ -562,6 +619,17 @@ module Kitchen
562
619
  @mutex = Mutex.new
563
620
  end
564
621
 
622
+ # Writes a log event if the given severity meets the current level.
623
+ #
624
+ # @param severity [Integer] a stdlib Logger severity constant
625
+ # @param message [#to_s, nil] the message to log; when nil the block's
626
+ # value is used, falling back to +progname+
627
+ # @param progname [#to_s, nil] used as the message when both +message+ and
628
+ # a block are absent
629
+ # @yield evaluates to the message to log, only when the severity is high
630
+ # enough to be recorded
631
+ # @return [true] always, once the event has been considered
632
+ # @api private
565
633
  def add(severity, message = nil, progname = nil)
566
634
  severity ||= UNKNOWN
567
635
  return true if severity < level
@@ -574,40 +642,102 @@ module Kitchen
574
642
  write_event(severity, message, "log")
575
643
  end
576
644
 
645
+ # Appends raw stream output, emitting a structured event per complete
646
+ # line.
647
+ #
648
+ # @param msg [String] a chunk of stream output
649
+ # @return [void]
650
+ # @api private
577
651
  def <<(msg)
578
652
  line_buffer << msg
579
653
  end
580
654
 
655
+ # Writes a banner event at info severity.
656
+ #
657
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
658
+ # used
659
+ # @yield evaluates to the message to log
660
+ # @return [void]
661
+ # @api private
581
662
  def banner(msg = nil)
582
663
  message = block_given? ? yield : msg
583
664
  write_event(INFO, message, "banner") unless INFO < level
584
665
  end
585
666
 
667
+ # Writes a stream event at the given severity.
668
+ #
669
+ # @param severity [Integer, Symbol] a stdlib Logger severity constant or its
670
+ # symbol name
671
+ # @param msg [#to_s] the message to log
672
+ # @return [void]
673
+ # @api private
586
674
  def stream(severity, msg)
587
675
  severity = severity_const(severity)
588
676
  write_event(severity, msg, "stream") unless severity < level
589
677
  end
590
678
 
679
+ # Writes a log event at debug severity.
680
+ #
681
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
682
+ # used
683
+ # @yield evaluates to the message to log
684
+ # @return [true]
685
+ # @api private
591
686
  def debug(msg = nil, &block)
592
687
  add(DEBUG, msg, nil, &block)
593
688
  end
594
689
 
690
+ # Writes a log event at info severity.
691
+ #
692
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
693
+ # used
694
+ # @yield evaluates to the message to log
695
+ # @return [true]
696
+ # @api private
595
697
  def info(msg = nil, &block)
596
698
  add(INFO, msg, nil, &block)
597
699
  end
598
700
 
701
+ # Writes a log event at warn severity.
702
+ #
703
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
704
+ # used
705
+ # @yield evaluates to the message to log
706
+ # @return [true]
707
+ # @api private
599
708
  def warn(msg = nil, &block)
600
709
  add(WARN, msg, nil, &block)
601
710
  end
602
711
 
712
+ # Writes a log event at error severity.
713
+ #
714
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
715
+ # used
716
+ # @yield evaluates to the message to log
717
+ # @return [true]
718
+ # @api private
603
719
  def error(msg = nil, &block)
604
720
  add(ERROR, msg, nil, &block)
605
721
  end
606
722
 
723
+ # Writes a log event at fatal severity.
724
+ #
725
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
726
+ # used
727
+ # @yield evaluates to the message to log
728
+ # @return [true]
729
+ # @api private
607
730
  def fatal(msg = nil, &block)
608
731
  add(FATAL, msg, nil, &block)
609
732
  end
610
733
 
734
+ # Writes a log event at unknown severity.
735
+ #
736
+ # @param msg [#to_s, nil] the message to log; when nil the block's value is
737
+ # used
738
+ # @yield evaluates to the message to log
739
+ # @return [true]
740
+ # @api private
611
741
  def unknown(msg = nil, &block)
612
742
  add(UNKNOWN, msg, nil, &block)
613
743
  end
@@ -632,6 +762,10 @@ module Kitchen
632
762
  level <= FATAL
633
763
  end
634
764
 
765
+ # Closes the underlying log device if it is open and supports closing.
766
+ #
767
+ # @return [void]
768
+ # @api private
635
769
  def close
636
770
  return unless @logdev.respond_to?(:close)
637
771
 
@@ -25,7 +25,7 @@ module Kitchen
25
25
 
26
26
  # @api private
27
27
  # @!macro logger_method
28
- # @method $1($2)
28
+ # @method $1(message_or_progname = nil, &block)
29
29
  # Log a message with severity of $1
30
30
  # @param message_or_progname [#to_s] the message to log. In the block
31
31
  # form, this is the progname to use in the log message.
@@ -42,6 +42,9 @@ module Kitchen
42
42
  @options = options
43
43
  end
44
44
 
45
+ # Returns the arguments in the form expected by `Kernel#exec`.
46
+ #
47
+ # @return [Array] the command, its arguments, and the options hash
45
48
  def exec_args
46
49
  [command, *arguments, options]
47
50
  end
@@ -33,7 +33,7 @@ module Kitchen
33
33
  [mc[:name], mc[:version]]
34
34
  end
35
35
 
36
- # Creates a new instances and loads in the contents of the metadata.rb
36
+ # Creates a new instance and loads in the contents of the metadata.rb
37
37
  # file. If you value your life, you may want to avoid reading the
38
38
  # implementation.
39
39
  #
@@ -42,6 +42,13 @@ module Kitchen
42
42
  instance_eval(File.read(metadata_file), metadata_file)
43
43
  end
44
44
 
45
+ # Captures any attribute call made while evaluating the metadata file,
46
+ # storing its first argument under the attribute name.
47
+ #
48
+ # @param meth [Symbol] the attribute name being set
49
+ # @param args [Array] the attribute's arguments; the first becomes the value
50
+ # @return [Object] the stored value
51
+ # @api private
45
52
  def method_missing(meth, *args, &_block)
46
53
  self[meth] = args.first
47
54
  end