puppet 3.2.4 → 3.3.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (562) hide show
  1. data/COMMITTERS.md +101 -42
  2. data/Gemfile +15 -4
  3. data/README.md +5 -1
  4. data/README_DEVELOPER.md +117 -54
  5. data/Rakefile +4 -0
  6. data/ext/build_defaults.yaml +3 -2
  7. data/ext/debian/puppet-common.manpages +33 -1
  8. data/ext/gentoo/init.d/puppet +1 -1
  9. data/ext/gentoo/init.d/puppetmaster +1 -1
  10. data/ext/redhat/puppet.spec.erb +0 -1
  11. data/install.rb +2 -1
  12. data/lib/hiera/backend/puppet_backend.rb +1 -1
  13. data/lib/puppet/application.rb +10 -9
  14. data/lib/puppet/application/agent.rb +87 -93
  15. data/lib/puppet/application/apply.rb +0 -2
  16. data/lib/puppet/application/device.rb +3 -3
  17. data/lib/puppet/application/kick.rb +2 -2
  18. data/lib/puppet/application/master.rb +41 -19
  19. data/lib/puppet/application/queue.rb +5 -3
  20. data/lib/puppet/bindings.rb +147 -0
  21. data/lib/puppet/configurer.rb +25 -15
  22. data/lib/puppet/configurer/fact_handler.rb +2 -9
  23. data/lib/puppet/daemon.rb +44 -33
  24. data/lib/puppet/defaults.rb +57 -26
  25. data/lib/puppet/error.rb +1 -1
  26. data/lib/puppet/external/dot.rb +2 -2
  27. data/lib/puppet/external/nagios/base.rb +1 -6
  28. data/lib/puppet/external/pson/common.rb +2 -2
  29. data/lib/puppet/external/pson/pure/generator.rb +2 -2
  30. data/lib/puppet/external/pson/pure/parser.rb +1 -1
  31. data/lib/puppet/face/ca.rb +1 -1
  32. data/lib/puppet/face/config.rb +1 -1
  33. data/lib/puppet/face/help.rb +2 -2
  34. data/lib/puppet/face/module/list.rb +2 -2
  35. data/lib/puppet/feature/rails.rb +1 -1
  36. data/lib/puppet/file_bucket/dipper.rb +0 -1
  37. data/lib/puppet/file_serving/base.rb +1 -1
  38. data/lib/puppet/file_serving/configuration/parser.rb +20 -14
  39. data/lib/puppet/forge.rb +0 -32
  40. data/lib/puppet/forge/cache.rb +1 -1
  41. data/lib/puppet/forge/errors.rb +3 -3
  42. data/lib/puppet/forge/repository.rb +7 -42
  43. data/lib/puppet/graph.rb +11 -0
  44. data/lib/puppet/graph/key.rb +26 -0
  45. data/lib/puppet/graph/prioritizer.rb +29 -0
  46. data/lib/puppet/graph/random_prioritizer.rb +16 -0
  47. data/lib/puppet/{rb_tree_map.rb → graph/rb_tree_map.rb} +3 -3
  48. data/lib/puppet/graph/relationship_graph.rb +246 -0
  49. data/lib/puppet/graph/sequential_prioritizer.rb +31 -0
  50. data/lib/puppet/{simple_graph.rb → graph/simple_graph.rb} +22 -3
  51. data/lib/puppet/graph/title_hash_prioritizer.rb +16 -0
  52. data/lib/puppet/indirector.rb +2 -2
  53. data/lib/puppet/indirector/catalog/compiler.rb +10 -7
  54. data/lib/puppet/indirector/catalog/static_compiler.rb +50 -0
  55. data/lib/puppet/indirector/certificate/rest.rb +1 -1
  56. data/lib/puppet/indirector/exec.rb +1 -1
  57. data/lib/puppet/indirector/facts/facter.rb +2 -2
  58. data/lib/puppet/indirector/facts/inventory_active_record.rb +0 -1
  59. data/lib/puppet/indirector/facts/network_device.rb +1 -1
  60. data/lib/puppet/indirector/file_bucket_file/file.rb +0 -1
  61. data/lib/puppet/indirector/indirection.rb +2 -2
  62. data/lib/puppet/indirector/memory.rb +9 -0
  63. data/lib/puppet/indirector/node/ldap.rb +2 -4
  64. data/lib/puppet/indirector/report/processor.rb +1 -2
  65. data/lib/puppet/indirector/report/rest.rb +1 -1
  66. data/lib/puppet/indirector/request.rb +32 -10
  67. data/lib/puppet/indirector/resource/rest.rb +1 -1
  68. data/lib/puppet/indirector/resource_type/parser.rb +31 -12
  69. data/lib/puppet/interface.rb +1 -1
  70. data/lib/puppet/interface/documentation.rb +7 -11
  71. data/lib/puppet/interface/option.rb +1 -1
  72. data/lib/puppet/interface/option_builder.rb +1 -1
  73. data/lib/puppet/metatype/manager.rb +2 -2
  74. data/lib/puppet/module.rb +7 -1
  75. data/lib/puppet/module_tool.rb +1 -1
  76. data/lib/puppet/module_tool/applications/application.rb +10 -0
  77. data/lib/puppet/module_tool/applications/installer.rb +6 -3
  78. data/lib/puppet/module_tool/dependency.rb +2 -0
  79. data/lib/puppet/module_tool/errors/upgrader.rb +1 -1
  80. data/lib/puppet/module_tool/metadata.rb +25 -13
  81. data/lib/puppet/module_tool/modulefile.rb +7 -7
  82. data/lib/puppet/module_tool/shared_behaviors.rb +4 -2
  83. data/lib/puppet/module_tool/skeleton.rb +1 -1
  84. data/lib/puppet/module_tool/skeleton/templates/generator/manifests/init.pp.erb +5 -5
  85. data/lib/puppet/module_tool/skeleton/templates/generator/tests/init.pp.erb +5 -4
  86. data/lib/puppet/network/auth_config_parser.rb +3 -0
  87. data/lib/puppet/network/authconfig.rb +0 -1
  88. data/lib/puppet/network/authorization.rb +1 -1
  89. data/lib/puppet/network/authstore.rb +2 -2
  90. data/lib/puppet/network/format_handler.rb +25 -114
  91. data/lib/puppet/network/format_support.rb +106 -0
  92. data/lib/puppet/network/formats.rb +10 -4
  93. data/lib/puppet/network/http/compression.rb +1 -1
  94. data/lib/puppet/network/http/connection.rb +76 -32
  95. data/lib/puppet/network/http/handler.rb +122 -61
  96. data/lib/puppet/network/http/rack/rest.rb +1 -1
  97. data/lib/puppet/network/http/webrick/rest.rb +9 -3
  98. data/lib/puppet/network/http_pool.rb +2 -2
  99. data/lib/puppet/network/resolver.rb +1 -0
  100. data/lib/puppet/network/server.rb +5 -81
  101. data/lib/puppet/node/environment.rb +256 -13
  102. data/lib/puppet/node/facts.rb +28 -2
  103. data/lib/puppet/parameter.rb +27 -18
  104. data/lib/puppet/parameter/boolean.rb +20 -0
  105. data/lib/puppet/parameter/path.rb +1 -1
  106. data/lib/puppet/parameter/value.rb +1 -1
  107. data/lib/puppet/parameter/value_collection.rb +1 -1
  108. data/lib/puppet/parser/ast/arithmetic_operator.rb +8 -0
  109. data/lib/puppet/parser/ast/casestatement.rb +0 -3
  110. data/lib/puppet/parser/ast/lambda.rb +25 -6
  111. data/lib/puppet/parser/ast/leaf.rb +10 -3
  112. data/lib/puppet/parser/ast/nop.rb +1 -1
  113. data/lib/puppet/parser/ast/resource_override.rb +0 -2
  114. data/lib/puppet/parser/compiler.rb +92 -34
  115. data/lib/puppet/parser/files.rb +0 -5
  116. data/lib/puppet/parser/functions/create_resources.rb +23 -46
  117. data/lib/puppet/parser/functions/each.rb +0 -2
  118. data/lib/puppet/parser/functions/extlookup.rb +2 -2
  119. data/lib/puppet/parser/functions/foreach.rb +0 -2
  120. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  121. data/lib/puppet/parser/functions/lookup.rb +44 -0
  122. data/lib/puppet/parser/functions/slice.rb +1 -1
  123. data/lib/puppet/parser/grammar.ra +0 -1
  124. data/lib/puppet/parser/lexer.rb +0 -1
  125. data/lib/puppet/parser/parser.rb +0 -1
  126. data/lib/puppet/parser/parser_factory.rb +3 -2
  127. data/lib/puppet/parser/parser_support.rb +1 -1
  128. data/lib/puppet/parser/relationship.rb +1 -1
  129. data/lib/puppet/parser/scope.rb +49 -24
  130. data/lib/puppet/parser/type_loader.rb +13 -18
  131. data/lib/puppet/pops.rb +45 -0
  132. data/lib/puppet/pops/adaptable.rb +2 -2
  133. data/lib/puppet/pops/adapters.rb +4 -0
  134. data/lib/puppet/pops/binder/binder.rb +421 -0
  135. data/lib/puppet/pops/binder/binder_issues.rb +142 -0
  136. data/lib/puppet/pops/binder/bindings_checker.rb +217 -0
  137. data/lib/puppet/pops/binder/bindings_composer.rb +241 -0
  138. data/lib/puppet/pops/binder/bindings_factory.rb +847 -0
  139. data/lib/puppet/pops/binder/bindings_label_provider.rb +46 -0
  140. data/lib/puppet/pops/binder/bindings_loader.rb +79 -0
  141. data/lib/puppet/pops/binder/bindings_model.rb +215 -0
  142. data/lib/puppet/pops/binder/bindings_model_dumper.rb +205 -0
  143. data/lib/puppet/pops/binder/bindings_validator_factory.rb +28 -0
  144. data/lib/puppet/pops/binder/config/binder_config.rb +139 -0
  145. data/lib/puppet/pops/binder/config/binder_config_checker.rb +183 -0
  146. data/lib/puppet/pops/binder/config/diagnostic_producer.rb +32 -0
  147. data/lib/puppet/pops/binder/config/issues.rb +106 -0
  148. data/lib/puppet/pops/binder/hiera2.rb +10 -0
  149. data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +148 -0
  150. data/lib/puppet/pops/binder/hiera2/config.rb +69 -0
  151. data/lib/puppet/pops/binder/hiera2/config_checker.rb +68 -0
  152. data/lib/puppet/pops/binder/hiera2/diagnostic_producer.rb +36 -0
  153. data/lib/puppet/pops/binder/hiera2/issues.rb +67 -0
  154. data/lib/puppet/pops/binder/hiera2/json_backend.rb +18 -0
  155. data/lib/puppet/pops/binder/hiera2/yaml_backend.rb +21 -0
  156. data/lib/puppet/pops/binder/injector.rb +688 -0
  157. data/lib/puppet/pops/binder/injector_entry.rb +53 -0
  158. data/lib/puppet/pops/binder/key_factory.rb +61 -0
  159. data/lib/puppet/pops/binder/producers.rb +829 -0
  160. data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +67 -0
  161. data/lib/puppet/pops/binder/scheme_handler/confdir_scheme.rb +34 -0
  162. data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +92 -0
  163. data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +84 -0
  164. data/lib/puppet/pops/binder/scheme_handler/symbolic_scheme.rb +54 -0
  165. data/lib/puppet/pops/binder/system_bindings.rb +72 -0
  166. data/lib/puppet/pops/issue_reporter.rb +75 -0
  167. data/lib/puppet/pops/issues.rb +9 -5
  168. data/lib/puppet/pops/model/ast_transformer.rb +4 -4
  169. data/lib/puppet/pops/model/ast_tree_dumper.rb +1 -1
  170. data/lib/puppet/pops/model/factory.rb +25 -13
  171. data/lib/puppet/pops/model/model.rb +1 -1
  172. data/lib/puppet/pops/model/tree_dumper.rb +2 -2
  173. data/lib/puppet/pops/parser/egrammar.ra +0 -1
  174. data/lib/puppet/pops/parser/eparser.rb +1 -2
  175. data/lib/puppet/pops/parser/evaluating_parser.rb +162 -0
  176. data/lib/puppet/pops/parser/lexer.rb +8 -6
  177. data/lib/puppet/pops/types/class_loader.rb +118 -0
  178. data/lib/puppet/pops/types/type_calculator.rb +557 -0
  179. data/lib/puppet/pops/types/type_factory.rb +147 -0
  180. data/lib/puppet/pops/types/type_parser.rb +117 -0
  181. data/lib/puppet/pops/types/types.rb +132 -0
  182. data/lib/puppet/pops/validation.rb +146 -17
  183. data/lib/puppet/pops/validation/checker3_1.rb +1 -1
  184. data/lib/puppet/pops/validation/validator_factory_3_1.rb +6 -16
  185. data/lib/puppet/property.rb +3 -3
  186. data/lib/puppet/property/keyvalue.rb +1 -1
  187. data/lib/puppet/provider.rb +2 -2
  188. data/lib/puppet/provider/aixobject.rb +19 -21
  189. data/lib/puppet/provider/augeas/augeas.rb +3 -1
  190. data/lib/puppet/provider/command.rb +2 -2
  191. data/lib/puppet/provider/group/aix.rb +1 -1
  192. data/lib/puppet/provider/group/ldap.rb +1 -1
  193. data/lib/puppet/provider/macauthorization/macauthorization.rb +1 -1
  194. data/lib/puppet/provider/mailalias/aliases.rb +3 -8
  195. data/lib/puppet/provider/mcx/mcxcontent.rb +7 -1
  196. data/lib/puppet/provider/mount.rb +8 -3
  197. data/lib/puppet/provider/nameservice.rb +1 -1
  198. data/lib/puppet/provider/nameservice/directoryservice.rb +5 -5
  199. data/lib/puppet/provider/package/appdmg.rb +1 -1
  200. data/lib/puppet/provider/package/apt.rb +0 -1
  201. data/lib/puppet/provider/package/dpkg.rb +86 -32
  202. data/lib/puppet/provider/package/fink.rb +0 -2
  203. data/lib/puppet/provider/package/freebsd.rb +0 -2
  204. data/lib/puppet/provider/package/openbsd.rb +57 -10
  205. data/lib/puppet/provider/package/opkg.rb +0 -1
  206. data/lib/puppet/provider/package/pacman.rb +0 -1
  207. data/lib/puppet/provider/package/pip.rb +1 -1
  208. data/lib/puppet/provider/package/pkgdmg.rb +17 -6
  209. data/lib/puppet/provider/package/pkgutil.rb +1 -1
  210. data/lib/puppet/provider/package/portage.rb +9 -1
  211. data/lib/puppet/provider/package/ports.rb +2 -2
  212. data/lib/puppet/provider/package/rpm.rb +29 -12
  213. data/lib/puppet/provider/package/rug.rb +1 -1
  214. data/lib/puppet/provider/package/urpmi.rb +11 -15
  215. data/lib/puppet/provider/package/windows/exe_package.rb +1 -1
  216. data/lib/puppet/provider/package/windows/package.rb +1 -26
  217. data/lib/puppet/provider/package/yum.rb +1 -1
  218. data/lib/puppet/provider/package/zypper.rb +22 -3
  219. data/lib/puppet/provider/parsedfile.rb +1 -12
  220. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +1 -1
  221. data/lib/puppet/provider/service/base.rb +1 -1
  222. data/lib/puppet/provider/service/daemontools.rb +3 -3
  223. data/lib/puppet/provider/service/debian.rb +1 -1
  224. data/lib/puppet/provider/service/init.rb +14 -20
  225. data/lib/puppet/provider/service/openrc.rb +3 -1
  226. data/lib/puppet/provider/service/redhat.rb +5 -8
  227. data/lib/puppet/provider/service/runit.rb +3 -2
  228. data/lib/puppet/provider/service/systemd.rb +1 -1
  229. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  230. data/lib/puppet/provider/sshkey/parsed.rb +0 -2
  231. data/lib/puppet/provider/user/aix.rb +25 -12
  232. data/lib/puppet/provider/user/directoryservice.rb +4 -7
  233. data/lib/puppet/provider/user/ldap.rb +0 -1
  234. data/lib/puppet/provider/user/user_role_add.rb +2 -0
  235. data/lib/puppet/provider/user/useradd.rb +1 -1
  236. data/lib/puppet/provider/zone/solaris.rb +1 -2
  237. data/lib/puppet/reference/metaparameter.rb +1 -1
  238. data/lib/puppet/reference/type.rb +1 -1
  239. data/lib/puppet/reports/rrdgraph.rb +1 -1
  240. data/lib/puppet/reports/tagmail.rb +1 -1
  241. data/lib/puppet/resource.rb +16 -4
  242. data/lib/puppet/resource/catalog.rb +111 -173
  243. data/lib/puppet/resource/status.rb +42 -3
  244. data/lib/puppet/resource/type.rb +33 -46
  245. data/lib/puppet/resource/type_collection.rb +19 -15
  246. data/lib/puppet/run.rb +5 -1
  247. data/lib/puppet/scheduler/scheduler.rb +14 -15
  248. data/lib/puppet/settings.rb +78 -41
  249. data/lib/puppet/settings/boolean_setting.rb +0 -2
  250. data/lib/puppet/settings/config_file.rb +0 -2
  251. data/lib/puppet/settings/directory_setting.rb +0 -2
  252. data/lib/puppet/settings/duration_setting.rb +0 -2
  253. data/lib/puppet/settings/enum_setting.rb +16 -0
  254. data/lib/puppet/settings/file_setting.rb +0 -2
  255. data/lib/puppet/settings/path_setting.rb +0 -2
  256. data/lib/puppet/settings/string_setting.rb +0 -3
  257. data/lib/puppet/settings/terminus_setting.rb +0 -2
  258. data/lib/puppet/ssl/certificate_authority.rb +102 -9
  259. data/lib/puppet/test/test_helper.rb +1 -0
  260. data/lib/puppet/transaction.rb +130 -292
  261. data/lib/puppet/transaction/additional_resource_generator.rb +126 -0
  262. data/lib/puppet/transaction/event.rb +16 -1
  263. data/lib/puppet/transaction/report.rb +34 -14
  264. data/lib/puppet/transaction/resource_harness.rb +16 -19
  265. data/lib/puppet/type.rb +59 -53
  266. data/lib/puppet/type/component.rb +0 -2
  267. data/lib/puppet/type/cron.rb +13 -2
  268. data/lib/puppet/type/exec.rb +5 -7
  269. data/lib/puppet/type/file.rb +9 -32
  270. data/lib/puppet/type/file/content.rb +4 -1
  271. data/lib/puppet/type/file/ctime.rb +3 -1
  272. data/lib/puppet/type/file/ensure.rb +1 -1
  273. data/lib/puppet/type/file/mode.rb +0 -1
  274. data/lib/puppet/type/file/mtime.rb +2 -1
  275. data/lib/puppet/type/group.rb +7 -9
  276. data/lib/puppet/type/host.rb +1 -2
  277. data/lib/puppet/type/mcx.rb +0 -1
  278. data/lib/puppet/type/mount.rb +38 -6
  279. data/lib/puppet/type/package.rb +2 -2
  280. data/lib/puppet/type/resources.rb +5 -4
  281. data/lib/puppet/type/schedule.rb +1 -4
  282. data/lib/puppet/type/selmodule.rb +1 -1
  283. data/lib/puppet/type/service.rb +1 -3
  284. data/lib/puppet/type/tidy.rb +3 -3
  285. data/lib/puppet/type/user.rb +9 -13
  286. data/lib/puppet/type/yumrepo.rb +11 -7
  287. data/lib/puppet/util.rb +14 -7
  288. data/lib/puppet/util/autoload.rb +0 -1
  289. data/lib/puppet/util/backups.rb +1 -3
  290. data/lib/puppet/util/classgen.rb +1 -1
  291. data/lib/puppet/util/command_line/puppet_option_parser.rb +1 -3
  292. data/lib/puppet/util/command_line/trollop.rb +1 -1
  293. data/lib/puppet/util/constant_inflector.rb +1 -2
  294. data/lib/puppet/util/errors.rb +1 -0
  295. data/lib/puppet/util/file_watcher.rb +28 -0
  296. data/lib/puppet/util/fileparsing.rb +1 -3
  297. data/lib/puppet/util/filetype.rb +0 -1
  298. data/lib/puppet/util/http_proxy.rb +38 -0
  299. data/lib/puppet/util/ldap/manager.rb +1 -2
  300. data/lib/puppet/util/log.rb +31 -10
  301. data/lib/puppet/util/log/destinations.rb +0 -50
  302. data/lib/puppet/util/metric.rb +8 -1
  303. data/lib/puppet/util/monkey_patches.rb +14 -148
  304. data/lib/puppet/util/network_device/cisco/facts.rb +1 -1
  305. data/lib/puppet/util/network_device/config.rb +6 -9
  306. data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
  307. data/lib/puppet/util/pidlock.rb +3 -0
  308. data/lib/puppet/util/posix.rb +1 -1
  309. data/lib/puppet/util/profiler.rb +1 -1
  310. data/lib/puppet/util/rdoc.rb +1 -1
  311. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +0 -1
  312. data/lib/puppet/util/rdoc/generators/template/puppet/puppet.rb +50 -42
  313. data/lib/puppet/util/retryaction.rb +0 -1
  314. data/lib/puppet/util/symbolic_file_mode.rb +5 -1
  315. data/lib/puppet/util/tagging.rb +0 -2
  316. data/lib/puppet/util/warnings.rb +3 -0
  317. data/lib/puppet/util/watched_file.rb +37 -0
  318. data/lib/puppet/util/watcher.rb +17 -0
  319. data/lib/puppet/util/watcher/change_watcher.rb +33 -0
  320. data/lib/puppet/util/watcher/periodic_watcher.rb +37 -0
  321. data/lib/puppet/util/watcher/timer.rb +19 -0
  322. data/lib/puppet/util/windows/user.rb +1 -1
  323. data/lib/puppet/version.rb +1 -1
  324. data/lib/puppetx.rb +109 -0
  325. data/lib/puppetx/puppet/bindings_scheme_handler.rb +130 -0
  326. data/lib/puppetx/puppet/hiera2_backend.rb +31 -0
  327. data/lib/puppetx/puppet/syntax_checker.rb +91 -0
  328. data/lib/puppetx/puppetlabs/syntax_checkers/json.rb +39 -0
  329. data/lib/semver.rb +1 -1
  330. data/man/man8/puppet-kick.8 +1 -1
  331. data/spec/fixtures/integration/provider/cron/crontab/unspecialized +15 -0
  332. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/binder_config.yaml +18 -0
  333. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/hiera.yaml +8 -0
  334. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/common.yaml +1 -0
  335. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/hiera.yaml +10 -0
  336. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/binder_config.yaml +19 -0
  337. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/common.yaml +1 -0
  338. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/hiera.yaml +11 -0
  339. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/localhost.yaml +1 -0
  340. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/common.yaml +3 -0
  341. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/hiera.yaml +13 -0
  342. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppet/bindings/awesome/default.rb +4 -0
  343. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_backend.rb +11 -0
  344. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_scheme_handler.rb +18 -0
  345. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/localhost.yaml +1 -0
  346. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/common.yaml +3 -0
  347. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/hiera_config.yaml +9 -0
  348. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/common.yaml +2 -0
  349. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/hiera.yaml +11 -0
  350. data/spec/fixtures/unit/pops/binder/config/binder_config/ok/binder_config.yaml +9 -0
  351. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/hiera.yaml +9 -0
  352. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.json +9 -0
  353. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.yaml +5 -0
  354. data/spec/fixtures/unit/pops/binder/hiera2/config/bad_syntax/hiera.yaml +10 -0
  355. data/spec/fixtures/unit/pops/binder/hiera2/config/malformed_hierarchy/hiera.yaml +8 -0
  356. data/spec/fixtures/unit/pops/binder/hiera2/config/missing/foo.txt +1 -0
  357. data/spec/fixtures/unit/pops/binder/hiera2/config/no_backends/hiera.yaml +7 -0
  358. data/spec/fixtures/unit/pops/binder/hiera2/config/no_hierarchy/hiera.yaml +4 -0
  359. data/spec/fixtures/unit/pops/binder/hiera2/config/not_a_hash/hiera.yaml +2 -0
  360. data/spec/fixtures/unit/pops/binder/hiera2/config/ok/hiera.yaml +8 -0
  361. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/empty/common.yaml +0 -0
  362. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/invalid/common.yaml +1 -0
  363. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/ok/common.yaml +2 -0
  364. data/spec/fixtures/unit/provider/package/openbsd/pkginfo_flavors.list +2 -0
  365. data/spec/integration/agent/logging_spec.rb +178 -0
  366. data/spec/integration/configurer_spec.rb +1 -1
  367. data/spec/integration/defaults_spec.rb +0 -6
  368. data/spec/integration/network/authconfig_spec.rb +19 -0
  369. data/spec/integration/network/server/webrick_spec.rb +10 -11
  370. data/spec/integration/parser/catalog_spec.rb +85 -0
  371. data/spec/integration/provider/cron/crontab_spec.rb +11 -0
  372. data/spec/integration/provider/mount_spec.rb +1 -0
  373. data/spec/integration/transaction_spec.rb +8 -8
  374. data/spec/integration/type/file_spec.rb +1 -1
  375. data/spec/integration/util/settings_spec.rb +58 -11
  376. data/spec/lib/matchers/include_in_order.rb +21 -0
  377. data/spec/lib/matchers/include_in_order_spec.rb +30 -0
  378. data/spec/lib/matchers/relationship_graph_matchers.rb +48 -0
  379. data/spec/lib/puppet_spec/compiler.rb +24 -0
  380. data/spec/lib/puppet_spec/pops.rb +16 -0
  381. data/spec/spec_helper.rb +0 -1
  382. data/spec/unit/application/agent_spec.rb +145 -145
  383. data/spec/unit/application/apply_spec.rb +1 -1
  384. data/spec/unit/application/doc_spec.rb +1 -1
  385. data/spec/unit/application/face_base_spec.rb +3 -3
  386. data/spec/unit/application/facts_spec.rb +1 -0
  387. data/spec/unit/application/master_spec.rb +0 -15
  388. data/spec/unit/application/queue_spec.rb +6 -12
  389. data/spec/unit/application/resource_spec.rb +1 -1
  390. data/spec/unit/configurer/fact_handler_spec.rb +19 -50
  391. data/spec/unit/configurer_spec.rb +23 -7
  392. data/spec/unit/daemon_spec.rb +97 -121
  393. data/spec/unit/defaults_spec.rb +44 -0
  394. data/spec/unit/face/node_spec.rb +2 -2
  395. data/spec/unit/file_serving/configuration/parser_spec.rb +23 -33
  396. data/spec/unit/file_serving/configuration_spec.rb +2 -2
  397. data/spec/unit/file_serving/mount/file_spec.rb +4 -4
  398. data/spec/unit/forge/repository_spec.rb +9 -29
  399. data/spec/unit/graph/key_spec.rb +41 -0
  400. data/spec/unit/{rb_tree_map_spec.rb → graph/rb_tree_map_spec.rb} +7 -7
  401. data/spec/unit/graph/relationship_graph_spec.rb +393 -0
  402. data/spec/unit/graph/sequential_prioritizer_spec.rb +32 -0
  403. data/spec/unit/{simple_graph_spec.rb → graph/simple_graph.rb} +42 -254
  404. data/spec/unit/graph/title_hash_prioritizer_spec.rb +49 -0
  405. data/spec/unit/hiera_puppet_spec.rb +1 -1
  406. data/spec/unit/indirector/catalog/active_record_spec.rb +4 -2
  407. data/spec/unit/indirector/catalog/compiler_spec.rb +20 -26
  408. data/spec/unit/indirector/face_spec.rb +1 -1
  409. data/spec/unit/indirector/facts/facter_spec.rb +11 -1
  410. data/spec/unit/indirector/facts/network_device_spec.rb +11 -1
  411. data/spec/unit/indirector/hiera_spec.rb +1 -1
  412. data/spec/unit/indirector/instrumentation_data/local_spec.rb +1 -1
  413. data/spec/unit/indirector/instrumentation_listener/local_spec.rb +1 -1
  414. data/spec/unit/indirector/request_spec.rb +92 -39
  415. data/spec/unit/indirector/rest_spec.rb +1 -0
  416. data/spec/unit/indirector_spec.rb +2 -2
  417. data/spec/unit/interface/option_builder_spec.rb +1 -0
  418. data/spec/unit/interface/option_spec.rb +1 -0
  419. data/spec/unit/interface_spec.rb +2 -2
  420. data/spec/unit/module_tool/applications/installer_spec.rb +49 -2
  421. data/spec/unit/module_tool/metadata_spec.rb +13 -0
  422. data/spec/unit/network/authstore_spec.rb +1 -1
  423. data/spec/unit/network/format_handler_spec.rb +33 -282
  424. data/spec/unit/network/format_support_spec.rb +199 -0
  425. data/spec/unit/network/formats_spec.rb +2 -2
  426. data/spec/unit/network/http/connection_spec.rb +88 -7
  427. data/spec/unit/network/http/handler_spec.rb +271 -249
  428. data/spec/unit/network/http/rack/rest_spec.rb +1 -1
  429. data/spec/unit/network/http/webrick/rest_spec.rb +73 -22
  430. data/spec/unit/network/http_pool_spec.rb +40 -0
  431. data/spec/unit/network/server_spec.rb +18 -207
  432. data/spec/unit/node/facts_spec.rb +68 -17
  433. data/spec/unit/other/selinux_spec.rb +24 -20
  434. data/spec/unit/parameter/boolean_spec.rb +25 -0
  435. data/spec/unit/parameter/value_collection_spec.rb +7 -7
  436. data/spec/unit/parameter_spec.rb +10 -13
  437. data/spec/unit/parser/ast/function_spec.rb +4 -4
  438. data/spec/unit/parser/ast/leaf_spec.rb +45 -6
  439. data/spec/unit/parser/collector_spec.rb +3 -3
  440. data/spec/unit/parser/compiler_spec.rb +4 -3
  441. data/spec/unit/parser/functions/create_resources_spec.rb +9 -25
  442. data/spec/unit/parser/functions/extlookup_spec.rb +2 -2
  443. data/spec/unit/parser/functions/hiera_include_spec.rb +12 -0
  444. data/spec/unit/parser/functions/lookup_spec.rb +96 -0
  445. data/spec/unit/parser/functions/regsubst_spec.rb +2 -2
  446. data/spec/unit/parser/functions/split_spec.rb +2 -2
  447. data/spec/unit/parser/functions/sprintf_spec.rb +1 -1
  448. data/spec/unit/parser/functions/versioncmp_spec.rb +2 -2
  449. data/spec/unit/parser/functions_spec.rb +7 -7
  450. data/spec/unit/parser/lexer_spec.rb +1 -1
  451. data/spec/unit/parser/methods/collect_spec.rb +43 -0
  452. data/spec/unit/parser/resource_spec.rb +9 -9
  453. data/spec/unit/parser/scope_spec.rb +45 -2
  454. data/spec/unit/parser/type_loader_spec.rb +159 -175
  455. data/spec/unit/pops/binder/binder_spec.rb +62 -0
  456. data/spec/unit/pops/binder/bindings_checker_spec.rb +196 -0
  457. data/spec/unit/pops/binder/bindings_composer_spec.rb +89 -0
  458. data/spec/unit/pops/binder/bindings_validator_factory_spec.rb +18 -0
  459. data/spec/unit/pops/binder/config/binder_config_spec.rb +48 -0
  460. data/spec/unit/pops/binder/hiera2/bindings_provider_spec.rb +74 -0
  461. data/spec/unit/pops/binder/hiera2/config_spec.rb +61 -0
  462. data/spec/unit/pops/binder/hiera2/yaml_backend_spec.rb +33 -0
  463. data/spec/unit/pops/binder/injector_spec.rb +789 -0
  464. data/spec/unit/pops/containment_spec.rb +1 -0
  465. data/spec/unit/pops/issues_spec.rb +1 -1
  466. data/spec/unit/pops/parser/evaluating_parser_spec.rb +88 -0
  467. data/spec/unit/pops/parser/lexer_spec.rb +1 -1
  468. data/spec/unit/pops/parser/parse_calls_spec.rb +4 -0
  469. data/spec/unit/pops/parser/parser_spec.rb +1 -1
  470. data/spec/unit/pops/types/type_calculator_spec.rb +484 -0
  471. data/spec/unit/pops/types/type_factory_spec.rb +65 -0
  472. data/spec/unit/pops/types/type_parser_spec.rb +93 -0
  473. data/spec/unit/property/list_spec.rb +1 -1
  474. data/spec/unit/property/ordered_list_spec.rb +1 -1
  475. data/spec/unit/provider/aixobject_spec.rb +101 -0
  476. data/spec/unit/provider/augeas/augeas_spec.rb +14 -3
  477. data/spec/unit/provider/mcx/mcxcontent_spec.rb +52 -16
  478. data/spec/unit/provider/mount/parsed_spec.rb +44 -56
  479. data/spec/unit/provider/mount_spec.rb +11 -2
  480. data/spec/unit/provider/naginator_spec.rb +8 -0
  481. data/spec/unit/provider/package/apt_spec.rb +5 -1
  482. data/spec/unit/provider/package/aptitude_spec.rb +9 -5
  483. data/spec/unit/provider/package/aptrpm_spec.rb +2 -2
  484. data/spec/unit/provider/package/dpkg_spec.rb +274 -99
  485. data/spec/unit/provider/package/openbsd_spec.rb +84 -1
  486. data/spec/unit/provider/package/opkg_spec.rb +3 -3
  487. data/spec/unit/provider/package/pip_spec.rb +16 -0
  488. data/spec/unit/provider/package/pkgdmg_spec.rb +62 -7
  489. data/spec/unit/provider/package/rpm_spec.rb +112 -21
  490. data/spec/unit/provider/package/urpmi.rb +80 -0
  491. data/spec/unit/provider/package/windows/exe_package_spec.rb +1 -1
  492. data/spec/unit/provider/package/yum_spec.rb +85 -0
  493. data/spec/unit/provider/package/zypper_spec.rb +25 -6
  494. data/spec/unit/provider/parsedfile_spec.rb +3 -2
  495. data/spec/unit/provider/service/init_spec.rb +10 -10
  496. data/spec/unit/provider/service/openrc_spec.rb +16 -0
  497. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  498. data/spec/unit/provider/service/redhat_spec.rb +7 -0
  499. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +2 -2
  500. data/spec/unit/provider/user/aix_spec.rb +89 -0
  501. data/spec/unit/provider/user/directoryservice_spec.rb +11 -4
  502. data/spec/unit/provider/user/user_role_add_spec.rb +18 -0
  503. data/spec/unit/provider_spec.rb +2 -13
  504. data/spec/unit/reports/http_spec.rb +1 -1
  505. data/spec/unit/resource/catalog_spec.rb +23 -97
  506. data/spec/unit/resource/resource_type.json +34 -0
  507. data/spec/unit/resource/status_spec.rb +56 -0
  508. data/spec/unit/resource/type_collection_spec.rb +6 -6
  509. data/spec/unit/resource/type_spec.rb +25 -5
  510. data/spec/unit/resource_spec.rb +68 -24
  511. data/spec/unit/run_spec.rb +16 -0
  512. data/spec/unit/scheduler/scheduler_spec.rb +14 -27
  513. data/spec/unit/semver_spec.rb +5 -0
  514. data/spec/unit/settings/enum_setting_spec.rb +27 -0
  515. data/spec/unit/settings_spec.rb +53 -44
  516. data/spec/unit/ssl/certificate_authority_spec.rb +155 -19
  517. data/spec/unit/transaction/additional_resource_generator_spec.rb +419 -0
  518. data/spec/unit/transaction/event_manager_spec.rb +2 -2
  519. data/spec/unit/transaction/event_spec.rb +57 -0
  520. data/spec/unit/transaction/report_spec.rb +66 -0
  521. data/spec/unit/transaction/resource_harness_spec.rb +27 -20
  522. data/spec/unit/transaction_spec.rb +182 -390
  523. data/spec/unit/type/augeas_spec.rb +3 -3
  524. data/spec/unit/type/component_spec.rb +0 -9
  525. data/spec/unit/type/computer_spec.rb +1 -1
  526. data/spec/unit/type/cron_spec.rb +2 -2
  527. data/spec/unit/type/exec_spec.rb +4 -2
  528. data/spec/unit/type/file/content_spec.rb +11 -0
  529. data/spec/unit/type/file/group_spec.rb +1 -1
  530. data/spec/unit/type/file_spec.rb +16 -8
  531. data/spec/unit/type/mount_spec.rb +445 -259
  532. data/spec/unit/type/package_spec.rb +4 -4
  533. data/spec/unit/type/resources_spec.rb +30 -1
  534. data/spec/unit/type/user_spec.rb +26 -3
  535. data/spec/unit/type/yumrepo_spec.rb +7 -27
  536. data/spec/unit/type/zone_spec.rb +4 -1
  537. data/spec/unit/type_spec.rb +66 -33
  538. data/spec/unit/util/backups_spec.rb +3 -3
  539. data/spec/unit/util/http_proxy_spec.rb +83 -0
  540. data/spec/unit/util/log_spec.rb +79 -8
  541. data/spec/unit/util/metric_spec.rb +12 -0
  542. data/spec/unit/util/monkey_patches_spec.rb +6 -0
  543. data/spec/unit/util/network_device/config_spec.rb +26 -64
  544. data/spec/unit/util/pidlock_spec.rb +4 -1
  545. data/spec/unit/util/tagging_spec.rb +5 -9
  546. data/spec/unit/util/warnings_spec.rb +1 -1
  547. data/spec/unit/util/watched_file_spec.rb +52 -0
  548. data/spec/unit/util/watcher/periodic_watcher_spec.rb +52 -0
  549. data/spec/unit/util/watcher_spec.rb +56 -0
  550. data/spec/unit/util_spec.rb +16 -0
  551. metadata +2767 -2576
  552. data/ext/debian/puppet.manpages +0 -32
  553. data/ext/osx/PackageInfo.plist +0 -36
  554. data/ext/osx/createpackage.sh +0 -187
  555. data/ext/redhat/rundir-perms.patch +0 -28
  556. data/lib/puppet/external/base64.rb +0 -19
  557. data/lib/puppet/util/graph.rb +0 -27
  558. data/lib/puppet/util/loadedfile.rb +0 -61
  559. data/lib/puppet/util/log_paths.rb +0 -22
  560. data/lib/puppet/util/subclass_loader.rb +0 -78
  561. data/spec/monkey_patches/publicize_methods.rb +0 -11
  562. data/spec/unit/util/loadedfile_spec.rb +0 -71
