cuken 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (396) hide show
  1. data/Gemfile +5 -3
  2. data/Gemfile.lock +61 -18
  3. data/LICENSE +13 -0
  4. data/NOTICE +3 -0
  5. data/Rakefile +3 -3
  6. data/VERSION +1 -1
  7. data/cucumber.yml +8 -0
  8. data/cuken.gemspec +397 -13
  9. data/examples/chef/features/support/env.rb +16 -0
  10. data/features/chef/cookbooks/cookbook.feature +14 -0
  11. data/features/chef/cookbooks/metadata.feature +40 -0
  12. data/features/chef/cookbooks/repo.feature +13 -0
  13. data/features/chef/knife.feature +140 -0
  14. data/features/chef/knife_steps.feature +19 -0
  15. data/features/command_steps.feature +68 -0
  16. data/features/commands.feature +5 -5
  17. data/features/common_steps.feature +13 -0
  18. data/features/data/Rakefile +38 -0
  19. data/features/data/apt/chef-integration-test-1.0/debian/changelog +5 -0
  20. data/features/data/apt/chef-integration-test-1.0/debian/compat +1 -0
  21. data/features/data/apt/chef-integration-test-1.0/debian/control +13 -0
  22. data/features/data/apt/chef-integration-test-1.0/debian/copyright +34 -0
  23. data/features/data/apt/chef-integration-test-1.0/debian/files +1 -0
  24. data/features/data/apt/chef-integration-test-1.0/debian/rules +13 -0
  25. data/features/data/apt/chef-integration-test-1.0/debian/source/format +1 -0
  26. data/features/data/apt/chef-integration-test-1.1/debian/changelog +11 -0
  27. data/features/data/apt/chef-integration-test-1.1/debian/compat +1 -0
  28. data/features/data/apt/chef-integration-test-1.1/debian/control +13 -0
  29. data/features/data/apt/chef-integration-test-1.1/debian/copyright +34 -0
  30. data/features/data/apt/chef-integration-test-1.1/debian/files +1 -0
  31. data/features/data/apt/chef-integration-test-1.1/debian/rules +13 -0
  32. data/features/data/apt/chef-integration-test-1.1/debian/source/format +1 -0
  33. data/features/data/apt/chef-integration-test_1.0-1_amd64.changes +22 -0
  34. data/features/data/apt/chef-integration-test_1.0-1_amd64.deb +0 -0
  35. data/features/data/apt/chef-integration-test_1.0.orig.tar.gz +0 -0
  36. data/features/data/apt/chef-integration-test_1.1-1_amd64.changes +22 -0
  37. data/features/data/apt/chef-integration-test_1.1-1_amd64.deb +0 -0
  38. data/features/data/apt/chef-integration-test_1.1.orig.tar.gz +0 -0
  39. data/features/data/apt/var/www/apt/conf/distributions +7 -0
  40. data/features/data/apt/var/www/apt/conf/incoming +4 -0
  41. data/features/data/apt/var/www/apt/conf/pulls +3 -0
  42. data/features/data/apt/var/www/apt/db/checksums.db +0 -0
  43. data/features/data/apt/var/www/apt/db/contents.cache.db +0 -0
  44. data/features/data/apt/var/www/apt/db/packages.db +0 -0
  45. data/features/data/apt/var/www/apt/db/references.db +0 -0
  46. data/features/data/apt/var/www/apt/db/release.caches.db +0 -0
  47. data/features/data/apt/var/www/apt/db/version +4 -0
  48. data/features/data/apt/var/www/apt/dists/sid/Release +19 -0
  49. data/features/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages +16 -0
  50. data/features/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages.gz +0 -0
  51. data/features/data/apt/var/www/apt/dists/sid/main/binary-amd64/Release +5 -0
  52. data/features/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.0-1_amd64.deb +0 -0
  53. data/features/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.1-1_amd64.deb +0 -0
  54. data/features/data/config/client.rb +23 -0
  55. data/features/data/config/client_with_checksum_caching.rb +23 -0
  56. data/features/data/config/knife-stephen.rb +12 -0
  57. data/features/data/config/knife.rb +11 -0
  58. data/features/data/config/rake.rb +57 -0
  59. data/features/data/config/server.rb +52 -0
  60. data/features/data/cookbook_tarballs/empty_tarball.tar.gz +0 -0
  61. data/features/data/cookbook_tarballs/new.tar.gz +0 -0
  62. data/features/data/cookbook_tarballs/not_a_tarball.txt +1 -0
  63. data/features/data/cookbook_tarballs/original.tar.gz +0 -0
  64. data/features/data/cookbooks/attribute_include/README.rdoc +8 -0
  65. data/features/data/cookbooks/attribute_include/attributes/a.rb +4 -0
  66. data/features/data/cookbooks/attribute_include/attributes/b.rb +2 -0
  67. data/features/data/cookbooks/attribute_include/metadata.rb +6 -0
  68. data/features/data/cookbooks/attribute_include/recipes/default.rb +23 -0
  69. data/features/data/cookbooks/attribute_include_default/README.rdoc +8 -0
  70. data/features/data/cookbooks/attribute_include_default/attributes/a.rb +5 -0
  71. data/features/data/cookbooks/attribute_include_default/attributes/default.rb +2 -0
  72. data/features/data/cookbooks/attribute_include_default/metadata.rb +6 -0
  73. data/features/data/cookbooks/attribute_include_default/recipes/default.rb +23 -0
  74. data/features/data/cookbooks/attribute_settings/README.rdoc +8 -0
  75. data/features/data/cookbooks/attribute_settings/attributes/default.rb +3 -0
  76. data/features/data/cookbooks/attribute_settings/default.rb +1 -0
  77. data/features/data/cookbooks/attribute_settings/metadata.rb +6 -0
  78. data/features/data/cookbooks/attribute_settings/recipes/default.rb +21 -0
  79. data/features/data/cookbooks/attribute_settings/recipes/default_in_recipe.rb +25 -0
  80. data/features/data/cookbooks/attribute_settings_normal/README.rdoc +8 -0
  81. data/features/data/cookbooks/attribute_settings_normal/attributes/.default.rb.swo +0 -0
  82. data/features/data/cookbooks/attribute_settings_normal/attributes/default.rb +2 -0
  83. data/features/data/cookbooks/attribute_settings_normal/default.rb +1 -0
  84. data/features/data/cookbooks/attribute_settings_normal/metadata.rb +6 -0
  85. data/features/data/cookbooks/attribute_settings_normal/recipes/.default.rb.swo +0 -0
  86. data/features/data/cookbooks/attribute_settings_normal/recipes/.default_in_recipe.rb.swo +0 -0
  87. data/features/data/cookbooks/attribute_settings_normal/recipes/default.rb +21 -0
  88. data/features/data/cookbooks/attribute_settings_normal/recipes/normal_in_recipe.rb +25 -0
  89. data/features/data/cookbooks/attribute_settings_override/README.rdoc +8 -0
  90. data/features/data/cookbooks/attribute_settings_override/attributes/default.rb +2 -0
  91. data/features/data/cookbooks/attribute_settings_override/default.rb +1 -0
  92. data/features/data/cookbooks/attribute_settings_override/metadata.rb +6 -0
  93. data/features/data/cookbooks/attribute_settings_override/recipes/default.rb +21 -0
  94. data/features/data/cookbooks/attribute_settings_override/recipes/normal_in_recipe.rb +25 -0
  95. data/features/data/cookbooks/attribute_settings_override/recipes/override_in_recipe.rb +21 -0
  96. data/features/data/cookbooks/delayed_notifications/recipes/bad_syntax_notifies.rb +14 -0
  97. data/features/data/cookbooks/delayed_notifications/recipes/default.rb +18 -0
  98. data/features/data/cookbooks/delayed_notifications/recipes/forward_references.rb +10 -0
  99. data/features/data/cookbooks/delayed_notifications/recipes/invalid_forward_reference.rb +16 -0
  100. data/features/data/cookbooks/delayed_notifications/recipes/notify_a_resource_from_a_single_source.rb +26 -0
  101. data/features/data/cookbooks/delayed_notifications/recipes/notify_a_resource_from_multiple_sources.rb +31 -0
  102. data/features/data/cookbooks/delayed_notifications/recipes/notify_different_resources_for_different_actions.rb +31 -0
  103. data/features/data/cookbooks/deploy/recipes/callbacks.rb +78 -0
  104. data/features/data/cookbooks/deploy/recipes/default.rb +51 -0
  105. data/features/data/cookbooks/deploy/recipes/deploy_commit1.rb +25 -0
  106. data/features/data/cookbooks/deploy/recipes/deploy_commit2.rb +25 -0
  107. data/features/data/cookbooks/deploy/recipes/embedded_recipe_callbacks.rb +70 -0
  108. data/features/data/cookbooks/deploy/recipes/revision_deploy.rb +51 -0
  109. data/features/data/cookbooks/deploy/recipes/rollback_commit2.rb +24 -0
  110. data/features/data/cookbooks/deploy/templates/default/app_config.yml.erb +23 -0
  111. data/features/data/cookbooks/deploy/templates/default/database.yml.erb +18 -0
  112. data/features/data/cookbooks/deploy/templates/default/embedded_recipe_before_symlink.rb.erb +4 -0
  113. data/features/data/cookbooks/deploy/templates/default/sneaky_after_restart_hook.rb.erb +4 -0
  114. data/features/data/cookbooks/deploy/templates/default/sneaky_before_migrate_hook.rb.erb +2 -0
  115. data/features/data/cookbooks/deploy/templates/default/sneaky_before_restart_hook.rb.erb +4 -0
  116. data/features/data/cookbooks/deploy/templates/default/sneaky_before_symlink_hook.rb.erb +2 -0
  117. data/features/data/cookbooks/directory_provider/recipes/create.rb +25 -0
  118. data/features/data/cookbooks/directory_provider/recipes/default.rb +18 -0
  119. data/features/data/cookbooks/directory_provider/recipes/delete.rb +29 -0
  120. data/features/data/cookbooks/directory_provider/recipes/delete_nonexistent.rb +23 -0
  121. data/features/data/cookbooks/directory_provider/recipes/owner_update.rb +31 -0
  122. data/features/data/cookbooks/directory_provider/recipes/set_the_accessibility_of_a_created_directory.rb +55 -0
  123. data/features/data/cookbooks/execute_commands/metadata.rb +5 -0
  124. data/features/data/cookbooks/execute_commands/recipes/4k.rb +25 -0
  125. data/features/data/cookbooks/execute_commands/recipes/debug.rb +22 -0
  126. data/features/data/cookbooks/execute_commands/recipes/default.rb +22 -0
  127. data/features/data/cookbooks/execute_commands/recipes/umask.rb +23 -0
  128. data/features/data/cookbooks/integration_setup/attributes/integration.rb +25 -0
  129. data/features/data/cookbooks/integration_setup/recipes/default.rb +24 -0
  130. data/features/data/cookbooks/lwrp/providers/default.rb +9 -0
  131. data/features/data/cookbooks/lwrp/providers/lwp_non_default.rb +3 -0
  132. data/features/data/cookbooks/lwrp/providers/lwp_overridden_load_current_resource.rb +8 -0
  133. data/features/data/cookbooks/lwrp/providers/provider_is_omitted.rb +3 -0
  134. data/features/data/cookbooks/lwrp/recipes/default_everything.rb +4 -0
  135. data/features/data/cookbooks/lwrp/recipes/non_default_provider.rb +6 -0
  136. data/features/data/cookbooks/lwrp/recipes/non_default_resource.rb +6 -0
  137. data/features/data/cookbooks/lwrp/recipes/overridden_provider_load_current_resource.rb +6 -0
  138. data/features/data/cookbooks/lwrp/recipes/overridden_resource_initialize.rb +6 -0
  139. data/features/data/cookbooks/lwrp/recipes/provider_invokes_resource.rb +6 -0
  140. data/features/data/cookbooks/lwrp/recipes/provider_is_a_class.rb +6 -0
  141. data/features/data/cookbooks/lwrp/recipes/provider_is_a_string.rb +6 -0
  142. data/features/data/cookbooks/lwrp/recipes/provider_is_a_symbol.rb +6 -0
  143. data/features/data/cookbooks/lwrp/recipes/provider_is_omitted.rb +3 -0
  144. data/features/data/cookbooks/lwrp/resources/default.rb +4 -0
  145. data/features/data/cookbooks/lwrp/resources/lwr_non_default.rb +3 -0
  146. data/features/data/cookbooks/lwrp/resources/lwr_overridden_initialize.rb +8 -0
  147. data/features/data/cookbooks/lwrp/resources/provider_is_omitted.rb +1 -0
  148. data/features/data/cookbooks/manage_files/recipes/create_a_file.rb +22 -0
  149. data/features/data/cookbooks/manage_files/recipes/default.rb +19 -0
  150. data/features/data/cookbooks/manage_files/recipes/delete_a_file.rb +24 -0
  151. data/features/data/cookbooks/manage_files/recipes/delete_a_file_that_does_not_already_exist.rb +22 -0
  152. data/features/data/cookbooks/manage_files/recipes/manage_file_contents.rb +23 -0
  153. data/features/data/cookbooks/manage_files/recipes/set_the_accessibility_of_a_created_file.rb +79 -0
  154. data/features/data/cookbooks/manage_files/recipes/set_the_owner_of_a_created_file.rb +23 -0
  155. data/features/data/cookbooks/manage_files/recipes/touch_a_file.rb +22 -0
  156. data/features/data/cookbooks/metadata/metadata.rb +17 -0
  157. data/features/data/cookbooks/metadata/recipes/default.rb +18 -0
  158. data/features/data/cookbooks/no_attributes/README.rdoc +8 -0
  159. data/features/data/cookbooks/no_attributes/metadata.rb +6 -0
  160. data/features/data/cookbooks/no_attributes/recipes/default.rb +21 -0
  161. data/features/data/cookbooks/node_cookbook_sync/README.rdoc +8 -0
  162. data/features/data/cookbooks/node_cookbook_sync/attributes/attr_file.rb +0 -0
  163. data/features/data/cookbooks/node_cookbook_sync/definitions/def_file.rb +0 -0
  164. data/features/data/cookbooks/node_cookbook_sync/libraries/lib_file.rb +0 -0
  165. data/features/data/cookbooks/node_cookbook_sync/metadata.rb +6 -0
  166. data/features/data/cookbooks/node_cookbook_sync/recipes/default.rb +18 -0
  167. data/features/data/cookbooks/packages/recipes/default.rb +0 -0
  168. data/features/data/cookbooks/packages/recipes/gem_package.rb +26 -0
  169. data/features/data/cookbooks/packages/recipes/install_apt_package.rb +3 -0
  170. data/features/data/cookbooks/packages/recipes/install_dpkg_package.rb +4 -0
  171. data/features/data/cookbooks/packages/recipes/install_gem_noshell.rb +26 -0
  172. data/features/data/cookbooks/packages/recipes/install_gem_package_twice.rb +26 -0
  173. data/features/data/cookbooks/packages/recipes/macports_install_bad_package.rb +3 -0
  174. data/features/data/cookbooks/packages/recipes/macports_install_yydecode.rb +3 -0
  175. data/features/data/cookbooks/packages/recipes/macports_purge_yydecode.rb +3 -0
  176. data/features/data/cookbooks/packages/recipes/macports_remove_yydecode.rb +3 -0
  177. data/features/data/cookbooks/packages/recipes/macports_upgrade_yydecode.rb +7 -0
  178. data/features/data/cookbooks/packages/recipes/manually_upgrade_gem_package.rb +32 -0
  179. data/features/data/cookbooks/packages/recipes/upgrade_gem_noshell.rb +33 -0
  180. data/features/data/cookbooks/packages/recipes/upgrade_gem_package.rb +33 -0
  181. data/features/data/cookbooks/recipe_include/README.rdoc +8 -0
  182. data/features/data/cookbooks/recipe_include/metadata.rb +6 -0
  183. data/features/data/cookbooks/recipe_include/recipes/default.rb +21 -0
  184. data/features/data/cookbooks/recipe_include/recipes/second.rb +23 -0
  185. data/features/data/cookbooks/roles/recipes/default.rb +26 -0
  186. data/features/data/cookbooks/roles/recipes/env_test.rb +25 -0
  187. data/features/data/cookbooks/run_interval/recipes/default.rb +27 -0
  188. data/features/data/cookbooks/scm/metadata.rb +8 -0
  189. data/features/data/cookbooks/scm/recipes/git.rb +25 -0
  190. data/features/data/cookbooks/search/attributes/search_attrs.rb +1 -0
  191. data/features/data/cookbooks/search/recipes/default.rb +18 -0
  192. data/features/data/cookbooks/search/recipes/search_data.rb +28 -0
  193. data/features/data/cookbooks/search/recipes/search_data_manual.rb +33 -0
  194. data/features/data/cookbooks/search/recipes/search_data_noblock.rb +32 -0
  195. data/features/data/cookbooks/show_cookbook/README.rdoc +8 -0
  196. data/features/data/cookbooks/show_cookbook/attributes/attr_file.rb +0 -0
  197. data/features/data/cookbooks/show_cookbook/definitions/def_file.rb +0 -0
  198. data/features/data/cookbooks/show_cookbook/files/default/prime_time.txt +0 -0
  199. data/features/data/cookbooks/show_cookbook/files/host-latte/prime_time.txt +0 -0
  200. data/features/data/cookbooks/show_cookbook/files/mac_os_x-10.5/prime_time.txt +0 -0
  201. data/features/data/cookbooks/show_cookbook/files/mac_os_x/prime_time.txt +0 -0
  202. data/features/data/cookbooks/show_cookbook/libraries/lib_file.rb +0 -0
  203. data/features/data/cookbooks/show_cookbook/metadata.rb +6 -0
  204. data/features/data/cookbooks/show_cookbook/recipes/default.rb +18 -0
  205. data/features/data/cookbooks/show_cookbook/templates/default/prime_time.txt.erb +0 -0
  206. data/features/data/cookbooks/show_cookbook/templates/host-latte/prime_time.txt.erb +0 -0
  207. data/features/data/cookbooks/show_cookbook/templates/mac_os_x-10.5/prime_time.txt.erb +0 -0
  208. data/features/data/cookbooks/show_cookbook/templates/mac_os_x/prime_time.txt.erb +0 -0
  209. data/features/data/cookbooks/synchronize/recipes/default.rb +18 -0
  210. data/features/data/cookbooks/synchronize_deps/metadata.json +30 -0
  211. data/features/data/cookbooks/synchronize_deps/metadata.rb +1 -0
  212. data/features/data/cookbooks/synchronize_deps/recipes/default.rb +18 -0
  213. data/features/data/cookbooks/template/README.rdoc +8 -0
  214. data/features/data/cookbooks/template/metadata.rb +6 -0
  215. data/features/data/cookbooks/template/recipes/default.rb +26 -0
  216. data/features/data/cookbooks/template/recipes/interval.rb +37 -0
  217. data/features/data/cookbooks/template/recipes/render_node_attrs.rb +26 -0
  218. data/features/data/cookbooks/template/templates/default/node.txt.erb +3 -0
  219. data/features/data/cookbooks/template/templates/default/template.txt.erb +1 -0
  220. data/features/data/cookbooks/transfer_remote_directories/files/default/transfer_directory_feature/bar.txt +1 -0
  221. data/features/data/cookbooks/transfer_remote_directories/files/default/transfer_directory_feature/baz.txt +1 -0
  222. data/features/data/cookbooks/transfer_remote_directories/files/default/transfer_directory_feature/foo.txt +1 -0
  223. data/features/data/cookbooks/transfer_remote_directories/recipes/transfer_directory.rb +29 -0
  224. data/features/data/cookbooks/transfer_remote_files/files/default/transfer_a_file_from_a_cookbook.txt +1 -0
  225. data/features/data/cookbooks/transfer_remote_files/metadata.json +30 -0
  226. data/features/data/cookbooks/transfer_remote_files/metadata.rb +1 -0
  227. data/features/data/cookbooks/transfer_remote_files/recipes/change_remote_file_perms_trickery.rb +33 -0
  228. data/features/data/cookbooks/transfer_remote_files/recipes/default.rb +18 -0
  229. data/features/data/cookbooks/transfer_remote_files/recipes/should_prefer_the_file_for_this_specific_host.rb +22 -0
  230. data/features/data/cookbooks/transfer_remote_files/recipes/transfer_a_file_from_a_cookbook.rb +22 -0
  231. data/features/data/cookbooks/transfer_remote_files/recipes/transfer_a_file_from_a_specific_cookbook.rb +20 -0
  232. data/features/data/cookbooks/transfer_remote_files/recipes/transfer_a_non-existent_file_from_a_cookbook.rb +22 -0
  233. data/features/data/cookbooks/transfer_remote_files_definition/definitions/transfer.rb +6 -0
  234. data/features/data/cookbooks/transfer_remote_files_definition/files/default/easy.txt +1 -0
  235. data/features/data/cookbooks/transfer_some_cookbook_files/files/default/should_be_transferred.txt +3 -0
  236. data/features/data/cookbooks/transfer_some_cookbook_files/files/default/should_not_be_transferred.txt +2 -0
  237. data/features/data/cookbooks/transfer_some_cookbook_files/recipes/default.rb +26 -0
  238. data/features/data/cookbooks/transfer_some_cookbook_files/templates/default/should_be_transferred.erb +2 -0
  239. data/features/data/cookbooks/transfer_some_cookbook_files/templates/default/should_not_be_transferred.erb +3 -0
  240. data/features/data/cookbooks/version_deps/metadata.rb +1 -0
  241. data/features/data/cookbooks/version_deps/recipes/default.rb +1 -0
  242. data/features/data/cookbooks/versions/metadata.rb +5 -0
  243. data/features/data/cookbooks/versions/recipes/default.rb +5 -0
  244. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_1.0.0/metadata.json +31 -0
  245. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_1.0.0/metadata.rb +8 -0
  246. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_1.0.0/recipes/default.rb +18 -0
  247. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_2.0.0/metadata.json +29 -0
  248. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_2.0.0/metadata.rb +6 -0
  249. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_2.0.0/recipes/default.rb +18 -0
  250. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_3.0.0/metadata.json +30 -0
  251. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_3.0.0/metadata.rb +7 -0
  252. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_a_3.0.0/recipes/default.rb +18 -0
  253. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_1.0.0/metadata.json +31 -0
  254. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_1.0.0/metadata.rb +8 -0
  255. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_1.0.0/recipes/default.rb +18 -0
  256. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_2.0.0/metadata.json +31 -0
  257. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_2.0.0/metadata.rb +8 -0
  258. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_2.0.0/recipes/default.rb +18 -0
  259. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_3.0.0/metadata.json +30 -0
  260. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_3.0.0/metadata.rb +7 -0
  261. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_b_3.0.0/recipes/default.rb +18 -0
  262. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_1.0.0/metadata.json +31 -0
  263. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_1.0.0/metadata.rb +8 -0
  264. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_1.0.0/recipes/default.rb +18 -0
  265. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_2.0.0/metadata.json +29 -0
  266. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_2.0.0/metadata.rb +6 -0
  267. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_2.0.0/recipes/default.rb +18 -0
  268. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_3.0.0/metadata.json +29 -0
  269. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_3.0.0/metadata.rb +6 -0
  270. data/features/data/cookbooks_not_uploaded_at_feature_start/dep_test_c_3.0.0/recipes/default.rb +18 -0
  271. data/features/data/cookbooks_not_uploaded_at_feature_start/test_cookbook/attributes/attr1.rb +1 -0
  272. data/features/data/cookbooks_not_uploaded_at_feature_start/test_cookbook/attributes/attr2.rb +1 -0
  273. data/features/data/cookbooks_not_uploaded_at_feature_start/test_cookbook/recipes/default.rb +2 -0
  274. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_empty_except_metadata/metadata.json +38 -0
  275. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_empty_except_metadata/metadata.rb +6 -0
  276. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_nometadata/attributes/attributes.rb +1 -0
  277. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_nometadata/recipes/default.rb +2 -0
  278. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid/attributes/attributes.rb +1 -0
  279. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid/metadata.json +38 -0
  280. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid/metadata.rb +6 -0
  281. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid/recipes/default.rb +2 -0
  282. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.1.0_with_different_dependencies/attributes/attributes.rb +1 -0
  283. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.1.0_with_different_dependencies/metadata.json +40 -0
  284. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.1.0_with_different_dependencies/metadata.rb +7 -0
  285. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.1.0_with_different_dependencies/recipes/default.rb +2 -0
  286. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.2.0/attributes/attributes.rb +1 -0
  287. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.2.0/metadata.json +38 -0
  288. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.2.0/metadata.rb +6 -0
  289. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_valid_v0.2.0/recipes/default.rb +2 -0
  290. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_wrong_metadata/metadata.json +40 -0
  291. data/features/data/cookbooks_not_uploaded_at_feature_start/testcookbook_wrong_metadata/recipes/default.rb +1 -0
  292. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.0/metadata.json +39 -0
  293. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.0/metadata.rb +6 -0
  294. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.0/recipes/default.rb +18 -0
  295. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.1/metadata.json +39 -0
  296. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.1/metadata.rb +6 -0
  297. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.1.1/recipes/default.rb +18 -0
  298. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.10.0/metadata.json +39 -0
  299. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.10.0/metadata.rb +6 -0
  300. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.10.0/recipes/default.rb +18 -0
  301. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.2.0/metadata.json +39 -0
  302. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.2.0/metadata.rb +6 -0
  303. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.2.0/recipes/default.rb +18 -0
  304. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.0/metadata.json +39 -0
  305. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.0/metadata.rb +6 -0
  306. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.0/recipes/default.rb +18 -0
  307. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.7/metadata.json +39 -0
  308. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.7/metadata.rb +6 -0
  309. data/features/data/cookbooks_not_uploaded_at_feature_start/version_test_0.9.7/recipes/default.rb +18 -0
  310. data/features/data/cookbooks_not_uploaded_at_feature_start/version_updated/attributes/attributes.rb +1 -0
  311. data/features/data/cookbooks_not_uploaded_at_feature_start/version_updated/metadata.json +29 -0
  312. data/features/data/cookbooks_not_uploaded_at_feature_start/version_updated/metadata.rb +6 -0
  313. data/features/data/cookbooks_not_uploaded_at_feature_start/version_updated/recipes/default.rb +2 -0
  314. data/features/data/cookbooks_not_uploaded_at_feature_start/versions/metadata.json +38 -0
  315. data/features/data/cookbooks_not_uploaded_at_feature_start/versions/metadata.rb +5 -0
  316. data/features/data/cookbooks_not_uploaded_at_feature_start/versions/recipes/default.rb +5 -0
  317. data/features/data/gems/Marshal.4.8 +0 -0
  318. data/features/data/gems/Marshal.4.8.Z +0 -0
  319. data/features/data/gems/latest_specs.4.8 +0 -0
  320. data/features/data/gems/latest_specs.4.8.gz +0 -0
  321. data/features/data/gems/prerelease_specs.4.8 +0 -0
  322. data/features/data/gems/prerelease_specs.4.8.gz +0 -0
  323. data/features/data/gems/quick/Marshal.4.8/chef-integration-test-0.1.0.gemspec.rz +0 -0
  324. data/features/data/gems/quick/Marshal.4.8/chef-integration-test-0.1.1.gemspec.rz +0 -0
  325. data/features/data/gems/quick/chef-integration-test-0.1.0.gemspec.rz +0 -0
  326. data/features/data/gems/quick/chef-integration-test-0.1.1.gemspec.rz +0 -0
  327. data/features/data/gems/quick/index +2 -0
  328. data/features/data/gems/quick/index.rz +0 -0
  329. data/features/data/gems/quick/latest_index +1 -0
  330. data/features/data/gems/quick/latest_index.rz +0 -0
  331. data/features/data/gems/specs.4.8 +0 -0
  332. data/features/data/gems/specs.4.8.gz +0 -0
  333. data/features/data/gems/yaml +122 -0
  334. data/features/data/gems/yaml.Z +0 -0
  335. data/features/data/json_attribs/attribute_settings.json +3 -0
  336. data/features/data/json_attribs/json_runlist_and_attrs.json +4 -0
  337. data/features/data/myapp.bundle +0 -0
  338. data/features/data/node-load-test.rb +84 -0
  339. data/features/data/node-simple.rb +18 -0
  340. data/features/data/repositories/chef-repo/.gitignore +2 -0
  341. data/features/data/repositories/chef-repo/README.md +66 -0
  342. data/features/data/repositories/chef-repo/Rakefile +65 -0
  343. data/features/data/repositories/chef-repo/certificates/README.md +19 -0
  344. data/features/data/repositories/chef-repo/config/rake.rb +38 -0
  345. data/features/data/repositories/chef-repo/cookbooks/README.md +53 -0
  346. data/features/data/repositories/chef-repo/data_bags/README.md +23 -0
  347. data/features/data/repositories/chef-repo/roles/README.md +16 -0
  348. data/features/data/repositories/cookbooks/hosts/attributes/hosts.rb +1 -0
  349. data/features/data/repositories/cookbooks/hosts/cc.gemspec +36 -0
  350. data/features/data/repositories/cookbooks/hosts/metadata.json +41 -0
  351. data/features/data/repositories/cookbooks/hosts/metadata.rb +4 -0
  352. data/features/data/repositories/cookbooks/hosts/recipes/default.rb +6 -0
  353. data/features/data/repositories/cookbooks/hosts/templates/default/hosts.erb +27 -0
  354. data/features/data/search-tests/do_knife_search_test.rb +175 -0
  355. data/features/data/search-tests/search-test-nodes.rb +174 -0
  356. data/features/data/test_git_repo.tar.gz +0 -0
  357. data/features/file_steps.feature +70 -0
  358. data/features/files.feature +30 -16
  359. data/features/ssh.feature +2 -1
  360. data/features/ssh_steps.feature +20 -0
  361. data/features/step_definitions/cuken_steps.rb +10 -0
  362. data/features/support/env.rb +1 -0
  363. data/lib/cuken/api/chef.rb +115 -0
  364. data/lib/cuken/api/chef/common.rb +80 -0
  365. data/lib/cuken/api/file.rb +23 -3
  366. data/lib/cuken/chef.rb +3 -0
  367. data/lib/cuken/common.rb +0 -1
  368. data/lib/cuken/cucumber/chef.rb +16 -0
  369. data/lib/cuken/cucumber/chef/common.rb +68 -0
  370. data/lib/cuken/cucumber/chef/cookbook.rb +75 -0
  371. data/lib/cuken/cucumber/chef/cookbook_steps.rb +406 -0
  372. data/lib/cuken/cucumber/chef/deploy_steps.rb +84 -0
  373. data/lib/cuken/cucumber/chef/done_directory_steps.rb +41 -0
  374. data/lib/cuken/cucumber/chef/done_file_steps.rb +107 -0
  375. data/lib/cuken/cucumber/chef/done_knife_steps.rb +34 -0
  376. data/lib/cuken/cucumber/chef/fixture_steps.rb +413 -0
  377. data/lib/cuken/cucumber/chef/knife.rb +34 -0
  378. data/lib/cuken/cucumber/chef/node.rb +27 -0
  379. data/lib/cuken/cucumber/chef/node_steps.rb +88 -0
  380. data/lib/cuken/cucumber/chef/packages.rb +144 -0
  381. data/lib/cuken/cucumber/chef/pending_steps.rb +21 -0
  382. data/lib/cuken/cucumber/chef/recipe_steps.rb +23 -0
  383. data/lib/cuken/cucumber/chef/request_steps.rb +98 -0
  384. data/lib/cuken/cucumber/chef/response_steps.rb +233 -0
  385. data/lib/cuken/cucumber/chef/result_steps.rb +15 -0
  386. data/lib/cuken/cucumber/chef/run_client_steps.rb +260 -0
  387. data/lib/cuken/cucumber/chef/run_solo.rb +78 -0
  388. data/lib/cuken/cucumber/chef/sandbox_steps.rb +137 -0
  389. data/lib/cuken/cucumber/chef/search_steps.rb +70 -0
  390. data/lib/cuken/cucumber/chef/webrat_steps.rb +39 -0
  391. data/lib/cuken/cucumber/cmd.rb +18 -1
  392. data/lib/cuken/cucumber/common.rb +4 -0
  393. data/lib/cuken/cucumber/file.rb +25 -27
  394. data/lib/cuken/cucumber/ssh.rb +6 -6
  395. metadata +427 -27
  396. data/LICENSE.txt +0 -20
