test-kitchen 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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