@@ -0,0 +1,199 @@
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/network/format_handler'
5
+ require 'puppet/network/format_support'
6
+
7
+ class FormatTester
8
+ include Puppet::Network::FormatSupport
9
+ end
10
+
11
+ describe Puppet::Network::FormatHandler do
12
+ before(:each) do
13
+ @saved_formats = Puppet::Network::FormatHandler.instance_variable_get(:@formats).dup
14
+ Puppet::Network::FormatHandler.instance_variable_set(:@formats, {})
15
+ end
16
+
17
+ after(:each) do
18
+ Puppet::Network::FormatHandler.instance_variable_set(:@formats, @saved_formats)
19
+ end
20
+
21
+ describe "when listing formats" do
22
+ before(:each) do
23
+ one = Puppet::Network::FormatHandler.create(:one, :weight => 1)
24
+ one.stubs(:supported?).returns(true)
25
+ two = Puppet::Network::FormatHandler.create(:two, :weight => 6)
26
+ two.stubs(:supported?).returns(true)
27
+ three = Puppet::Network::FormatHandler.create(:three, :weight => 2)
28
+ three.stubs(:supported?).returns(true)
29
+ four = Puppet::Network::FormatHandler.create(:four, :weight => 8)
30
+ four.stubs(:supported?).returns(false)
31
+ end
32
+
33
+ it "should return all supported formats in decreasing order of weight" do
34
+ FormatTester.supported_formats.should == [:two, :three, :one]
35
+ end
36
+ end
37
+
38
+ it "should return the first format as the default format" do
39
+ FormatTester.expects(:supported_formats).returns [:one, :two]
40
+ FormatTester.default_format.should == :one
41
+ end
42
+
43
+ describe "with a preferred serialization format setting" do
44
+ before do
45
+ one = Puppet::Network::FormatHandler.create(:one, :weight => 1)
46
+ one.stubs(:supported?).returns(true)
47
+ two = Puppet::Network::FormatHandler.create(:two, :weight => 6)
48
+ two.stubs(:supported?).returns(true)
49
+ end
50
+
51
+ describe "that is supported" do
52
+ before do
53
+ Puppet[:preferred_serialization_format] = :one
54
+ end
55
+
56
+ it "should return the preferred serialization format first" do
57
+ FormatTester.supported_formats.should == [:one, :two]
58
+ end
59
+ end
60
+
61
+ describe "that is not supported" do
62
+ before do
63
+ Puppet[:preferred_serialization_format] = :unsupported
64
+ end
65
+
66
+ it "should return the default format first" do
67
+ FormatTester.supported_formats.should == [:two, :one]
68
+ end
69
+
70
+ it "should log a debug message" do
71
+ Puppet.expects(:debug).with("Value of 'preferred_serialization_format' (unsupported) is invalid for FormatTester, using default (two)")
72
+ Puppet.expects(:debug).with("FormatTester supports formats: two one")
73
+ FormatTester.supported_formats
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "when using formats" do
79
+ let(:format) { Puppet::Network::FormatHandler.create(:my_format, :mime => "text/myformat") }
80
+
81
+ it "should use the Format to determine whether a given format is supported" do
82
+ format.expects(:supported?).with(FormatTester)
83
+ FormatTester.support_format?(:my_format)
84
+ end
85
+
86
+ it "should call the format-specific converter when asked to convert from a given format" do
87
+ format.expects(:intern).with(FormatTester, "mydata")
88
+ FormatTester.convert_from(:my_format, "mydata")
89
+ end
90
+
91
+ it "should call the format-specific converter when asked to convert from a given format by mime-type" do
92
+ format.expects(:intern).with(FormatTester, "mydata")
93
+ FormatTester.convert_from("text/myformat", "mydata")
94
+ end
95
+
96
+ it "should call the format-specific converter when asked to convert from a given format by format instance" do
97
+ format.expects(:intern).with(FormatTester, "mydata")
98
+ FormatTester.convert_from(format, "mydata")
99
+ end
100
+
101
+ it "should raise a FormatError when an exception is encountered when converting from a format" do
102
+ format.expects(:intern).with(FormatTester, "mydata").raises "foo"
103
+ expect do
104
+ FormatTester.convert_from(:my_format, "mydata")
105
+ end.to raise_error(
106
+ Puppet::Network::FormatHandler::FormatError,
107
+ 'Could not intern from my_format: foo'
108
+ )
109
+ end
110
+
111
+ it "should be able to use a specific hook for converting into multiple instances" do
112
+ format.expects(:intern_multiple).with(FormatTester, "mydata")
113
+
114
+ FormatTester.convert_from_multiple(:my_format, "mydata")
115
+ end
116
+
117
+ it "should raise a FormatError when an exception is encountered when converting multiple items from a format" do
118
+ format.expects(:intern_multiple).with(FormatTester, "mydata").raises "foo"
119
+ expect do
120
+ FormatTester.convert_from_multiple(:my_format, "mydata")
121
+ end.to raise_error(Puppet::Network::FormatHandler::FormatError, 'Could not intern_multiple from my_format: foo')
122
+ end
123
+
124
+ it "should be able to use a specific hook for rendering multiple instances" do
125
+ format.expects(:render_multiple).with("mydata")
126
+
127
+ FormatTester.render_multiple(:my_format, "mydata")
128
+ end
129
+
130
+ it "should raise a FormatError when an exception is encountered when rendering multiple items into a format" do
131
+ format.expects(:render_multiple).with("mydata").raises "foo"
132
+ expect do
133
+ FormatTester.render_multiple(:my_format, "mydata")
134
+ end.to raise_error(Puppet::Network::FormatHandler::FormatError, 'Could not render_multiple to my_format: foo')
135
+ end
136
+ end
137
+
138
+ describe "when an instance" do
139
+ let(:format) { Puppet::Network::FormatHandler.create(:foo, :mime => "text/foo") }
140
+
141
+ it "should list as supported a format that reports itself supported" do
142
+ format.expects(:supported?).returns true
143
+ FormatTester.new.support_format?(:foo).should be_true
144
+ end
145
+
146
+ it "should raise a FormatError when a rendering error is encountered" do
147
+ tester = FormatTester.new
148
+ format.expects(:render).with(tester).raises "eh"
149
+
150
+ expect do
151
+ tester.render(:foo)
152
+ end.to raise_error(Puppet::Network::FormatHandler::FormatError, 'Could not render to foo: eh')
153
+ end
154
+
155
+ it "should call the format-specific converter when asked to convert to a given format" do
156
+ tester = FormatTester.new
157
+ format.expects(:render).with(tester).returns "foo"
158
+
159
+ tester.render(:foo).should == "foo"
160
+ end
161
+
162
+ it "should call the format-specific converter when asked to convert to a given format by mime-type" do
163
+ tester = FormatTester.new
164
+ format.expects(:render).with(tester).returns "foo"
165
+
166
+ tester.render("text/foo").should == "foo"
167
+ end
168
+
169
+ it "should call the format converter when asked to convert to a given format instance" do
170
+ tester = FormatTester.new
171
+ format.expects(:render).with(tester).returns "foo"
172
+
173
+ tester.render(format).should == "foo"
174
+ end
175
+
176
+ it "should render to the default format if no format is provided when rendering" do
177
+ FormatTester.expects(:default_format).returns :foo
178
+ tester = FormatTester.new
179
+
180
+ format.expects(:render).with(tester)
181
+ tester.render
182
+ end
183
+
184
+ it "should call the format-specific converter when asked for the mime-type of a given format" do
185
+ tester = FormatTester.new
186
+ format.expects(:mime).returns "text/foo"
187
+
188
+ tester.mime(:foo).should == "text/foo"
189
+ end
190
+
191
+ it "should return the default format mime-type if no format is provided" do
192
+ FormatTester.expects(:default_format).returns :foo
193
+ tester = FormatTester.new
194
+
195
+ format.expects(:mime).returns "text/foo"
196
+ tester.mime.should == "text/foo"
197
+ end
198
+ end
199
+ end
@@ -315,8 +315,8 @@ describe "Puppet Network Format" do
315
315
  end