@@ -0,0 +1,80 @@
1
+ module ::Cuken
2
+ module Api
3
+ module Chef
4
+ module Common
5
+
6
+ include Grit
7
+
8
+ attr_accessor :recipe, :cookbook, :api_response, :inflated_response, :log_level,
9
+ :chef_args, :config_file, :stdout, :stderr, :status, :exception,
10
+ :gemserver_thread, :sandbox_url,
11
+ :uri, :client_private_key_path, :admin_client_name,
12
+ :client_name, :client_knife_path, :cookbook_paths, :cookbooks_paths,
13
+ :knife_debug, :local_cookbook_repo, :remote_cookbook_repo,
14
+ :local_chef_repo, :remote_chef_repo
15
+
16
+ def self.ohai
17
+ # ohai takes a while, so only ever run it once.
18
+ @ohai ||= begin
19
+ o = Ohai::System.new
20
+ o.all_plugins
21
+ o
22
+ end
23
+ end
24
+
25
+ def ohai
26
+ ::Cuken::Api::Chef::Common.ohai
27
+ end
28
+
29
+ def chef
30
+ @remote_chef_repo ||= "git://github.com/opscode/chef-repo.git"
31
+ @knife_debug = true if @knife_debug.nil?
32
+ @cookbooks_paths ||= []
33
+ @cookbook_paths ||= []
34
+ @chef ||= self
35
+ end
36
+
37
+ def knife
38
+ 'knife '
39
+ end
40
+
41
+ def client
42
+ @client ||= begin
43
+ c = ::Chef::Client.new
44
+ c.ohai = ohai
45
+ c
46
+ end
47
+ end
48
+
49
+ def make_admin
50
+ admin_client
51
+ @rest = ::Chef::REST.new(Chef::Config[:registration_url], 'bobo', "#{tmpdir}/bobo.pem")
52
+ #Chef::Config[:client_key] = "#{tmpdir}/bobo.pem"
53
+ #Chef::Config[:node_name] = "bobo"
54
+ end
55
+
56
+ def make_non_admin
57
+ r = ::Chef::REST.new(::Chef::Config[:registration_url], ::Chef::Config[:validation_client_name], ::Chef::Config[:validation_key])
58
+ r.register("not_admin", "#{tmpdir}/not_admin.pem")
59
+ c = ::Chef::ApiClient.cdb_load("not_admin")
60
+ c.cdb_save
61
+ @rest = ::Chef::REST.new(::Chef::Config[:registration_url], 'not_admin', "#{tmpdir}/not_admin.pem")
62
+ #Chef::Config[:client_key] = "#{tmpdir}/not_admin.pem"
63
+ #Chef::Config[:node_name] = "not_admin"
64
+ end
65
+
66
+ def admin_client
67
+ unless @admin_client
68
+ r = ::Chef::REST.new(::Chef::Config[:registration_url], ::Chef::Config[:validation_client_name], ::Chef::Config[:validation_key])
69
+ r.register("bobo", "#{tmpdir}/bobo.pem")
70
+ c = ::Chef::ApiClient.cdb_load("bobo")
71
+ c.admin(true)
72
+ c.cdb_save
73
+ @admin_client = c
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -6,7 +6,27 @@ module Cuken
6
6
  module File
