test-kitchen 1.23.3 → 1.23.4

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 (254) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kitchen/version.rb +1 -1
  3. data/support/chef-client-zero.rb +1 -1
  4. metadata +5 -324
  5. data/.gitattributes +0 -3
  6. data/.github/ISSUE_TEMPLATE.md +0 -56
  7. data/.github/lock.yml +0 -1
  8. data/.gitignore +0 -38
  9. data/.gitmodules +0 -0
  10. data/.kitchen.appveyor.yml +0 -25
  11. data/.kitchen.dokken.yml +0 -31
  12. data/.kitchen.proxy.yml +0 -27
  13. data/.rubocop.yml +0 -5
  14. data/.travis.yml +0 -57
  15. data/.yardopts +0 -3
  16. data/Berksfile +0 -3
  17. data/CHANGELOG.md +0 -1510
  18. data/CONTRIBUTING.md +0 -14
  19. data/ECOSYSTEM.md +0 -93
  20. data/Gemfile +0 -40
  21. data/Gemfile.proxy_tests +0 -4
  22. data/Guardfile +0 -42
  23. data/MAINTAINERS.md +0 -29
  24. data/README.md +0 -138
  25. data/RELEASE_NOTES.md +0 -167
  26. data/Rakefile +0 -77
  27. data/appveyor.yml +0 -47
  28. data/docs/CONTRIBUTING.md +0 -8
  29. data/docs/LICENSE +0 -22
  30. data/docs/README.md +0 -78
  31. data/docs/archetypes/default.md +0 -6
  32. data/docs/config.toml +0 -36
  33. data/docs/content/docs/_index.md +0 -5
  34. data/docs/content/docs/drivers/_index.md +0 -27
  35. data/docs/content/docs/drivers/azurerm.md +0 -44
  36. data/docs/content/docs/drivers/vagrant.md +0 -39
  37. data/docs/content/docs/getting-started/00-introduction.md +0 -14
  38. data/docs/content/docs/getting-started/01-installing.md +0 -64
  39. data/docs/content/docs/getting-started/02-getting-help.md +0 -59
  40. data/docs/content/docs/getting-started/03-creating-cookbook.md +0 -46
  41. data/docs/content/docs/getting-started/04-kitchen-yml.md +0 -56
  42. data/docs/content/docs/getting-started/05-instances.md +0 -79
  43. data/docs/content/docs/getting-started/06-writing-recipe.md +0 -21
  44. data/docs/content/docs/getting-started/07-running-converge.md +0 -134
  45. data/docs/content/docs/getting-started/08-manually-verifying.md +0 -55
  46. data/docs/content/docs/getting-started/09-writing-test.md +0 -49
  47. data/docs/content/docs/getting-started/10-running-verify.md +0 -120
  48. data/docs/content/docs/getting-started/11-running-test.md +0 -168
  49. data/docs/content/docs/getting-started/12-adding-platform.md +0 -206
  50. data/docs/content/docs/getting-started/13-adding-feature.md +0 -30
  51. data/docs/content/docs/getting-started/14-adding-suite.md +0 -60
  52. data/docs/content/docs/getting-started/15-adding-test.md +0 -66
  53. data/docs/content/docs/getting-started/16-adding-recipe.md +0 -53
  54. data/docs/content/docs/getting-started/17-excluding-platforms.md +0 -101
  55. data/docs/content/docs/getting-started/18-next-steps.md +0 -23
  56. data/docs/content/docs/getting-started/_index.md +0 -5
  57. data/docs/content/docs/provisioners/_index.md +0 -36
  58. data/docs/content/docs/provisioners/chef.md +0 -69
  59. data/docs/content/docs/provisioners/shell.md +0 -31
  60. data/docs/content/docs/reference/_index.md +0 -5
  61. data/docs/content/docs/reference/configuration.md +0 -53
  62. data/docs/content/docs/reference/examples.md +0 -97
  63. data/docs/content/docs/reference/faq.md +0 -58
  64. data/docs/content/docs/reference/fixtures.md +0 -32
  65. data/docs/content/docs/reference/glossary.md +0 -34
  66. data/docs/content/docs/reference/lifecycle-hooks.md +0 -68
  67. data/docs/content/docs/reference/reboots.md +0 -24
  68. data/docs/content/docs/verifiers/_index.md +0 -14
  69. data/docs/content/docs/verifiers/inspec.md +0 -44
  70. data/docs/content/docs/verifiers/serverspec.md +0 -20
  71. data/docs/static/images/chef-logo.png +0 -0
  72. data/docs/static/images/chef-logo.svg +0 -1
  73. data/docs/static/images/github-banner.png +0 -0
  74. data/docs/static/images/github-banner.svg +0 -71
  75. data/docs/static/images/kitchen-logo.png +0 -0
  76. data/docs/static/images/logo-block.svg +0 -222
  77. data/docs/static/images/logo.png +0 -0
  78. data/docs/static/images/logos-group.png +0 -0
  79. data/docs/static/images/terminal-1.png +0 -0
  80. data/docs/static/images/terminal-1.svg +0 -589
  81. data/docs/static/images/terminal-2.png +0 -0
  82. data/docs/static/images/terminal-2.svg +0 -235
  83. data/docs/static/images/terminal-3.png +0 -0
  84. data/docs/static/images/terminal-3.svg +0 -439
  85. data/docs/static/index.html +0 -59
  86. data/docs/static/javascripts/all.js +0 -348
  87. data/docs/static/javascripts/vendor/foundation.min.js +0 -4
  88. data/docs/static/javascripts/vendor/jquery.min.js +0 -5
  89. data/docs/static/javascripts/vendor/what-input.js +0 -336
  90. data/docs/static/stylesheets/site.css +0 -4667
  91. data/docs/themes/kitchen/layouts/_default/baseof.html +0 -53
  92. data/docs/themes/kitchen/layouts/_default/list.html +0 -4
  93. data/docs/themes/kitchen/layouts/_default/redirect.html +0 -10
  94. data/docs/themes/kitchen/layouts/_default/single.html +0 -6
  95. data/docs/themes/kitchen/layouts/partials/core/head.html +0 -6
  96. data/docs/themes/kitchen/layouts/partials/kitchen/footer.html +0 -18
  97. data/docs/themes/kitchen/layouts/partials/kitchen/head.html +0 -4
  98. data/docs/themes/kitchen/layouts/partials/kitchen/header.html +0 -26
  99. data/docs/themes/kitchen/layouts/partials/search-docs.html +0 -3
  100. data/docs/themes/kitchen/layouts/partials/sidebar.html +0 -33
  101. data/docs/themes/kitchen/layouts/shortcodes/button.html +0 -1
  102. data/docs/themes/kitchen/layouts/shortcodes/codeblock.html +0 -8
  103. data/docs/themes/kitchen/layouts/shortcodes/cta.html +0 -5
  104. data/docs/themes/kitchen/layouts/shortcodes/danger.html +0 -1
  105. data/docs/themes/kitchen/layouts/shortcodes/example_fqdn.html +0 -1
  106. data/docs/themes/kitchen/layouts/shortcodes/info.html +0 -1
  107. data/docs/themes/kitchen/layouts/shortcodes/ol-styled.html +0 -3
  108. data/docs/themes/kitchen/layouts/shortcodes/success.html +0 -1
  109. data/docs/themes/kitchen/layouts/shortcodes/tip.html +0 -1
  110. data/docs/themes/kitchen/layouts/shortcodes/warning.html +0 -1
  111. data/docs/themes/kitchen/static/css/kitchen.css +0 -10
  112. data/docs/themes/kitchen/static/css/kitchen.css.map +0 -7
  113. data/docs/themes/kitchen/static/fonts/Muli-Bold.ttf +0 -0
  114. data/docs/themes/kitchen/static/fonts/Muli-Regular.ttf +0 -0
  115. data/docs/themes/kitchen/static/fonts/Muli-SemiBold.ttf +0 -0
  116. data/docs/themes/kitchen/static/fonts/fontawesome/fa-brands-400.eot +0 -0
  117. data/docs/themes/kitchen/static/fonts/fontawesome/fa-brands-400.svg +0 -1104
  118. data/docs/themes/kitchen/static/fonts/fontawesome/fa-brands-400.ttf +0 -0
  119. data/docs/themes/kitchen/static/fonts/fontawesome/fa-brands-400.woff +0 -0
  120. data/docs/themes/kitchen/static/fonts/fontawesome/fa-brands-400.woff2 +0 -0
  121. data/docs/themes/kitchen/static/fonts/fontawesome/fa-regular-400.eot +0 -0
  122. data/docs/themes/kitchen/static/fonts/fontawesome/fa-regular-400.svg +0 -372
  123. data/docs/themes/kitchen/static/fonts/fontawesome/fa-regular-400.ttf +0 -0
  124. data/docs/themes/kitchen/static/fonts/fontawesome/fa-regular-400.woff +0 -0
  125. data/docs/themes/kitchen/static/fonts/fontawesome/fa-regular-400.woff2 +0 -0
  126. data/docs/themes/kitchen/static/fonts/fontawesome/fa-solid-900.eot +0 -0
  127. data/docs/themes/kitchen/static/fonts/fontawesome/fa-solid-900.svg +0 -1896
  128. data/docs/themes/kitchen/static/fonts/fontawesome/fa-solid-900.ttf +0 -0
  129. data/docs/themes/kitchen/static/fonts/fontawesome/fa-solid-900.woff +0 -0
  130. data/docs/themes/kitchen/static/fonts/fontawesome/fa-solid-900.woff2 +0 -0
  131. data/docs/themes/kitchen/static/images/chef-logo-light.svg +0 -36
  132. data/docs/themes/kitchen/static/images/chef-logo-white.svg +0 -38
  133. data/docs/themes/kitchen/static/images/chef-logo.svg +0 -37
  134. data/docs/themes/kitchen/static/images/favicon.ico +0 -0
  135. data/docs/themes/kitchen/static/js/scripts-all.js +0 -7
  136. data/docs/themes/kitchen/static/js/source/chef-hugo.js +0 -116
  137. data/docs/themes/kitchen/static/js/source/omnitruck.js +0 -82
  138. data/docs/themes/kitchen/static/js/source/segment.js +0 -52
  139. data/docs/themes/kitchen/static/sass/_buttons.scss +0 -161
  140. data/docs/themes/kitchen/static/sass/_core.scss +0 -24
  141. data/docs/themes/kitchen/static/sass/_forms.scss +0 -14
  142. data/docs/themes/kitchen/static/sass/_mixins.scss +0 -133
  143. data/docs/themes/kitchen/static/sass/_typography.scss +0 -34
  144. data/docs/themes/kitchen/static/sass/_variables.scss +0 -82
  145. data/docs/themes/kitchen/static/sass/kitchen.scss +0 -7
  146. data/docs/themes/kitchen/static/sass/kitchen/_footer.scss +0 -50
  147. data/docs/themes/kitchen/static/sass/kitchen/_header.scss +0 -187
  148. data/docs/themes/kitchen/static/sass/kitchen/_homepage.scss +0 -27
  149. data/docs/themes/kitchen/static/sass/kitchen/_utility-bar.scss +0 -173
  150. data/docs/themes/kitchen/static/sass/partials/_alerts.scss +0 -32
  151. data/docs/themes/kitchen/static/sass/partials/_bg.scss +0 -19
  152. data/docs/themes/kitchen/static/sass/partials/_blurbs.scss +0 -25
  153. data/docs/themes/kitchen/static/sass/partials/_callout.scss +0 -15
  154. data/docs/themes/kitchen/static/sass/partials/_cards.scss +0 -54
  155. data/docs/themes/kitchen/static/sass/partials/_dropdown.scss +0 -77
  156. data/docs/themes/kitchen/static/sass/partials/_grid.scss +0 -87
  157. data/docs/themes/kitchen/static/sass/partials/_padding.scss +0 -73
  158. data/docs/themes/kitchen/static/sass/partials/_sidebar.scss +0 -71
  159. data/docs/themes/kitchen/static/sass/partials/_tabs.scss +0 -125
  160. data/docs/themes/kitchen/static/sass/typography/_chroma.scss +0 -366
  161. data/docs/themes/kitchen/static/sass/typography/_code.scss +0 -72
  162. data/docs/themes/kitchen/static/sass/typography/_headers.scss +0 -90
  163. data/docs/themes/kitchen/static/sass/typography/_links.scss +0 -127
  164. data/docs/themes/kitchen/static/sass/typography/_lists.scss +0 -155
  165. data/docs/themes/kitchen/static/sass/typography/_prose.scss +0 -29
  166. data/docs/themes/kitchen/static/sass/typography/_text.scss +0 -221
  167. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_animated.scss +0 -20
  168. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_bordered-pulled.scss +0 -20
  169. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_core.scss +0 -16
  170. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_fixed-width.scss +0 -6
  171. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_icons.scss +0 -992
  172. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_larger.scss +0 -23
  173. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_list.scss +0 -18
  174. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_mixins.scss +0 -57
  175. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_rotated-flipped.scss +0 -23
  176. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_screen-reader.scss +0 -5
  177. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_stacked.scss +0 -31
  178. data/docs/themes/kitchen/static/sass/vendor/fontawesome/_variables.scss +0 -1005
  179. data/docs/themes/kitchen/static/sass/vendor/fontawesome/fa-brands.scss +0 -21
  180. data/docs/themes/kitchen/static/sass/vendor/fontawesome/fa-regular.scss +0 -22
  181. data/docs/themes/kitchen/static/sass/vendor/fontawesome/fa-solid.scss +0 -23
  182. data/docs/themes/kitchen/static/sass/vendor/fontawesome/fontawesome.scss +0 -16
  183. data/docs/themes/kitchen/theme.toml +0 -8
  184. data/features/kitchen_action_commands.feature +0 -164
  185. data/features/kitchen_command.feature +0 -16
  186. data/features/kitchen_console_command.feature +0 -35
  187. data/features/kitchen_defaults.feature +0 -38
  188. data/features/kitchen_diagnose_command.feature +0 -96
  189. data/features/kitchen_help_command.feature +0 -16
  190. data/features/kitchen_init_command.feature +0 -254
  191. data/features/kitchen_list_command.feature +0 -140
  192. data/features/kitchen_login_command.feature +0 -62
  193. data/features/kitchen_sink_command.feature +0 -30
  194. data/features/kitchen_test_command.feature +0 -88
  195. data/features/step_definitions/gem_steps.rb +0 -24
  196. data/features/step_definitions/git_steps.rb +0 -5
  197. data/features/step_definitions/output_steps.rb +0 -5
  198. data/features/support/env.rb +0 -74
  199. data/spec/kitchen/base64_stream_spec.rb +0 -74
  200. data/spec/kitchen/cli_spec.rb +0 -54
  201. data/spec/kitchen/collection_spec.rb +0 -76
  202. data/spec/kitchen/color_spec.rb +0 -51
  203. data/spec/kitchen/config_spec.rb +0 -434
  204. data/spec/kitchen/configurable_spec.rb +0 -1113
  205. data/spec/kitchen/data_munger_spec.rb +0 -2800
  206. data/spec/kitchen/diagnostic_spec.rb +0 -128
  207. data/spec/kitchen/driver/base_spec.rb +0 -132
  208. data/spec/kitchen/driver/dummy_spec.rb +0 -193
  209. data/spec/kitchen/driver/exec_spec.rb +0 -75
  210. data/spec/kitchen/driver/proxy_spec.rb +0 -127
  211. data/spec/kitchen/driver/ssh_base_spec.rb +0 -1136
  212. data/spec/kitchen/driver_spec.rb +0 -106
  213. data/spec/kitchen/errors_spec.rb +0 -317
  214. data/spec/kitchen/instance_spec.rb +0 -1372
  215. data/spec/kitchen/lazy_hash_spec.rb +0 -113
  216. data/spec/kitchen/lifecycle_hooks_spec.rb +0 -171
  217. data/spec/kitchen/loader/yaml_spec.rb +0 -787
  218. data/spec/kitchen/logger_spec.rb +0 -425
  219. data/spec/kitchen/logging_spec.rb +0 -56
  220. data/spec/kitchen/login_command_spec.rb +0 -67
  221. data/spec/kitchen/metadata_chopper_spec.rb +0 -79
  222. data/spec/kitchen/platform_spec.rb +0 -88
  223. data/spec/kitchen/provisioner/base_spec.rb +0 -393
  224. data/spec/kitchen/provisioner/chef/policyfile_spec.rb +0 -140
  225. data/spec/kitchen/provisioner/chef_apply_spec.rb +0 -131
  226. data/spec/kitchen/provisioner/chef_base_spec.rb +0 -1565
  227. data/spec/kitchen/provisioner/chef_solo_spec.rb +0 -602
  228. data/spec/kitchen/provisioner/chef_zero_spec.rb +0 -1013
  229. data/spec/kitchen/provisioner/dummy_spec.rb +0 -96
  230. data/spec/kitchen/provisioner/shell_spec.rb +0 -623
  231. data/spec/kitchen/provisioner_spec.rb +0 -101
  232. data/spec/kitchen/shell_out_spec.rb +0 -146
  233. data/spec/kitchen/ssh_spec.rb +0 -584
  234. data/spec/kitchen/state_file_spec.rb +0 -122
  235. data/spec/kitchen/suite_spec.rb +0 -61
  236. data/spec/kitchen/transport/base_spec.rb +0 -140
  237. data/spec/kitchen/transport/exec_spec.rb +0 -79
  238. data/spec/kitchen/transport/ssh_spec.rb +0 -1317
  239. data/spec/kitchen/transport/winrm_spec.rb +0 -1320
  240. data/spec/kitchen/transport_spec.rb +0 -106
  241. data/spec/kitchen/util_spec.rb +0 -250
  242. data/spec/kitchen/verifier/base_spec.rb +0 -346
  243. data/spec/kitchen/verifier/busser_spec.rb +0 -580
  244. data/spec/kitchen/verifier/dummy_spec.rb +0 -96
  245. data/spec/kitchen/verifier/shell_spec.rb +0 -157
  246. data/spec/kitchen/verifier_spec.rb +0 -114
  247. data/spec/kitchen_spec.rb +0 -112
  248. data/spec/spec_helper.rb +0 -110
  249. data/spec/support/powershell_max_size_spec.rb +0 -39
  250. data/test-kitchen.gemspec +0 -49
  251. data/test/cookbooks/test_cookbook/metadata.rb +0 -6
  252. data/test/cookbooks/test_cookbook/recipes/default.rb +0 -1
  253. data/test/integration/default/default_spec.rb +0 -3
  254. data/testing_windows.md +0 -38