316
316
 
317
317
  [[1, 2], ["one"], [{ 1 => 1 }]].each do |input|
318
- it "should render #{input.inspect} as JSON" do
319
- subject.render(input).should == json.render(input).chomp
318
+ it "should render #{input.inspect} as one item per line" do
319
+ subject.render(input).should == input.collect { |item| item.to_s + "\n" }.join('')
320
320
  end
321
321
  end
322
322
 
@@ -39,8 +39,47 @@ describe Puppet::Network::HTTP::Connection do
39
39
  end
40
40
 
41
41
  it "can set ssl using an option" do
42
- Puppet::Network::HTTP::Connection.new(host, port, false).send(:connection).should_not be_use_ssl
43
- Puppet::Network::HTTP::Connection.new(host, port, true).send(:connection).should be_use_ssl
42
+ Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false).send(:connection).should_not be_use_ssl
43
+ Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true).send(:connection).should be_use_ssl
44
+ end
45
+
46
+ describe "peer verification" do
47
+ def setup_standard_ssl_configuration
48
+ ca_cert_file = File.expand_path('/path/to/ssl/certs/ca_cert.pem')
49
+ FileTest.stubs(:exist?).with(ca_cert_file).returns(true)
50
+
51
+ ssl_configuration = stub('ssl_configuration', :ca_auth_file => ca_cert_file)
52
+ Puppet::Network::HTTP::Connection.any_instance.stubs(:ssl_configuration).returns(ssl_configuration)
53
+ end
54
+
55
+ def setup_standard_hostcert
56
+ host_cert_file = File.expand_path('/path/to/ssl/certs/host_cert.pem')
57
+ FileTest.stubs(:exist?).with(host_cert_file).returns(true)
58
+
59
+ Puppet[:hostcert] = host_cert_file
60
+ end
61
+
62
+ def setup_standard_ssl_host
63
+ cert = stub('cert', :content => 'real_cert')
64
+ key = stub('key', :content => 'real_key')
65
+ host = stub('host', :certificate => cert, :key => key, :ssl_store => stub('store'))
66
+
67
+ Puppet::Network::HTTP::Connection.any_instance.stubs(:ssl_host).returns(host)
68
+ end
69
+
70
+ before do
71
+ setup_standard_ssl_configuration
72
+ setup_standard_hostcert
73
+ setup_standard_ssl_host
74
+ end
75
+
76
+ it "can enable peer verification" do
77
+ Puppet::Network::HTTP::Connection.new(host, port, :verify_peer => true).send(:connection).verify_mode.should == OpenSSL::SSL::VERIFY_PEER
78
+ end
79
+
80
+ it "can disable peer verification" do
81
+ Puppet::Network::HTTP::Connection.new(host, port, :verify_peer => false).send(:connection).verify_mode.should == OpenSSL::SSL::VERIFY_NONE
82
+ end
44
83
  end