7
7
  include Etc
8
8
 
9
- def parse_mode(mode)
9
+ def check_file_content(file, partial_content, expect_match, times = 1)
10
+ regexp = regexp(partial_content)
11
+ seen_count = 0
12
+ prep_for_fs_check do
13
+ content = IO.read(file)
14
+ while (seen_count < times.to_i || content =~ regexp)do
15
+ if content =~ regexp
16
+ content = content.sub(regexp,'')
17
+ seen_count+=1
18
+ end
19
+ end
20
+ if expect_match
21
+ seen_count.should == times.to_i
22
+ else
23
+ seen_count.should_not == times.to_i
24
+ end
25
+ end
26
+ end
27
+
28
+ def parse_mode(mode, octal=false)
29
+ return mode.to_s if octal
10
30
  if mode.respond_to?(:oct)
11
31
  mode.oct.to_s(8)
12
32
  else
@@ -21,10 +41,10 @@ module Cuken
21
41
  end
22
42
  end
23
43
 
24
- def check_octalmodes(expected_mode, filename)
44
+ def check_modes(expected_mode, filename, octal = false)
25
45
  in_current_dir do
26
46
  cstats = ::File.stat(filename)
27
- parse_mode(cstats.mode)[/#{parse_mode(expected_mode)}\Z/].should_not be_nil
47
+ parse_mode(cstats.mode, octal).should match /#{expected_mode}\Z/# ].should_not be_nil
28
48
  end
29
49
  end
30
50
 
@@ -0,0 +1,3 @@
1
+ require 'cuken/common'
2
+ require 'cuken/api/chef'
3
+ require 'cuken/cucumber/chef'
@@ -3,4 +3,3 @@ require 'aruba/cucumber' unless defined? Aruba
3
3
 
4
4
  require 'cuken/api/common'
5
5
  require 'cuken/cucumber/common'
6
-
@@ -0,0 +1,16 @@
1
+ load 'aruba/cucumber.rb' unless defined? ::Aruba
2
+ require 'grit'
3
+
4
+ World(::Cuken::Api::Chef)
5
+
6
+ Before do
7
+ @aruba_timeout_seconds.nil? || @aruba_timeout_seconds < 20 ? @aruba_timeout_seconds = 20 : @aruba_timeout_seconds
8
+ end
9
+
10
+ Before('@work_in_cwd') do
11
+ @dirs = [Pathname.getwd.expand_path.realpath.to_s]
12
+ end
13
+
14
+ require 'cuken/cucumber/chef/common'
15
+ require 'cuken/cucumber/chef/knife'
16
+ require 'cuken/cucumber/chef/cookbook'
@@ -0,0 +1,68 @@
1
+ #
2
+ # Author:: Hedgehog (<hedgehogshiatus@gmail.com>)
3
+ # Copyright:: Copyright (c) 2011 Hedgehog.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ World(::Cuken::Api::Chef)
18
+
19
+ Before do
20
+ @aruba_timeout_seconds.nil? || @aruba_timeout_seconds < 3 ? @aruba_timeout_seconds = 3 : @aruba_timeout_seconds
21
+ end
22
+
23
+ Given /^the Chef server URI "([^"]*)"$/ do |uri|
24
+ chef.uri = uri
25
+ end
26
+
27
+ Given /^the Chef client "([^"]*)"$/ do |name|
28
+ chef.client_name = name
29
+ end
30
+
31
+ Given /^the Chef admin client "([^"]*)"$/ do |name|
32
+ chef.admin_client_name = name
33
+ end
34
+
35
+ Given /^the Chef client private key path "([^"]*)"$/ do |path|
36
+ in_current_dir do
37
+ chef.client_private_key_path = Pathname(path)
38
+ end
39
+ end
40
+
41
+ Given /^the remote chef repository "([^"]*)"$/ do |chf_pth|
42
+ in_current_dir do
43
+ chef.remote_chef_repo = Pathname(chf_pth).expand_path.realdirpath
44
+ end
45
+ end
46
+
47
+ Given /^the local chef repository "([^"]*)"$/ do |chf_pth|
48
+ in_current_dir do
49
+ chef.local_chef_repo = Pathname(chf_pth).expand_path.realdirpath
50
+ end
51
+ end
52
+
53
+ Then /^the local chef repository exists$/ do
54
+ chef.local_chef_repo.exist?.should be_true
55
+ #TODO: check_file_presence([file], true), etc.
56
+ end
57
+
58
+ Given /^I clone the remote chef repository branch "([^"]*)" to "([^"]*)"$/ do |brnch, path|
59
+ @chef_repo_path = "We are here..."
60
+ chef.local_chef_repo = chef_clone_repo(path, false, chef.remote_chef_repo, brnch)
61
+ end
62
+
63
+ Given /^a default base chef repository in "([^"]*)"$/ do |path|
64
+ chef.local_chef_repo = chef_clone_repo(path)
65
+ chef.local_chef_repo.exist?.should be_true
66
+ end
67
+
68
+
@@ -0,0 +1,75 @@
1
+ #
2
+ # Author:: Hedgehog (<hedgehogshiatus@gmail.com>)
3
+ # Copyright:: Copyright (c) 2011 Hedgehog.
4
+ # Portions of this work are derived from the Chef project
5
+ # The original license header follows:
6
+ #
7
+ # Author:: Adam Jacob (<adam@opscode.com>)
8
+ # Author:: Christopher Walters (<cw@opscode.com>)
9
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
10
+ # Copyright:: Copyright (c) 2008, 2010 Opscode, Inc.
11
+ # License:: Apache License, Version 2.0
12
+ #
13
+ # Licensed under the Apache License, Version 2.0 (the "License");
14
+ # you may not use this file except in compliance with the License.
15
+ # You may obtain a copy of the License at
16
+ #
17
+ # http://www.apache.org/licenses/LICENSE-2.0
18
+ #
19
+ # Unless required by applicable law or agreed to in writing, software
20
+ # distributed under the License is distributed on an "AS IS" BASIS,
21
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ # See the License for the specific language governing permissions and
23
+ # limitations under the License.
24
+ #
25
+
26
+ Given /^the remote cookbook repository "([^"]*)"$/ do |ckbk_repo|
27
+ in_current_dir do
28
+ chef.remote_cookbook_repo = Pathname(ckbk_repo).expand_path.realdirpath
29
+ end
30
+ end
31
+
32
+ Given /^the local cookbook repository "([^"]*)"$/ do |ckbk_repo|
33
+ in_current_dir do
34
+ chef.local_cookbook_repo = Pathname(ckbk_repo).expand_path.realdirpath
35
+ end
36
+ end
37
+
38
+ Then /^the local cookbook repository exists$/ do
39
+ chef.local_cookbook_repo.exist?.should be_true
40
+ #TODO: check_file_presence([file], true), etc.
41
+ end
42
+
43
+ Given /^a cookbook path "([^"]*)"$/ do |path|
44
+ in_current_dir do
45
+ chef.cookbook_paths << Pathname(path).expand_path.realdirpath
46
+ end
47
+ end
48
+
49
+ Then /^the local cookbook "([^"]*)" exists$/ do |ckbk|
50
+ chef.cookbook_paths.each do |pn|
51
+ curr_ckbk = pn.basename.to_s
52
+ curr_ckbk.should == ckbk if curr_ckbk == ckbk
53
+ end
54
+ #TODO: check_file_presence([file], true), etc.
55
+ end
56
+
57
+ Given /^I clone the remote cookbook repository branch "([^"]*)" to "([^"]*)"$/ do |brnch, ckbk_path|
58
+ chef.local_cookbook_repo = chef_clone_repo(ckbk_path, true, chef.remote_cookbook_repo, brnch)
59
+ end
60
+
61
+ When /^I successfully generate all cookbook metadata$/ do
62
+ chef.cookbook_paths.each do |pn|
63
+ curr_ckbk = pn.basename.to_s
64
+ run_knife_command("cookbook metadata #{curr_ckbk}")
65
+ end
66
+ end
67
+
68
+ When /^I successfully generate cookbook "([^"]*)" metadata$/ do |ckbk|
69
+ chef.cookbook_paths.each do |pn|
70
+ curr_ckbk = pn.basename.to_s
71
+ if curr_ckbk == ckbk
72
+ run_knife_command("cookbook metadata #{curr_ckbk}")
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,406 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008, 2010 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require 'chef/cookbook/file_system_file_vendor'
22
+
23
+ def compare_manifests(manifest1, manifest2)
24
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
25
+ next unless manifest1[segment]
26
+ manifest2.should have_key(segment)
27
+
28
+ manifest2_records_by_path = manifest2[segment].inject({}) {|memo,manifest2_record| memo[manifest2_record[:path]] = manifest2_record; memo}
29
+ manifest1[segment].each do |manifest1_record|
30
+ path = manifest1_record[:path]
31
+
32
+ manifest2_records_by_path.should have_key(path)
33
+ manifest1_record.should == manifest2_records_by_path[path]
34
+ end
35
+ end
36
+ end
37
+
38
+ Before do
39
+ save_cookbook_path = Chef::Config[:cookbook_path]
40
+ FileUtils.mkdir "#{datadir}/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_empty" unless File.exist?("#{datadir}/cookbooks_not_uploaded_at_feature_start/testcookbook_invalid_empty")
41
+ Chef::Config[:cookbook_path] = File.join(datadir, "cookbooks_not_uploaded_at_feature_start")
42
+ Chef::Cookbook::FileVendor.on_create {|manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest) }
43
+ @cookbook_loader_not_uploaded_at_feature_start = Chef::CookbookLoader.new
44
+ Chef::Config[:cookbook_path] = save_cookbook_path
45
+ end
46
+
47
+ #Given /^a local cookbook repository$/ do
48
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir'))
49
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir', 'cookbooks'))
50
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir', 'config'))
51
+ # system("cp #{datadir}/Rakefile #{tmpdir}/cookbooks_dir")
52
+ # system("cp -r #{datadir}/config/* #{tmpdir}/cookbooks_dir/config")
53
+ # system("cp -r #{datadir}/cookbooks/* #{tmpdir}/cookbooks_dir/cookbooks")
54
+ # cleanup_dirs << "#{tmpdir}/cookbooks_dir"
55
+ #end
56
+
57
+ #Given /^a local cookbook named '(.+)'$/ do |cb|
58
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir'))
59
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir', 'cookbooks'))
60
+ # Dir.mkdir(File.join(tmpdir, 'cookbooks_dir', 'config'))
61
+ # system("cp #{datadir}/Rakefile #{tmpdir}/cookbooks_dir")
62
+ # system("cp -r #{datadir}/config/* #{tmpdir}/cookbooks_dir/config")
63
+ # system("cp -r #{datadir}/cookbooks/#{cb} #{tmpdir}/cookbooks_dir/cookbooks")
64
+ # cleanup_dirs << "#{tmpdir}/cookbooks_dir"
65
+ #end
66
+
67
+ Given "I upload the cookbook" do
68
+ cookbook_name, recipe_name = recipe.split('::')
69
+ shell_out!("#{KNIFE_CMD} cookbook upload -c #{KNIFE_CONFIG} -a -o #{INTEGRATION_COOKBOOKS}")
70
+ end
71
+
72
+ Given /^I delete the cookbook's on disk checksum files$/ do
73
+ #pp :checksums => @last_uploaded_cookbook.checksums.keys
74
+ #pending # express the regexp above with the code you wish you had
75
+ @last_uploaded_cookbook.checksums.keys.each do |file_checksum|
76
+ file_location_in_checksum_repo = File.join(datadir, 'repo', 'checksums', file_checksum[0...2], file_checksum)
77
+ #pp :expected_cksum_path => {file_checksum => file_location_in_checksum_repo}
78
+ #puts "deleting checksum file #{file_location_in_checksum_repo}"
79
+ FileUtils.rm(file_location_in_checksum_repo)
80
+ end
81
+ end
82
+
83
+ #When /^I run the task to generate cookbook metadata for '(.+)'$/ do |cb|
84
+ # self.cookbook = cb
85
+ # When('I run the task to generate cookbook metadata')
86
+ #end
87
+ #
88
+ #When /^I run the task to generate cookbook metadata$/ do
89
+ # to_run = "#{KNIFE_CMD} cookbook metadata"
90
+ # if cookbook
91
+ # to_run += " #{cookbook}"
92
+ # else
93
+ # to_run += " -a"
94
+ # end
95
+ # to_run += " -o #{File.join(tmpdir, 'cookbooks_dir', 'cookbooks')}"
96
+ # Dir.chdir(File.join(tmpdir, 'cookbooks_dir', 'cookbooks')) do
97
+ # self.status = Chef::Mixin::Command.popen4(to_run) do |p, i, o, e|
98
+ # self.stdout = o.gets(nil)
99
+ # self.stderr = o.gets(nil)
100
+ # end
101
+ # end
102
+ #end
103
+
104
+ #####
105
+ # Cookbook upload/download-specific steps
106
+ #####
107
+
108
+ When /^I create a versioned cookbook(?: named '(.*?)')?(?: versioned '(.*?)')? with '(.*?)'$/ do |request_name, request_version, cookbook_name|
109
+ cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name]
110
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless cookbook
111
+
112
+ begin
113
+ self.api_response = rest.put_rest("/cookbooks/#{request_name}/#{request_version}", cookbook)
114
+ self.inflated_response = api_response
115
+ rescue => e
116
+ self.exception = e
117
+ end
118
+ end
119
+
120
+ # The argument handling in the above step defn isn't working for me, so dup city.
121
+ # :/
122
+ When "I create a cookbook named '$cookbook_name' with only the metadata file" do |cookbook_name|
123
+ cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name.to_sym]
124
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless cookbook
125
+
126
+ begin
127
+ self.api_response = rest.put_rest("/cookbooks/#{cookbook_name}/1.0.0", cookbook)
128
+ self.inflated_response = api_response
129
+ rescue => e
130
+ Chef::Log.debug("Caught exception #{e} from HTTP request")
131
+ self.exception = e
132
+ end
133
+ end
134
+
135
+ When /^I create a sandbox named '(.+)' for cookbook '([^\']+)'(?: minus files '(.+)')?$/ do |sandbox_name, cookbook_name, filenames_to_exclude|
136
+ cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name]
137
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless cookbook
138
+
139
+ if filenames_to_exclude
140
+ filenames_to_exclude = filenames_to_exclude.split(",").inject({}) { |memo, filename| memo[filename] = 1; memo }
141
+ else
142
+ filenames_to_exclude = Hash.new
143
+ end
144
+
145
+ # add all the checksums from the given cookbook into the sandbox.
146
+ checksums = Hash.new
147
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
148
+ next unless cookbook.manifest[segment]
149
+ cookbook.manifest[segment].each do |manifest_record|
150
+ # include the checksum, unless it was included in the filenames to exclude
151
+ checksums[manifest_record[:checksum]] = nil unless filenames_to_exclude.has_key?(manifest_record[:path])
152
+ end
153
+ end
154
+
155
+ sandbox = {
156
+ :checksums => checksums
157
+ }
158
+
159
+ begin
160
+ self.api_response = self.inflated_response = nil
161
+ self.exception = nil
162
+
163
+ self.inflated_response = rest.post_rest('/sandboxes', sandbox)
164
+ self.sandbox_url = self.inflated_response['uri']
165
+
166
+ @stash['sandbox_response'] = self.inflated_response
167
+ rescue
168
+ Chef::Log.debug("Caught exception in sandbox create (POST) request: #{$!.message}: #{$!.backtrace.join("\n")}")
169
+ self.exception = $!
170
+ end
171
+ end
172
+
173
+ Then /^I upload a file named '(.+)' from cookbook '(.+)' to the sandbox/ do |path, cookbook_name|
174
+ cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name]
175
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless cookbook
176
+
177
+ if path =~ /([^\/]+)\/(.+)/
178
+ segment, path_no_segment = $1, $2
179
+ else
180
+ segment = :root_files
181
+ path_no_segment = path
182
+ end
183
+ if cookbook.manifest[segment]
184
+ manifest_record = cookbook.manifest[segment].find {|manifest_record| manifest_record[:path] == path }
185
+ end
186
+ raise ArgumentError, "no such file in cookbooks_not_uploaded_at_feature_start/#{cookbook_name}: #{path}" unless manifest_record
187
+
188
+ full_path = File.join(datadir, "cookbooks_not_uploaded_at_feature_start", cookbook_name, path)
189
+
190
+ begin
191
+ url = @stash['sandbox_response']['checksums'][manifest_record[:checksum]]['url']
192
+ upload_to_sandbox(full_path, manifest_record[:checksum], url)
193
+ rescue
194
+ Chef::Log.debug("Caught exception in cookbook/sandbox checksum upload (PUT) request: #{$!.message}: #{$!.backtrace.join("\n")}")
195
+ self.exception = $!
196
+ end
197
+ end
198
+
199
+ # Shortcut for uploading a whole cookbook based on data in the
200
+ # cookbooks_not_uploaded_at_feature_start directory
201
+ Then /I fully upload a sandboxed cookbook (force-)?named '([^\']+)' versioned '([^\']+)' with '(.+)'/ do |forced, request_name, request_version, cookbook_name|
202
+ @last_uploaded_cookbook = cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name]
203
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless cookbook
204
+
205
+ # If they said 'force-named', we will reach into the cookbook and change its
206
+ # name. This is to get around the fact that CookbookLoader uses the
207
+ # directory name as the cookbook name. This is super awesome right here.
208
+ if forced == "force-"
209
+ # If the paths contain the name of the old cookbook name, change it to the
210
+ # new cookbook name.
211
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
212
+ next unless cookbook.manifest[segment]
213
+ cookbook.manifest[segment].each do |manifest_record|
214
+ if manifest_record[:path] =~ /^(.+)\/#{cookbook.name}\/(.+)$/
215
+ manifest_record[:path] = "#{$1}/#{request_name}/#{$2}"
216
+ end
217
+ end
218
+ end
219
+ cookbook.name = request_name
220
+ cookbook.manifest[:cookbook_name] = request_name
221
+ cookbook.manifest[:name] = "#{cookbook.manifest[:cookbook_name]}-#{cookbook.manifest[:version]}"
222
+ end
223
+
224
+ When "I create a sandbox named 'sandbox1' for cookbook '#{cookbook_name}'"
225
+ Then "the inflated responses key 'uri' should match '^http://.+/sandboxes/[^\/]+$'"
226
+
227
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
228
+ next unless cookbook.manifest[segment]
229
+ cookbook.manifest[segment].each do |manifest_record|
230
+ full_path = File.join(datadir, "cookbooks_not_uploaded_at_feature_start", cookbook_name, manifest_record[:path])
231
+
232
+ begin
233
+ csum_entry = @stash['sandbox_response']['checksums'][manifest_record[:checksum]]
234
+ next unless csum_entry['url']
235
+ url = @stash['sandbox_response']['checksums'][manifest_record[:checksum]]['url']
236
+ upload_to_sandbox(full_path, manifest_record[:checksum], url)
237
+ rescue
238
+ Chef::Log.debug("Caught exception in cookbook/sandbox checksum upload (PUT) request: #{$!.message}: #{$!.backtrace.join("\n")}")
239
+ self.exception = $!
240
+ end
241
+ Then "the response code should be '200'"
242
+ end
243
+ end
244
+
245
+ When "I commit the sandbox"
246
+ Then "I should not get an exception"
247
+ When "I create a versioned cookbook named '#{request_name}' versioned '#{request_version}' with '#{cookbook_name}'"
248
+ Then "I should not get an exception"
249
+ end
250
+
251
+ When /I download the cookbook manifest for '(.+)' version '(.+)'$/ do |cookbook_name, cookbook_version|
252
+ self.api_response = self.inflated_response = self.exception = nil
253
+
254
+ When "I 'GET' to the path '/cookbooks/#{cookbook_name}/#{cookbook_version}'"
255
+ @downloaded_cookbook = self.inflated_response
256
+ end
257
+
258
+ Then /the downloaded cookbook manifest contents should match '(.+)'$/ do |cookbook_name|
259
+ expected_cookbook = @cookbook_loader_not_uploaded_at_feature_start[cookbook_name]
260
+ raise ArgumentError, "no such cookbook in cookbooks_not_uploaded_at_feature_start: #{cookbook_name}" unless expected_cookbook
261
+
262
+ downloaded_cookbook_manifest = Mash.new(@downloaded_cookbook.manifest)
263
+ downloaded_cookbook_manifest.delete("uri")
264
+
265
+ # remove the uri's from the manifest records
266
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
267
+ next unless downloaded_cookbook_manifest[segment]
268
+ downloaded_cookbook_manifest[segment].each do |downloaded_manifest_record|
269
+ downloaded_manifest_record.delete("url")
270
+ end
271
+ end
272
+
273
+ # ensure that each file expected (from the cookbook on disk) was downloaded,
274
+ # and then do the opposite.
275
+ begin
276
+ compare_manifests(expected_cookbook.manifest, downloaded_cookbook_manifest)
277
+ compare_manifests(downloaded_cookbook_manifest, expected_cookbook.manifest)
278
+ rescue
279
+ pp({:expected_cookbook_manifest => expected_cookbook.manifest})
280
+ pp({:downloaded_cookbook_manifest => downloaded_cookbook_manifest})
281
+
282
+ raise
283
+ end
284
+ end
285
+
286
+ When /I download the file '([^\']+)' from the downloaded cookbook manifest/ do |path|
287
+ raise "no @downloaded_cookbook" unless @downloaded_cookbook
288
+
289
+ # TODO: timh, 2010-5-26: Cookbook really should have a "get me a file by its
290
+ # path" method.
291
+ if path =~ /^([^\/]+)\/(.+)$/
292
+ segment, path_in_segment = $1, $2
293
+ else
294
+ segment = :root_files
295
+ path_in_segment = path
296
+ end
297
+
298
+ raise "no such file #{path}" unless @downloaded_cookbook.manifest[segment]
299
+ found_manifest_record = @downloaded_cookbook.manifest[segment].find {|manifest_record| manifest_record[:path] == path}
300
+ raise "no such file #{path}" unless found_manifest_record
301
+
302
+ begin
303
+ cookbook_name = @downloaded_cookbook.name
304
+ cookbook_version = @downloaded_cookbook.version
305
+
306
+ checksum = found_manifest_record[:checksum]
307
+
308
+ self.api_response = nil
309
+ self.inflated_response = nil
310
+ self.exception = nil
311
+
312
+ url = found_manifest_record[:url]
313
+ downloaded_cookbook_file = rest.get_rest(url, true)
314
+ @downloaded_cookbook_file_contents = IO.read(downloaded_cookbook_file.path)
315
+ rescue
316
+ self.exception = $!
317
+ end
318
+ end
319
+
320
+ Then /^the downloaded cookbook file contents should match the pattern '(.+)'$/ do |pattern|
321
+ raise "no @downloaded_cookbook_file_contents" unless @downloaded_cookbook_file_contents
322
+
323
+ @downloaded_cookbook_file_contents.should =~ /#{pattern}/
324
+ end
325
+
326
+ Then /^the dependencies in its metadata should be an empty hash$/ do
327
+ inflated_response.metadata.dependencies.should == {}
328
+ end
329
+
330
+ Then /^the metadata should include a dependency on '(.+)'$/ do |key|
331
+ inflated_response.metadata.dependencies.should have_key(key)
332
+ end
333
+
334
+ RSpec::Matchers.define :have_been_deleted do
335
+ match do |file_name|
336
+ ! File.exist?(file_name)
337
+ end
338
+ failure_message_for_should do |file_name|
339
+ "Expected file #{file_name} to have been deleted but it was not"
340
+ end
341
+ failure_message_for_should_not do |player|
342
+ "Expected file #{file_name} to not have been deleted but it was (i.e., it should exist)"
343
+ end
344
+ description do
345
+ "The file should have been deleted"
346
+ end
347
+ end
348
+
349
+ Then /^the cookbook's files should have been deleted$/ do
350
+ #pp @last_uploaded_cookbook
351
+ @last_uploaded_cookbook.checksums.keys.each do |file_checksum|
352
+ file_location_in_checksum_repo = File.join(datadir, 'repo', 'checksums', file_checksum[0...2], file_checksum)
353
+ #pp :expected_cksum_path => {file_checksum => file_location_in_checksum_repo}
354
+ file_location_in_checksum_repo.should have_been_deleted
355
+ end
356
+ end
357
+
358
+ RSpec::Matchers.define :have_checksum_document do |checksum|
359
+ match do |checksum_list|
360
+ checksum_list.include?(checksum)
361
+ end
362
+ failure_message_for_should do |checksum_list|
363
+ "Expected checksum document #{checksum} to exist in couchdb but it is not in the list of existing checksums:\n#{checksum_list.sort.join("\n")}\n"
364
+ end
365
+ failure_message_for_should_not do |checksum_list|
366
+ "Expected checksum document #{checksum} not to exist in couchdb but it is in the list of existing checksums:\n#{checksum_list.sort.join("\n")}\n"
367
+ end
368
+ description do
369
+ "The checksum should exist"
370
+ end
371
+ end
372
+
373
+ Then /^the cookbook's checksums should be removed from couchdb$/ do
374
+ #pp @last_uploaded_cookbook
375
+ all_checksum_docs = couchdb_rest_client.get_rest('/_design/checksums/_view/all')["rows"]
376
+ checksums_in_couchdb = all_checksum_docs.map {|c| c["key"]}
377
+ #pp :checksums_in_couchdb => checksums_in_couchdb
378
+ @last_uploaded_cookbook.checksums.keys.each do |checksum|
379
+ checksums_in_couchdb.should_not have_checksum_document(checksum)
380
+ end
381
+ end
382
+
383
+ Given "I upload multiple versions of the 'version_test' cookbook" do
384
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.1.0' with 'version_test_0.1.0'"
385
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.1.1' with 'version_test_0.1.1'"
386
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.2.0' with 'version_test_0.2.0'"
387
+ end
388
+
389
+ Given "I upload multiple versions of the 'version_test' cookbook that do not lexically sort correctly" do
390
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.9.0' with 'version_test_0.9.0'"
391
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.10.0' with 'version_test_0.10.0'"
392
+ When "I fully upload a sandboxed cookbook force-named 'version_test' versioned '0.9.7' with 'version_test_0.9.7'"
393
+ end
394
+
395
+ Given "I upload the set of 'dep_test_*' cookbooks" do
396
+ %w{a b c}.each do |letter|
397
+ %w{1 2 3}.each do |number|
398
+ When "I fully upload a sandboxed cookbook force-named 'dep_test_#{letter}' versioned '#{number}.0.0' with 'dep_test_#{letter}_#{number}.0.0'"
399
+ end
400
+ end
401
+ end
402
+
403
+ Then /^cookbook '(.+)' should have version '(.+)'$/ do |cookbook, version|
404
+ Then "the inflated responses key '#{cookbook}' should exist"
405
+ Then "the inflated responses key 'dep_test_a' should match '\"version\":\"#{version}\"' as json"
406
+ end