puppet 4.2.3 → 4.3.0

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 (337) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +1 -1
  3. data/ext/debian/puppet.init +0 -1
  4. data/ext/debian/puppet.logrotate +14 -5
  5. data/ext/osx/puppet.plist +0 -2
  6. data/ext/redhat/client.init +13 -5
  7. data/ext/redhat/logrotate +15 -3
  8. data/ext/redhat/puppet.spec.erb +5 -1
  9. data/ext/redhat/server.init +1 -1
  10. data/ext/systemd/puppet.service +1 -0
  11. data/lib/puppet.rb +12 -0
  12. data/lib/puppet/agent.rb +4 -4
  13. data/lib/puppet/agent/locker.rb +11 -2
  14. data/lib/puppet/application/agent.rb +5 -1
  15. data/lib/puppet/application/apply.rb +4 -0
  16. data/lib/puppet/application/filebucket.rb +78 -4
  17. data/lib/puppet/application/lookup.rb +356 -0
  18. data/lib/puppet/application/master.rb +3 -0
  19. data/lib/puppet/configurer.rb +9 -5
  20. data/lib/puppet/context.rb +16 -1
  21. data/lib/puppet/context/trusted_information.rb +21 -1
  22. data/lib/puppet/daemon.rb +17 -13
  23. data/lib/puppet/data_binding.rb +4 -2
  24. data/lib/puppet/data_providers.rb +12 -13
  25. data/lib/puppet/data_providers/data_adapter.rb +7 -68
  26. data/lib/puppet/data_providers/data_function_support.rb +5 -26
  27. data/lib/puppet/data_providers/function_env_data_provider.rb +0 -10
  28. data/lib/puppet/data_providers/function_module_data_provider.rb +0 -22
  29. data/lib/puppet/data_providers/hiera_config.rb +106 -0
  30. data/lib/puppet/data_providers/hiera_env_data_provider.rb +18 -0
  31. data/lib/puppet/data_providers/hiera_interpolate.rb +97 -0
  32. data/lib/puppet/data_providers/hiera_module_data_provider.rb +23 -0
  33. data/lib/puppet/data_providers/hiera_support.rb +37 -0
  34. data/lib/puppet/data_providers/json_data_provider_factory.rb +31 -0
  35. data/lib/puppet/data_providers/lookup_adapter.rb +200 -0
  36. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +32 -0
  37. data/lib/puppet/defaults.rb +12 -2
  38. data/lib/puppet/error.rb +4 -0
  39. data/lib/puppet/face/module/changes.rb +2 -1
  40. data/lib/puppet/feature/cfacter.rb +1 -0
  41. data/lib/puppet/file_bucket/dipper.rb +58 -2
  42. data/lib/puppet/functions.rb +2 -4
  43. data/lib/puppet/functions/assert_type.rb +48 -12
  44. data/lib/puppet/functions/defined.rb +79 -48
  45. data/lib/puppet/functions/each.rb +85 -27
  46. data/lib/puppet/functions/filter.rb +58 -23
  47. data/lib/puppet/functions/hiera.rb +76 -3
  48. data/lib/puppet/functions/hiera_array.rb +65 -3
  49. data/lib/puppet/functions/hiera_hash.rb +74 -2
  50. data/lib/puppet/functions/hiera_include.rb +75 -2
  51. data/lib/puppet/functions/lookup.rb +19 -17
  52. data/lib/puppet/functions/map.rb +56 -21
  53. data/lib/puppet/functions/match.rb +29 -12
  54. data/lib/puppet/functions/reduce.rb +95 -58
  55. data/lib/puppet/functions/versioncmp.rb +36 -0
  56. data/lib/puppet/functions/with.rb +15 -7
  57. data/lib/puppet/indirector/catalog/compiler.rb +3 -3
  58. data/lib/puppet/indirector/catalog/static_compiler.rb +46 -30
  59. data/lib/puppet/indirector/data_binding/none.rb +4 -1
  60. data/lib/puppet/indirector/file_bucket_file/file.rb +58 -1
  61. data/lib/puppet/indirector/hiera.rb +4 -0
  62. data/lib/puppet/indirector/json.rb +1 -1
  63. data/lib/puppet/indirector/msgpack.rb +1 -1
  64. data/lib/puppet/indirector/request.rb +7 -8
  65. data/lib/puppet/indirector/resource_type/parser.rb +5 -3
  66. data/lib/puppet/info_service.rb +7 -0
  67. data/lib/puppet/info_service/class_information_service.rb +111 -0
  68. data/lib/puppet/module_tool/metadata.rb +32 -9
  69. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +42 -38
  70. data/lib/puppet/network/authconfig.rb +21 -1
  71. data/lib/puppet/network/authorization.rb +8 -1
  72. data/lib/puppet/network/http/api/master/v3.rb +7 -1
  73. data/lib/puppet/network/http/api/master/v3/environment.rb +59 -0
  74. data/lib/puppet/node/environment.rb +9 -2
  75. data/lib/puppet/parser.rb +3 -0
  76. data/lib/puppet/parser/ast/pops_bridge.rb +39 -1
  77. data/lib/puppet/parser/compiler.rb +302 -12
  78. data/lib/puppet/parser/compiler/catalog_validator.rb +33 -0
  79. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +64 -0
  80. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +38 -0
  81. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +20 -0
  82. data/lib/puppet/parser/environment_compiler.rb +165 -0
  83. data/lib/puppet/parser/functions/assert_type.rb +46 -16
  84. data/lib/puppet/parser/functions/defined.rb +105 -68
  85. data/lib/puppet/parser/functions/each.rb +85 -27
  86. data/lib/puppet/parser/functions/filter.rb +59 -23
  87. data/lib/puppet/parser/functions/hiera.rb +83 -27
  88. data/lib/puppet/parser/functions/hiera_array.rb +71 -28
  89. data/lib/puppet/parser/functions/hiera_hash.rb +81 -30
  90. data/lib/puppet/parser/functions/hiera_include.rb +81 -40
  91. data/lib/puppet/parser/functions/map.rb +55 -20
  92. data/lib/puppet/parser/functions/match.rb +27 -12
  93. data/lib/puppet/parser/functions/reduce.rb +97 -60
  94. data/lib/puppet/parser/functions/with.rb +16 -8
  95. data/lib/puppet/parser/resource.rb +98 -19
  96. data/lib/puppet/plugins/configuration.rb +3 -2
  97. data/lib/puppet/plugins/data_providers.rb +12 -60
  98. data/lib/puppet/plugins/data_providers/data_provider.rb +283 -0
  99. data/lib/puppet/plugins/data_providers/registry.rb +84 -0
  100. data/lib/puppet/pops.rb +19 -17
  101. data/lib/puppet/pops/adapters.rb +12 -0
  102. data/lib/puppet/pops/binder/binder.rb +2 -2
  103. data/lib/puppet/pops/binder/bindings_checker.rb +1 -1
  104. data/lib/puppet/pops/binder/bindings_label_provider.rb +3 -1
  105. data/lib/puppet/pops/binder/bindings_loader.rb +6 -2
  106. data/lib/puppet/pops/binder/bindings_model_meta.rb +2 -2
  107. data/lib/puppet/pops/binder/config/binder_config.rb +1 -1
  108. data/lib/puppet/pops/binder/injector.rb +4 -4
  109. data/lib/puppet/pops/binder/key_factory.rb +3 -9
  110. data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +68 -9
  111. data/lib/puppet/pops/evaluator/access_operator.rb +27 -60
  112. data/lib/puppet/pops/evaluator/closure.rb +8 -8
  113. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -1
  114. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  115. data/lib/puppet/pops/evaluator/literal_evaluator.rb +87 -0
  116. data/lib/puppet/pops/evaluator/relationship_operator.rb +7 -1
  117. data/lib/puppet/pops/functions/dispatcher.rb +3 -3
  118. data/lib/puppet/pops/issues.rb +1 -1
  119. data/lib/puppet/pops/label_provider.rb +1 -1
  120. data/lib/puppet/pops/lookup.rb +25 -47
  121. data/lib/puppet/pops/lookup/explainer.rb +402 -0
  122. data/lib/puppet/pops/lookup/invocation.rb +117 -0
  123. data/lib/puppet/pops/merge_strategy.rb +73 -5
  124. data/lib/puppet/pops/model/factory.rb +34 -0
  125. data/lib/puppet/pops/model/model_label_provider.rb +10 -1
  126. data/lib/puppet/pops/model/model_meta.rb +15 -0
  127. data/lib/puppet/pops/model/model_tree_dumper.rb +18 -0
  128. data/lib/puppet/pops/parser/code_merger.rb +13 -1
  129. data/lib/puppet/pops/parser/egrammar.ra +56 -3
  130. data/lib/puppet/pops/parser/eparser.rb +1549 -1352
  131. data/lib/puppet/pops/parser/lexer2.rb +31 -6
  132. data/lib/puppet/pops/parser/locator.rb +1 -1
  133. data/lib/puppet/pops/parser/parser_support.rb +25 -13
  134. data/lib/puppet/pops/types/enumeration.rb +1 -2
  135. data/lib/puppet/pops/types/type_asserter.rb +16 -15
  136. data/lib/puppet/pops/types/type_assertion_error.rb +1 -0
  137. data/lib/puppet/pops/types/type_calculator.rb +171 -1020
  138. data/lib/puppet/pops/types/type_factory.rb +87 -148
  139. data/lib/puppet/pops/types/type_mismatch_describer.rb +743 -0
  140. data/lib/puppet/pops/types/type_parser.rb +116 -127
  141. data/lib/puppet/pops/types/types.rb +1394 -255
  142. data/lib/puppet/pops/types/types_meta.rb +0 -234
  143. data/lib/puppet/pops/validation.rb +7 -2
  144. data/lib/puppet/pops/validation/checker4_0.rb +28 -0
  145. data/lib/puppet/provider/augeas/augeas.rb +50 -0
  146. data/lib/puppet/provider/group/directoryservice.rb +10 -0
  147. data/lib/puppet/provider/package/dnf.rb +41 -0
  148. data/lib/puppet/provider/package/gem.rb +7 -2
  149. data/lib/puppet/provider/package/rpm.rb +1 -0
  150. data/lib/puppet/provider/package/windows/exe_package.rb +10 -8
  151. data/lib/puppet/provider/package/windows/msi_package.rb +4 -3
  152. data/lib/puppet/provider/package/windows/package.rb +9 -1
  153. data/lib/puppet/provider/package/yum.rb +14 -9
  154. data/lib/puppet/provider/service/bsd.rb +1 -1
  155. data/lib/puppet/provider/service/debian.rb +21 -0
  156. data/lib/puppet/provider/service/init.rb +6 -0
  157. data/lib/puppet/provider/service/rcng.rb +51 -0
  158. data/lib/puppet/provider/service/redhat.rb +2 -1
  159. data/lib/puppet/provider/service/smf.rb +43 -2
  160. data/lib/puppet/provider/service/src.rb +27 -0
  161. data/lib/puppet/provider/service/systemd.rb +15 -3
  162. data/lib/puppet/provider/sshkey/parsed.rb +19 -9
  163. data/lib/puppet/reference/report.rb +9 -12
  164. data/lib/puppet/reports.rb +5 -1
  165. data/lib/puppet/resource.rb +50 -73
  166. data/lib/puppet/resource/capability_finder.rb +95 -0
  167. data/lib/puppet/resource/catalog.rb +47 -7
  168. data/lib/puppet/resource/status.rb +0 -2
  169. data/lib/puppet/resource/type.rb +238 -44
  170. data/lib/puppet/resource/type_collection.rb +60 -2
  171. data/lib/puppet/settings.rb +2 -2
  172. data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
  173. data/lib/puppet/ssl/oids.rb +9 -1
  174. data/lib/puppet/transaction.rb +4 -1
  175. data/lib/puppet/transaction/additional_resource_generator.rb +71 -8
  176. data/lib/puppet/transaction/resource_harness.rb +9 -4
  177. data/lib/puppet/type.rb +74 -3
  178. data/lib/puppet/type/augeas.rb +8 -0
  179. data/lib/puppet/type/file/source.rb +14 -12
  180. data/lib/puppet/type/user.rb +4 -2
  181. data/lib/puppet/util/windows/security.rb +4 -1
  182. data/lib/puppet/util/windows/taskscheduler.rb +1 -1
  183. data/lib/puppet/version.rb +1 -1
  184. data/spec/fixtures/unit/application/environments/production/data/common.yaml +3 -0
  185. data/spec/fixtures/unit/application/environments/production/environment.conf +1 -0
  186. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/data/bad.json +3 -0
  187. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/environment.conf +2 -0
  188. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/hiera.yaml +5 -0
  189. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/manifests/site.pp +5 -0
  190. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml +3 -0
  191. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/environment.conf +2 -0
  192. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/hiera.yaml +5 -0
  193. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/manifests/site.pp +5 -0
  194. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/data/common.yaml +2 -0
  195. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/environment.conf +2 -0
  196. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/manifests/site.pp +1 -0
  197. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/data/common.yaml +2 -0
  198. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/manifests/init.pp +5 -0
  199. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/metadata.json +9 -0
  200. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/first.json +3 -0
  201. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/name.yaml +2 -0
  202. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/second.json +3 -0
  203. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/single.yaml +2 -0
  204. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data2/single.yaml +2 -0
  205. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/environment.conf +2 -0
  206. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/hiera.yaml +18 -0
  207. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/manifests/site.pp +5 -0
  208. data/spec/fixtures/unit/data_providers/environments/hiera_misc/data/common.yaml +46 -0
  209. data/spec/fixtures/unit/data_providers/environments/hiera_misc/environment.conf +2 -0
  210. data/spec/fixtures/unit/data_providers/environments/hiera_misc/manifests/site.pp +1 -0
  211. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/data/common.yaml +30 -0
  212. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/manifests/init.pp +13 -0
  213. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/metadata.json +9 -0
  214. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/environment.conf +2 -0
  215. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/manifests/site.pp +1 -0
  216. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/first.json +3 -0
  217. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/name.yaml +1 -0
  218. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/second.json +3 -0
  219. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/single.yaml +2 -0
  220. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data2/single.yaml +2 -0
  221. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/hiera.yaml +18 -0
  222. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/manifests/init.pp +5 -0
  223. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/metadata.json +9 -0
  224. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_env_data.rb +1 -0
  225. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_module_data.rb +1 -0
  226. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +3 -0
  227. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/hiera.yaml +8 -0
  228. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/manifests/init.pp +5 -0
  229. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/metadata.json +9 -0
  230. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/lib/puppet/functions/meta/data.rb +9 -0
  231. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/manifests/init.pp +3 -0
  232. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/metadata.json +9 -0
  233. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet/bindings/metawcp/default.rb +10 -0
  234. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet_x/thallgren/sample_module_data.rb +23 -0
  235. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/manifests/init.pp +3 -0
  236. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/metadata.json +9 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-security.txt +184 -0
  238. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
  239. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
  241. data/spec/integration/data_binding_spec.rb +229 -0
  242. data/spec/integration/file_bucket/file_spec.rb +2 -2
  243. data/spec/integration/parser/compiler_spec.rb +23 -19
  244. data/spec/integration/parser/resource_expressions_spec.rb +4 -4
  245. data/spec/integration/parser/undef_param_spec.rb +1 -1
  246. data/spec/integration/resource/catalog_spec.rb +1 -1
  247. data/spec/integration/type/package_spec.rb +2 -0
  248. data/spec/integration/util/windows/security_spec.rb +18 -0
  249. data/spec/lib/matchers/include_in_order.rb +2 -2
  250. data/spec/shared_behaviours/iterative_functions.rb +8 -8
  251. data/spec/spec_helper.rb +7 -0
  252. data/spec/unit/agent/locker_spec.rb +4 -4
  253. data/spec/unit/agent_spec.rb +0 -8
  254. data/spec/unit/application/agent_spec.rb +5 -0
  255. data/spec/unit/application/apply_spec.rb +8 -0
  256. data/spec/unit/application/filebucket_spec.rb +87 -1
  257. data/spec/unit/application/lookup_spec.rb +195 -0
  258. data/spec/unit/appmgmt_spec.rb +657 -0
  259. data/spec/unit/capability_spec.rb +414 -0
  260. data/spec/unit/configurer_spec.rb +7 -1
  261. data/spec/unit/context/trusted_information_spec.rb +24 -1
  262. data/spec/unit/daemon_spec.rb +18 -8
  263. data/spec/unit/data_providers/hiera_data_provider_spec.rb +201 -0
  264. data/spec/unit/file_bucket/dipper_spec.rb +210 -1
  265. data/spec/unit/functions/assert_type_spec.rb +5 -7
  266. data/spec/unit/functions/defined_spec.rb +2 -2
  267. data/spec/unit/functions/epp_spec.rb +2 -2
  268. data/spec/unit/functions/lookup_spec.rb +200 -9
  269. data/spec/unit/functions/regsubst_spec.rb +17 -8
  270. data/spec/unit/functions/scanf_spec.rb +1 -1
  271. data/spec/unit/functions/split_spec.rb +2 -2
  272. data/spec/unit/functions/versioncmp_spec.rb +36 -0
  273. data/spec/unit/functions4_spec.rb +58 -72
  274. data/spec/unit/indirector/catalog/compiler_spec.rb +28 -8
  275. data/spec/unit/indirector/catalog/static_compiler_spec.rb +38 -20
  276. data/spec/unit/indirector/data_binding/none_spec.rb +2 -2
  277. data/spec/unit/indirector/file_bucket_file/file_spec.rb +52 -1
  278. data/spec/unit/indirector/request_spec.rb +8 -8
  279. data/spec/unit/info_service_spec.rb +236 -0
  280. data/spec/unit/module_tool/metadata_spec.rb +31 -2
  281. data/spec/unit/network/authconfig_spec.rb +62 -32
  282. data/spec/unit/network/authorization_spec.rb +30 -2
  283. data/spec/unit/network/http/connection_spec.rb +14 -19
  284. data/spec/unit/parser/compiler_spec.rb +86 -2
  285. data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
  286. data/spec/unit/parser/resource_spec.rb +2 -20
  287. data/spec/unit/pops/binder/config/binder_config_spec.rb +1 -1
  288. data/spec/unit/pops/binder/injector_spec.rb +3 -3
  289. data/spec/unit/pops/evaluator/access_ops_spec.rb +13 -11
  290. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +1 -2
  291. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +19 -11
  292. data/spec/unit/pops/evaluator/literal_evaluator_spec.rb +43 -0
  293. data/spec/unit/pops/label_provider_spec.rb +5 -1
  294. data/spec/unit/pops/parser/lexer2_spec.rb +33 -7
  295. data/spec/unit/pops/parser/parse_application_spec.rb +40 -0
  296. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +4 -0
  297. data/spec/unit/pops/parser/parse_capabilities_spec.rb +47 -0
  298. data/spec/unit/pops/parser/parse_site_spec.rb +38 -0
  299. data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
  300. data/spec/unit/pops/parser/parser_spec.rb +18 -0
  301. data/spec/unit/pops/types/type_calculator_spec.rb +427 -444
  302. data/spec/unit/pops/types/type_factory_spec.rb +12 -12
  303. data/spec/unit/pops/types/type_parser_spec.rb +7 -12
  304. data/spec/unit/pops/validator/validator_spec.rb +25 -0
  305. data/spec/unit/provider/augeas/augeas_spec.rb +50 -0
  306. data/spec/unit/provider/group/directoryservice_spec.rb +33 -0
  307. data/spec/unit/provider/group/windows_adsi_spec.rb +3 -0
  308. data/spec/unit/provider/package/dnf_spec.rb +92 -0
  309. data/spec/unit/provider/package/gem_spec.rb +7 -0
  310. data/spec/unit/provider/package/rpm_spec.rb +25 -2
  311. data/spec/unit/provider/package/windows/package_spec.rb +41 -0
  312. data/spec/unit/provider/package/yum_spec.rb +21 -13
  313. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +10 -0
  314. data/spec/unit/provider/service/debian_spec.rb +27 -0
  315. data/spec/unit/provider/service/rcng_spec.rb +41 -0
  316. data/spec/unit/provider/service/redhat_spec.rb +8 -1
  317. data/spec/unit/provider/service/smf_spec.rb +30 -5
  318. data/spec/unit/provider/service/src_spec.rb +19 -4
  319. data/spec/unit/provider/service/systemd_spec.rb +78 -29
  320. data/spec/unit/provider/sshkey/parsed_spec.rb +23 -0
  321. data/spec/unit/reports_spec.rb +10 -0
  322. data/spec/unit/resource/capability_finder_spec.rb +56 -0
  323. data/spec/unit/resource/catalog_spec.rb +31 -8
  324. data/spec/unit/resource/type_collection_spec.rb +23 -2
  325. data/spec/unit/resource/type_spec.rb +1 -1
  326. data/spec/unit/resource_spec.rb +22 -4
  327. data/spec/unit/settings_spec.rb +90 -1
  328. data/spec/unit/ssl/certificate_authority/interface_spec.rb +4 -3
  329. data/spec/unit/ssl/oids_spec.rb +8 -0
  330. data/spec/unit/transaction/additional_resource_generator_spec.rb +78 -5
  331. data/spec/unit/transaction/report_spec.rb +24 -1
  332. data/spec/unit/type/package_spec.rb +1 -0
  333. data/spec/unit/type/user_spec.rb +14 -7
  334. data/spec/unit/type_spec.rb +1 -1
  335. metadata +169 -5
  336. data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +0 -175
  337. data/spec/integration/data_binding.rb +0 -104