45
84
 
46
85
  context "proxy and timeout settings should propagate" do
@@ -62,6 +101,10 @@ describe Puppet::Network::HTTP::Connection do
62
101
  subject.send(:connection).proxy_address.should be_nil
63
102
  end
64
103
 
104
+ it "should raise Puppet::Error when invalid options are specified" do
105
+ expect { Puppet::Network::HTTP::Connection.new(host, port, :invalid_option => nil) }.to raise_error(Puppet::Error, 'Unrecognized option(s): :invalid_option')
106
+ end
107
+
65
108
  end
66
109
 
67
110
  describe "when doing SSL setup for http instances" do
@@ -86,7 +129,7 @@ describe Puppet::Network::HTTP::Connection do
86
129
  end
87
130
 
88
131
  shared_examples "HTTPS setup without all certificates" do
89
- subject { Puppet::Network::HTTP::Connection.new(host, port, true).send(:connection) }
132
+ subject { Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true).send(:connection) }
90
133
 
91
134
  it { should be_use_ssl }
92
135
  its(:cert) { should be_nil }
@@ -123,7 +166,7 @@ describe Puppet::Network::HTTP::Connection do
123
166
  end
124
167
 
125
168
  context "with both the host and CA cert" do
126
- subject { Puppet::Network::HTTP::Connection.new(host, port, true).send(:connection) }
169
+ subject { Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true).send(:connection) }
127
170
 