@@ -1,101 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2013, 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/configurable"
22
- require "kitchen/errors"
23
- require "kitchen/logging"
24
- require "kitchen/provisioner"
25
- require "kitchen/provisioner/base"
26
-
27
- module Kitchen
28
- module Provisioner
29
- class Coolbeans < Kitchen::Provisioner::Base
30
- end
31
-
32
- class ItDepends < Kitchen::Provisioner::Base
33
- attr_reader :verify_call_count
34
-
35
- def initialize(config = {})
36
- @verify_call_count = 0
37
- super
38
- end
39
-
40
- def verify_dependencies
41
- @verify_call_count += 1
42
- end
43
- end
44
-
45
- class UnstableDepends < Kitchen::Provisioner::Base
46
- def verify_dependencies
47
- raise UserError, "Oh noes, you don't have software!"
48
- end
49
- end
50
- end
51
- end
52
-
53
- describe Kitchen::Provisioner do
54
- describe ".for_plugin" do
55
- before do
56
- Kitchen::Provisioner.stubs(:require).returns(true)
57
- end
58
-
59
- it "returns a provisioner object of the correct class" do
60
- provisioner = Kitchen::Provisioner.for_plugin("coolbeans", {})
61
-
62
- provisioner.must_be_kind_of Kitchen::Provisioner::Coolbeans
63
- end
64
-
65
- it "returns a provisioner initialized with its config" do
66
- provisioner = Kitchen::Provisioner.for_plugin("coolbeans", foo: "bar")
67
-
68
- provisioner[:foo].must_equal "bar"
69
- end
70
-
71
- it "calls #verify_dependencies on the provisioner object" do
72
- provisioner = Kitchen::Provisioner.for_plugin("it_depends", {})
73
-
74
- provisioner.verify_call_count.must_equal 1
75
- end
76
-
77
- it "calls #verify_dependencies once per provisioner require" do
78
- Kitchen::Provisioner.stubs(:require).returns(true, false)
79
- provisioner1 = Kitchen::Provisioner.for_plugin("it_depends", {})
80
- provisioner1.verify_call_count.must_equal 1
81
- provisioner2 = Kitchen::Provisioner.for_plugin("it_depends", {})
82
-
83
- provisioner2.verify_call_count.must_equal 0
84
- end
85
-
86
- it "raises ClientError if the provisioner could not be required" do
87
- Kitchen::Provisioner.stubs(:require).raises(LoadError)
88
-
89
- proc { Kitchen::Provisioner.for_plugin("coolbeans", {}) }
90
- .must_raise Kitchen::ClientError
91
- end
92
-
93
- it "raises ClientError if the provisioner's class constant was not found" do
94
- # pretend require worked
95
- Kitchen::Provisioner.stubs(:require).returns(true)
96
-
97
- proc { Kitchen::Provisioner.for_plugin("nope", {}) }
98
- .must_raise Kitchen::ClientError
99
- end
100
- end
101
- end
@@ -1,146 +0,0 @@
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/errors"
22
- require "kitchen/shell_out"
23
- require "kitchen/util"
24
-
25
- module Kitchen
26
- class Shelly
27
- include Kitchen::ShellOut
28
-
29
- attr_reader :logs
30
-
31
- def debug(msg)
32
- @logs ||= []
33
- @logs << msg
34
- end
35
-
36
- def logger
37
- "alogger"
38
- end
39
- end
40
- end
41
-
42
- describe Kitchen::ShellOut do
43
- let(:command) do
44
- stub(
45
- run_command: true,
46
- error!: true,
47
- stdout: "",
48
- execution_time: 123
49
- )
50
- end
51
-
52
- let(:subject) { Kitchen::Shelly.new }
53
-
54
- describe "#run_command" do
55
- let(:opts) do
56
- { live_stream: "alogger", timeout: 60_000 }
57
- end
58
-
59
- before do
60
- Mixlib::ShellOut.stubs(:new).returns(command)
61
- end
62
-
63
- it "builds a Mixlib::ShellOut object with default options" do
64
- Mixlib::ShellOut.unstub(:new)
65
- Mixlib::ShellOut.expects(:new).with("yoyo", opts).returns(command)
66
-
67
- subject.run_command("yoyo")
68
- end
69
-
70
- [:timeout, :cwd, :environment].each do |attr|
71
- it "builds a Mixlib::ShellOut object with a custom #{attr}" do
72
- opts[attr] = "custom"
73
-
74
- Mixlib::ShellOut.unstub(:new)
75
- Mixlib::ShellOut.expects(:new).with("yoyo", opts).returns(command)
76
-
77
- subject.run_command("yoyo", attr => "custom")
78
- end
79
- end
80
-
81
- it "returns the command's standard out" do
82
- command.stubs(:stdout).returns("sweetness")
83
-
84
- subject.run_command("icecream").must_equal "sweetness"
85
- end
86
-
87
- it "raises a ShellCommandFailed if the command does not cleanly exit" do
88
- command.stubs(:error!)
89
- .raises(Mixlib::ShellOut::ShellCommandFailed, "boom bad")
90
-
91
- err = proc { subject.run_command("boom") }
92
- .must_raise Kitchen::ShellOut::ShellCommandFailed
93
- err.message.must_equal "boom bad"
94
- end
95
-
96
- it "raises a Kitchen::Errror tagged exception for unknown exceptions" do
97
- command.stubs(:error!).raises(IOError, "boom bad")
98
-
99
- err = proc { subject.run_command("boom") }.must_raise IOError
100
- err.must_be_kind_of Kitchen::Error
101
- err.message.must_equal "boom bad"
102
- end
103
-
104
- it "prepends with sudo if :use_sudo is truthy" do
105
- Mixlib::ShellOut.unstub(:new)
106
- Mixlib::ShellOut.expects(:new).with("sudo -E yo", opts).returns(command)
107
-
108
- subject.run_command("yo", use_sudo: true)
109
- end
110
-
111
- it "prepends with custom :sudo_command if :use_sudo is truthy" do
112
- Mixlib::ShellOut.unstub(:new)
113
- Mixlib::ShellOut.expects(:new).with("wat yo", opts).returns(command)
114
-
115
- subject.run_command("yo", use_sudo: true, sudo_command: "wat")
116
- end
117
-
118
- it "logs a debug BEGIN message" do
119
- subject.run_command("echo whoopa\ndoopa\ndo")
120
-
121
- subject.logs.first
122
- .must_equal "[local command] BEGIN (echo whoopa\ndoopa\ndo)"
123
- end
124
-
125
- it "logs a debug BEGIN message with custom log subject" do
126
- subject.run_command("tenac", log_subject: "thed")
127
-
128
- subject.logs.first.must_equal "[thed command] BEGIN (tenac)"
129
- end
130
-
131
- it "truncates the debug BEGIN command if it spans multiple lines" do
132
- end
133
-
134
- it "logs a debug END message" do
135
- subject.run_command("echo whoopa doopa")
136
-
137
- subject.logs.last.must_equal "[local command] END (2m3.00s)"
138
- end
139
-
140
- it "logs a debug END message with custom log subject" do
141
- subject.run_command("tenac", log_subject: "thed")
142
-
143
- subject.logs.last.must_equal "[thed command] END (2m3.00s)"
144
- end
145
- end
146
- end
@@ -1,584 +0,0 @@
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/ssh"
22
- require "tmpdir"
23
- require "net/ssh/test"
24
-
25
- describe Kitchen::SSH do
26
- include Net::SSH::Test
27
-
28
- let(:logged_output) { StringIO.new }
29
- let(:logger) { Logger.new(logged_output) }
30
- let(:opts) { Hash.new }
31
- let(:ssh) { Kitchen::SSH.new("foo", "me", opts) }
32
- let(:conn) { Net::SSH::Test::Extensions::IO.with_test_extension { connection } }
33
-
34
- before do
35
- logger.level = Logger::DEBUG
36
- opts[:logger] = logger
37
- Net::SSH.stubs(:start).returns(conn)
38
- end
39
-
40
- describe "establishing a connection" do
41
- [
42
- Errno::EACCES, Errno::EADDRINUSE, Errno::ECONNREFUSED,
43
- Errno::ECONNRESET, Errno::ENETUNREACH, Errno::EHOSTUNREACH,
44
- Net::SSH::Disconnect, Net::SSH::AuthenticationFailed, Net::SSH::ConnectionTimeout
45
- ].each do |klass|
46
- describe "raising #{klass}" do
47
- before do
48
- Net::SSH.stubs(:start).raises(klass)
49
- opts[:ssh_retries] = 3
50
- ssh.stubs(:sleep)
51
- end
52
-
53
- it "reraises the #{klass} exception" do
54
- proc { ssh.exec("nope") }.must_raise klass
55
- end
56
-
57
- it "attempts to connect ':ssh_retries' times" do
58
- begin
59
- ssh.exec("nope")
60
- rescue # rubocop:disable Lint/HandleExceptions
61
- end
62
-
63
- logged_output.string.lines.count do |l|
64
- l =~ debug_line("[SSH] opening connection to me@foo:22<{:ssh_retries=>3}>")
65
- end.must_equal opts[:ssh_retries]
66
- end
67
-
68
- it "sleeps for 1 second between retries" do
69
- ssh.unstub(:sleep)
70
- ssh.expects(:sleep).with(1).twice
71
-
72
- begin
73
- ssh.exec("nope")
74
- rescue # rubocop:disable Lint/HandleExceptions
75
- end
76
- end
77
-
78
- it "logs the first 2 retry failures on info" do
79
- begin
80
- ssh.exec("nope")
81
- rescue # rubocop:disable Lint/HandleExceptions
82
- end
83
-
84
- logged_output.string.lines.count do |l|
85
- l =~ info_line_with("[SSH] connection failed, retrying ")
86
- end.must_equal 2
87
- end
88
-
89
- it "logs the last retry failures on warn" do
90
- begin
91
- ssh.exec("nope")
92
- rescue # rubocop:disable Lint/HandleExceptions
93
- end
94
-
95
- logged_output.string.lines.count do |l|
96
- l =~ warn_line_with("[SSH] connection failed, terminating ")
97
- end.must_equal 1
98
- end
99
- end
100
- end
101
- end
102
-
103
- describe "#exec" do
104
- describe "for a successful command" do
105
- before do
106
- story do |script|
107
- channel = script.opens_channel
108
- channel.sends_request_pty
109
- channel.sends_exec("doit")
110
- channel.gets_data("ok\n")
111
- channel.gets_extended_data("some stderr stuffs\n")
112
- channel.gets_exit_status(0)
113
- channel.gets_close
114
- channel.sends_close
115
- end
116
- end
117
-
118
- it "logger displays command on debug" do
119
- assert_scripted { ssh.exec("doit") }
120
-
121
- logged_output.string.must_match debug_line(
122
- "[SSH] me@foo:22<{}> (doit)"
123
- )
124
- end
125
-
126
- it "logger displays establishing connection on debug" do
127
- assert_scripted { ssh.exec("doit") }
128
-
129
- logged_output.string.must_match debug_line(
130
- "[SSH] opening connection to me@foo:22<{}>"
131
- )
132
- end
133
-
134
- it "logger captures stdout" do
135
- assert_scripted { ssh.exec("doit") }
136
-
137
- logged_output.string.must_match(/^ok$/)
138
- end
139
-
140
- it "logger captures stderr" do
141
- assert_scripted { ssh.exec("doit") }
142
-
143
- logged_output.string.must_match(/^some stderr stuffs$/)
144
- end
145
- end
146
-
147
- describe "for a failed command" do
148
- before do
149
- story do |script|
150
- channel = script.opens_channel
151
- channel.sends_request_pty
152
- channel.sends_exec("doit")
153
- channel.gets_data("nope\n")
154
- channel.gets_extended_data("youdead\n")
155
- channel.gets_exit_status(42)
156
- channel.gets_close
157
- channel.sends_close
158
- end
159
- end
160
-
161
- it "logger displays command on debug" do
162
- begin
163
- assert_scripted { ssh.exec("doit") }
164
- rescue # rubocop:disable Lint/HandleExceptions
165
- end
166
-
167
- logged_output.string.must_match debug_line(
168
- "[SSH] me@foo:22<{}> (doit)"
169
- )
170
- end
171
-
172
- it "logger displays establishing connection on debug" do
173
- begin
174
- assert_scripted { ssh.exec("doit") }
175
- rescue # rubocop:disable Lint/HandleExceptions
176
- end
177
-
178
- logged_output.string.must_match debug_line(
179
- "[SSH] opening connection to me@foo:22<{}>"
180
- )
181
- end
182
-
183
- it "logger captures stdout" do
184
- begin
185
- assert_scripted { ssh.exec("doit") }
186
- rescue # rubocop:disable Lint/HandleExceptions
187
- end
188
-
189
- logged_output.string.must_match(/^nope$/)
190
- end
191
-
192
- it "logger captures stderr" do
193
- begin
194
- assert_scripted { ssh.exec("doit") }
195
- rescue # rubocop:disable Lint/HandleExceptions
196
- end
197
-
198
- logged_output.string.must_match(/^youdead$/)
199
- end
200
-
201
- it "raises an SSHFailed exception" do
202
- err = proc { assert_scripted { ssh.exec("doit") } }.must_raise Kitchen::SSHFailed
203
- err.message.must_equal "SSH exited (42) for command: [doit]"
204
- end
205
- end
206
- end
207
-
208
- describe "#upload!" do
209
- let(:content) { "a" * 1234 }
210
-
211
- let(:src) do
212
- file = Tempfile.new("file")
213
- file.write("a" * 1234)
214
- file.close
215
- FileUtils.chmod(0755, file.path)
216
- file
217
- end
218
-
219
- before do
220
- expect_scp_session("-t /tmp/remote") do |channel|
221
- file_mode = running_tests_on_windows? ? 0644 : 0755
222
- channel.gets_data("\0")
223
- channel.sends_data("C#{padded_octal_string(file_mode)} 1234 #{File.basename(src.path)}\n")
224
- channel.gets_data("\0")
225
- channel.sends_data("a" * 1234)
226
- channel.sends_data("\0")
227
- channel.gets_data("\0")
228
- end
229
- end
230
-
231
- after do
232
- src.unlink
233
- end
234
-
235
- it "uploads a file to remote over scp" do
236
- assert_scripted do
237
- ssh.upload!(src.path, "/tmp/remote")
238
- end
239
- end
240
-
241
- it "logs upload progress to debug" do
242
- assert_scripted do
243
- ssh.upload!(src.path, "/tmp/remote")
244
- end
245
-
246
- logged_output.string.must_match debug_line(
247
- "[SSH] opening connection to me@foo:22<{}>"
248
- )
249
- logged_output.string.must_match debug_line(
250
- "Uploaded #{src.path} (1234 bytes)"
251
- )
252
- end
253
- end
254
-
255
- describe "#upload_path!" do
256
- before do
257
- @dir = Dir.mktmpdir("local")
258
-
259
- # Since File.chmod is a NOOP on Windows
260
- @tmp_dir_mode = running_tests_on_windows? ? 0755 : 0700
261
- @alpha_file_mode = running_tests_on_windows? ? 0644 : 0644
262
- @beta_file_mode = running_tests_on_windows? ? 0444 : 0555
263
-
264
- FileUtils.chmod(0700, @dir)
265
- File.open("#{@dir}/alpha", "wb") { |f| f.write("alpha-contents\n") }
266
- FileUtils.chmod(0644, "#{@dir}/alpha")
267
- FileUtils.mkdir_p("#{@dir}/subdir")
268
- FileUtils.chmod(0755, "#{@dir}/subdir")
269
- File.open("#{@dir}/subdir/beta", "wb") { |f| f.write("beta-contents\n") }
270
- FileUtils.chmod(0555, "#{@dir}/subdir/beta")
271
- File.open("#{@dir}/zulu", "wb") { |f| f.write("zulu-contents\n") }
272
- FileUtils.chmod(0444, "#{@dir}/zulu")
273
-
274
- expect_scp_session("-t -r /tmp/remote") do |channel|
275
- channel.gets_data("\0")
276
- channel.sends_data("D#{padded_octal_string(@tmp_dir_mode)} 0 #{File.basename(@dir)}\n")
277
- channel.gets_data("\0")
278
- channel.sends_data("C#{padded_octal_string(@alpha_file_mode)} 15 alpha\n")
279
- channel.gets_data("\0")
280
- channel.sends_data("alpha-contents\n")
281
- channel.sends_data("\0")
282
- channel.gets_data("\0")
283
- channel.sends_data("D0755 0 subdir\n")
284
- channel.gets_data("\0")
285
- channel.sends_data("C#{padded_octal_string(@beta_file_mode)} 14 beta\n")
286
- channel.gets_data("\0")
287
- channel.sends_data("beta-contents\n")
288
- channel.sends_data("\0")
289
- channel.gets_data("\0")
290
- channel.sends_data("E\n")
291
- channel.gets_data("\0")
292
- channel.sends_data("C0444 14 zulu\n")
293
- channel.gets_data("\0")
294
- channel.sends_data("zulu-contents\n")
295
- channel.sends_data("\0")
296
- channel.gets_data("\0")
297
- channel.sends_data("E\n")
298
- channel.gets_data("\0")
299
- end
300
- end
301
-
302
- after do
303
- FileUtils.remove_entry_secure(@dir)
304
- end
305
-
306
- it "uploads a file to remote over scp" do
307
- with_sorted_dir_entries do
308
- assert_scripted { ssh.upload_path!(@dir, "/tmp/remote") }
309
- end
310
- end
311
-
312
- it "logs upload progress to debug" do
313
- remote_base = "#{Dir.tmpdir}/#{File.basename(@dir)}"
314
-
315
- with_sorted_dir_entries do
316
- assert_scripted { ssh.upload_path!(@dir, "/tmp/remote") }
317
- end
318
-
319
- logged_output.string.must_match debug_line(
320
- "[SSH] opening connection to me@foo:22<{}>"
321
- )
322
- logged_output.string.must_match debug_line(
323
- "Uploaded #{remote_base}/alpha (15 bytes)"
324
- )
325
- logged_output.string.must_match debug_line(
326
- "Uploaded #{remote_base}/subdir/beta (14 bytes)"
327
- )
328
- logged_output.string.must_match debug_line(
329
- "Uploaded #{remote_base}/zulu (14 bytes)"
330
- )
331
- end
332
- end
333
-
334
- describe "#shutdown" do
335
- before do
336
- story do |script|
337
- channel = script.opens_channel
338
- channel.sends_request_pty
339
- channel.sends_exec("doit")
340
- channel.gets_data("ok\n")
341
- channel.gets_exit_status(0)
342
- channel.gets_close
343
- channel.sends_close
344
- end
345
- end
346
-
347
- it "logger displays closing connection on debug" do
348
- conn.expects(:shutdown!)
349
-
350
- assert_scripted do
351
- ssh.exec("doit")
352
- ssh.shutdown
353
- end
354
-
355
- logged_output.string.must_match debug_line(
356
- "[SSH] closing connection to me@foo:22<{}>"
357
- )
358
- end
359
-
360
- it "only closes the connection once for multiple calls" do
361
- conn.expects(:shutdown!).once
362
-
363
- assert_scripted do
364
- ssh.exec("doit")
365
- ssh.shutdown
366
- ssh.shutdown
367
- ssh.shutdown
368
- end
369
- end
370
- end
371
-
372
- describe "block form" do
373
- before do
374
- story do |script|
375
- channel = script.opens_channel
376
- channel.sends_request_pty
377
- channel.sends_exec("doit")
378
- channel.gets_data("ok\n")
379
- channel.gets_exit_status(0)
380
- channel.gets_close
381
- channel.sends_close
382
- end
383
- end
384
-
385
- it "shuts down the connection when block closes" do
386
- conn.expects(:shutdown!)
387
-
388
- Net::SSH::Test::Extensions::IO.with_test_extension do
389
- Kitchen::SSH.new("foo", "me", opts) do |ssh|
390
- ssh.exec("doit")
391
- end
392
- end
393
- end
394
- end
395
-
396
- describe "#login_command" do
397
- let(:login_command) { ssh.login_command }
398
- let(:args) { login_command.arguments.join(" ") }
399
-
400
- it "returns a LoginCommand" do
401
- login_command.must_be_instance_of Kitchen::LoginCommand
402
- end
403
-
404
- it "is an SSH command" do
405
- login_command.command.must_equal "ssh"
406
- args.must_match %r{ me@foo$}
407
- end
408
-
409
- it "sets the UserKnownHostsFile option" do
410
- args.must_match regexify("-o UserKnownHostsFile=/dev/null ")
411
- end
412
-
413
- it "sets the StrictHostKeyChecking option" do
414
- args.must_match regexify(" -o StrictHostKeyChecking=no ")
415
- end
416
-
417
- it "won't set IdentitiesOnly option by default" do
418
- args.wont_match regexify(" -o IdentitiesOnly=")
419
- end
420
-
421
- it "sets the IdentiesOnly option if :keys option is given" do
422
- opts[:keys] = ["yep"]
423
-
424
- args.must_match regexify(" -o IdentitiesOnly=yes ")
425
- end
426
-
427
- it "sets the LogLevel option to VERBOSE if logger is set to debug" do
428
- logger.level = ::Logger::DEBUG
429
- opts[:logger] = logger
430
-
431
- args.must_match regexify(" -o LogLevel=VERBOSE ")
432
- end
433
-
434
- it "sets the LogLevel option to ERROR if logger is not set to debug" do
435
- logger.level = ::Logger::INFO
436
- opts[:logger] = logger
437
-
438
- args.must_match regexify(" -o LogLevel=ERROR ")
439
- end
440
-
441
- it "won't set the ForwardAgent option by default" do
442
- args.wont_match regexify(" -o ForwardAgent=")
443
- end
444
-
445
- it "sets the ForwardAgent option to yes if truthy" do
446
- opts[:forward_agent] = "yep"
447
-
448
- args.must_match regexify(" -o ForwardAgent=yes")
449
- end
450
-
451
- it "sets the ForwardAgent option to no if falsey" do
452
- opts[:forward_agent] = false
453
-
454
- args.must_match regexify(" -o ForwardAgent=no")
455
- end
456
-
457
- it "won't add any SSH keys by default" do
458
- args.wont_match regexify(" -i ")
459
- end
460
-
461
- it "sets SSH keys options if given" do
462
- opts[:keys] = %w{one two}
463
-
464
- args.must_match regexify(" -i one ")
465
- args.must_match regexify(" -i two ")
466
- end
467
-
468
- it "sets the port option to 22 by default" do
469
- args.must_match regexify(" -p 22 ")
470
- end
471
-
472
- it "sets the port option" do
473
- opts[:port] = 1234
474
-
475
- args.must_match regexify(" -p 1234 ")
476
- end
477
- end
478
-
479
- describe "#test_ssh" do
480
- let(:tcp_socket) { stub(select_for_read?: true, close: true) }
481
-
482
- before { ssh.stubs(:sleep) }
483
-
484
- it "returns a truthy value" do
485
- TCPSocket.stubs(:new).returns(tcp_socket)
486
-
487
- Net::SSH::Test::Extensions::IO.with_test_extension do
488
- result = ssh.send(:test_ssh)
489
- result.wont_equal nil
490
- result.wont_equal false
491
- end
492
- end
493
-
494
- it "closes socket when finished" do
495
- TCPSocket.stubs(:new).returns(tcp_socket)
496
- tcp_socket.expects(:close)
497
-
498
- Net::SSH::Test::Extensions::IO.with_test_extension { ssh.send(:test_ssh) }
499
- end
500
-
501
- [
502
- SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH,
503
- Errno::ENETUNREACH, IOError
504
- ].each do |klass|
505
- describe "when #{klass} is raised" do
506
- before { TCPSocket.stubs(:new).raises(klass) }
507
-
508
- it "returns false" do
509
- ssh.send(:test_ssh).must_equal false
510
- end
511
-
512
- it "sleeps for 2 seconds" do
513
- ssh.expects(:sleep).with(2)
514
-
515
- ssh.send(:test_ssh)
516
- end
517
- end
518
- end
519
-
520
- [
521
- Errno::EPERM, Errno::ETIMEDOUT
522
- ].each do |klass|
523
- describe "when #{klass} is raised" do
524
- it "returns false when #{klass} is raised" do
525
- TCPSocket.stubs(:new).raises(klass)
526
-
527
- ssh.send(:test_ssh).must_equal false
528
- end
529
- end
530
- end
531
- end
532
-
533
- describe "#wait" do
534
- let(:not_ready) do
535
- stub(select_for_read?: false, idle!: true, close: true)
536
- end
537
-
538
- let(:ready) do
539
- stub(select_for_read?: true, close: true)
540
- end
541
-
542
- it "logs to info for each retry" do
543
- TCPSocket.stubs(:new).returns(not_ready, not_ready, ready)
544
- Net::SSH::Test::Extensions::IO.with_test_extension { ssh.wait }
545
-
546
- logged_output.string.lines.count do |l|
547
- l =~ info_line_with("Waiting for foo:22...")
548
- end.must_equal 2
549
- end
550
- end
551
-
552
- def expect_scp_session(args)
553
- story do |script|
554
- channel = script.opens_channel
555
- channel.sends_exec("scp #{args}")
556
- yield channel if block_given?
557
- channel.sends_eof
558
- channel.gets_exit_status(0)
559
- channel.gets_eof
560
- channel.gets_close
561
- channel.sends_close
562
- end
563
- end
564
-
565
- def regexify(string)
566
- Regexp.new(Regexp.escape(string))
567
- end
568
-
569
- def debug_line(msg)
570
- /^D, .* : #{Regexp.escape(msg)}$/
571
- end
572
-
573
- def debug_line_with(msg)
574
- /^D, .* : #{Regexp.escape(msg)}/
575
- end
576
-
577
- def info_line_with(msg)
578
- /^I, .* : #{Regexp.escape(msg)}/
579
- end
580
-
581
- def warn_line_with(msg)
582
- /^W, .* : #{Regexp.escape(msg)}/
583
- end
584
- end