test-kitchen 1.23.3 → 1.23.4

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