128
171
  before :each do
129
172
  FileTest.expects(:exist?).with(Puppet[:hostcert]).returns(true)
@@ -145,11 +188,10 @@ describe Puppet::Network::HTTP::Connection do
145
188
  end
146
189
  end
147
190
 
148
-
149
191
  context "when methods that accept a block are called with a block" do
150
192
  let (:host) { "my_server" }
151
193
  let (:port) { 8140 }
152
- let (:subject) { Puppet::Network::HTTP::Connection.new(host, port, false) }
194
+ let (:subject) { Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false) }
153
195
  let (:httpok) { Net::HTTPOK.new('1.1', 200, '') }
154
196
 
155
197
  before :each do
@@ -185,6 +227,7 @@ describe Puppet::Network::HTTP::Connection do
185
227
 
186
228
  let (:host) { "my_server" }
187
229
  let (:port) { 8140 }
230
+ let (:httpok) { Net::HTTPOK.new('1.1', 200, '') }
188
231
  let (:subject) { Puppet::Network::HTTP::Connection.new(host, port) }
189
232
 
190
233
  def a_connection_that_verifies(args)
@@ -269,11 +312,49 @@ describe Puppet::Network::HTTP::Connection do
269
312
  connection.verify_callback.call(true, context)
270
313
  connection.verify_callback.call(true, context)
