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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Rakefile +10 -0
- data/lib/kitchen/cli.rb +60 -5
- data/lib/kitchen/color.rb +7 -0
- data/lib/kitchen/command/action.rb +1 -1
- data/lib/kitchen/command/diagnose.rb +1 -1
- data/lib/kitchen/command/login.rb +1 -1
- data/lib/kitchen/command/logs.rb +4 -0
- data/lib/kitchen/command/package.rb +1 -1
- data/lib/kitchen/command.rb +25 -2
- data/lib/kitchen/config.rb +5 -5
- data/lib/kitchen/configurable.rb +17 -4
- data/lib/kitchen/data_munger.rb +19 -0
- data/lib/kitchen/driver/base.rb +3 -3
- data/lib/kitchen/driver/dummy.rb +9 -3
- data/lib/kitchen/errors.rb +7 -1
- data/lib/kitchen/generator/init.rb +4 -0
- data/lib/kitchen/instance.rb +27 -12
- data/lib/kitchen/lazy_hash.rb +2 -2
- data/lib/kitchen/lifecycle_hook/base.rb +14 -4
- data/lib/kitchen/lifecycle_hook/local.rb +2 -0
- data/lib/kitchen/lifecycle_hook/remote.rb +3 -1
- data/lib/kitchen/loader/yaml.rb +8 -4
- data/lib/kitchen/logger.rb +142 -8
- data/lib/kitchen/logging.rb +1 -1
- data/lib/kitchen/login_command.rb +3 -0
- data/lib/kitchen/metadata_chopper.rb +8 -1
- data/lib/kitchen/platform_filter.rb +4 -4
- data/lib/kitchen/plugin.rb +4 -1
- data/lib/kitchen/plugin_base.rb +5 -0
- data/lib/kitchen/provisioner/base.rb +5 -5
- data/lib/kitchen/provisioner/dummy.rb +1 -1
- data/lib/kitchen/provisioner/external.rb +22 -0
- data/lib/kitchen/provisioner.rb +1 -1
- data/lib/kitchen/state_file.rb +1 -1
- data/lib/kitchen/suite.rb +1 -1
- data/lib/kitchen/transport/base.rb +1 -1
- data/lib/kitchen/transport/dummy.rb +21 -3
- data/lib/kitchen/transport/exec.rb +1 -1
- data/lib/kitchen/transport/ssh.rb +13 -6
- data/lib/kitchen/transport/winrm.rb +12 -6
- data/lib/kitchen/util.rb +12 -4
- data/lib/kitchen/verifier/base.rb +5 -5
- data/lib/kitchen/verifier/busser.rb +1 -1
- data/lib/kitchen/verifier/shell.rb +1 -1
- data/lib/kitchen/version.rb +4 -1
- data/lib/kitchen/which.rb +2 -0
- data/lib/kitchen.rb +2 -2
- data/lib/vendor/hash_recursive_merge.rb +5 -0
- data/templates/driver/README.md.erb +1 -1
- data/test-kitchen.gemspec +2 -2
- metadata +2 -2
data/lib/kitchen/instance.rb
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
|
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
|
-
# @
|
|
797
|
+
# @return [Integer] the index position
|
|
783
798
|
# @api private
|
|
784
799
|
def self.index(transition)
|
|
785
800
|
if transition.nil?
|
data/lib/kitchen/lazy_hash.rb
CHANGED
|
@@ -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
|
|
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
|
-
#
|
|
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
|
|
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
|
data/lib/kitchen/loader/yaml.rb
CHANGED
|
@@ -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
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
data/lib/kitchen/logger.rb
CHANGED
|
@@ -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.
|
|
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
|
|
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
|
|
data/lib/kitchen/logging.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Kitchen
|
|
|
25
25
|
|
|
26
26
|
# @api private
|
|
27
27
|
# @!macro logger_method
|
|
28
|
-
# @method $1(
|
|
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.
|
|
@@ -33,7 +33,7 @@ module Kitchen
|
|
|
33
33
|
[mc[:name], mc[:version]]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# Creates a new
|
|
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
|