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,106 +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/shell_out"
25
- require "kitchen/driver"
26
- require "kitchen/driver/base"
27
-
28
- module Kitchen
29
- module Driver
30
- class Coolbeans < Kitchen::Driver::Base
31
- end
32
-
33
- class ItDepends < Kitchen::Driver::Base
34
- attr_reader :verify_call_count
35
-
36
- def initialize(config = {})
37
- @verify_call_count = 0
38
- super
39
- end
40
-
41
- def verify_dependencies
42
- @verify_call_count += 1
43
- end
44
- end
45
-
46
- class UnstableDepends < Kitchen::Driver::Base
47
- def verify_dependencies
48
- raise UserError, "Oh noes, you don't have software!"
49
- end
50
- end
51
- end
52
- end
53
-
54
- describe Kitchen::Driver do
55
- describe ".for_plugin" do
56
- before do
57
- Kitchen::Driver.stubs(:require).returns(true)
58
- end
59
-
60
- it "returns a driver object of the correct class" do
61
- driver = Kitchen::Driver.for_plugin("coolbeans", {})
62
-
63
- driver.must_be_kind_of Kitchen::Driver::Coolbeans
64
- end
65
-
66
- it "returns a driver initialized with its config" do
67
- driver = Kitchen::Driver.for_plugin("coolbeans", jelly: "beans")
68
-
69
- driver[:jelly].must_equal "beans"
70
- end
71
-
72
- it "calls #verify_dependencies on the driver object" do
73
- driver = Kitchen::Driver.for_plugin("it_depends", {})
74
-
75
- driver.verify_call_count.must_equal 1
76
- end
77
-
78
- it "calls #verify_dependencies once per driver require" do
79
- Kitchen::Driver.stubs(:require).returns(true, false)
80
- driver1 = Kitchen::Driver.for_plugin("it_depends", {})
81
- driver1.verify_call_count.must_equal 1
82
- driver2 = Kitchen::Driver.for_plugin("it_depends", {})
83
-
84
- driver2.verify_call_count.must_equal 0
85
- end
86
-
87
- it "raises ClientError if the driver could not be required" do
88
- Kitchen::Driver.stubs(:require).raises(LoadError)
89
-
90
- proc { Kitchen::Driver.for_plugin("coolbeans", {}) }
91
- .must_raise Kitchen::ClientError
92
- end
93
-
94
- it "raises ClientError if the driver's class constant could not be found" do
95
- Kitchen::Driver.stubs(:require).returns(true) # pretend require worked
96
-
97
- proc { Kitchen::Driver.for_plugin("nope", {}) }
98
- .must_raise Kitchen::ClientError
99
- end
100
-
101
- it "raises UserError if #verify_dependencies fails" do
102
- proc { Kitchen::Driver.for_plugin("unstable_depends", {}) }
103
- .must_raise Kitchen::UserError
104
- end
105
- end
106
- end
@@ -1,317 +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"
22
- require "kitchen/errors"
23
-
24
- describe Kitchen::Error do
25
- let(:exception) { Kitchen::StandardError.new("shoot") }
26
-
27
- describe ".formatted_exception" do
28
- it "returns an array of a formatted message" do
29
- Kitchen::Error.formatted_exception(exception).must_equal([
30
- "------Exception-------",
31
- "Class: Kitchen::StandardError",
32
- "Message: shoot",
33
- "----------------------",
34
- ])
35
- end
36
-
37
- it "takes a customized title" do
38
- Kitchen::Error.formatted_exception(exception, "Trouble").first
39
- .must_equal("-------Trouble--------")
40
- end
41
- end
42
-
43
- describe ".formatted_exception" do
44
- it "returns an array of a formatted message with a nil backtrace" do
45
- Kitchen::Error.formatted_trace(exception).must_equal([
46
- "------Exception-------",
47
- "Class: Kitchen::StandardError",
48
- "Message: shoot",
49
- "----------------------",
50
- ])
51
- end
52
-
53
- it "returns an array containing the exception's backtrace" do
54
- begin
55
- raise Kitchen::StandardError, "shoot"
56
- rescue => e
57
- Kitchen::Error.formatted_trace(e)[5...-1].must_equal e.backtrace
58
- end
59
- end
60
-
61
- it "returns an array containing a nested exception, if given" do
62
- begin
63
- raise IOError, "no disk, yo"
64
- rescue
65
- e = Kitchen::StandardError.new("shoot")
66
-
67
- Kitchen::Error.formatted_trace(e).must_equal([
68
- "------Exception-------",
69
- "Class: Kitchen::StandardError",
70
- "Message: shoot",
71
- "----------------------",
72
- "---Nested Exception---",
73
- "Class: IOError",
74
- "Message: no disk, yo",
75
- "----------------------",
76
- ])
77
- end
78
- end
79
-
80
- it "returns an array when an error has more than one error in original" do
81
- error_array = []
82
- error_array << Kitchen::StandardError.new("one")
83
- error_array << Kitchen::StandardError.new("two")
84
- composite_error = Kitchen::StandardError.new("array", error_array)
85
-
86
- Kitchen::Error.formatted_trace(composite_error).must_equal([
87
- "------Exception-------",
88
- "Class: Kitchen::StandardError",
89
- "Message: array",
90
- "----------------------",
91
- "-Composite Exception--",
92
- "Class: Kitchen::StandardError",
93
- "Message: one", "----------------------",
94
- "-Composite Exception--",
95
- "Class: Kitchen::StandardError",
96
- "Message: two",
97
- "----------------------"
98
- ])
99
- end
100
- end
101
- end
102
-
103
- describe Kitchen::StandardError do
104
- it "is a kind of Kitchen::Error" do
105
- Kitchen::StandardError.new("oops").must_be_kind_of Kitchen::Error
106
- end
107
-
108
- it "by default, sets original exception to the last raised exception" do
109
- begin
110
- raise IOError, "crap"
111
- rescue
112
- original = Kitchen::StandardError.new("oops").original
113
- original.must_be_kind_of IOError
114
- original.message.must_equal "crap"
115
- end
116
- end
117
-
118
- it "can embed an exception when constructing" do
119
- original = Kitchen::StandardError.new("durn", IOError.new("ack")).original
120
- original.must_be_kind_of IOError
121
- original.message.must_equal "ack"
122
- end
123
- end
124
-
125
- [
126
- Kitchen::UserError, Kitchen::ClientError, Kitchen::TransientFailure
127
- ].each do |klass|
128
- describe klass do
129
- it "is a kind of Kitchen::StandardError" do
130
- klass.new("oops").must_be_kind_of Kitchen::StandardError
131
- end
132
- end
133
- end
134
-
135
- [
136
- Kitchen::ActionFailed, Kitchen::InstanceFailure
137
- ].each do |klass|
138
- describe klass do
139
- it "is a kind of Kitchen::TransientFailure" do
140
- klass.new("oops").must_be_kind_of Kitchen::TransientFailure
141
- end
142
- end
143
- end
144
-
145
- describe Kitchen do
146
- describe ".with_friendly_errors" do
147
- let(:logger_io) { StringIO.new }
148
- let(:logger) { Kitchen::Logger.new(logdev: logger_io) }
149
-
150
- before do
151
- Kitchen.stubs(:tty?).returns(true)
152
- @orig_stderr = $stderr
153
- $stderr = StringIO.new
154
- @orig_logger = Kitchen.logger
155
- Kitchen.logger = logger
156
- end
157
-
158
- after do
159
- $stderr = @orig_stderr
160
- Kitchen.logger = @orig_logger
161
- end
162
-
163
- describe "for instance failures" do
164
- def go_boom
165
- Kitchen.with_friendly_errors do
166
- begin
167
- raise IOError, "no stuff"
168
- rescue
169
- raise Kitchen::InstanceFailure, "cannot do that"
170
- end
171
- end
172
- end
173
-
174
- it "exits with 10" do
175
- begin
176
- go_boom
177
- rescue SystemExit => e
178
- e.status.must_equal 10
179
- end
180
- end
181
-
182
- it "prints a message on STDERR" do
183
- output = [
184
- ">>>>>> cannot do that",
185
- ">>>>>> ------Exception-------",
186
- ">>>>>> Class: IOError",
187
- ">>>>>> Message: no stuff",
188
- ">>>>>> ----------------------",
189
- ].map { |l| Kitchen::Color.colorize(l, :red) }.join("\n").concat("\n")
190
-
191
- begin
192
- go_boom
193
- rescue SystemExit
194
- $stderr.string.must_equal output
195
- end
196
- end
197
-
198
- it "prints a message on STDERR without color" do
199
- Kitchen.stubs(:tty?).returns(false)
200
- output = [
201
- ">>>>>> cannot do that",
202
- ">>>>>> ------Exception-------",
203
- ">>>>>> Class: IOError",
204
- ">>>>>> Message: no stuff",
205
- ">>>>>> ----------------------",
206
- ].join("\n").concat("\n")
207
-
208
- begin
209
- go_boom
210
- rescue SystemExit
211
- $stderr.string.must_equal output
212
- end
213
- end
214
-
215
- it "logs the exception message on the common logger's error severity" do
216
- begin
217
- go_boom
218
- rescue SystemExit
219
- logger_io.string.must_match(/ERROR -- Kitchen: cannot do that$/)
220
- end
221
- end
222
-
223
- it "logs the exception message on debug, if set" do
224
- logger.level = ::Logger::DEBUG
225
-
226
- begin
227
- go_boom
228
- rescue SystemExit
229
- logger_io.string.must_match(/DEBUG -- Kitchen: cannot do that$/)
230
- end
231
- end
232
- end
233
-
234
- describe "for unexpected failures" do
235
- def go_boom
236
- Kitchen.with_friendly_errors do
237
- begin
238
- raise IOError, "wtf?"
239
- rescue
240
- raise Kitchen::StandardError, "ah crap"
241
- end
242
- end
243
- end
244
-
245
- it "exits with 20" do
246
- begin
247
- go_boom
248
- rescue SystemExit => e
249
- e.status.must_equal 20
250
- end
251
- end
252
-
253
- it "prints a message on STDERR" do
254
- output = [
255
- ">>>>>> ------Exception-------",
256
- ">>>>>> Class: Kitchen::StandardError",
257
- ">>>>>> Message: ah crap",
258
- ">>>>>> ----------------------",
259
- ">>>>>> Please see .kitchen/logs/kitchen.log for more details",
260
- ">>>>>> Also try running `kitchen diagnose --all` for configuration\n",
261
- ].map { |l| Kitchen::Color.colorize(l, :red) }.join("\n").concat("\n")
262
-
263
- begin
264
- go_boom
265
- rescue SystemExit
266
- $stderr.string.must_equal output
267
- end
268
- end
269
-
270
- it "prints a message on STDERR without color" do
271
- Kitchen.stubs(:tty?).returns(false)
272
- output = [
273
- ">>>>>> ------Exception-------",
274
- ">>>>>> Class: Kitchen::StandardError",
275
- ">>>>>> Message: ah crap",
276
- ">>>>>> ----------------------",
277
- ">>>>>> Please see .kitchen/logs/kitchen.log for more details",
278
- ">>>>>> Also try running `kitchen diagnose --all` for configuration",
279
- ].join("\n").concat("\n")
280
-
281
- begin
282
- go_boom
283
- rescue SystemExit
284
- $stderr.string.must_equal output
285
- end
286
- end
287
-
288
- it "logs the exception message on the common logger's error severity" do
289
- begin
290
- go_boom
291
- rescue SystemExit
292
- logger_io.string
293
- .must_match(/ERROR -- Kitchen: ------Exception-------$/)
294
- logger_io.string
295
- .must_match(/ERROR -- Kitchen: Class: Kitchen::StandardError$/)
296
- logger_io.string
297
- .must_match(/ERROR -- Kitchen: ------Backtrace-------$/)
298
- end
299
- end
300
-
301
- it "logs the exception message on debug, if set" do
302
- logger.level = ::Logger::DEBUG
303
-
304
- begin
305
- go_boom
306
- rescue SystemExit
307
- logger_io.string
308
- .must_match(/DEBUG -- Kitchen: ------Exception-------$/)
309
- logger_io.string
310
- .must_match(/DEBUG -- Kitchen: Class: Kitchen::StandardError$/)
311
- logger_io.string
312
- .must_match(/DEBUG -- Kitchen: ------Backtrace-------$/)
313
- end
314
- end
315
- end
316
- end
317
- end
@@ -1,1372 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2012, 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
- require "stringio"
21
-
22
- require "kitchen/logging"
23
- require "kitchen/instance"
24
- require "kitchen/driver"
25
- require "kitchen/driver/dummy"
26
- require "kitchen/platform"
27
- require "kitchen/provisioner"
28
- require "kitchen/provisioner/dummy"
29
- require "kitchen/suite"
30
- require "kitchen/transport/dummy"
31
- require "kitchen/verifier/dummy"
32
-
33
- class DummyStateFile
34
- def initialize(*)
35
- @_state = {}
36
- end
37
-
38
- def read
39
- @_state.dup
40
- end
41
-
42
- def write(state)
43
- @_state = state.dup
44
- end
45
-
46
- def destroy
47
- @_state = {}
48
- end
49
-
50
- def diagnose
51
- {}
52
- end
53
- end
54
-
55
- class SerialDummyDriver < Kitchen::Driver::Dummy
56
- no_parallel_for :create, :destroy
57
-
58
- attr_reader :action_in_mutex
59
-
60
- def initialize(config = {})
61
- super(config)
62
- @action_in_mutex = {}
63
- end
64
-
65
- def track_locked(action)
66
- @action_in_mutex ||= {}
67
- @action_in_mutex[action] = Kitchen::Instance.mutexes[self.class].locked?
68
- end
69
-
70
- def create(state)
71
- track_locked(:create)
72
- super
73
- end
74
-
75
- def destroy(state)
76
- track_locked(:destroy)
77
- super
78
- end
79
- end
80
-
81
- class LegacyDriver < Kitchen::Driver::SSHBase
82
- attr_reader :called_converge, :called_setup, :called_verify
83
-
84
- def converge(_)
85
- @called_converge
86
- end
87
-
88
- def setup(_)
89
- @called_setup
90
- end
91
-
92
- def verify(_)
93
- @called_verify
94
- end
95
- end
96
-
97
- describe Kitchen::Instance do
98
- let(:driver) { Kitchen::Driver::Dummy.new({}) }
99
- let(:logger_io) { StringIO.new }
100
- let(:logger) { Kitchen::Logger.new(logdev: logger_io) }
101
- let(:instance) { Kitchen::Instance.new(opts) }
102
- let(:lifecycle_hooks) { Kitchen::LifecycleHooks.new({}) }
103
- let(:provisioner) { Kitchen::Provisioner::Dummy.new({}) }
104
- let(:state_file) { DummyStateFile.new }
105
- let(:transport) { Kitchen::Transport::Dummy.new({}) }
106
- let(:verifier) { Kitchen::Verifier::Dummy.new({}) }
107
-
108
- let(:opts) do
109
- { suite: suite, platform: platform, driver: driver, lifecycle_hooks: lifecycle_hooks,
110
- provisioner: provisioner, verifier: verifier,
111
- logger: logger, state_file: state_file, transport: transport }
112
- end
113
-
114
- def suite(name = "suite")
115
- @suite ||= Kitchen::Suite.new(name: name)
116
- end
117
-
118
- def platform(name = "platform")
119
- @platform ||= Kitchen::Platform.new(name: name)
120
- end
121
-
122
- describe ".name_for" do
123
- it "combines the suite and platform names with a dash" do
124
- Kitchen::Instance.name_for(suite("suite"), platform("platform"))
125
- .must_equal "suite-platform"
126
- end
127
-
128
- it "squashes periods in suite name" do
129
- Kitchen::Instance.name_for(suite("suite.ness"), platform("platform"))
130
- .must_equal "suiteness-platform"
131
- end
132
-
133
- it "squashes periods in platform name" do
134
- Kitchen::Instance.name_for(suite("suite"), platform("platform.s"))
135
- .must_equal "suite-platforms"
136
- end
137
-
138
- it "squashes periods in suite and platform names" do
139
- Kitchen::Instance.name_for(suite("s.s"), platform("p.p"))
140
- .must_equal "ss-pp"
141
- end
142
-
143
- it "transforms underscores to dashes in suite name" do
144
- Kitchen::Instance.name_for(suite("suite_ness"), platform("platform"))
145
- .must_equal "suite-ness-platform"
146
- end
147
-
148
- it "transforms underscores to dashes in platform name" do
149
- Kitchen::Instance.name_for(suite("suite"), platform("platform_s"))
150
- .must_equal "suite-platform-s"
151
- end
152
-
153
- it "transforms underscores to dashes in suite and platform names" do
154
- Kitchen::Instance.name_for(suite("_s__s_"), platform("pp_"))
155
- .must_equal "-s--s--pp-"
156
- end
157
-
158
- it "transforms forward slashes to dashes in suite name" do
159
- Kitchen::Instance.name_for(suite("suite/ness"), platform("platform"))
160
- .must_equal "suite-ness-platform"
161
- end
162
-
163
- it "transforms forward slashes to dashes in platform name" do
164
- Kitchen::Instance.name_for(suite("suite"), platform("platform/s"))
165
- .must_equal "suite-platform-s"
166
- end
167
-
168
- it "transforms forward slashes to dashes in suite and platform names" do
169
- Kitchen::Instance.name_for(suite("/s//s/"), platform("pp/"))
170
- .must_equal "-s--s--pp-"
171
- end
172
- end
173
-
174
- describe "#suite" do
175
- it "returns its suite" do
176
- instance.suite.must_equal suite
177
- end
178
-
179
- it "raises an ArgumentError if missing" do
180
- opts.delete(:suite)
181
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
182
- end
183
- end
184
-
185
- describe "#platform" do
186
- it "returns its platform" do
187
- instance.platform.must_equal platform
188
- end
189
-
190
- it "raises an ArgumentError if missing" do
191
- opts.delete(:platform)
192
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
193
- end
194
- end
195
-
196
- describe "#driver" do
197
- it "returns its driver" do
198
- instance.driver.must_equal driver
199
- end
200
-
201
- it "raises an ArgumentError if missing" do
202
- opts.delete(:driver)
203
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
204
- end
205
-
206
- it "sets Driver#instance to itself" do
207
- # it's mind-bottling
208
- instance.driver.instance.must_equal instance
209
- end
210
- end
211
-
212
- describe "#logger" do
213
- it "returns its logger" do
214
- instance.logger.must_equal logger
215
- end
216
-
217
- it "uses Kitchen.logger by default" do
218
- opts.delete(:logger)
219
- instance.logger.must_equal Kitchen.logger
220
- end
221
- end
222
-
223
- describe "#provisioner" do
224
- it "returns its provisioner" do
225
- instance.provisioner.must_equal provisioner
226
- end
227
-
228
- it "raises an ArgumentError if missing" do
229
- opts.delete(:provisioner)
230
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
231
- end
232
-
233
- it "sets Provisioner#instance to itself" do
234
- # it's mind-bottling
235
- instance.provisioner.instance.must_equal instance
236
- end
237
- end
238
-
239
- describe "#transport" do
240
- it "returns its transport" do
241
- instance.transport.must_equal transport
242
- end
243
-
244
- it "raises an ArgumentError if missing" do
245
- opts.delete(:transport)
246
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
247
- end
248
-
249
- it "sets Transport#instance to itself" do
250
- # it's mind-bottling
251
- instance.transport.instance.must_equal instance
252
- end
253
- end
254
-
255
- describe "#verifier" do
256
- it "returns its verifier" do
257
- instance.verifier.must_equal verifier
258
- end
259
-
260
- it "raises and ArgumentError if missing" do
261
- opts.delete(:verifier)
262
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
263
- end
264
-
265
- it "sets Verifier#instance to itself" do
266
- # it's mind-bottling
267
- instance.verifier.instance.must_equal instance
268
- end
269
- end
270
-
271
- describe "#state_file" do
272
- it "raises an ArgumentError if missing" do
273
- opts.delete(:state_file)
274
- proc { Kitchen::Instance.new(opts) }.must_raise Kitchen::ClientError
275
- end
276
- end
277
-
278
- it "#name returns it name" do
279
- instance.name.must_equal "suite-platform"
280
- end
281
-
282
- it "#to_str returns a string representation with its name" do
283
- instance.to_str.must_equal "<suite-platform>"
284
- end
285
-
286
- it "#login executes the transport's login_command" do
287
- conn = stub("connection")
288
- state_file.write(last_action: "create")
289
- transport.stubs(:connection).with(last_action: "create")
290
- .returns(conn)
291
- conn.stubs(:login_command)
292
- .returns(Kitchen::LoginCommand.new("echo", ["hello"], purple: true))
293
- Kernel.expects(:exec).with("echo", "hello", purple: true)
294
-
295
- instance.login
296
- end
297
-
298
- it "#login raises a UserError if the instance is not created" do
299
- state_file.write({})
300
-
301
- proc { instance.login }.must_raise Kitchen::UserError
302
- end
303
-
304
- describe "#diagnose" do
305
- it "returns a hash" do
306
- instance.diagnose.must_be_instance_of Hash
307
- end
308
-
309
- it "sets :platform key to platform's diagnose info" do
310
- platform.stubs(:diagnose).returns(a: "b")
311
-
312
- instance.diagnose[:platform].must_equal(a: "b")
313
- end
314
-
315
- it "sets :platform key to :unknown if obj can't respond to #diagnose" do
316
- opts[:platform] = Class.new(platform.class) do
317
- undef_method :diagnose
318
- end.new(name: "whoop")
319
-
320
- instance.diagnose[:platform].must_equal :unknown
321
- end
322
-
323
- it "sets :state_file key to state_file's diganose info" do
324
- state_file.stubs(:diagnose).returns(a: "b")
325
-
326
- instance.diagnose[:state_file].must_equal(a: "b")
327
- end
328
-
329
- it "sets :state_file key to :unknown if obj can't respond to #diagnose" do
330
- opts[:state_file] = Class.new(state_file.class) do
331
- undef_method :diagnose
332
- end.new
333
-
334
- instance.diagnose[:state_file].must_equal :unknown
335
- end
336
-
337
- it "sets :provisioner key to provisioner's diganose info" do
338
- provisioner.stubs(:diagnose).returns(a: "b")
339
-
340
- instance.diagnose[:provisioner].must_equal(a: "b")
341
- end
342
-
343
- it "sets :provisioner key to :unknown if obj can't respond to #diagnose" do
344
- opts[:provisioner] = Class.new(provisioner.class) do
345
- undef_method :diagnose
346
- end.new
347
-
348
- instance.diagnose[:provisioner].must_equal :unknown
349
- end
350
-
351
- it "sets :verifier key to verifier's diganose info" do
352
- verifier.stubs(:diagnose).returns(a: "b")
353
-
354
- instance.diagnose[:verifier].must_equal(a: "b")
355
- end
356
-
357
- it "sets :verifier key to :unknown if obj can't respond to #diagnose" do
358
- opts[:verifier] = Class.new(verifier.class) do
359
- undef_method :diagnose
360
- end.new({})
361
-
362
- instance.diagnose[:verifier].must_equal :unknown
363
- end
364
-
365
- it "sets :transport key to transport's diganose info" do
366
- transport.stubs(:diagnose).returns(a: "b")
367
-
368
- instance.diagnose[:transport].must_equal(a: "b")
369
- end
370
-
371
- it "sets :transport key to :unknown if obj can't respond to #diagnose" do
372
- opts[:transport] = Class.new(transport.class) do
373
- undef_method :diagnose
374
- end.new
375
-
376
- instance.diagnose[:transport].must_equal :unknown
377
- end
378
- end
379
-
380
- describe "#diagnose_plugins" do
381
- it "returns a hash" do
382
- instance.diagnose_plugins.must_be_instance_of Hash
383
- end
384
-
385
- it "sets :driver key to driver's plugin_diagnose info" do
386
- driver.class.stubs(:diagnose).returns(a: "b")
387
-
388
- instance.diagnose_plugins[:driver].must_equal(
389
- name: "Dummy",
390
- a: "b"
391
- )
392
- end
393
-
394
- it "sets :driver key to :unknown if class doesn't have #diagnose" do
395
- opts[:driver] = Class.new(driver.class) do
396
- undef_method :diagnose_plugin
397
- end.new({})
398
-
399
- instance.diagnose_plugins[:driver].must_equal(:unknown)
400
- end
401
-
402
- it "sets :provisioner key to provisioner's plugin_diagnose info" do
403
- provisioner.class.stubs(:diagnose).returns(a: "b")
404
-
405
- instance.diagnose_plugins[:provisioner].must_equal(
406
- name: "Dummy",
407
- a: "b"
408
- )
409
- end
410
-
411
- it "sets :provisioner key to :unknown if class doesn't have #diagnose" do
412
- opts[:provisioner] = Class.new(driver.class) do
413
- undef_method :diagnose_plugin
414
- end.new({})
415
-
416
- instance.diagnose_plugins[:provisioner].must_equal(:unknown)
417
- end
418
-
419
- it "sets :verifier key to verifier's plugin_diagnose info" do
420
- verifier.class.stubs(:diagnose).returns(a: "b")
421
-
422
- instance.diagnose_plugins[:verifier].must_equal(
423
- name: "Dummy",
424
- a: "b"
425
- )
426
- end
427
-
428
- it "sets :verifier key to :unknown if class doesn't have #diagnose" do
429
- opts[:verifier] = Class.new(verifier.class) do
430
- undef_method :diagnose_plugin
431
- end.new({})
432
-
433
- instance.diagnose_plugins[:verifier].must_equal(:unknown)
434
- end
435
-
436
- it "sets :transport key to transport's plugin_diagnose info" do
437
- transport.class.stubs(:diagnose).returns(a: "b")
438
-
439
- instance.diagnose_plugins[:transport].must_equal(
440
- name: "Dummy",
441
- a: "b"
442
- )
443
- end
444
-
445
- it "sets :transport key to :unknown if class doesn't have #diagnose" do
446
- opts[:transport] = Class.new(transport.class) do
447
- undef_method :diagnose_plugin
448
- end.new({})
449
-
450
- instance.diagnose_plugins[:transport].must_equal(:unknown)
451
- end
452
- end
453
-
454
- describe "performing actions" do
455
- describe "#create" do
456
- describe "with no state" do
457
- it "calls Driver#create with empty state hash" do
458
- driver.expects(:create).with({})
459
-
460
- instance.create
461
- end
462
-
463
- it "writes the state file with last_action" do
464
- instance.create
465
-
466
- state_file.read[:last_action].must_equal "create"
467
- end
468
-
469
- it "logs the action start" do
470
- instance.create
471
-
472
- logger_io.string.must_match regex_for("Creating #{instance.to_str}")
473
- end
474
-
475
- it "logs the action finish" do
476
- instance.create
477
-
478
- logger_io.string
479
- .must_match regex_for("Finished creating #{instance.to_str}")
480
- end
481
-
482
- it "calls lifecycle hooks" do
483
- lifecycle_hooks.expects(:run).with(instance, :create, state_file, :pre)
484
- lifecycle_hooks.expects(:run).with(instance, :create, state_file, :post)
485
-
486
- instance.create
487
- end
488
- end
489
-
490
- describe "with last_action of create" do
491
- before { state_file.write(last_action: "create") }
492
-
493
- it "calls Driver#create with state hash" do
494
- driver.expects(:create)
495
- .with { |state| state[:last_action] == "create" }
496
-
497
- instance.create
498
- end
499
-
500
- it "writes the state file with last_action" do
501
- instance.create
502
-
503
- state_file.read[:last_action].must_equal "create"
504
- end
505
- end
506
- end
507
-
508
- describe "#converge" do
509
- describe "with no state" do
510
- it "calls Driver#create and Provisioner#call with empty state hash" do
511
- driver.expects(:create).with({})
512
- provisioner.expects(:call)
513
- .with { |state| state[:last_action] == "create" }
514
-
515
- instance.converge
516
- end
517
-
518
- it "writes the state file with last_action" do
519
- instance.converge
520
-
521
- state_file.read[:last_action].must_equal "converge"
522
- end
523
-
524
- it "logs the action start" do
525
- instance.converge
526
-
527
- logger_io.string.must_match regex_for("Converging #{instance.to_str}")
528
- end
529
-
530
- it "logs the action finish" do
531
- instance.converge
532
-
533
- logger_io.string
534
- .must_match regex_for("Finished converging #{instance.to_str}")
535
- end
536
-
537
- it "calls lifecycle hooks" do
538
- lifecycle_hooks.expects(:run).with(instance, :create, state_file, :pre)
539
- lifecycle_hooks.expects(:run).with(instance, :create, state_file, :post)
540
- lifecycle_hooks.expects(:run).with(instance, :converge, state_file, :pre)
541
- lifecycle_hooks.expects(:run).with(instance, :converge, state_file, :post)
542
-
543
- instance.converge
544
- end
545
- end
546
-
547
- describe "with last action of create" do
548
- before { state_file.write(last_action: "create") }
549
-
550
- it "calls Provisioner#call with state hash" do
551
- provisioner.expects(:call)
552
- .with { |state| state[:last_action] == "create" }
553
-
554
- instance.converge
555
- end
556
-
557
- it "writes the state file with last_action" do
558
- instance.converge
559
-
560
- state_file.read[:last_action].must_equal "converge"
561
- end
562
-
563
- it "calls lifecycle hooks" do
564
- lifecycle_hooks.expects(:run).with(instance, :converge, state_file, :pre)
565
- lifecycle_hooks.expects(:run).with(instance, :converge, state_file, :post)
566
-
567
- instance.converge
568
- end
569
- end
570
-
571
- describe "with last action of converge" do
572
- before { state_file.write(last_action: "converge") }
573
-
574
- it "calls Provisioner#call with state hash" do
575
- provisioner.expects(:call)
576
- .with { |state| state[:last_action] == "converge" }
577
-
578
- instance.converge
579
- end
580
-
581
- it "writes the state file with last_action" do
582
- instance.converge
583
-
584
- state_file.read[:last_action].must_equal "converge"
585
- end
586
- end
587
- end
588
-
589
- describe "#setup" do
590
- describe "with no state" do
591
- it "calls create and converge with empty state hash" do
592
- driver.expects(:create).with({})
593
- provisioner.expects(:call)
594
- .with { |state| state[:last_action] == "create" }
595
- driver.expects(:setup)
596
- .with { |state| state[:last_action] == "converge" }
597
- .never
598
-
599
- instance.setup
600
- end
601
-
602
- it "writes the state file with last_action" do
603
- instance.setup
604
-
605
- state_file.read[:last_action].must_equal "setup"
606
- end
607
-
608
- it "logs the action start" do
609
- instance.setup
610
-
611
- logger_io.string.must_match regex_for("Setting up #{instance.to_str}")
612
- end
613
-
614
- it "logs the action finish" do
615
- instance.setup
616
-
617
- logger_io.string
618
- .must_match regex_for("Finished setting up #{instance.to_str}")
619
- end
620
- end
621
-
622
- describe "with last action of create" do
623
- before { state_file.write(last_action: "create") }
624
-
625
- it "calls Provisioner#call with state hash" do
626
- provisioner.expects(:call)
627
- .with { |state| state[:last_action] == "create" }
628
- driver.expects(:setup)
629
- .with { |state| state[:last_action] == "converge" }
630
- .never
631
-
632
- instance.setup
633
- end
634
-
635
- it "writes the state file with last_action" do
636
- instance.setup
637
-
638
- state_file.read[:last_action].must_equal "setup"
639
- end
640
- end
641
-
642
- describe "with last action of converge" do
643
- before { state_file.write(last_action: "converge") }
644
-
645
- it "calls nothing with state hash" do
646
- driver.expects(:setup)
647
- .with { |state| state[:last_action] == "converge" }
648
- .never
649
-
650
- instance.setup
651
- end
652
-
653
- it "writes the state file with last_action" do
654
- instance.setup
655
-
656
- state_file.read[:last_action].must_equal "setup"
657
- end
658
- end
659
-
660
- describe "with last action of setup" do
661
- before { state_file.write(last_action: "setup") }
662
-
663
- it "calls nothing with state hash" do
664
- driver.expects(:setup)
665
- .with { |state| state[:last_action] == "setup" }
666
- .never
667
-
668
- instance.setup
669
- end
670
-
671
- it "writes the state file with last_action" do
672
- instance.setup
673
-
674
- state_file.read[:last_action].must_equal "setup"
675
- end
676
- end
677
- end
678
-
679
- describe "#verify" do
680
- describe "with no state" do
681
- it "calls create, converge, and verify with empty state hash" do
682
- driver.expects(:create).with({})
683
- provisioner.expects(:call)
684
- .with { |state| state[:last_action] == "create" }
685
- driver.expects(:setup)
686
- .with { |state| state[:last_action] == "converge" }
687
- .never
688
- verifier.expects(:call)
689
- .with { |state| state[:last_action] == "setup" }
690
-
691
- instance.verify
692
- end
693
-
694
- it "writes the state file with last_action" do
695
- instance.verify
696
-
697
- state_file.read[:last_action].must_equal "verify"
698
- end
699
-
700
- it "logs the action start" do
701
- instance.verify
702
-
703
- logger_io.string.must_match regex_for("Verifying #{instance.to_str}")
704
- end
705
-
706
- it "logs the action finish" do
707
- instance.verify
708
-
709
- logger_io.string
710
- .must_match regex_for("Finished verifying #{instance.to_str}")
711
- end
712
- end
713
-
714
- describe "with last of create" do
715
- before { state_file.write(last_action: "create") }
716
-
717
- it "calls converge, and verify with state hash" do
718
- provisioner.expects(:call)
719
- .with { |state| state[:last_action] == "create" }
720
- driver.expects(:setup)
721
- .with { |state| state[:last_action] == "converge" }
722
- .never
723
- verifier.expects(:call)
724
- .with { |state| state[:last_action] == "setup" }
725
-
726
- instance.verify
727
- end
728
-
729
- it "writes the state file with last_action" do
730
- instance.verify
731
-
732
- state_file.read[:last_action].must_equal "verify"
733
- end
734
- end
735
-
736
- describe "with last of converge" do
737
- before { state_file.write(last_action: "converge") }
738
-
739
- it "calls Verifier#call with state hash" do
740
- driver.expects(:setup)
741
- .with { |state| state[:last_action] == "converge" }
742
- .never
743
- verifier.expects(:call)
744
- .with { |state| state[:last_action] == "setup" }
745
-
746
- instance.verify
747
- end
748
-
749
- it "writes the state file with last_action" do
750
- instance.verify
751
-
752
- state_file.read[:last_action].must_equal "verify"
753
- end
754
- end
755
-
756
- describe "with last of setup" do
757
- before { state_file.write(last_action: "setup") }
758
-
759
- it "calls Verifier#call with state hash" do
760
- verifier.expects(:call)
761
- .with { |state| state[:last_action] == "setup" }
762
-
763
- instance.verify
764
- end
765
-
766
- it "writes the state file with last_action" do
767
- instance.verify
768
-
769
- state_file.read[:last_action].must_equal "verify"
770
- end
771
- end
772
-
773
- describe "with last of verify" do
774
- before { state_file.write(last_action: "verify") }
775
-
776
- it "calls Verifier#call with state hash" do
777
- verifier.expects(:call)
778
- .with { |state| state[:last_action] == "verify" }
779
-
780
- instance.verify
781
- end
782
-
783
- it "writes the state file with last_action" do
784
- instance.verify
785
-
786
- state_file.read[:last_action].must_equal "verify"
787
- end
788
- end
789
- end
790
-
791
- describe "#destroy" do
792
- describe "with no state" do
793
- it "calls Driver#destroy with empty state hash" do
794
- driver.expects(:destroy).with({})
795
-
796
- instance.destroy
797
- end
798
-
799
- it "destroys the state file" do
800
- state_file.expects(:destroy)
801
-
802
- instance.destroy
803
- end
804
-
805
- it "logs the action start" do
806
- instance.destroy
807
-
808
- logger_io.string
809
- .must_match regex_for("Destroying #{instance.to_str}")
810
- end
811
-
812
- it "logs the create finish" do
813
- instance.destroy
814
-
815
- logger_io.string
816
- .must_match regex_for("Finished destroying #{instance.to_str}")
817
- end
818
- end
819
-
820
- [:create, :converge, :setup, :verify].each do |action|
821
- describe "with last_action of #{action}" do
822
- before { state_file.write(last_action: action) }
823
-
824
- it "calls Driver#create with state hash" do
825
- driver.expects(:destroy)
826
- .with { |state| state[:last_action] == action }
827
-
828
- instance.destroy
829
- end
830
-
831
- it "destroys the state file" do
832
- state_file.expects(:destroy)
833
-
834
- instance.destroy
835
- end
836
- end
837
- end
838
- end
839
-
840
- describe "#test" do
841
- describe "with no state" do
842
- it "calls destroy, create, converge, setup, verify, destroy" do
843
- driver.expects(:destroy)
844
- driver.expects(:create)
845
- provisioner.expects(:call)
846
- verifier.expects(:call)
847
- driver.expects(:destroy)
848
-
849
- instance.test
850
- end
851
-
852
- it "logs the action start" do
853
- instance.test
854
-
855
- logger_io.string.must_match regex_for("Testing #{instance.to_str}")
856
- end
857
-
858
- it "logs the action finish" do
859
- instance.test
860
-
861
- logger_io.string
862
- .must_match regex_for("Finished testing #{instance.to_str}")
863
- end
864
- end
865
-
866
- [:create, :converge, :setup, :verify].each do |action|
867
- describe "with last action of #{action}" do
868
- before { state_file.write(last_action: action) }
869
-
870
- it "calls destroy, create, converge, setup, verify, destroy" do
871
- driver.expects(:destroy)
872
- driver.expects(:create)
873
- provisioner.expects(:call)
874
- verifier.expects(:call)
875
- driver.expects(:destroy)
876
-
877
- instance.test
878
- end
879
- end
880
- end
881
-
882
- describe "with destroy mode of never" do
883
- it "calls destroy, create, converge, setup, verify" do
884
- driver.expects(:destroy).once
885
- driver.expects(:create)
886
- provisioner.expects(:call)
887
- verifier.expects(:call)
888
-
889
- instance.test(:never)
890
- end
891
- end
892
-
893
- describe "with destroy mode of always" do
894
- it "calls destroy at even when action fails" do
895
- driver.expects(:destroy)
896
- driver.expects(:create)
897
- provisioner.expects(:call).raises(Kitchen::ActionFailed)
898
- driver.expects(:destroy)
899
-
900
- begin
901
- instance.test(:always)
902
- rescue # rubocop:disable Lint/HandleExceptions
903
- end
904
- end
905
- end
906
-
907
- describe "with destroy mode of passing" do
908
- it "doesn't call Driver#destroy at when action fails" do
909
- driver.stubs(:create).raises(Kitchen::ActionFailed)
910
-
911
- driver.expects(:destroy).once
912
-
913
- begin
914
- instance.test(:passing)
915
- rescue # rubocop:disable Lint/HandleExceptions
916
- end
917
- end
918
- end
919
- end
920
-
921
- describe "#remote_exec" do
922
- before { state_file.write(last_action: "create") }
923
-
924
- it "calls Transport#execute with command" do
925
- connection = mock("connection")
926
- connection.expects(:execute).with("uptime")
927
- transport.stubs(:connection).yields(connection)
928
-
929
- instance.remote_exec("uptime")
930
- end
931
- end
932
-
933
- [:create, :converge, :setup, :verify, :test].each do |action|
934
- describe "#{action} on driver crash with ActionFailed" do
935
- before do
936
- driver.stubs(:create).raises(Kitchen::ActionFailed, "death")
937
- end
938
-
939
- it "write the state file with last action" do
940
- begin
941
- instance.public_send(action)
942
- rescue Kitchen::Error
943
- true # no need to act here
944
- end
945
-
946
- state_file.read[:last_action].must_be_nil
947
- end
948
-
949
- it "raises an InstanceFailure" do
950
- proc { instance.public_send(action) }
951
- .must_raise Kitchen::InstanceFailure
952
- end
953
-
954
- it "populates the InstanceFailure message" do
955
- begin
956
- instance.public_send(action)
957
- rescue Kitchen::Error => e
958
- e.message.must_match regex_for(
959
- "Create failed on instance #{instance.to_str}")
960
- end
961
- end
962
-
963
- it "logs the failure" do
964
- begin
965
- instance.public_send(action)
966
- rescue Kitchen::Error
967
- true # no need to act here
968
- end
969
-
970
- logger_io.string.must_match regex_for(
971
- "Create failed on instance #{instance.to_str}")
972
- end
973
- end
974
-
975
- describe "on driver crash with unexpected exception class" do
976
- before do
977
- driver.stubs(:create).raises(RuntimeError, "watwat")
978
- end
979
-
980
- it "write the state file with last action" do
981
- begin
982
- instance.public_send(action)
983
- rescue Kitchen::Error
984
- true # no need to act here
985
- end
986
-
987
- state_file.read[:last_action].must_be_nil
988
- end
989
-
990
- it "raises an ActionFailed" do
991
- proc { instance.public_send(action) }
992
- .must_raise Kitchen::ActionFailed
993
- end
994
-
995
- it "populates the ActionFailed message" do
996
- begin
997
- instance.public_send(action)
998
- rescue Kitchen::Error => e
999
- e.message.must_match regex_for(
1000
- "Failed to complete #create action: [watwat]")
1001
- end
1002
- end
1003
-
1004
- it "logs the failure" do
1005
- begin
1006
- instance.public_send(action)
1007
- rescue Kitchen::Error
1008
- true # no need to act here
1009
- end
1010
-
1011
- logger_io.string.must_match regex_for(
1012
- "Create failed on instance #{instance.to_str}")
1013
- end
1014
- end
1015
- end
1016
-
1017
- describe "crashes preserve last action for desired verify action" do
1018
- before do
1019
- verifier.stubs(:call).raises(Kitchen::ActionFailed, "death")
1020
- end
1021
-
1022
- [:create, :converge, :setup].each do |action|
1023
- it "for last state #{action}" do
1024
- state_file.write(last_action: action.to_s)
1025
- begin
1026
- instance.verify
1027
- rescue Kitchen::Error
1028
- true # no need to act here
1029
- end
1030
-
1031
- state_file.read[:last_action].must_equal "setup"
1032
- end
1033
- end
1034
-
1035
- it "for last state verify" do
1036
- state_file.write(last_action: "verify")
1037
- begin
1038
- instance.verify
1039
- rescue Kitchen::Error
1040
- true # no need to act here
1041
- end
1042
-
1043
- state_file.read[:last_action].must_equal "verify"
1044
- end
1045
- end
1046
-
1047
- describe "on drivers with serial actions" do
1048
- let(:driver) { SerialDummyDriver.new({}) }
1049
-
1050
- it "runs in a synchronized block for serial actions" do
1051
- instance.test
1052
-
1053
- driver.action_in_mutex[:create].must_equal true
1054
- driver.action_in_mutex[:destroy].must_equal true
1055
- end
1056
- end
1057
-
1058
- describe "with legacy Driver::SSHBase subclasses" do
1059
- let(:driver) { LegacyDriver.new({}) }
1060
-
1061
- describe "#converge" do
1062
- describe "with no state" do
1063
- it "calls Driver#create and Driver#converge with empty state hash" do
1064
- driver.expects(:create).with({})
1065
- driver.expects(:converge)
1066
- .with { |state| state[:last_action] == "create" }
1067
-
1068
- instance.converge
1069
- end
1070
- end
1071
-
1072
- describe "with last action of create" do
1073
- before { state_file.write(last_action: "create") }
1074
-
1075
- it "calls Driver#converge with state hash" do
1076
- driver.expects(:converge)
1077
- .with { |state| state[:last_action] == "create" }
1078
-
1079
- instance.converge
1080
- end
1081
- end
1082
-
1083
- describe "with last action of converge" do
1084
- before { state_file.write(last_action: "converge") }
1085
-
1086
- it "calls Driver#converge with state hash" do
1087
- driver.expects(:converge)
1088
- .with { |state| state[:last_action] == "converge" }
1089
-
1090
- instance.converge
1091
- end
1092
- end
1093
- end
1094
-
1095
- describe "#setup" do
1096
- describe "with no state" do
1097
- it "calls create, converge, and setup with empty state hash" do
1098
- driver.expects(:create).with({})
1099
- driver.expects(:converge)
1100
- .with { |state| state[:last_action] == "create" }
1101
- driver.expects(:setup)
1102
- .with { |state| state[:last_action] == "converge" }
1103
-
1104
- instance.setup
1105
- end
1106
- end
1107
-
1108
- describe "with last action of create" do
1109
- before { state_file.write(last_action: "create") }
1110
-
1111
- it "calls Provisioner#call and setup with state hash" do
1112
- driver.expects(:converge)
1113
- .with { |state| state[:last_action] == "create" }
1114
- driver.expects(:setup)
1115
- .with { |state| state[:last_action] == "converge" }
1116
-
1117
- instance.setup
1118
- end
1119
- end
1120
-
1121
- describe "with last action of converge" do
1122
- before { state_file.write(last_action: "converge") }
1123
-
1124
- it "calls Driver#setup with state hash" do
1125
- driver.expects(:setup)
1126
- .with { |state| state[:last_action] == "converge" }
1127
-
1128
- instance.setup
1129
- end
1130
- end
1131
-
1132
- describe "with last action of setup" do
1133
- before { state_file.write(last_action: "setup") }
1134
-
1135
- it "calls Driver#setup with state hash" do
1136
- driver.expects(:setup)
1137
- .with { |state| state[:last_action] == "setup" }
1138
-
1139
- instance.setup
1140
- end
1141
- end
1142
- end
1143
-
1144
- describe "#verify" do
1145
- describe "with no state" do
1146
- it "calls create, converge, setup, and verify with empty state hash" do
1147
- driver.expects(:create).with({})
1148
- driver.expects(:converge)
1149
- .with { |state| state[:last_action] == "create" }
1150
- driver.expects(:setup)
1151
- .with { |state| state[:last_action] == "converge" }
1152
- driver.expects(:verify)
1153
- .with { |state| state[:last_action] == "setup" }
1154
-
1155
- instance.verify
1156
- end
1157
- end
1158
-
1159
- describe "with last of create" do
1160
- before { state_file.write(last_action: "create") }
1161
-
1162
- it "calls converge, setup, and verify with state hash" do
1163
- driver.expects(:converge)
1164
- .with { |state| state[:last_action] == "create" }
1165
- driver.expects(:setup)
1166
- .with { |state| state[:last_action] == "converge" }
1167
- driver.expects(:verify)
1168
- .with { |state| state[:last_action] == "setup" }
1169
-
1170
- instance.verify
1171
- end
1172
- end
1173
-
1174
- describe "with last of converge" do
1175
- before { state_file.write(last_action: "converge") }
1176
-
1177
- it "calls Driver#setup, and verify with state hash" do
1178
- driver.expects(:setup)
1179
- .with { |state| state[:last_action] == "converge" }
1180
- driver.expects(:verify)
1181
- .with { |state| state[:last_action] == "setup" }
1182
-
1183
- instance.verify
1184
- end
1185
- end
1186
-
1187
- describe "with last of setup" do
1188
- before { state_file.write(last_action: "setup") }
1189
-
1190
- it "calls Driver#verify with state hash" do
1191
- driver.expects(:verify)
1192
- .with { |state| state[:last_action] == "setup" }
1193
-
1194
- instance.verify
1195
- end
1196
- end
1197
-
1198
- describe "with last of verify" do
1199
- before { state_file.write(last_action: "verify") }
1200
-
1201
- it "calls Driver#verify with state hash" do
1202
- driver.expects(:verify)
1203
- .with { |state| state[:last_action] == "verify" }
1204
-
1205
- instance.verify
1206
- end
1207
- end
1208
- end
1209
-
1210
- describe "#test" do
1211
- describe "with no state" do
1212
- it "calls destroy, create, converge, setup, verify, destroy" do
1213
- driver.expects(:destroy)
1214
- driver.expects(:create)
1215
- driver.expects(:converge)
1216
- driver.expects(:setup)
1217
- driver.expects(:verify)
1218
- driver.expects(:destroy)
1219
-
1220
- instance.test
1221
- end
1222
- end
1223
-
1224
- [:create, :converge, :setup, :verify].each do |action|
1225
- describe "with last action of #{action}" do
1226
- before { state_file.write(last_action: action) }
1227
-
1228
- it "calls destroy, create, converge, setup, verify, destroy" do
1229
- driver.expects(:destroy)
1230
- driver.expects(:create)
1231
- driver.expects(:converge)
1232
- driver.expects(:setup)
1233
- driver.expects(:verify)
1234
- driver.expects(:destroy)
1235
-
1236
- instance.test
1237
- end
1238
- end
1239
- end
1240
-
1241
- describe "with destroy mode of never" do
1242
- it "calls destroy, create, converge, setup, verify" do
1243
- driver.expects(:destroy).once
1244
- driver.expects(:create)
1245
- driver.expects(:converge)
1246
- driver.expects(:setup)
1247
- driver.expects(:verify)
1248
-
1249
- instance.test(:never)
1250
- end
1251
- end
1252
-
1253
- describe "with destroy mode of always" do
1254
- it "calls destroy at even when action fails" do
1255
- driver.expects(:destroy)
1256
- driver.expects(:create)
1257
- driver.expects(:converge).raises(Kitchen::ActionFailed)
1258
- driver.expects(:destroy)
1259
-
1260
- begin
1261
- instance.test(:always)
1262
- rescue # rubocop:disable Lint/HandleExceptions
1263
- end
1264
- end
1265
- end
1266
- end
1267
-
1268
- it "#login executes the driver's login_command" do
1269
- state_file.write(last_action: "create")
1270
- driver.stubs(:login_command).with(last_action: "create")
1271
- .returns(Kitchen::LoginCommand.new("echo", ["hello"], purple: true))
1272
- Kernel.expects(:exec).with("echo", "hello", purple: true)
1273
-
1274
- instance.login
1275
- end
1276
- end
1277
- end
1278
-
1279
- describe Kitchen::Instance::FSM do
1280
- let(:fsm) { Kitchen::Instance::FSM }
1281
-
1282
- describe ".actions" do
1283
- it "passing nils returns destroy" do
1284
- fsm.actions(nil, nil).must_equal [:destroy]
1285
- end
1286
-
1287
- it "accepts a string for desired argument" do
1288
- fsm.actions(nil, "create").must_equal [:create]
1289
- end
1290
-
1291
- it "accepts a symbol for desired argument" do
1292
- fsm.actions(nil, :create).must_equal [:create]
1293
- end
1294
-
1295
- it "starting from no state to create returns create" do
1296
- fsm.actions(nil, :create).must_equal [:create]
1297
- end
1298
-
1299
- it "starting from :create to create returns create" do
1300
- fsm.actions(:create, :create).must_equal [:create]
1301
- end
1302
-
1303
- it "starting from no state to converge returns create, converge" do
1304
- fsm.actions(nil, :converge).must_equal [:create, :converge]
1305
- end
1306
-
1307
- it "starting from create to converge returns converge" do
1308
- fsm.actions(:create, :converge).must_equal [:converge]
1309
- end
1310
-
1311
- it "starting from converge to converge returns converge" do
1312
- fsm.actions(:converge, :converge).must_equal [:converge]
1313
- end
1314
-
1315
- it "starting from no state to setup returns create, converge, setup" do
1316
- fsm.actions(nil, :setup).must_equal [:create, :converge, :setup]
1317
- end
1318
-
1319
- it "starting from create to setup returns converge, setup" do
1320
- fsm.actions(:create, :setup).must_equal [:converge, :setup]
1321
- end
1322
-
1323
- it "starting from converge to setup returns setup" do
1324
- fsm.actions(:converge, :setup).must_equal [:setup]
1325
- end
1326
-
1327
- it "starting from setup to setup return setup" do
1328
- fsm.actions(:setup, :setup).must_equal [:setup]
1329
- end
1330
-
1331
- it "starting from no state to verify returns create, converge, setup, verify" do
1332
- fsm.actions(nil, :verify).must_equal [:create, :converge, :setup, :verify]
1333
- end
1334
-
1335
- it "starting from create to verify returns converge, setup, verify" do
1336
- fsm.actions(:create, :verify).must_equal [:converge, :setup, :verify]
1337
- end
1338
-
1339
- it "starting from converge to verify returns setup, verify" do
1340
- fsm.actions(:converge, :verify).must_equal [:setup, :verify]
1341
- end
1342
-
1343
- it "starting from setup to verify returns verify" do
1344
- fsm.actions(:setup, :verify).must_equal [:verify]
1345
- end
1346
-
1347
- it "starting from verify to verify returns verify" do
1348
- fsm.actions(:verify, :verify).must_equal [:verify]
1349
- end
1350
-
1351
- [:verify, :setup, :converge].each do |s|
1352
- it "starting from #{s} to create returns create" do
1353
- fsm.actions(s, :create).must_equal [:create]
1354
- end
1355
- end
1356
-
1357
- [:verify, :setup].each do |s|
1358
- it "starting from #{s} to converge returns converge" do
1359
- fsm.actions(s, :converge).must_equal [:converge]
1360
- end
1361
- end
1362
-
1363
- it "starting from verify to setup returns setup" do
1364
- fsm.actions(:verify, :setup).must_equal [:setup]
1365
- end
1366
- end
1367
- end
1368
-
1369
- def regex_for(string)
1370
- Regexp.new(Regexp.escape(string))
1371
- end
1372
- end