271
314
  true
272
- end
315
+ end.returns(httpok)
273
316
 
274
317
  subject.expects(:warn_if_near_expiration).with(cert, cert)
275
318
 
276
319
  subject.request(:get, stubs('request'))
277
320
  end
278
321
  end
322
+
323
+ context "when response is a redirect" do
324
+ let (:other_host) { "redirected" }
325
+ let (:other_port) { 9292 }
326
+ let (:other_path) { "other-path" }
327
+ let (:subject) { Puppet::Network::HTTP::Connection.new("my_server", 8140, :use_ssl => false) }
328
+ let (:httpredirection) { Net::HTTPFound.new('1.1', 302, 'Moved Temporarily') }
329
+ let (:httpok) { Net::HTTPOK.new('1.1', 200, '') }
330
+
331
+ before :each do
332
+ httpredirection['location'] = "http://#{other_host}:#{other_port}/#{other_path}"
333
+ httpredirection.stubs(:read_body).returns("This resource has moved")
334
+
335
+ socket = stub_everything("socket")
336
+ TCPSocket.stubs(:open).returns(socket)
337
+
338
+ Net::HTTP::Get.any_instance.stubs(:exec).returns("")
339
+ Net::HTTP::Post.any_instance.stubs(:exec).returns("")
340
+ end
341
+
342
+ it "should redirect to the final resource location" do
343
+ httpok.stubs(:read_body).returns(:body)
344
+ Net::HTTPResponse.stubs(:read_new).returns(httpredirection).then.returns(httpok)
345
+
346
+ subject.get("/foo").body.should == :body
347
+ subject.port.should == other_port
348
+ subject.address.should == other_host
349
+ end
350
+
351
+ it "should raise an error after too many redirections" do
352
+ Net::HTTPResponse.stubs(:read_new).returns(httpredirection)
353
+
354
+ expect {
355
+ subject.get("/foo")
356
+ }.to raise_error(Puppet::Network::HTTP::RedirectionLimitExceededException)
357
+ end
358
+ end
359
+
279
360
  end
@@ -4,8 +4,126 @@ require 'puppet/network/http'
4
4
  require 'puppet/network/http/handler'
5
5
  require 'puppet/network/authorization'
6
6
  require 'puppet/network/authentication'
7
+ require 'puppet/indirector/memory'
7
8
 
8
9
  describe Puppet::Network::HTTP::Handler do
10
+ before :each do
11
+ class Puppet::TestModel
12
+ extend Puppet::Indirector
13
+ indirects :test_model
14
+ attr_accessor :name, :data
15
+ def initialize(name = "name", data = '')
16
+ @name = name
17
+ @data = data
18
+ end
19
+
20
+ def self.from_pson(pson)
21
+ new(pson["name"], pson["data"])
22
+ end
23
+
24
+ def to_pson
25
+ {
26
+ "name" => @name,
27
+ "data" => @data
28
+ }.to_pson
29
+ end
30
+
31
+ def ==(other)
32
+ other.is_a? Puppet::TestModel and other.name == name and other.data == data
33
+ end
34
+ end
35
+
36
+ # The subclass must not be all caps even though the superclass is
37
+ class Puppet::TestModel::Memory < Puppet::Indirector::Memory
38
+ end
39
+
40
+ Puppet::TestModel.indirection.terminus_class = :memory
41
+ end
42
+
43
+ after :each do
44
+ Puppet::TestModel.indirection.delete
45
+ # Remove the class, unlinking it from the rest of the system.
46
+ Puppet.send(:remove_const, :TestModel)
47
+ end
48
+
49
+ let(:terminus_class) { Puppet::TestModel::Memory }
50
+ let(:terminus) { Puppet::TestModel.indirection.terminus(:memory) }
51
+ let(:indirection) { Puppet::TestModel.indirection }
52
+ let(:model) { Puppet::TestModel }
53
+
54
+ def a_request
55
+ {
56
+ :accept_header => "pson",
57
+ :content_type_header => "text/yaml",
58
+ :http_method => "HEAD",
59
+ :path => "/production/#{indirection.name}/unknown",
60
+ :params => {},
61
+ :client_cert => nil,
62
+ :headers => {},
63
+ :body => nil
64
+ }
65
+ end
66
+
67
+ def a_request_that_heads(data, request = {})
68
+ {
69
+ :accept_header => request[:accept_header],
70
+ :content_type_header => "text/yaml",
71
+ :http_method => "HEAD",
72
+ :path => "/production/#{indirection.name}/#{data.name}",
73
+ :params => {},
74
+ :client_cert => nil,
75
+ :body => nil
76
+ }
77
+ end
78
+
79
+ def a_request_that_submits(data, request = {})
80
+ {
81
+ :accept_header => request[:accept_header],
82
+ :content_type_header => "text/yaml",
83
+ :http_method => "PUT",
84
+ :path => "/production/#{indirection.name}/#{data.name}",
85
+ :params => {},
86
+ :client_cert => nil,
87
+ :body => data.render("text/yaml")
88
+ }
89
+ end
90
+
91
+ def a_request_that_destroys(data, request = {})
92
+ {
93
+ :accept_header => request[:accept_header],
94
+ :content_type_header => "text/yaml",
95
+ :http_method => "DELETE",
96
+ :path => "/production/#{indirection.name}/#{data.name}",
97
+ :params => {},
98
+ :client_cert => nil,
99
+ :body => ''
100
+ }
101
+ end
102
+
103
+ def a_request_that_finds(data, request = {})
104
+ {
105
+ :accept_header => request[:accept_header],
106
+ :content_type_header => "text/yaml",
107
+ :http_method => "GET",
108
+ :path => "/production/#{indirection.name}/#{data.name}",
109
+ :params => {},
110
+ :client_cert => nil,
111
+ :body => ''
112
+ }
113
+ end
114
+
115
+ def a_request_that_searches(key, request = {})
116
+ {
117
+ :accept_header => request[:accept_header],
118
+ :content_type_header => "text/yaml",
119
+ :http_method => "GET",
120
+ :path => "/production/#{indirection.name}s/#{key}",
121
+ :params => {},
122
+ :client_cert => nil,
123
+ :body => ''
124
+ }
125
+ end
126
+
9
127
  let(:handler) { TestingHandler.new }
10
128
 
11
129
  it "should include the v1 REST API" do
@@ -28,37 +146,15 @@ describe Puppet::Network::HTTP::Handler do
28
146
  end
29
147
 
30
148
  describe "when processing a request" do
31
- let(:request) do
32
- {
33
- :accept_header => "format_one,format_two",
34
- :content_type_header => "text/yaml",
35
- :http_method => "GET",
36
- :path => "/my_handler/my_result",
37
- :params => {},
38
- :client_cert => nil
39
- }
40
- end
41
-
42
149
  let(:response) { mock('http response') }
43
150
 
44
151
  before do
45
- @model_class = stub('indirected model class')
46
- @indirection = stub('indirection')
47
- @model_class.stubs(:indirection).returns(@indirection)
48
-
49
- @result = stub 'result', :render => "mytext"
50
-
51
- request[:headers] = {
52
- "Content-Type" => request[:content_type_header],
53
- "Accept" => request[:accept_header]
54
- }
55
-
56
152
  handler.stubs(:check_authorization)
57
153
  handler.stubs(:warn_if_near_expiration)
58
- handler.stubs(:headers).returns(request[:headers])
59
154
  end
60
155
 
61
156
  it "should check the client certificate for upcoming expiration" do
157
+ request = a_request
62
158
  cert = mock 'cert'
63
159
  handler.stubs(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}])
64
160
  handler.expects(:client_cert).returns(cert).with(request)
@@ -68,6 +164,7 @@ describe Puppet::Network::HTTP::Handler do
68
164
  end
69
165
 
70
166
  it "should setup a profiler when the puppet-profiling header exists" do
167
+ request = a_request
71
168
  request[:headers][Puppet::Network::HTTP::HEADER_ENABLE_PROFILING.downcase] = "true"
72
169
 
73
170
  handler.process(request, response)
@@ -76,6 +173,7 @@ describe Puppet::Network::HTTP::Handler do
76
173
  end
77
174
 
78
175
  it "should not setup profiler when the profile parameter is missing" do
176
+ request = a_request
79
177
  request[:params] = { }
80
178
 
81
179
  handler.process(request, response)
@@ -84,6 +182,7 @@ describe Puppet::Network::HTTP::Handler do
84
182
  end
85
183
 
86
184
  it "should create an indirection request from the path, parameters, and http method" do
185
+ request = a_request
87
186
  request[:path] = "mypath"
88
187
  request[:http_method] = "mymethod"
89
188
  request[:params] = { :params => "mine" }
@@ -96,6 +195,7 @@ describe Puppet::Network::HTTP::Handler do
96
195
  end
97
196
 
98
197
  it "should call the 'do' method and delegate authorization to the authorization layer" do
198
+ request = a_request
99
199
  handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}])
100
200
 
101
201
  handler.expects(:do_mymethod).with("facts", "key", {:node => "name"}, request, response)
@@ -106,6 +206,7 @@ describe Puppet::Network::HTTP::Handler do
106
206
  end
107
207
 
108
208
  it "should return 403 if the request is not authorized" do
209
+ request = a_request
109
210
  handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}])
110
211
 
111
212
  handler.expects(:do_mymethod).never
@@ -118,6 +219,7 @@ describe Puppet::Network::HTTP::Handler do
118
219
  end
119
220
 
120
221
  it "should serialize a controller exception when an exception is thrown while finding the model instance" do
222
+ request = a_request
121
223
  handler.expects(:uri2indirection).returns(["facts", :find, "key", {:node => "name"}])
122
224
 
123
225
  handler.expects(:do_find).raises(ArgumentError, "The exception")
@@ -127,15 +229,33 @@ describe Puppet::Network::HTTP::Handler do
127
229
 
