test-kitchen 1.6.0 → 1.7.0

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +8 -7
  3. data/.github/ISSUE_TEMPLATE.md +56 -0
  4. data/.gitignore +28 -27
  5. data/.kitchen.ci.yml +23 -0
  6. data/.kitchen.proxy.yml +27 -0
  7. data/.rubocop.yml +3 -3
  8. data/.travis.yml +70 -53
  9. data/.yardopts +3 -3
  10. data/Berksfile +3 -0
  11. data/CHANGELOG.md +1083 -1051
  12. data/CONTRIBUTING.md +14 -14
  13. data/Gemfile +19 -14
  14. data/Gemfile.proxy_tests +4 -5
  15. data/Guardfile +42 -42
  16. data/LICENSE +15 -15
  17. data/MAINTAINERS.md +23 -24
  18. data/README.md +135 -135
  19. data/Rakefile +61 -76
  20. data/appveyor.yml +44 -34
  21. data/features/kitchen_action_commands.feature +164 -164
  22. data/features/kitchen_command.feature +16 -16
  23. data/features/kitchen_console_command.feature +34 -34
  24. data/features/kitchen_defaults.feature +38 -38
  25. data/features/kitchen_diagnose_command.feature +96 -96
  26. data/features/kitchen_driver_create_command.feature +64 -64
  27. data/features/kitchen_driver_discover_command.feature +25 -25
  28. data/features/kitchen_help_command.feature +16 -16
  29. data/features/kitchen_init_command.feature +274 -274
  30. data/features/kitchen_list_command.feature +104 -104
  31. data/features/kitchen_login_command.feature +62 -62
  32. data/features/kitchen_sink_command.feature +30 -30
  33. data/features/kitchen_test_command.feature +88 -88
  34. data/features/step_definitions/gem_steps.rb +36 -36
  35. data/features/step_definitions/git_steps.rb +5 -5
  36. data/features/step_definitions/output_steps.rb +5 -5
  37. data/features/support/env.rb +75 -75
  38. data/lib/kitchen.rb +150 -150
  39. data/lib/kitchen/base64_stream.rb +55 -55
  40. data/lib/kitchen/cli.rb +419 -419
  41. data/lib/kitchen/collection.rb +55 -55
  42. data/lib/kitchen/color.rb +65 -65
  43. data/lib/kitchen/command.rb +185 -185
  44. data/lib/kitchen/command/action.rb +45 -45
  45. data/lib/kitchen/command/console.rb +58 -58
  46. data/lib/kitchen/command/diagnose.rb +92 -92
  47. data/lib/kitchen/command/driver_discover.rb +105 -105
  48. data/lib/kitchen/command/exec.rb +41 -41
  49. data/lib/kitchen/command/list.rb +119 -119
  50. data/lib/kitchen/command/login.rb +43 -43
  51. data/lib/kitchen/command/sink.rb +54 -54
  52. data/lib/kitchen/command/test.rb +51 -51
  53. data/lib/kitchen/config.rb +322 -322
  54. data/lib/kitchen/configurable.rb +529 -529
  55. data/lib/kitchen/data_munger.rb +959 -960
  56. data/lib/kitchen/diagnostic.rb +141 -141
  57. data/lib/kitchen/driver.rb +56 -56
  58. data/lib/kitchen/driver/base.rb +134 -134
  59. data/lib/kitchen/driver/dummy.rb +108 -108
  60. data/lib/kitchen/driver/proxy.rb +72 -72
  61. data/lib/kitchen/driver/ssh_base.rb +357 -357
  62. data/lib/kitchen/errors.rb +229 -229
  63. data/lib/kitchen/generator/driver_create.rb +177 -177
  64. data/lib/kitchen/generator/init.rb +296 -296
  65. data/lib/kitchen/instance.rb +662 -662
  66. data/lib/kitchen/lazy_hash.rb +142 -142
  67. data/lib/kitchen/loader/yaml.rb +349 -349
  68. data/lib/kitchen/logger.rb +423 -423
  69. data/lib/kitchen/logging.rb +56 -56
  70. data/lib/kitchen/login_command.rb +52 -52
  71. data/lib/kitchen/metadata_chopper.rb +52 -52
  72. data/lib/kitchen/platform.rb +67 -67
  73. data/lib/kitchen/provisioner.rb +54 -54
  74. data/lib/kitchen/provisioner/base.rb +236 -236
  75. data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
  76. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
  77. data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
  78. data/lib/kitchen/provisioner/chef_apply.rb +124 -125
  79. data/lib/kitchen/provisioner/chef_base.rb +341 -294
  80. data/lib/kitchen/provisioner/chef_solo.rb +88 -89
  81. data/lib/kitchen/provisioner/chef_zero.rb +245 -245
  82. data/lib/kitchen/provisioner/dummy.rb +79 -79
  83. data/lib/kitchen/provisioner/shell.rb +138 -138
  84. data/lib/kitchen/rake_tasks.rb +63 -63
  85. data/lib/kitchen/shell_out.rb +93 -93
  86. data/lib/kitchen/ssh.rb +276 -276
  87. data/lib/kitchen/state_file.rb +120 -120
  88. data/lib/kitchen/suite.rb +51 -51
  89. data/lib/kitchen/thor_tasks.rb +66 -66
  90. data/lib/kitchen/transport.rb +54 -54
  91. data/lib/kitchen/transport/base.rb +176 -176
  92. data/lib/kitchen/transport/dummy.rb +79 -79
  93. data/lib/kitchen/transport/ssh.rb +364 -364
  94. data/lib/kitchen/transport/winrm.rb +486 -486
  95. data/lib/kitchen/util.rb +147 -147
  96. data/lib/kitchen/verifier.rb +55 -55
  97. data/lib/kitchen/verifier/base.rb +235 -235
  98. data/lib/kitchen/verifier/busser.rb +277 -277
  99. data/lib/kitchen/verifier/dummy.rb +79 -79
  100. data/lib/kitchen/verifier/shell.rb +101 -101
  101. data/lib/kitchen/version.rb +21 -21
  102. data/lib/vendor/hash_recursive_merge.rb +82 -82
  103. data/spec/kitchen/base64_stream_spec.rb +77 -77
  104. data/spec/kitchen/cli_spec.rb +56 -56
  105. data/spec/kitchen/collection_spec.rb +80 -80
  106. data/spec/kitchen/color_spec.rb +54 -54
  107. data/spec/kitchen/config_spec.rb +408 -408
  108. data/spec/kitchen/configurable_spec.rb +1095 -1062
  109. data/spec/kitchen/data_munger_spec.rb +2694 -2383
  110. data/spec/kitchen/diagnostic_spec.rb +129 -129
  111. data/spec/kitchen/driver/base_spec.rb +121 -121
  112. data/spec/kitchen/driver/dummy_spec.rb +199 -199
  113. data/spec/kitchen/driver/proxy_spec.rb +138 -138
  114. data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
  115. data/spec/kitchen/driver_spec.rb +112 -112
  116. data/spec/kitchen/errors_spec.rb +309 -309
  117. data/spec/kitchen/instance_spec.rb +1419 -1419
  118. data/spec/kitchen/lazy_hash_spec.rb +117 -117
  119. data/spec/kitchen/loader/yaml_spec.rb +774 -774
  120. data/spec/kitchen/logger_spec.rb +429 -429
  121. data/spec/kitchen/logging_spec.rb +59 -59
  122. data/spec/kitchen/login_command_spec.rb +68 -68
  123. data/spec/kitchen/metadata_chopper_spec.rb +82 -82
  124. data/spec/kitchen/platform_spec.rb +89 -89
  125. data/spec/kitchen/provisioner/base_spec.rb +386 -386
  126. data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
  127. data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1067
  128. data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
  129. data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
  130. data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
  131. data/spec/kitchen/provisioner/shell_spec.rb +566 -566
  132. data/spec/kitchen/provisioner_spec.rb +107 -107
  133. data/spec/kitchen/shell_out_spec.rb +150 -150
  134. data/spec/kitchen/ssh_spec.rb +693 -693
  135. data/spec/kitchen/state_file_spec.rb +129 -129
  136. data/spec/kitchen/suite_spec.rb +62 -62
  137. data/spec/kitchen/transport/base_spec.rb +89 -89
  138. data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
  139. data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
  140. data/spec/kitchen/transport_spec.rb +112 -112
  141. data/spec/kitchen/util_spec.rb +165 -165
  142. data/spec/kitchen/verifier/base_spec.rb +362 -362
  143. data/spec/kitchen/verifier/busser_spec.rb +610 -610
  144. data/spec/kitchen/verifier/dummy_spec.rb +99 -99
  145. data/spec/kitchen/verifier/shell_spec.rb +160 -158
  146. data/spec/kitchen/verifier_spec.rb +120 -120
  147. data/spec/kitchen_spec.rb +114 -114
  148. data/spec/spec_helper.rb +85 -85
  149. data/spec/support/powershell_max_size_spec.rb +40 -40
  150. data/support/busser_install_command.ps1 +14 -14
  151. data/support/busser_install_command.sh +14 -14
  152. data/support/chef-client-zero.rb +77 -77
  153. data/support/chef_base_init_command.ps1 +18 -18
  154. data/support/chef_base_init_command.sh +2 -2
  155. data/support/chef_base_install_command.ps1 +85 -85
  156. data/support/chef_base_install_command.sh +229 -229
  157. data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
  158. data/support/chef_zero_prepare_command_legacy.sh +10 -10
  159. data/support/download_helpers.sh +109 -109
  160. data/support/dummy-validation.pem +27 -27
  161. data/templates/driver/CHANGELOG.md.erb +3 -3
  162. data/templates/driver/Gemfile.erb +3 -3
  163. data/templates/driver/README.md.erb +64 -64
  164. data/templates/driver/Rakefile.erb +21 -21
  165. data/templates/driver/driver.rb.erb +23 -23
  166. data/templates/driver/gemspec.erb +29 -29
  167. data/templates/driver/gitignore.erb +17 -17
  168. data/templates/driver/license_apachev2.erb +15 -15
  169. data/templates/driver/license_lgplv3.erb +16 -16
  170. data/templates/driver/license_mit.erb +22 -22
  171. data/templates/driver/license_reserved.erb +5 -5
  172. data/templates/driver/tailor.erb +4 -4
  173. data/templates/driver/travis.yml.erb +11 -11
  174. data/templates/driver/version.rb.erb +12 -12
  175. data/templates/init/chefignore.erb +1 -1
  176. data/templates/init/kitchen.yml.erb +18 -18
  177. data/test-kitchen.gemspec +62 -62
  178. data/test/integration/default/default_spec.rb +3 -0
  179. data/testing_windows.md +37 -37
  180. metadata +23 -11
