cuken 0.1.1 → 0.1.2

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