128
230
  it "should set the format to text/plain when serializing an exception" do
129
231
  handler.expects(:set_content_type).with(response, "text/plain")
232
+
233
+ handler.do_exception(response, "A test", 404)
234
+ end
235
+
236
+ it "sends an exception string with the given status" do
237
+ handler.expects(:set_response).with(response, "A test", 404)
238
+
130
239
  handler.do_exception(response, "A test", 404)
131
240
  end
132
241
 
242
+ it "sends an exception error with the exception's status" do
243
+ data = Puppet::TestModel.new("not_found", "not found")
244
+ request = a_request_that_finds(data, :accept_header => "pson")
245
+
246
+ error = Puppet::Network::HTTP::Handler::HTTPNotFoundError.new("Could not find test_model not_found")
247
+ handler.expects(:set_response).with(response, error.to_s, error.status)
248
+
249
+ handler.process(request, response)
250
+ end
251
+
133
252
  it "should raise an error if the request is formatted in an unknown format" do
134
253
  handler.stubs(:content_type_header).returns "unknown format"
135
254
  lambda { handler.request_format(request) }.should raise_error
136
255
  end
137
256
 
138
257
  it "should still find the correct format if content type contains charset information" do
258
+ request = a_request
139
259
  handler.stubs(:content_type_header).returns "text/plain; charset=UTF-8"
140
260
  handler.request_format(request).should == "s"
141
261
  end
@@ -157,310 +277,204 @@ describe Puppet::Network::HTTP::Handler do
157
277
  end
158
278
 
159
279
  describe "when finding a model instance" do
160
- before do
161
- @indirection.stubs(:find).returns @result
162
- Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
280
+ it "uses the first supported format for the response" do
281
+ data = Puppet::TestModel.new("my data", "some data")
282
+ indirection.save(data, "my data")
283
+ request = a_request_that_finds(data, :accept_header => "unknown, pson, yaml")
163
284
 
164
- @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
165
- Puppet::Network::FormatHandler.stubs(:format).returns @format
285
+ handler.expects(:set_response).with(response, data.render(:pson))
286
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
166
287
 
167
- @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
168
- Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
288
+ handler.do_find(indirection.name, "my data", {}, request, response)
169
289
  end
170
290
 
171
- it "should use the indirection request to find the model class" do
172
- handler.do_find("my_handler", "my_result", {}, request, response)
173
- end
174
-
175
- it "should use the escaped request key" do
176
- @indirection.expects(:find).with("my_result", anything).returns @result
177
- handler.do_find("my_handler", "my_result", {}, request, response)
178
- end
179
-
180
- it "should use a common method for determining the request parameters" do
181
- @indirection.expects(:find).with(anything, has_entries(:foo => :baz, :bar => :xyzzy)).returns @result
182
-
183
- handler.do_find("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, request, response)
184
- end
185
-
186
- it "should set the content type to the first format specified in the accept header" do
187
- handler.expects(:accept_header).with(request).returns "one,two"
188
- handler.expects(:set_content_type).with(response, @oneformat)
189
- handler.do_find("my_handler", "my_result", {}, request, response)
190
- end
191
-
192
- it "should fail if no accept header is provided" do
193
- handler.expects(:accept_header).with(request).returns nil
194
- lambda { handler.do_find("my_handler", "my_result", {}, request, response) }.should raise_error(ArgumentError)
195
- end
291
+ it "responds with a 406 error when no accept header is provided" do
292
+ data = Puppet::TestModel.new("my data", "some data")
293
+ indirection.save(data, "my data")
294
+ request = a_request_that_finds(data, :accept_header => nil)
196
295
 
197
- it "should fail if the accept header does not contain a valid format" do
198
- handler.expects(:accept_header).with(request).returns ""
199
- lambda { handler.do_find("my_handler", "my_result", {}, request, response) }.should raise_error(RuntimeError)
296
+ expect do
297
+ handler.do_find(indirection.name, "my data", {}, request, response)
298
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotAcceptableError)
200
299
  end
201
300
 
202
- it "should not use an unsuitable format" do
203
- handler.expects(:accept_header).with(request).returns "foo,bar"
204
- foo = mock 'foo', :suitable? => false
205
- bar = mock 'bar', :suitable? => true
206
- Puppet::Network::FormatHandler.expects(:format).with("foo").returns foo
207
- Puppet::Network::FormatHandler.expects(:format).with("bar").returns bar
208
-
209
- handler.expects(:set_content_type).with(response, bar) # the suitable one
301
+ it "raises an error when no accepted formats are known" do
302
+ data = Puppet::TestModel.new("my data", "some data")
303
+ indirection.save(data, "my data")
304
+ request = a_request_that_finds(data, :accept_header => "unknown, also/unknown")
210
305
 
211
- handler.do_find("my_handler", "my_result", {}, request, response)
212
- end
213
-
214
- it "should render the result using the first format specified in the accept header" do
215
-
216
- handler.expects(:accept_header).with(request).returns "one,two"
217
- @result.expects(:render).with(@oneformat)
218
-
219
- handler.do_find("my_handler", "my_result", {}, request, response)
306
+ expect do
307
+ handler.do_find(indirection.name, "my data", {}, request, response)
308
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotAcceptableError)
220
309
  end
221
310
 
222
311
  it "should pass the result through without rendering it if the result is a string" do
223
- @indirection.stubs(:find).returns "foo"
224
- handler.expects(:set_response).with(response, "foo")
225
- handler.do_find("my_handler", "my_result", {}, request, response)
226
- end
227
-
228
- it "should use the default status when a model find call succeeds" do
229
- handler.expects(:set_response).with(anything, anything, nil)
230
- handler.do_find("my_handler", "my_result", {}, request, response)
231
- end
312
+ data = Puppet::TestModel.new("my data", "some data")
313
+ data_string = "my data string"
314
+ request = a_request_that_finds(data, :accept_header => "pson")
315
+ indirection.expects(:find).returns(data_string)
232
316
 
233
- it "should return a serialized object when a model find call succeeds" do
234
- @model_instance = stub('model instance')
235
- @model_instance.expects(:render).returns "my_rendered_object"
317
+ handler.expects(:set_response).with(response, data_string)
318
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
236
319
 
237
- handler.expects(:set_response).with(anything, "my_rendered_object", anything)
238
- @indirection.stubs(:find).returns(@model_instance)
239
- handler.do_find("my_handler", "my_result", {}, request, response)
320
+ handler.do_find(indirection.name, "my data", {}, request, response)
240
321
  end
241
322
 
242
323
  it "should return a 404 when no model instance can be found" do
243
- @model_class.stubs(:name).returns "my name"
244
- handler.expects(:set_response).with(anything, anything, 404)
245
- @indirection.stubs(:find).returns(nil)
246
- handler.do_find("my_handler", "my_result", {}, request, response)
247
- end
248
-
249
- it "should write a log message when no model instance can be found" do
250
- @model_class.stubs(:name).returns "my name"
251
- @indirection.stubs(:find).returns(nil)
252
-
253
- Puppet.expects(:info).with("Could not find my_handler for 'my_result'")
324
+ data = Puppet::TestModel.new("my data", "some data")
325
+ request = a_request_that_finds(data, :accept_header => "unknown, pson, yaml")
254
326
 
255
- handler.do_find("my_handler", "my_result", {}, request, response)
256
- end
257
-
258
-
259
- it "should serialize the result in with the appropriate format" do
260
- @model_instance = stub('model instance')
261
-
262
- handler.expects(:format_to_use).returns(@oneformat)
263
- @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object"
264
- @indirection.stubs(:find).returns(@model_instance)
265
- handler.do_find("my_handler", "my_result", {}, request, response)
327
+ expect do
328
+ handler.do_find(indirection.name, "my data", {}, request, response)
329
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotFoundError)
266
330
  end
267
331
  end
268
332
 
269
333
  describe "when performing head operation" do
270
- before do
271
- handler.stubs(:model).with("my_handler").returns(stub 'model', :indirection => @model_class)
272
- request[:http_method] = "HEAD"
273
- request[:path] = "/production/my_handler/my_result"
274
- request[:params] = {}
275
-
276
- @model_class.stubs(:head).returns true
277
- end
278
-
279
- it "should use the escaped request key" do
280
- @model_class.expects(:head).with("my_result", anything).returns true
281
- handler.process(request, response)
282
- end
283
-
284
334
  it "should not generate a response when a model head call succeeds" do
335
+ data = Puppet::TestModel.new("my data", "some data")
336
+ indirection.save(data, "my data")
337
+ request = a_request_that_heads(data)
338
+
285
339
  handler.expects(:set_response).never
340
+
286
341
  handler.process(request, response)
287
342
  end
288
343
 
289
344
  it "should return a 404 when the model head call returns false" do
290
- handler.expects(:set_response).with(anything, anything, 404)
291
- @model_class.stubs(:head).returns(false)
345
+ data = Puppet::TestModel.new("my data", "data not there")
346
+ request = a_request_that_heads(data)
347
+
348
+ handler.expects(:set_response).with(response, "Not Found: Could not find test_model my data", 404)
349
+
292
350
  handler.process(request, response)
293
351
  end
294
352
  end
295
353
 
296
354
  describe "when searching for model instances" do
297
- before do
298
- Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
355
+ it "uses the first supported format for the response" do
356
+ data = Puppet::TestModel.new("my data", "some data")
357
+ indirection.save(data, "my data")
358
+ request = a_request_that_searches("my", :accept_header => "unknown, pson, yaml")
299
359
 
300
- result1 = mock 'result1'
301
- result2 = mock 'results'
360
+ handler.expects(:set_response).with(response, Puppet::TestModel.render_multiple(:pson, [data]))
361
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
302
362
 