@@ -0,0 +1,657 @@
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
3
+ require 'puppet_spec/compiler'
4
+ require_relative 'pops/parser/parser_rspec_helper'
5
+ require 'puppet/parser/environment_compiler'
6
+
7
+ describe "Application instantiation" do
8
+ include PuppetSpec::Compiler
9
+ # We pull this in because we need access to with_app_management; and
10
+ # since that has to root around in the guts of the Pops parser, there's
11
+ # no really elegant way to do this
12
+ include ParserRspecHelper
13
+
14
+ def compile_to_env_catalog(string)
15
+ Puppet[:code] = string
16
+ env = Puppet::Node::Environment.create("test", ["/dev/null"])
17
+ Puppet::Parser::EnvironmentCompiler.compile(env).filter { |r| r.virtual? }
18
+ end
19
+
20
+
21
+ before :each do
22
+ with_app_management(true)
23
+ Puppet::Type.newtype :cap, :is_capability => true do
24
+ newparam :name
25
+ newparam :host
26
+ end
27
+ end
28
+
29
+ after :each do
30
+ Puppet::Type.rmtype(:cap)
31
+ with_app_management(false)
32
+ end
33
+
34
+ MANIFEST = <<-EOS
35
+ define prod($host) {
36
+ notify { "host ${host}":}
37
+ }
38
+
39
+ Prod produces Cap { }
40
+
41
+ define cons($host) {
42
+ notify { "host ${host}": }
43
+ }
44
+
45
+ Cons consumes Cap { }
46
+
47
+ application app {
48
+ prod { one: host => ahost, export => Cap[cap] }
49
+ cons { two: host => ahost, consume => Cap[cap] }
50
+ cons { three: consume => Cap[cap] }
51
+ }
52
+
53
+ site {
54
+ app { anapp:
55
+ nodes => {
56
+ Node[first] => Prod[one],
57
+ Node[second] => Cons[two]
58
+ }
59
+ }
60
+ }
61
+ EOS
62
+
63
+ MANIFEST_WO_EXPORT = <<-EOS
64
+ define prod($host) {
65
+ notify { "host ${host}":}
66
+ }
67
+
68
+ Prod produces Cap { }
69
+
70
+ define cons($host) {
71
+ notify { "host ${host}": }
72
+ }
73
+
74
+ Cons consumes Cap { }
75
+
76
+ application app {
77
+ cons { two: host => ahost, consume => Cap[cap] }
78
+ }
79
+
80
+ site {
81
+ app { anapp:
82
+ nodes => {
83
+ Node[first] => Prod[one],
84
+ Node[second] => Cons[two]
85
+ }
86
+ }
87
+ }
88
+ EOS
89
+
90
+ MANIFEST_WO_NODE = <<-EOS
91
+ define prod($host) {
92
+ notify { "host ${host}":}
93
+ }
94
+
95
+ Prod produces Cap { }
96
+
97
+ define cons($host) {
98
+ notify { "host ${host}": }
99
+ }
100
+
101
+ Cons consumes Cap { }
102
+
103
+ application app {
104
+ prod { one: host => ahost, export => Cap[cap] }
105
+ cons { two: host => ahost, consume => Cap[cap] }
106
+ }
107
+
108
+ site {
109
+ app { anapp:
110
+ }
111
+ }
112
+ EOS
113
+
114
+ MANIFEST_WITH_STRING_NODES = <<-EOS
115
+ application app {
116
+ }
117
+
118
+ site {
119
+ app { anapp:
120
+ nodes => "foobar",
121
+ }
122
+ }
123
+ EOS
124
+
125
+ MANIFEST_WITH_FALSE_NODES = <<-EOS
126
+ application app {
127
+ }
128
+
129
+ site {
130
+ app { anapp:
131
+ nodes => false,
132
+ }
133
+ }
134
+ EOS
135
+
136
+ MANIFEST_REQ_WO_EXPORT = <<-EOS
137
+ define prod($host) {
138
+ notify { "host ${host}":}
139
+ }
140
+
141
+ Prod produces Cap { }
142
+
143
+ define cons($host) {
144
+ notify { "host ${host}": }
145
+ }
146
+
147
+ Cons consumes Cap { }
148
+
149
+ application app {
150
+ cons { two: host => ahost, require => Cap[cap] }
151
+ }
152
+
153
+ site {
154
+ app { anapp:
155
+ nodes => {
156
+ Node[first] => Prod[one],
157
+ Node[second] => Cons[two]
158
+ }
159
+ }
160
+ }
161
+ EOS
162
+
163
+ MANIFEST_WITH_DOUBLE_EXPORT = <<-EOS
164
+ define prod($host) {
165
+ notify { "host ${host}":}
166
+ }
167
+
168
+ Prod produces Cap { }
169
+
170
+ define cons($host) {
171
+ notify { "host ${host}": }
172
+ }
173
+
174
+ Cons consumes Cap { }
175
+
176
+ application app {
177
+ prod { one: host => ahost, export => Cap[cap] }
178
+ prod { two: host => anotherhost, export => Cap[cap] }
179
+ cons { two: host => ahost, consume => Cap[cap] }
180
+ }
181
+
182
+ site {
183
+ app { anapp:
184
+ nodes => {
185
+ Node[first] => Prod[one],
186
+ Node[second] => Cons[two]
187
+ }
188
+ }
189
+ }
190
+ EOS
191
+
192
+ FAULTY_MANIFEST = <<-EOS
193
+ define prod($host) {
194
+ notify { "host ${host}":}
195
+ }
196
+
197
+ Prod produces Cap { }
198
+
199
+ define cons($host) {
200
+ notify { "host ${host}": }
201
+ }
202
+
203
+ Cons consumes Cap { }
204
+
205
+ application app {
206
+ prod { one: host => ahost, export => Cap[cap] }
207
+ cons { two: host => ahost, consume => Cap[cap] }
208
+ }
209
+
210
+ # app is not in site => error
211
+ app { anapp:
212
+ nodes => {
213
+ Node[first] => Prod[one],
214
+ Node[second] => Cons[two]
215
+ }
216
+ }
217
+ EOS
218
+
219
+ MANIFEST_WITH_SITE = <<-EOS
220
+ define prod($host) {
221
+ notify { "host ${host}":}
222
+ }
223
+
224
+ Prod produces Cap { }
225
+
226
+ define cons($host) {
227
+ notify { "host ${host}": }
228
+ }
229
+
230
+ Cons consumes Cap { }
231
+
232
+ application app {
233
+ prod { one: host => ahost, export => Cap[cap] }
234
+ cons { two: host => ahost, consume => Cap[cap] }
235
+ }
236
+
237
+ $one = not_the_value_one
238
+ $two = two
239
+
240
+ node default {
241
+ notify { "on a node": }
242
+ }
243
+
244
+ notify { 'ignore me': }
245
+
246
+ site {
247
+ $one = one
248
+ app { anapp:
249
+ nodes => {
250
+ Node[first] => Prod[$one],
251
+ Node[second] => Cons[$two]
252
+ }
253
+ }
254
+ }
255
+ EOS
256
+
257
+ MANIFEST_WITH_ILLEGAL_RESOURCE = <<-EOS
258
+ define prod($host) {
259
+ notify { "host ${host}":}
260
+ }
261
+
262
+ Prod produces Cap { }
263
+
264
+ define cons($host) {
265
+ notify { "host ${host}": }
266
+ }
267
+
268
+ Cons consumes Cap { }
269
+
270
+ application app {
271
+ prod { one: host => ahost, export => Cap[cap] }
272
+ cons { two: consume => Cap[cap] }
273
+ }
274
+
275
+ site {
276
+ # The rouge expression is here
277
+ notify { 'fail me': }
278
+ $one = one
279
+ app { anapp:
280
+ nodes => {
281
+ Node[first] => Prod[one],
282
+ Node[second] => Cons[two]
283
+ }
284
+ }
285
+ }
286
+ EOS
287
+
288
+ MANIFEST_WITH_CLASS = <<-EOS
289
+ define test($host) {
290
+ notify { "c $host": }
291
+ }
292
+
293
+ class prod($host) {
294
+ notify { "p $host": }
295
+ }
296
+
297
+ class cons($host) {
298
+ test { c: host => $host }
299
+ }
300
+
301
+ Class[prod] produces Cap {}
302
+
303
+ Class[cons] consumes Cap {}
304
+
305
+ application app {
306
+ class { prod: host => 'ahost', export => Cap[cap]}
307
+ class { cons: consume => Cap[cap]}
308
+ }
309
+
310
+ site {
311
+ app { anapp:
312
+ nodes => {
313
+ Node[first] => Class[prod],
314
+ Node[second] => Class[cons]
315
+ }
316
+ }
317
+ }
318
+ EOS
319
+
320
+
321
+ describe "a node catalog" do
322
+ it "is unaffected for a non-participating node" do
323
+ catalog = compile_to_catalog(MANIFEST, Puppet::Node.new('other'))
324
+ types = catalog.resource_keys.map { |type, _| type }.uniq.sort
325
+ expect(types).to eq(["Class", "Stage"])
326
+ end
327
+
328
+ it "an application instance must be contained in a site" do
329
+ expect { compile_to_catalog(FAULTY_MANIFEST, Puppet::Node.new('first'))
330
+ }.to raise_error(/Application instances .* can only be contained within a Site/)
331
+ end
332
+
333
+ it "does not raise an error when node mappings are not provided" do
334
+ expect { compile_to_catalog(MANIFEST_WO_NODE) }.to_not raise_error
335
+ end
336
+
337
+ it "raises an error if node mapping is a string" do
338
+ expect { compile_to_catalog(MANIFEST_WITH_STRING_NODES)
339
+ }.to raise_error(/Invalid node mapping in .*: Mapping must be a hash/)
340
+ end
341
+
342
+ it "raises an error if node mapping is false" do
343
+ expect { compile_to_catalog(MANIFEST_WITH_FALSE_NODES)
344
+ }.to raise_error(/Invalid node mapping in .*: Mapping must be a hash/)
345
+ end
346
+
347
+ it "detects that consumed capability is never exported" do
348
+ expect { compile_to_env_catalog(MANIFEST_WO_EXPORT)
349
+ }.to raise_error(/Capability 'Cap\[cap\]' referenced by 'consume' is never exported/)
350
+ end
351
+
352
+ it "detects that required capability is never exported" do
353
+ expect { compile_to_env_catalog(MANIFEST_REQ_WO_EXPORT)
354
+ }.to raise_error(/Capability 'Cap\[cap\]' referenced by 'require' is never exported/)
355
+ end
356
+
357
+ it "detects that a capability is exported more than once" do
358
+ expect { compile_to_env_catalog(MANIFEST_WITH_DOUBLE_EXPORT)
359
+ }.to raise_error(/'Cap\[cap\]' is exported by both 'Prod\[one\]' and 'Prod\[two\]'/)
360
+ end
361
+
362
+ context "for producing node" do
363
+ let(:compiled_node) { Puppet::Node.new('first') }
364
+ let(:compiled_catalog) { compile_to_catalog(MANIFEST, compiled_node)}
365
+
366
+ { "App[anapp]" => 'application instance',
367
+ "Cap[cap]" => 'capability resource',
368
+ "Prod[one]" => 'component',
369
+ "Notify[host ahost]" => 'node resource'
370
+ }.each do |k,v|
371
+ it "contains the #{v} (#{k})" do
372
+ expect(compiled_catalog.resource(k)).not_to be_nil
373
+ end
374
+ end
375
+
376
+ it "does not contain the consumed resource (Cons[two])" do
377
+ expect(compiled_catalog.resource("Cons[two]")).to be_nil
378
+ end
379
+ end
380
+
381
+ context "for consuming node" do
382
+ let(:compiled_node) { Puppet::Node.new('second') }
383
+ let(:compiled_catalog) { compile_to_catalog(MANIFEST, compiled_node)}
384
+ let(:cap) {
385
+ the_cap = Puppet::Resource.new("Cap", "cap")
386
+ the_cap["host"] = "ahost"
387
+ the_cap
388
+ }
389
+
390
+ { "App[anapp]" => 'application instance',
391
+ "Cap[cap]" => 'capability resource',
392
+ "Cons[two]" => 'component',
393
+ "Notify[host ahost]" => 'node resource'
394
+ }.each do |k,v|
395
+ it "contains the #{v} (#{k})" do
396
+ # Mock the connection to Puppet DB
397
+ Puppet::Resource::CapabilityFinder.expects(:find).returns(cap)
398
+ expect(compiled_catalog.resource(k)).not_to be_nil
399
+ end
400
+ end
401
+
402
+ it "does not contain the produced resource (Prod[one])" do
403
+ # Mock the connection to Puppet DB
404
+ Puppet::Resource::CapabilityFinder.expects(:find).returns(cap)
405
+ expect(compiled_catalog.resource("Prod[one]")).to be_nil
406
+ end
407
+ end
408
+
409
+ context "for node with class producer" do
410
+ let(:compiled_node) { Puppet::Node.new('first') }
411
+ let(:compiled_catalog) { compile_to_catalog(MANIFEST_WITH_CLASS, compiled_node)}
412
+
413
+ { "App[anapp]" => 'application instance',
414
+ "Cap[cap]" => 'capability resource',
415
+ "Class[prod]" => 'class',
416
+ "Notify[p ahost]" => 'node resource'
417
+ }.each do |k,v|
418
+ it "contains the #{v} (#{k})" do
419
+ cat = compiled_catalog
420
+ expect(cat.resource(k)).not_to be_nil
421
+ end
422
+ end
423
+
424
+ it "does not contain the consumed resource (Class[cons])" do
425
+ expect(compiled_catalog.resource("Class[cons]")).to be_nil
426
+ end
427
+ end
428
+
429
+ context "for node with class consumer" do
430
+ let(:compiled_node) { Puppet::Node.new('second') }
431
+ let(:compiled_catalog) { compile_to_catalog(MANIFEST_WITH_CLASS, compiled_node)}
432
+ let(:cap) {
433
+ the_cap = Puppet::Resource.new("Cap", "cap")
434
+ the_cap["host"] = "ahost"
435
+ the_cap
436
+ }
437
+
438
+ { "App[anapp]" => 'application instance',
439
+ "Cap[cap]" => 'capability resource',
440
+ "Class[cons]" => 'class',
441
+ "Notify[c ahost]" => 'node resource'
442
+ }.each do |k,v|
443
+ it "contains the #{v} (#{k})" do
444
+ # Mock the connection to Puppet DB
445
+ Puppet::Resource::CapabilityFinder.expects(:find).returns(cap)
446
+ expect(compiled_catalog.resource(k)).not_to be_nil
447
+ end
448
+ end
449
+
450
+ it "does not contain the produced resource (Class[prod])" do
451
+ # Mock the connection to Puppet DB
452
+ Puppet::Resource::CapabilityFinder.expects(:find).returns(cap)
453
+ expect(compiled_catalog.resource("Class[prod]")).to be_nil
454
+ end
455
+ end
456
+
457
+ context "when using a site expression" do
458
+ # The site expression must be evaluated in a node catalog compilation because
459
+ # the application instantiations inside it may contain other logic (local variables)
460
+ # that are used to instantiate an application. The application instances are needed.
461
+ #
462
+ it "the node expressions is evaluated" do
463
+ catalog = compile_to_catalog(MANIFEST_WITH_SITE, Puppet::Node.new('other'))
464
+ types = catalog.resource_keys.map { |type, _| type }.uniq.sort
465
+ expect(types).to eq(["Class", "Node", "Notify", "Stage"])
466
+ expect(catalog.resource("Notify[on a node]")).to_not be_nil
467
+ expect(catalog.resource("Notify[on the site]")).to be_nil
468
+ end
469
+
470
+ end
471
+
472
+ context "when using a site expression" do
473
+ it "the site expression is not evaluated in a node compilation" do
474
+ catalog = compile_to_catalog(MANIFEST_WITH_SITE, Puppet::Node.new('other'))
475
+ types = catalog.resource_keys.map { |type, _| type }.uniq.sort
476
+ expect(types).to eq(["Class", "Node", "Notify", "Stage"])
477
+ expect(catalog.resource("Notify[on a node]")).to_not be_nil
478
+ expect(catalog.resource("Notify[on the site]")).to be_nil
479
+ end
480
+
481
+ end
482
+ end
483
+
484
+
485
+ describe "in the environment catalog" do
486
+ it "does not fail if there is no site expression" do
487
+ expect {
488
+ catalog = compile_to_env_catalog(<<-EOC).to_resource
489
+ notify { 'ignore me':}
490
+ EOC
491
+ }.to_not raise_error()
492
+ end
493
+
494
+ it "includes components and capability resources" do
495
+ catalog = compile_to_env_catalog(MANIFEST).to_resource
496
+ apps = catalog.resources.select do |res|
497
+ res.resource_type && res.resource_type.application?
498
+ end
499
+ expect(apps.size).to eq(1)
500
+ app = apps.first
501
+ expect(app["nodes"]).not_to be_nil
502
+ comps = catalog.direct_dependents_of(app).map(&:ref).sort
503
+ expect(comps).to eq(["Cons[three]", "Cons[two]", "Prod[one]"])
504
+
505
+ prod = catalog.resource("Prod[one]")
506
+ expect(prod).not_to be_nil
507
+ expect(prod.export.map(&:ref)).to eq(["Cap[cap]"])
508
+
509
+ cons = catalog.resource("Cons[two]")
510
+ expect(cons).not_to be_nil
511
+ expect(cons[:consume].ref).to eq("Cap[cap]")
512
+ end
513
+
514
+ it "includes class components" do
515
+ catalog = compile_to_env_catalog(MANIFEST_WITH_CLASS).to_resource
516
+ classes = catalog.resources.select do |res|
517
+ res.type == 'Class' && (res.title == 'Prod' || res.title == 'Cons')
518
+ end
519
+ expect(classes.size).to eq(2)
520
+ expect(classes.map(&:ref).sort).to eq(["Class[Cons]", "Class[Prod]"])
521
+
522
+ prod = catalog.resource("Class[prod]")
523
+ expect(prod).not_to be_nil
524
+ expect(prod.export.map(&:ref)).to eq(["Cap[cap]"])
525
+
526
+ cons = catalog.resource("Class[cons]")
527
+ expect(cons).not_to be_nil
528
+ expect(cons[:consume].ref).to eq("Cap[cap]")
529
+ end
530
+
531
+ it "an application instance must be contained in a site" do
532
+ expect { compile_to_env_catalog(FAULTY_MANIFEST)
533
+ }.to raise_error(/Application instances .* can only be contained within a Site/)
534
+ end
535
+
536
+ context "when using a site expression" do
537
+ it "includes components and capability resources" do
538
+ catalog = compile_to_env_catalog(MANIFEST_WITH_SITE).to_resource
539
+ apps = catalog.resources.select do |res|
540
+ res.resource_type && res.resource_type.application?
541
+ end
542
+ expect(apps.size).to eq(1)
543
+ app = apps.first
544
+ expect(app["nodes"]).not_to be_nil
545
+ comps = catalog.direct_dependents_of(app).map(&:ref).sort
546
+ expect(comps).to eq(["Cons[two]", "Prod[one]"])
547
+
548
+ prod = catalog.resource("Prod[one]")
549
+ expect(prod).not_to be_nil
550
+ expect(prod.export.map(&:ref)).to eq(["Cap[cap]"])
551
+
552
+ cons = catalog.resource("Cons[two]")
553
+ expect(cons).not_to be_nil
554
+ expect(cons[:consume].ref).to eq("Cap[cap]")
555
+ end
556
+
557
+ it "the site expression is evaluated in an environment compilation" do
558
+ catalog = compile_to_env_catalog(MANIFEST_WITH_SITE).to_resource
559
+ types = catalog.resource_keys.map { |type, _| type }.uniq.sort
560
+ expect(types).to eq(["App", "Class", "Cons", "Prod", "Site", "Stage"])
561
+ expect(catalog.resource("Notify[on a node]")).to be_nil
562
+ apps = catalog.resources.select do |res|
563
+ res.resource_type && res.resource_type.application?
564
+ end
565
+ expect(apps.size).to eq(1)
566
+ app = apps.first
567
+ comps = catalog.direct_dependents_of(app).map(&:ref).sort
568
+ expect(comps).to eq(["Cons[two]", "Prod[one]"])
569
+ end
570
+
571
+ it "fails if there are non component resources in the site" do
572
+ expect {
573
+ catalog = compile_to_env_catalog(MANIFEST_WITH_ILLEGAL_RESOURCE).to_resource
574
+ }.to raise_error(/Only application components can appear inside a site - Notify\[fail me\] is not allowed at line 20/)
575
+ end
576
+ end
577
+ end
578
+
579
+
580
+ describe "when validation of nodes" do
581
+ it 'validates that the key of a node mapping is a Node' do
582
+ expect { compile_to_catalog(<<-EOS, Puppet::Node.new('other'))
583
+ application app {
584
+ }
585
+
586
+ site {
587
+ app { anapp:
588
+ nodes => {
589
+ 'hello' => Node[other],
590
+ }
591
+ }
592
+ }
593
+ EOS
594
+ }.to raise_error(Puppet::Error, /hello is not a Node/)
595
+ end
596
+
597
+ it 'validates that the value of a node mapping is a resource' do
598
+ expect { compile_to_catalog(<<-EOS, Puppet::Node.new('other'))
599
+ application app {
600
+ }
601
+
602
+ site {
603
+ app { anapp:
604
+ nodes => {
605
+ Node[other] => 'hello'
606
+ }
607
+ }
608
+ }
609
+ EOS
610
+ }.to raise_error(Puppet::Error, /hello is not a resource/)
611
+ end
612
+
613
+ it 'validates that the value can be an array or resources' do
614
+ expect { compile_to_catalog(<<-EOS, Puppet::Node.new('other'))
615
+ define p {
616
+ notify {$title:}
617
+ }
618
+
619
+ application app {
620
+ p{one:}
621
+ p{two:}
622
+ }
623
+
624
+ site {
625
+ app { anapp:
626
+ nodes => {
627
+ Node[other] => [P[one],P[two]]
628
+ }
629
+ }
630
+ }
631
+ EOS
632
+ }.not_to raise_error
633
+ end
634
+
635
+ it 'validates that the is bound to exactly one node' do
636
+ expect { compile_to_catalog(<<-EOS, Puppet::Node.new('first'))
637
+ define p {
638
+ notify {$title:}
639
+ }
640
+
641
+ application app {
642
+ p{one:}
643
+ }
644
+
645
+ site {
646
+ app { anapp:
647
+ nodes => {
648
+ Node[first] => P[one],
649
+ Node[second] => P[one],
650
+ }
651
+ }
652
+ }
653
+ EOS
654
+ }.to raise_error(Puppet::Error, /maps component P\[one\] to multiple nodes/)
655
+ end
656
+ end
657
+ end