@@ -1,429 +1,429 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2014, Fletcher Nichol
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
-
19
- require_relative "../spec_helper"
20
-
21
- require "kitchen"
22
-
23
- describe Kitchen::Logger do
24
-
25
- before do
26
- Kitchen.stubs(:tty?).returns(true)
27
- @orig_stdout = $stdout
28
- $stdout = StringIO.new
29
- end
30
-
31
- after do
32
- $stdout = @orig_stdout
33
- end
34
-
35
- def colorize(*args)
36
- Kitchen::Color.colorize(*args)
37
- end
38
-
39
- let(:opts) do
40
- { :color => :red }
41
- end
42
-
43
- let(:logger) do
44
- Kitchen::Logger.new(opts)
45
- end
46
-
47
- it "sets the log level to :info by default" do
48
- logger.level.must_equal Kitchen::Util.to_logger_level(:info)
49
- logger.debug?.must_equal false
50
- logger.info?.must_equal true
51
- logger.error?.must_equal true
52
- logger.warn?.must_equal true
53
- logger.fatal?.must_equal true
54
- end
55
-
56
- it "sets a level at creation" do
57
- opts[:level] = Kitchen::Util.to_logger_level(:warn)
58
-
59
- logger.level.must_equal Kitchen::Util.to_logger_level(:warn)
60
- logger.info?.must_equal false
61
- logger.warn?.must_equal true
62
- logger.fatal?.must_equal true
63
- end
64
-
65
- it "sets a level after creation" do
66
- logger.level = Kitchen::Util.to_logger_level(:fatal)
67
-
68
- logger.level.must_equal Kitchen::Util.to_logger_level(:fatal)
69
- logger.warn?.must_equal false
70
- logger.fatal?.must_equal true
71
- end
72
-
73
- it "datetime_format is nil by default" do
74
- logger.datetime_format.must_equal nil
75
- end
76
-
77
- it "sets datetime_format after creation" do
78
- logger.datetime_format = "smart?"
79
-
80
- logger.datetime_format.must_equal "smart?"
81
- end
82
-
83
- it "sets progname to Kitchen by default" do
84
- logger.progname.must_equal "Kitchen"
85
- end
86
-
87
- it "sets progname at creation" do
88
- opts[:progname] = "Dream Theater"
89
-
90
- logger.progname.must_equal "Dream Theater"
91
- end
92
-
93
- it "sets progname after creation" do
94
- logger.progname = "MASTA"
95
-
96
- logger.progname.must_equal "MASTA"
97
- end
98
-
99
- describe "stdout-based logger" do
100
-
101
- let(:stdout) { StringIO.new }
102
-
103
- before { opts[:stdout] = stdout }
104
-
105
- it "sets up a simple STDOUT logger by default" do
106
- opts.delete(:stdout)
107
- logger.info("hello")
108
-
109
- $stdout.string.must_equal colorize(" hello", opts[:color]) + "\n"
110
- end
111
-
112
- it "sets up a simple STDOUT logger by default with no color" do
113
- Kitchen.stubs(:tty?).returns(false)
114
- opts.delete(:stdout)
115
- logger.info("hello")
116
-
117
- $stdout.string.must_equal " hello\n"
118
- end
119
-
120
- it "accepts a :stdout option to redirect output" do
121
- logger.info("hello")
122
-
123
- stdout.string.must_equal colorize(" hello", opts[:color]) + "\n"
124
- end
125
-
126
- it "accepts a :stdout option to redirect output with no color" do
127
- Kitchen.stubs(:tty?).returns(false)
128
- logger.info("hello")
129
-
130
- stdout.string.must_equal " hello\n"
131
- end
132
-
133
- describe "for severity" do
134
-
135
- before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
136
-
137
- it "logs to banner" do
138
- logger.banner("yo")
139
-
140
- stdout.string.must_equal colorize("-----> yo", opts[:color]) + "\n"
141
- end
142
-
143
- it "logs to banner with no color" do
144
- Kitchen.stubs(:tty?).returns(false)
145
- logger.banner("yo")
146
-
147
- stdout.string.must_equal "-----> yo\n"
148
- end
149
-
150
- it "logs to debug" do
151
- logger.debug("yo")
152
-
153
- stdout.string.must_equal colorize("D yo", opts[:color]) + "\n"
154
- end
155
-
156
- it "logs to debug with no color" do
157
- Kitchen.stubs(:tty?).returns(false)
158
- logger.debug("yo")
159
-
160
- stdout.string.must_equal "D yo\n"
161
- end
162
-
163
- it "logs to info" do
164
- logger.info("yo")
165
-
166
- stdout.string.must_equal colorize(" yo", opts[:color]) + "\n"
167
- end
168
-
169
- it "logs to info with no color" do
170
- Kitchen.stubs(:tty?).returns(false)
171
- logger.info("yo")
172
-
173
- stdout.string.must_equal " yo\n"
174
- end
175
-
176
- it "logs to error" do
177
- logger.error("yo")
178
-
179
- stdout.string.must_equal colorize(">>>>>> yo", opts[:color]) + "\n"
180
- end
181
-
182
- it "logs to error with no color" do
183
- Kitchen.stubs(:tty?).returns(false)
184
- logger.error("yo")
185
-
186
- stdout.string.must_equal ">>>>>> yo\n"
187
- end
188
-
189
- it "logs to warn" do
190
- logger.warn("yo")
191
-
192
- stdout.string.must_equal colorize("$$$$$$ yo", opts[:color]) + "\n"
193
- end
194
-
195
- it "logs to warn with no color" do
196
- Kitchen.stubs(:tty?).returns(false)
197
- logger.warn("yo")
198
-
199
- stdout.string.must_equal "$$$$$$ yo\n"
200
- end
201
-
202
- it "logs to fatal" do
203
- logger.fatal("yo")
204
-
205
- stdout.string.must_equal colorize("!!!!!! yo", opts[:color]) + "\n"
206
- end
207
-
208
- it "logs to fatal with no color" do
209
- Kitchen.stubs(:tty?).returns(false)
210
- logger.fatal("yo")
211
-
212
- stdout.string.must_equal "!!!!!! yo\n"
213
- end
214
-
215
- it "logs to unknown" do
216
- logger.unknown("yo")
217
-
218
- stdout.string.must_equal colorize("?????? yo", opts[:color]) + "\n"
219
- end
220
-
221
- it "logs to unknown with no color" do
222
- Kitchen.stubs(:tty?).returns(false)
223
- logger.unknown("yo")
224
-
225
- stdout.string.must_equal "?????? yo\n"
226
- end
227
- end
228
-
229
- describe "#<<" do
230
-
231
- it "message with a newline are logged on info" do
232
- logger << "yo\n"
233
-
234
- stdout.string.must_equal colorize(" yo", opts[:color]) + "\n"
235
- end
236
-
237
- it "message with multiple newlines are separately logged on info" do
238
- logger << "yo\nheya\n"
239
-
240
- stdout.string.must_equal(
241
- colorize(" yo", opts[:color]) + "\n" +
242
- colorize(" heya", opts[:color]) + "\n"
243
- )
244
- end
245
-
246
- it "message with info, error, and banner lines will be preserved" do
247
- logger << [
248
- "-----> banner",
249
- " info",
250
- ">>>>>> error",
251
- "vanilla"
252
- ].join("\n").concat("\n")
253
-
254
- stdout.string.must_equal(
255
- colorize("-----> banner", opts[:color]) + "\n" +
256
- colorize(" info", opts[:color]) + "\n" +
257
- colorize(">>>>>> error", opts[:color]) + "\n" +
258
- colorize(" vanilla", opts[:color]) + "\n"
259
- )
260
- end
261
-
262
- it "message with line that is not newline terminated will be buffered" do
263
- logger << [
264
- "-----> banner",
265
- " info",
266
- "partial"
267
- ].join("\n")
268
-
269
- stdout.string.must_equal(
270
- colorize("-----> banner", opts[:color]) + "\n" +
271
- colorize(" info", opts[:color]) + "\n"
272
- )
273
- end
274
-
275
- it "logger with buffered data will flush on next message with newline" do
276
- logger << "partial"
277
- logger << "ly\nokay\n"
278
-
279
- stdout.string.must_equal(
280
- colorize(" partially", opts[:color]) + "\n" +
281
- colorize(" okay", opts[:color]) + "\n"
282
- )
283
- end
284
-
285
- it "logger that receives mixed first chunk will flush next message with newline" do
286
- logger << "partially\no"
287
- logger << "kay\n"
288
-
289
- stdout.string.must_equal(
290
- colorize(" partially", opts[:color]) + "\n" +
291
- colorize(" okay", opts[:color]) + "\n"
292
- )
293
- end
294
-
295
- it "logger chomps carriage return characters" do
296
- logger << [
297
- "-----> banner\r",
298
- "vanilla\r"
299
- ].join("\n").concat("\n")
300
-
301
- stdout.string.must_equal(
302
- colorize("-----> banner", opts[:color]) + "\n" +
303
- colorize(" vanilla", opts[:color]) + "\n"
304
- )
305
- end
306
- end
307
- end
308
-
309
- describe "opened IO logdev-based logger" do
310
-
311
- let(:logdev) { StringIO.new }
312
-
313
- before { opts[:logdev] = logdev }
314
-
315
- describe "for severity" do
316
-
317
- before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
318
-
319
- let(:ts) { "\\[[^\\]]+\\]" }
320
-
321
- it "logs to banner" do
322
- logger.banner("yo")
323
-
324
- logdev.string.must_match(/^I, #{ts} INFO -- Kitchen: -----> yo$/)
325
- end
326
-
327
- it "logs to debug" do
328
- logger.debug("yo")
329
-
330
- logdev.string.must_match(/^D, #{ts} DEBUG -- Kitchen: yo$/)
331
- end
332
-
333
- it "logs to info" do
334
- logger.info("yo")
335
-
336
- logdev.string.must_match(/^I, #{ts} INFO -- Kitchen: yo$/)
337
- end
338
-
339
- it "logs to error" do
340
- logger.error("yo")
341
-
342
- logdev.string.must_match(/^E, #{ts} ERROR -- Kitchen: yo$/)
343
- end
344
-
345
- it "logs to warn" do
346
- logger.warn("yo")
347
-
348
- logdev.string.must_match(/^W, #{ts} WARN -- Kitchen: yo$/)
349
- end
350
-
351
- it "logs to fatal" do
352
- logger.fatal("yo")
353
-
354
- logdev.string.must_match(/^F, #{ts} FATAL -- Kitchen: yo$/)
355
- end
356
-
357
- it "logs to unknown" do
358
- logger.unknown("yo")
359
-
360
- logdev.string.must_match(/^A, #{ts} ANY -- Kitchen: yo$/)
361
- end
362
- end
363
- end
364
-
365
- describe "file IO logdev-based logger" do
366
-
367
- let(:logfile) { Dir::Tmpname.make_tmpname(%w[kitchen .log], nil) }
368
-
369
- before do
370
- opts[:logdev] = logfile
371
- FakeFS.activate!
372
- FileUtils.mkdir_p("/tmp")
373
- end
374
-
375
- after do
376
- FakeFS.deactivate!
377
- FakeFS::FileSystem.clear
378
- end
379
-
380
- describe "for severity" do
381
-
382
- before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
383
-
384
- let(:ts) { "\\[[^\\]]+\\]" }
385
-
386
- it "logs to banner" do
387
- logger.banner("yo")
388
-
389
- IO.read(logfile).must_match(/^I, #{ts} INFO -- Kitchen: -----> yo$/)
390
- end
391
-
392
- it "logs to debug" do
393
- logger.debug("yo")
394
-
395
- IO.read(logfile).must_match(/^D, #{ts} DEBUG -- Kitchen: yo$/)
396
- end
397
-
398
- it "logs to info" do
399
- logger.info("yo")
400
-
401
- IO.read(logfile).must_match(/^I, #{ts} INFO -- Kitchen: yo$/)
402
- end
403
-
404
- it "logs to error" do
405
- logger.error("yo")
406
-
407
- IO.read(logfile).must_match(/^E, #{ts} ERROR -- Kitchen: yo$/)
408
- end
409
-
410
- it "logs to warn" do
411
- logger.warn("yo")
412
-
413
- IO.read(logfile).must_match(/^W, #{ts} WARN -- Kitchen: yo$/)
414
- end
415
-
416
- it "logs to fatal" do
417
- logger.fatal("yo")
418
-
419
- IO.read(logfile).must_match(/^F, #{ts} FATAL -- Kitchen: yo$/)
420
- end
421
-
422
- it "logs to unknown" do
423
- logger.unknown("yo")
424
-
425
- IO.read(logfile).must_match(/^A, #{ts} ANY -- Kitchen: yo$/)
426
- end
427
- end
428
- end
429
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../spec_helper"
20
+
21
+ require "kitchen"
22
+
23
+ describe Kitchen::Logger do
24
+
25
+ before do
26
+ Kitchen.stubs(:tty?).returns(true)
27
+ @orig_stdout = $stdout
28
+ $stdout = StringIO.new
29
+ end
30
+
31
+ after do
32
+ $stdout = @orig_stdout
33
+ end
34
+
35
+ def colorize(*args)
36
+ Kitchen::Color.colorize(*args)
37
+ end
38
+
39
+ let(:opts) do
40
+ { :color => :red }
41
+ end
42
+
43
+ let(:logger) do
44
+ Kitchen::Logger.new(opts)
45
+ end
46
+
47
+ it "sets the log level to :info by default" do
48
+ logger.level.must_equal Kitchen::Util.to_logger_level(:info)
49
+ logger.debug?.must_equal false
50
+ logger.info?.must_equal true
51
+ logger.error?.must_equal true
52
+ logger.warn?.must_equal true
53
+ logger.fatal?.must_equal true
54
+ end
55
+
56
+ it "sets a level at creation" do
57
+ opts[:level] = Kitchen::Util.to_logger_level(:warn)
58
+
59
+ logger.level.must_equal Kitchen::Util.to_logger_level(:warn)
60
+ logger.info?.must_equal false
61
+ logger.warn?.must_equal true
62
+ logger.fatal?.must_equal true
63
+ end
64
+
65
+ it "sets a level after creation" do
66
+ logger.level = Kitchen::Util.to_logger_level(:fatal)
67
+
68
+ logger.level.must_equal Kitchen::Util.to_logger_level(:fatal)
69
+ logger.warn?.must_equal false
70
+ logger.fatal?.must_equal true
71
+ end
72
+
73
+ it "datetime_format is nil by default" do
74
+ logger.datetime_format.must_equal nil
75
+ end
76
+
77
+ it "sets datetime_format after creation" do
78
+ logger.datetime_format = "smart?"
79
+
80
+ logger.datetime_format.must_equal "smart?"
81
+ end
82
+
83
+ it "sets progname to Kitchen by default" do
84
+ logger.progname.must_equal "Kitchen"
85
+ end
86
+
87
+ it "sets progname at creation" do
88
+ opts[:progname] = "Dream Theater"
89
+
90
+ logger.progname.must_equal "Dream Theater"
91
+ end
92
+
93
+ it "sets progname after creation" do
94
+ logger.progname = "MASTA"
95
+
96
+ logger.progname.must_equal "MASTA"
97
+ end
98
+
99
+ describe "stdout-based logger" do
100
+
101
+ let(:stdout) { StringIO.new }
102
+
103
+ before { opts[:stdout] = stdout }
104
+
105
+ it "sets up a simple STDOUT logger by default" do
106
+ opts.delete(:stdout)
107
+ logger.info("hello")
108
+
109
+ $stdout.string.must_equal colorize(" hello", opts[:color]) + "\n"
110
+ end
111
+
112
+ it "sets up a simple STDOUT logger by default with no color" do
113
+ Kitchen.stubs(:tty?).returns(false)
114
+ opts.delete(:stdout)
115
+ logger.info("hello")
116
+
117
+ $stdout.string.must_equal " hello\n"
118
+ end
119
+
120
+ it "accepts a :stdout option to redirect output" do
121
+ logger.info("hello")
122
+
123
+ stdout.string.must_equal colorize(" hello", opts[:color]) + "\n"
124
+ end
125
+
126
+ it "accepts a :stdout option to redirect output with no color" do
127
+ Kitchen.stubs(:tty?).returns(false)
128
+ logger.info("hello")
129
+
130
+ stdout.string.must_equal " hello\n"
131
+ end
132
+
133
+ describe "for severity" do
134
+
135
+ before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
136
+
137
+ it "logs to banner" do
138
+ logger.banner("yo")
139
+
140
+ stdout.string.must_equal colorize("-----> yo", opts[:color]) + "\n"
141
+ end
142
+
143
+ it "logs to banner with no color" do
144
+ Kitchen.stubs(:tty?).returns(false)
145
+ logger.banner("yo")
146
+
147
+ stdout.string.must_equal "-----> yo\n"
148
+ end
149
+
150
+ it "logs to debug" do
151
+ logger.debug("yo")
152
+
153
+ stdout.string.must_equal colorize("D yo", opts[:color]) + "\n"
154
+ end
155
+
156
+ it "logs to debug with no color" do
157
+ Kitchen.stubs(:tty?).returns(false)
158
+ logger.debug("yo")
159
+
160
+ stdout.string.must_equal "D yo\n"
161
+ end
162
+
163
+ it "logs to info" do
164
+ logger.info("yo")
165
+
166
+ stdout.string.must_equal colorize(" yo", opts[:color]) + "\n"
167
+ end
168
+
169
+ it "logs to info with no color" do
170
+ Kitchen.stubs(:tty?).returns(false)
171
+ logger.info("yo")
172
+
173
+ stdout.string.must_equal " yo\n"
174
+ end
175
+
176
+ it "logs to error" do
177
+ logger.error("yo")
178
+
179
+ stdout.string.must_equal colorize(">>>>>> yo", opts[:color]) + "\n"
180
+ end
181
+
182
+ it "logs to error with no color" do
183
+ Kitchen.stubs(:tty?).returns(false)
184
+ logger.error("yo")
185
+
186
+ stdout.string.must_equal ">>>>>> yo\n"
187
+ end
188
+
189
+ it "logs to warn" do
190
+ logger.warn("yo")
191
+
192
+ stdout.string.must_equal colorize("$$$$$$ yo", opts[:color]) + "\n"
193
+ end
194
+
195
+ it "logs to warn with no color" do
196
+ Kitchen.stubs(:tty?).returns(false)
197
+ logger.warn("yo")
198
+
199
+ stdout.string.must_equal "$$$$$$ yo\n"
200
+ end
201
+
202
+ it "logs to fatal" do
203
+ logger.fatal("yo")
204
+
205
+ stdout.string.must_equal colorize("!!!!!! yo", opts[:color]) + "\n"
206
+ end
207
+
208
+ it "logs to fatal with no color" do
209
+ Kitchen.stubs(:tty?).returns(false)
210
+ logger.fatal("yo")
211
+
212
+ stdout.string.must_equal "!!!!!! yo\n"
213
+ end
214
+
215
+ it "logs to unknown" do
216
+ logger.unknown("yo")
217
+
218
+ stdout.string.must_equal colorize("?????? yo", opts[:color]) + "\n"
219
+ end
220
+
221
+ it "logs to unknown with no color" do
222
+ Kitchen.stubs(:tty?).returns(false)
223
+ logger.unknown("yo")
224
+
225
+ stdout.string.must_equal "?????? yo\n"
226
+ end
227
+ end
228
+
229
+ describe "#<<" do
230
+
231
+ it "message with a newline are logged on info" do
232
+ logger << "yo\n"
233
+
234
+ stdout.string.must_equal colorize(" yo", opts[:color]) + "\n"
235
+ end
236
+
237
+ it "message with multiple newlines are separately logged on info" do
238
+ logger << "yo\nheya\n"
239
+
240
+ stdout.string.must_equal(
241
+ colorize(" yo", opts[:color]) + "\n" +
242
+ colorize(" heya", opts[:color]) + "\n"
243
+ )
244
+ end
245
+
246
+ it "message with info, error, and banner lines will be preserved" do
247
+ logger << [
248
+ "-----> banner",
249
+ " info",
250
+ ">>>>>> error",
251
+ "vanilla"
252
+ ].join("\n").concat("\n")
253
+
254
+ stdout.string.must_equal(
255
+ colorize("-----> banner", opts[:color]) + "\n" +
256
+ colorize(" info", opts[:color]) + "\n" +
257
+ colorize(">>>>>> error", opts[:color]) + "\n" +
258
+ colorize(" vanilla", opts[:color]) + "\n"
259
+ )
260
+ end
261
+
262
+ it "message with line that is not newline terminated will be buffered" do
263
+ logger << [
264
+ "-----> banner",
265
+ " info",
266
+ "partial"
267
+ ].join("\n")
268
+
269
+ stdout.string.must_equal(
270
+ colorize("-----> banner", opts[:color]) + "\n" +
271
+ colorize(" info", opts[:color]) + "\n"
272
+ )
273
+ end
274
+
275
+ it "logger with buffered data will flush on next message with newline" do
276
+ logger << "partial"
277
+ logger << "ly\nokay\n"
278
+
279
+ stdout.string.must_equal(
280
+ colorize(" partially", opts[:color]) + "\n" +
281
+ colorize(" okay", opts[:color]) + "\n"
282
+ )
283
+ end
284
+
285
+ it "logger that receives mixed first chunk will flush next message with newline" do
286
+ logger << "partially\no"
287
+ logger << "kay\n"
288
+
289
+ stdout.string.must_equal(
290
+ colorize(" partially", opts[:color]) + "\n" +
291
+ colorize(" okay", opts[:color]) + "\n"
292
+ )
293
+ end
294
+
295
+ it "logger chomps carriage return characters" do
296
+ logger << [
297
+ "-----> banner\r",
298
+ "vanilla\r"
299
+ ].join("\n").concat("\n")
300
+
301
+ stdout.string.must_equal(
302
+ colorize("-----> banner", opts[:color]) + "\n" +
303
+ colorize(" vanilla", opts[:color]) + "\n"
304
+ )
305
+ end
306
+ end
307
+ end
308
+
309
+ describe "opened IO logdev-based logger" do
310
+
311
+ let(:logdev) { StringIO.new }
312
+
313
+ before { opts[:logdev] = logdev }
314
+
315
+ describe "for severity" do
316
+
317
+ before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
318
+
319
+ let(:ts) { "\\[[^\\]]+\\]" }
320
+
321
+ it "logs to banner" do
322
+ logger.banner("yo")
323
+
324
+ logdev.string.must_match(/^I, #{ts} INFO -- Kitchen: -----> yo$/)
325
+ end
326
+
327
+ it "logs to debug" do
328
+ logger.debug("yo")
329
+
330
+ logdev.string.must_match(/^D, #{ts} DEBUG -- Kitchen: yo$/)
331
+ end
332
+
333
+ it "logs to info" do
334
+ logger.info("yo")
335
+
336
+ logdev.string.must_match(/^I, #{ts} INFO -- Kitchen: yo$/)
337
+ end
338
+
339
+ it "logs to error" do
340
+ logger.error("yo")
341
+
342
+ logdev.string.must_match(/^E, #{ts} ERROR -- Kitchen: yo$/)
343
+ end
344
+
345
+ it "logs to warn" do
346
+ logger.warn("yo")
347
+
348
+ logdev.string.must_match(/^W, #{ts} WARN -- Kitchen: yo$/)
349
+ end
350
+
351
+ it "logs to fatal" do
352
+ logger.fatal("yo")
353
+
354
+ logdev.string.must_match(/^F, #{ts} FATAL -- Kitchen: yo$/)
355
+ end
356
+
357
+ it "logs to unknown" do
358
+ logger.unknown("yo")
359
+
360
+ logdev.string.must_match(/^A, #{ts} ANY -- Kitchen: yo$/)
361
+ end
362
+ end
363
+ end
364
+
365
+ describe "file IO logdev-based logger" do
366
+
367
+ let(:logfile) { Dir::Tmpname.make_tmpname(%w[kitchen .log], nil) }
368
+
369
+ before do
370
+ opts[:logdev] = logfile
371
+ FakeFS.activate!
372
+ FileUtils.mkdir_p("/tmp")
373
+ end
374
+
375
+ after do
376
+ FakeFS.deactivate!
377
+ FakeFS::FileSystem.clear
378
+ end
379
+
380
+ describe "for severity" do
381
+
382
+ before { opts[:level] = Kitchen::Util.to_logger_level(:debug) }
383
+
384
+ let(:ts) { "\\[[^\\]]+\\]" }
385
+
386
+ it "logs to banner" do
387
+ logger.banner("yo")
388
+
389
+ IO.read(logfile).must_match(/^I, #{ts} INFO -- Kitchen: -----> yo$/)
390
+ end
391
+
392
+ it "logs to debug" do
393
+ logger.debug("yo")
394
+
395
+ IO.read(logfile).must_match(/^D, #{ts} DEBUG -- Kitchen: yo$/)
396
+ end
397
+
398
+ it "logs to info" do
399
+ logger.info("yo")
400
+
401
+ IO.read(logfile).must_match(/^I, #{ts} INFO -- Kitchen: yo$/)
402
+ end
403
+
404
+ it "logs to error" do
405
+ logger.error("yo")
406
+
407
+ IO.read(logfile).must_match(/^E, #{ts} ERROR -- Kitchen: yo$/)
408
+ end
409
+
410
+ it "logs to warn" do
411
+ logger.warn("yo")
412
+
413
+ IO.read(logfile).must_match(/^W, #{ts} WARN -- Kitchen: yo$/)
414
+ end
415
+
416
+ it "logs to fatal" do
417
+ logger.fatal("yo")
418
+
419
+ IO.read(logfile).must_match(/^F, #{ts} FATAL -- Kitchen: yo$/)
420
+ end
421
+
422
+ it "logs to unknown" do
423
+ logger.unknown("yo")
424
+
425
+ IO.read(logfile).must_match(/^A, #{ts} ANY -- Kitchen: yo$/)
426
+ end
427
+ end
428
+ end
429
+ end