303
- @result = [result1, result2]
304
- @model_class.stubs(:render_multiple).returns "my rendered instances"
305
- @indirection.stubs(:search).returns(@result)
306
-
307
- @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
308
- Puppet::Network::FormatHandler.stubs(:format).returns @format
309
-
310
- @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
311
- Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
312
- end
313
-
314
- it "should use the indirection request to find the model" do
315
- handler.do_search("my_handler", "my_result", {}, request, response)
316
- end
317
-
318
- it "should use a common method for determining the request parameters" do
319
- @indirection.expects(:search).with(anything, has_entries(:foo => :baz, :bar => :xyzzy)).returns @result
320
- handler.do_search("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, request, response)
321
- end
322
-
323
- it "should use the default status when a model search call succeeds" do
324
- @indirection.stubs(:search).returns(@result)
325
- handler.do_search("my_handler", "my_result", {}, request, response)
326
- end
327
-
328
- it "should set the content type to the first format returned by the accept header" do
329
- handler.expects(:accept_header).with(request).returns "one,two"
330
- handler.expects(:set_content_type).with(response, @oneformat)
331
-
332
- handler.do_search("my_handler", "my_result", {}, request, response)
333
- end
334
-
335
- it "should return a list of serialized objects when a model search call succeeds" do
336
- handler.expects(:accept_header).with(request).returns "one,two"
337
-
338
- @indirection.stubs(:search).returns(@result)
339
-
340
- @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
341
-
342
- handler.expects(:set_response).with(anything, "my rendered instances")
343
- handler.do_search("my_handler", "my_result", {}, request, response)
363
+ handler.do_search(indirection.name, "my", {}, request, response)
344
364
  end
345
365
 
346
366
  it "should return [] when searching returns an empty array" do
347
- handler.expects(:accept_header).with(request).returns "one,two"
348
- @indirection.stubs(:search).returns([])
349
- @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]"
367
+ request = a_request_that_searches("nothing", :accept_header => "unknown, pson, yaml")
350
368
 
369
+ handler.expects(:set_response).with(response, Puppet::TestModel.render_multiple(:pson, []))
370
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
351
371
 
352
- handler.expects(:set_response).with(anything, "[]")
353
- handler.do_search("my_handler", "my_result", {}, request, response)
372
+ handler.do_search(indirection.name, "nothing", {}, request, response)
354
373
  end
355
374
 
356
375
  it "should return a 404 when searching returns nil" do
357
- @model_class.stubs(:name).returns "my name"
358
- handler.expects(:set_response).with(anything, anything, 404)
359
- @indirection.stubs(:search).returns(nil)
360
- handler.do_search("my_handler", "my_result", {}, request, response)
376
+ request = a_request_that_searches("nothing", :accept_header => "unknown, pson, yaml")
377
+ indirection.expects(:search).returns(nil)
378
+
379
+ expect do
380
+ handler.do_search(indirection.name, "nothing", {}, request, response)
381
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotFoundError)
361
382
  end
362
383
  end
363
384
 
364
385
  describe "when destroying a model instance" do
365
- before do
366
- Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
386
+ it "destroys the data indicated in the request" do
387
+ data = Puppet::TestModel.new("my data", "some data")
388
+ indirection.save(data, "my data")
389
+ request = a_request_that_destroys(data)
367
390
 
368
- @result = stub 'result', :render => "the result"
369
- @indirection.stubs(:destroy).returns @result
370
- end
391
+ handler.do_destroy(indirection.name, "my data", {}, request, response)
371
392
 
372
- it "should use the indirection request to find the model" do
373
- handler.do_destroy("my_handler", "my_result", {}, request, response)
393
+ Puppet::TestModel.indirection.find("my data").should be_nil
374
394
  end
375
395
 
376
- it "should use the escaped request key to destroy the instance in the model" do
377
- @indirection.expects(:destroy).with("foo bar", anything)
378
- handler.do_destroy("my_handler", "foo bar", {}, request, response)
379
- end
396
+ it "responds with yaml when no Accept header is given" do
397
+ data = Puppet::TestModel.new("my data", "some data")
398
+ indirection.save(data, "my data")
399
+ request = a_request_that_destroys(data, :accept_header => nil)
400
+
401
+ handler.expects(:set_response).with(response, data.render(:yaml))
402
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:yaml))
380
403
 
381
- it "should use a common method for determining the request parameters" do
382
- @indirection.expects(:destroy).with(anything, has_entries(:foo => :baz, :bar => :xyzzy))
383
- handler.do_destroy("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, request, response)
404
+ handler.do_destroy(indirection.name, "my data", {}, request, response)
384
405
  end
385
406
 
386
- it "should use the default status code a model destroy call succeeds" do
387
- handler.expects(:set_response).with(anything, anything, nil)
388
- handler.do_destroy("my_handler", "my_result", {}, request, response)
407
+ it "uses the first supported format for the response" do
408
+ data = Puppet::TestModel.new("my data", "some data")
409
+ indirection.save(data, "my data")
410
+ request = a_request_that_destroys(data, :accept_header => "unknown, pson, yaml")
411
+
412
+ handler.expects(:set_response).with(response, data.render(:pson))
413
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
414
+
415
+ handler.do_destroy(indirection.name, "my data", {}, request, response)
389
416
  end
390
417
 
391
- it "should return a yaml-encoded result when a model destroy call succeeds" do
392
- @result = stub 'result', :to_yaml => "the result"
393
- @indirection.expects(:destroy).returns(@result)
418
+ it "raises an error and does not destory when no accepted formats are known" do
419
+ data = Puppet::TestModel.new("my data", "some data")
420
+ indirection.save(data, "my data")
421
+ request = a_request_that_submits(data, :accept_header => "unknown, also/unknown")
394
422
 
395
- handler.expects(:set_response).with(anything, "the result", anything)
423
+ expect do
424
+ handler.do_destroy(indirection.name, "my data", {}, request, response)
425
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotAcceptableError)
396
426
 
397
- handler.do_destroy("my_handler", "my_result", {}, request, response)
427
+ Puppet::TestModel.indirection.find("my data").should_not be_nil
398
428
  end
399
429
  end
400
430
 
401
431
  describe "when saving a model instance" do
402
- before do
403
- Puppet::Indirector::Indirection.stubs(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class )
404
- handler.stubs(:body).returns('my stuff')
405
- handler.stubs(:content_type_header).returns("text/yaml")
406
-
407
- @result = stub 'result', :render => "the result"
408
-
409
- @model_instance = stub('indirected model instance')
410
- @model_class.stubs(:convert_from).returns(@model_instance)
411
- @indirection.stubs(:save)
432
+ it "should fail to save model if data is not specified" do
433
+ data = Puppet::TestModel.new("my data", "some data")
434
+ request = a_request_that_submits(data)
435
+ request[:body] = ''
412
436
 
413
- @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format"
414
- Puppet::Network::FormatHandler.stubs(:format).returns @format
415
- @yamlformat = stub 'yaml', :suitable? => true, :name => "yaml", :mime => "text/yaml"
416
- Puppet::Network::FormatHandler.stubs(:format).with("yaml").returns @yamlformat
437
+ expect { handler.do_save("my_handler", "my_result", {}, request, response) }.to raise_error(ArgumentError)
417
438
  end
418
439
 
419
- it "should use the indirection request to find the model" do
420
- handler.do_save("my_handler", "my_result", {}, request, response)
421
- end
440
+ it "saves the data sent in the request" do
441
+ data = Puppet::TestModel.new("my data", "some data")
442
+ request = a_request_that_submits(data)
422
443
 
423
- it "should use the 'body' hook to retrieve the body of the request" do
424
- handler.expects(:body).returns "my body"
425
- @model_class.expects(:convert_from).with(anything, "my body").returns @model_instance
444
+ handler.do_save(indirection.name, "my data", {}, request, response)
426
445
 
427
- handler.do_save("my_handler", "my_result", {}, request, response)
446
+ Puppet::TestModel.indirection.find("my data").should == data
428
447
  end
429
448
 
430
- it "should fail to save model if data is not specified" do
431
- handler.stubs(:body).returns('')
449
+ it "responds with yaml when no Accept header is given" do
450
+ data = Puppet::TestModel.new("my data", "some data")
451
+ request = a_request_that_submits(data, :accept_header => nil)
432
452
 
433
- lambda { handler.do_save("my_handler", "my_result", {}, request, response) }.should raise_error(ArgumentError)
434
- end
453
+ handler.expects(:set_response).with(response, data.render(:yaml))
454
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:yaml))
435
455
 
436
- it "should use a common method for determining the request parameters" do
437
- @indirection.expects(:save).with(@model_instance, 'key').once
438
- handler.do_save("my_handler", "key", {}, request, response)
456
+ handler.do_save(indirection.name, "my data", {}, request, response)
439
457
  end
440
458
 
441
- it "should use the default status when a model save call succeeds" do
442
- handler.expects(:set_response).with(anything, anything, nil)
443
- handler.do_save("my_handler", "my_result", {}, request, response)
444
- end
459
+ it "uses the first supported format for the response" do
460
+ data = Puppet::TestModel.new("my data", "some data")
461
+ request = a_request_that_submits(data, :accept_header => "unknown, pson, yaml")
445
462
 
446
- it "should return the yaml-serialized result when a model save call succeeds" do
447
- @indirection.stubs(:save).returns(@model_instance)
448
- @model_instance.expects(:to_yaml).returns('foo')
449
- handler.do_save("my_handler", "my_result", {}, request, response)
450
- end
463
+ handler.expects(:set_response).with(response, data.render(:pson))
464
+ handler.expects(:set_content_type).with(response, Puppet::Network::FormatHandler.format(:pson))
451
465
 
452
- it "should set the content to yaml" do
453
- handler.expects(:set_content_type).with(response, @yamlformat)
454
- handler.do_save("my_handler", "my_result", {}, request, response)
466
+ handler.do_save(indirection.name, "my data", {}, request, response)
455
467
  end
456
468
 
457
- it "should use the content-type header to know the body format" do
458
- handler.expects(:content_type_header).returns("text/format")
459
- Puppet::Network::FormatHandler.stubs(:mime).with("text/format").returns @format
469
+ it "raises an error and does not save when no accepted formats are known" do
470
+ data = Puppet::TestModel.new("my data", "some data")
471
+ request = a_request_that_submits(data, :accept_header => "unknown, also/unknown")
460
472
 
461
- @model_class.expects(:convert_from).with("format", anything).returns @model_instance
473
+ expect do
474
+ handler.do_save(indirection.name, "my data", {}, request, response)
475
+ end.to raise_error(Puppet::Network::HTTP::Handler::HTTPNotAcceptableError)
462
476
 
463
- handler.do_save("my_handler", "my_result", {}, request, response)
477
+ Puppet::TestModel.indirection.find("my data").should be_nil
464
478
  end
465
479
  end
466
480
  end
@@ -519,5 +533,13 @@ describe Puppet::Network::HTTP::Handler do
519
533
  def client_cert(request)
520
534
  request[:client_cert]
521
535
  end
536
+
537
+ def body(request)
538
+ request[:body]
539
+ end
540
+
541
+ def headers(request)
542
+ request[:headers] || {}
543
+ end
522
544
  end
523
545
  end