puppet 5.3.7 → 5.4.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 (454) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +42 -29
  3. data/README.md +8 -6
  4. data/ext/cert_inspector +2 -2
  5. data/ext/envpuppet +1 -1
  6. data/ext/gentoo/init.d/puppetmaster +4 -4
  7. data/ext/ips/puppet-agent +11 -11
  8. data/ext/ips/puppet-master +11 -11
  9. data/ext/puppet-test +1 -2
  10. data/ext/redhat/client.init +2 -2
  11. data/ext/redhat/logrotate +1 -1
  12. data/ext/solaris/smf/puppet +11 -11
  13. data/ext/solaris/smf/svc-puppetd +5 -5
  14. data/ext/solaris/smf/svc-puppetmasterd +5 -5
  15. data/ext/windows/service/daemon.rb +1 -1
  16. data/install.rb +2 -3
  17. data/lib/puppet/agent.rb +1 -1
  18. data/lib/puppet/application/cert.rb +1 -3
  19. data/lib/puppet/application/describe.rb +0 -1
  20. data/lib/puppet/application/device.rb +12 -99
  21. data/lib/puppet/application/filebucket.rb +32 -11
  22. data/lib/puppet/application/lookup.rb +1 -11
  23. data/lib/puppet/application/script.rb +261 -0
  24. data/lib/puppet/configurer.rb +3 -4
  25. data/lib/puppet/configurer/plugin_handler.rb +26 -9
  26. data/lib/puppet/context.rb +1 -1
  27. data/lib/puppet/datatypes.rb +213 -0
  28. data/lib/puppet/datatypes/error.rb +21 -0
  29. data/lib/puppet/datatypes/impl/error.rb +40 -0
  30. data/lib/puppet/defaults.rb +51 -20
  31. data/lib/puppet/environments.rb +17 -0
  32. data/lib/puppet/error.rb +17 -0
  33. data/lib/puppet/etc.rb +2 -2
  34. data/lib/puppet/external/pson/pure/generator.rb +1 -1
  35. data/lib/puppet/external/pson/pure/parser.rb +1 -1
  36. data/lib/puppet/face/config.rb +45 -0
  37. data/lib/puppet/face/epp.rb +3 -3
  38. data/lib/puppet/face/help/action.erb +3 -0
  39. data/lib/puppet/face/module/build.rb +1 -0
  40. data/lib/puppet/face/module/generate.rb +5 -0
  41. data/lib/puppet/face/module/install.rb +1 -0
  42. data/lib/puppet/face/module/search.rb +6 -2
  43. data/lib/puppet/face/module/uninstall.rb +1 -0
  44. data/lib/puppet/face/module/upgrade.rb +1 -0
  45. data/lib/puppet/face/parser.rb +0 -1
  46. data/lib/puppet/face/plugin.rb +1 -3
  47. data/lib/puppet/feature/base.rb +1 -1
  48. data/lib/puppet/feature/bolt.rb +3 -0
  49. data/lib/puppet/file_bucket/dipper.rb +1 -2
  50. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  51. data/lib/puppet/file_system/uniquefile.rb +2 -2
  52. data/lib/puppet/forge.rb +6 -0
  53. data/lib/puppet/functions.rb +70 -88
  54. data/lib/puppet/functions/all.rb +6 -2
  55. data/lib/puppet/functions/annotate.rb +1 -1
  56. data/lib/puppet/functions/any.rb +7 -3
  57. data/lib/puppet/functions/contain.rb +6 -0
  58. data/lib/puppet/functions/convert_to.rb +32 -0
  59. data/lib/puppet/functions/defined.rb +0 -3
  60. data/lib/puppet/functions/each.rb +10 -6
  61. data/lib/puppet/functions/filter.rb +16 -10
  62. data/lib/puppet/functions/find_file.rb +0 -1
  63. data/lib/puppet/functions/include.rb +6 -0
  64. data/lib/puppet/functions/map.rb +12 -9
  65. data/lib/puppet/functions/module_directory.rb +41 -0
  66. data/lib/puppet/functions/new.rb +1 -4
  67. data/lib/puppet/functions/regsubst.rb +1 -1
  68. data/lib/puppet/functions/require.rb +6 -0
  69. data/lib/puppet/generate/type.rb +1 -1
  70. data/lib/puppet/gettext/config.rb +2 -2
  71. data/lib/puppet/gettext/stubs.rb +1 -1
  72. data/lib/puppet/indirector/catalog/compiler.rb +0 -1
  73. data/lib/puppet/indirector/file_bucket_file/file.rb +6 -2
  74. data/lib/puppet/indirector/file_server.rb +1 -1
  75. data/lib/puppet/indirector/node/ldap.rb +19 -3
  76. data/lib/puppet/indirector/request.rb +10 -6
  77. data/lib/puppet/indirector/rest.rb +11 -12
  78. data/lib/puppet/info_service/class_information_service.rb +1 -1
  79. data/lib/puppet/interface/action.rb +11 -0
  80. data/lib/puppet/interface/action_builder.rb +8 -0
  81. data/lib/puppet/interface/option_manager.rb +1 -1
  82. data/lib/puppet/loaders.rb +2 -0
  83. data/lib/puppet/module.rb +6 -2
  84. data/lib/puppet/module_tool/applications/builder.rb +4 -0
  85. data/lib/puppet/module_tool/applications/installer.rb +3 -0
  86. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -0
  87. data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  88. data/lib/puppet/module_tool/applications/upgrader.rb +3 -0
  89. data/lib/puppet/module_tool/installed_modules.rb +1 -1
  90. data/lib/puppet/module_tool/metadata.rb +0 -1
  91. data/lib/puppet/network/authstore.rb +1 -1
  92. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  93. data/lib/puppet/network/http/connection.rb +1 -9
  94. data/lib/puppet/network/http/factory.rb +0 -3
  95. data/lib/puppet/network/http/webrick.rb +1 -0
  96. data/lib/puppet/network/rights.rb +1 -1
  97. data/lib/puppet/node.rb +53 -0
  98. data/lib/puppet/node/environment.rb +1 -1
  99. data/lib/puppet/parameter/boolean.rb +1 -1
  100. data/lib/puppet/parser.rb +1 -0
  101. data/lib/puppet/parser/abstract_compiler.rb +36 -0
  102. data/lib/puppet/parser/ast/branch.rb +1 -1
  103. data/lib/puppet/parser/ast/pops_bridge.rb +8 -52
  104. data/lib/puppet/parser/compiler.rb +4 -54
  105. data/lib/puppet/parser/functions.rb +0 -1
  106. data/lib/puppet/parser/functions/create_resources.rb +6 -0
  107. data/lib/puppet/parser/functions/fqdn_rand.rb +6 -2
  108. data/lib/puppet/parser/functions/inline_template.rb +6 -0
  109. data/lib/puppet/parser/functions/new.rb +47 -32
  110. data/lib/puppet/parser/functions/realize.rb +6 -0
  111. data/lib/puppet/parser/functions/return.rb +1 -22
  112. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  113. data/lib/puppet/parser/functions/scanf.rb +1 -1
  114. data/lib/puppet/parser/functions/sha256.rb +5 -0
  115. data/lib/puppet/parser/functions/tag.rb +6 -0
  116. data/lib/puppet/parser/functions/tagged.rb +6 -0
  117. data/lib/puppet/parser/functions/template.rb +5 -0
  118. data/lib/puppet/parser/scope.rb +28 -4
  119. data/lib/puppet/parser/script_compiler.rb +118 -0
  120. data/lib/puppet/parser/type_loader.rb +1 -1
  121. data/lib/puppet/pops.rb +1 -1
  122. data/lib/puppet/pops/evaluator/access_operator.rb +38 -4
  123. data/lib/puppet/pops/evaluator/closure.rb +12 -4
  124. data/lib/puppet/pops/evaluator/compare_operator.rb +4 -4
  125. data/lib/puppet/pops/evaluator/epp_evaluator.rb +13 -0
  126. data/lib/puppet/pops/evaluator/evaluator_impl.rb +38 -10
  127. data/lib/puppet/pops/evaluator/literal_evaluator.rb +1 -1
  128. data/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
  129. data/lib/puppet/pops/evaluator/runtime3_support.rb +2 -3
  130. data/lib/puppet/pops/functions/dispatch.rb +6 -5
  131. data/lib/puppet/pops/functions/function.rb +2 -2
  132. data/lib/puppet/pops/issues.rb +34 -2
  133. data/lib/puppet/pops/loader/base_loader.rb +10 -0
  134. data/lib/puppet/pops/loader/dependency_loader.rb +7 -0
  135. data/lib/puppet/pops/loader/loader.rb +21 -2
  136. data/lib/puppet/pops/loader/loader_paths.rb +180 -30
  137. data/lib/puppet/pops/loader/module_loaders.rb +202 -33
  138. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +84 -0
  139. data/lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb +9 -9
  140. data/lib/puppet/pops/loader/ruby_data_type_instantiator.rb +40 -0
  141. data/lib/puppet/pops/loader/runtime3_type_loader.rb +6 -1
  142. data/lib/puppet/pops/loader/static_loader.rb +23 -8
  143. data/lib/puppet/pops/loader/task_instantiator.rb +69 -0
  144. data/lib/puppet/pops/loader/type_definition_instantiator.rb +4 -0
  145. data/lib/puppet/pops/loaders.rb +122 -11
  146. data/lib/puppet/pops/lookup/data_dig_function_provider.rb +1 -1
  147. data/lib/puppet/pops/lookup/interpolation.rb +1 -1
  148. data/lib/puppet/pops/lookup/lookup_adapter.rb +0 -1
  149. data/lib/puppet/pops/model/ast.pp +3 -0
  150. data/lib/puppet/pops/model/ast.rb +34 -1
  151. data/lib/puppet/pops/model/factory.rb +30 -3
  152. data/lib/puppet/pops/model/model_label_provider.rb +1 -0
  153. data/lib/puppet/pops/model/model_tree_dumper.rb +12 -1
  154. data/lib/puppet/pops/model/tree_dumper.rb +1 -1
  155. data/lib/puppet/pops/parser/code_merger.rb +2 -2
  156. data/lib/puppet/pops/parser/egrammar.ra +44 -15
  157. data/lib/puppet/pops/parser/eparser.rb +1687 -1571
  158. data/lib/puppet/pops/parser/epp_support.rb +1 -3
  159. data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
  160. data/lib/puppet/pops/parser/interpolation_support.rb +2 -2
  161. data/lib/puppet/pops/parser/lexer2.rb +4 -4
  162. data/lib/puppet/pops/parser/lexer_support.rb +2 -2
  163. data/lib/puppet/pops/parser/locatable.rb +1 -1
  164. data/lib/puppet/pops/parser/locator.rb +7 -13
  165. data/lib/puppet/pops/parser/parser_support.rb +3 -3
  166. data/lib/puppet/pops/parser/slurp_support.rb +0 -3
  167. data/lib/puppet/pops/pcore.rb +45 -0
  168. data/lib/puppet/pops/resource/param.rb +1 -1
  169. data/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
  170. data/lib/puppet/pops/serialization/abstract_reader.rb +4 -0
  171. data/lib/puppet/pops/serialization/abstract_writer.rb +6 -0
  172. data/lib/puppet/pops/serialization/extension.rb +1 -0
  173. data/lib/puppet/pops/serialization/from_data_converter.rb +64 -10
  174. data/lib/puppet/pops/serialization/json_path.rb +2 -1
  175. data/lib/puppet/pops/serialization/object.rb +3 -4
  176. data/lib/puppet/pops/serialization/serializer.rb +2 -1
  177. data/lib/puppet/pops/serialization/to_data_converter.rb +7 -3
  178. data/lib/puppet/pops/time/timespan.rb +1 -1
  179. data/lib/puppet/pops/types/iterable.rb +38 -9
  180. data/lib/puppet/pops/types/p_init_type.rb +1 -1
  181. data/lib/puppet/pops/types/p_meta_type.rb +4 -0
  182. data/lib/puppet/pops/types/p_object_type.rb +146 -14
  183. data/lib/puppet/pops/types/p_object_type_extension.rb +218 -0
  184. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +0 -1
  185. data/lib/puppet/pops/types/p_sem_ver_type.rb +10 -2
  186. data/lib/puppet/pops/types/p_type_set_type.rb +0 -1
  187. data/lib/puppet/pops/types/p_uri_type.rb +190 -0
  188. data/lib/puppet/pops/types/puppet_object.rb +15 -1
  189. data/lib/puppet/pops/types/ruby_generator.rb +46 -54
  190. data/lib/puppet/pops/types/string_converter.rb +22 -1
  191. data/lib/puppet/pops/types/type_acceptor.rb +1 -1
  192. data/lib/puppet/pops/types/type_calculator.rb +13 -4
  193. data/lib/puppet/pops/types/type_factory.rb +29 -5
  194. data/lib/puppet/pops/types/type_formatter.rb +67 -4
  195. data/lib/puppet/pops/types/type_parser.rb +92 -4
  196. data/lib/puppet/pops/types/type_with_members.rb +43 -0
  197. data/lib/puppet/pops/types/types.rb +212 -80
  198. data/lib/puppet/pops/validation/checker4_0.rb +10 -6
  199. data/lib/puppet/pops/validation/tasks_checker.rb +60 -0
  200. data/lib/puppet/pops/validation/validator_factory_4_0.rb +6 -1
  201. data/lib/puppet/property.rb +1 -1
  202. data/lib/puppet/provider.rb +18 -8
  203. data/lib/puppet/provider/augeas/augeas.rb +3 -4
  204. data/lib/puppet/provider/exec.rb +0 -2
  205. data/lib/puppet/provider/group/groupadd.rb +25 -1
  206. data/lib/puppet/provider/group/windows_adsi.rb +7 -4
  207. data/lib/puppet/provider/mount.rb +25 -8
  208. data/lib/puppet/provider/nameservice.rb +9 -4
  209. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
  210. data/lib/puppet/provider/nameservice/objectadd.rb +13 -24
  211. data/lib/puppet/provider/nameservice/pw.rb +14 -14
  212. data/lib/puppet/provider/package/appdmg.rb +0 -1
  213. data/lib/puppet/provider/package/apple.rb +0 -1
  214. data/lib/puppet/provider/package/gem.rb +2 -2
  215. data/lib/puppet/provider/package/macports.rb +2 -2
  216. data/lib/puppet/provider/package/pkg.rb +3 -0
  217. data/lib/puppet/provider/package/pkgdmg.rb +0 -1
  218. data/lib/puppet/provider/package/portage.rb +0 -1
  219. data/lib/puppet/provider/package/yum.rb +23 -8
  220. data/lib/puppet/provider/package/zypper.rb +2 -2
  221. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +2 -2
  222. data/lib/puppet/provider/service/init.rb +1 -0
  223. data/lib/puppet/provider/service/launchd.rb +6 -7
  224. data/lib/puppet/provider/service/redhat.rb +3 -2
  225. data/lib/puppet/provider/service/systemd.rb +2 -2
  226. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  227. data/lib/puppet/provider/user/aix.rb +3 -2
  228. data/lib/puppet/provider/user/openbsd.rb +1 -1
  229. data/lib/puppet/provider/user/pw.rb +1 -1
  230. data/lib/puppet/provider/user/user_role_add.rb +7 -1
  231. data/lib/puppet/provider/user/useradd.rb +36 -6
  232. data/lib/puppet/provider/user/windows_adsi.rb +1 -1
  233. data/lib/puppet/provider/yumrepo/inifile.rb +2 -4
  234. data/lib/puppet/provider/zfs/zfs.rb +23 -3
  235. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  236. data/lib/puppet/reference/configuration.rb +0 -2
  237. data/lib/puppet/reference/type.rb +0 -1
  238. data/lib/puppet/resource.rb +1 -2
  239. data/lib/puppet/resource/catalog.rb +1 -1
  240. data/lib/puppet/resource/status.rb +0 -1
  241. data/lib/puppet/resource/type.rb +4 -4
  242. data/lib/puppet/resource/type_collection.rb +1 -1
  243. data/lib/puppet/settings/base_setting.rb +1 -1
  244. data/lib/puppet/settings/environment_conf.rb +0 -1
  245. data/lib/puppet/settings/ini_file.rb +66 -12
  246. data/lib/puppet/ssl/certificate_authority.rb +1 -1
  247. data/lib/puppet/ssl/certificate_request.rb +2 -2
  248. data/lib/puppet/ssl/certificate_revocation_list.rb +2 -1
  249. data/lib/puppet/ssl/certificate_signer.rb +11 -0
  250. data/lib/puppet/ssl/host.rb +2 -2
  251. data/lib/puppet/syntax_checkers/base64.rb +1 -1
  252. data/lib/puppet/transaction.rb +37 -14
  253. data/lib/puppet/transaction/report.rb +3 -1
  254. data/lib/puppet/type.rb +17 -4
  255. data/lib/puppet/type/cron.rb +1 -1
  256. data/lib/puppet/type/exec.rb +5 -4
  257. data/lib/puppet/type/file.rb +3 -3
  258. data/lib/puppet/type/file/checksum.rb +7 -1
  259. data/lib/puppet/type/file/checksum_value.rb +4 -3
  260. data/lib/puppet/type/group.rb +3 -0
  261. data/lib/puppet/type/k5login.rb +101 -0
  262. data/lib/puppet/type/macauthorization.rb +1 -1
  263. data/lib/puppet/type/mount.rb +6 -2
  264. data/lib/puppet/type/tidy.rb +6 -4
  265. data/lib/puppet/type/user.rb +26 -39
  266. data/lib/puppet/type/yumrepo.rb +9 -0
  267. data/lib/puppet/type/zfs.rb +4 -0
  268. data/lib/puppet/util.rb +8 -15
  269. data/lib/puppet/util/character_encoding.rb +2 -2
  270. data/lib/puppet/util/checksums.rb +82 -1
  271. data/lib/puppet/util/errors.rb +0 -2
  272. data/lib/puppet/util/filetype.rb +2 -2
  273. data/lib/puppet/util/json_lockfile.rb +1 -1
  274. data/lib/puppet/util/log.rb +1 -1
  275. data/lib/puppet/util/log/destinations.rb +10 -1
  276. data/lib/puppet/util/monkey_patches.rb +1 -1
  277. data/lib/puppet/util/network_device/cisco/device.rb +5 -5
  278. data/lib/puppet/util/network_device/config.rb +2 -3
  279. data/lib/puppet/util/platform.rb +13 -0
  280. data/lib/puppet/util/plist.rb +4 -4
  281. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +2 -2
  282. data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc2.rb +1 -1
  283. data/lib/puppet/util/reference.rb +8 -1
  284. data/lib/puppet/util/windows/adsi.rb +18 -15
  285. data/lib/puppet/util/windows/principal.rb +6 -7
  286. data/lib/puppet/util/windows/process.rb +1 -1
  287. data/lib/puppet/util/windows/registry.rb +2 -2
  288. data/lib/puppet/util/windows/sid.rb +7 -62
  289. data/lib/puppet/vendor/deep_merge/README.md +2 -2
  290. data/lib/puppet/vendor/pathspec/lib/pathspec/gitignorespec.rb +18 -18
  291. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version.rb +2 -2
  292. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version_range.rb +5 -5
  293. data/lib/puppet/vendor/semantic_puppet/locales/config.yaml +1 -1
  294. data/lib/puppet/version.rb +1 -1
  295. data/lib/puppet_pal.rb +874 -0
  296. data/locales/ja/puppet.po +140 -163
  297. data/locales/puppet.pot +940 -597
  298. data/man/man5/puppet.conf.5 +16 -91
  299. data/man/man8/puppet-agent.8 +2 -6
  300. data/man/man8/puppet-apply.8 +2 -2
  301. data/man/man8/puppet-ca.8 +1 -1
  302. data/man/man8/puppet-catalog.8 +1 -1
  303. data/man/man8/puppet-cert.8 +1 -1
  304. data/man/man8/puppet-certificate.8 +1 -1
  305. data/man/man8/puppet-certificate_request.8 +1 -1
  306. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  307. data/man/man8/puppet-config.8 +1 -1
  308. data/man/man8/puppet-describe.8 +1 -1
  309. data/man/man8/puppet-device.8 +11 -33
  310. data/man/man8/puppet-doc.8 +1 -1
  311. data/man/man8/puppet-epp.8 +1 -1
  312. data/man/man8/puppet-facts.8 +1 -1
  313. data/man/man8/puppet-filebucket.8 +4 -22
  314. data/man/man8/puppet-generate.8 +1 -1
  315. data/man/man8/puppet-help.8 +1 -1
  316. data/man/man8/puppet-key.8 +1 -1
  317. data/man/man8/puppet-lookup.8 +1 -1
  318. data/man/man8/puppet-man.8 +1 -1
  319. data/man/man8/puppet-master.8 +1 -1
  320. data/man/man8/puppet-module.8 +2 -11
  321. data/man/man8/puppet-node.8 +1 -1
  322. data/man/man8/puppet-parser.8 +1 -1
  323. data/man/man8/puppet-plugin.8 +1 -1
  324. data/man/man8/puppet-report.8 +1 -1
  325. data/man/man8/puppet-resource.8 +1 -1
  326. data/man/man8/puppet-status.8 +1 -1
  327. data/man/man8/puppet.8 +2 -2
  328. data/spec/integration/application/lookup_spec.rb +0 -21
  329. data/spec/integration/parser/compiler_spec.rb +18 -0
  330. data/spec/integration/parser/script_compiler_spec.rb +113 -0
  331. data/spec/integration/provider/mount_spec.rb +2 -0
  332. data/spec/integration/type/file_spec.rb +11 -3
  333. data/spec/integration/util/windows/adsi_spec.rb +1 -86
  334. data/spec/integration/util/windows/principal_spec.rb +1 -10
  335. data/spec/shared_contexts/checksum.rb +4 -1
  336. data/spec/shared_contexts/digests.rb +46 -1
  337. data/spec/shared_contexts/types_setup.rb +8 -3
  338. data/spec/unit/agent_spec.rb +2 -2
  339. data/spec/unit/application/cert_spec.rb +5 -17
  340. data/spec/unit/application/device_spec.rb +2 -96
  341. data/spec/unit/application/filebucket_spec.rb +18 -4
  342. data/spec/unit/configurer/plugin_handler_spec.rb +5 -32
  343. data/spec/unit/configurer_spec.rb +3 -3
  344. data/spec/unit/datatypes_spec.rb +304 -0
  345. data/spec/unit/defaults_spec.rb +41 -20
  346. data/spec/unit/face/config_spec.rb +46 -1
  347. data/spec/unit/face/epp_face_spec.rb +7 -3
  348. data/spec/unit/face/module/search_spec.rb +11 -0
  349. data/spec/unit/face/parser_spec.rb +2 -2
  350. data/spec/unit/file_bucket/dipper_spec.rb +12 -1
  351. data/spec/unit/forge/module_release_spec.rb +70 -0
  352. data/spec/unit/functions/break_spec.rb +34 -2
  353. data/spec/unit/functions/contain_spec.rb +1 -0
  354. data/spec/unit/functions/convert_to_spec.rb +22 -0
  355. data/spec/unit/functions/epp_spec.rb +5 -0
  356. data/spec/unit/functions/include_spec.rb +15 -0
  357. data/spec/unit/functions/module_directory_spec.rb +43 -0
  358. data/spec/unit/functions/new_spec.rb +14 -14
  359. data/spec/unit/functions/require_spec.rb +2 -0
  360. data/spec/unit/functions/shared.rb +12 -0
  361. data/spec/unit/functions/step_spec.rb +1 -1
  362. data/spec/unit/functions4_spec.rb +49 -4
  363. data/spec/unit/indirector/catalog/compiler_spec.rb +3 -3
  364. data/spec/unit/indirector/file_bucket_file/file_spec.rb +148 -94
  365. data/spec/unit/indirector/node/ldap_spec.rb +15 -12
  366. data/spec/unit/indirector/rest_spec.rb +0 -43
  367. data/spec/unit/interface/action_spec.rb +33 -0
  368. data/spec/unit/module_tool/applications/builder_spec.rb +7 -0
  369. data/spec/unit/module_tool/applications/installer_spec.rb +8 -0
  370. data/spec/unit/module_tool/applications/uninstaller_spec.rb +8 -0
  371. data/spec/unit/module_tool/applications/upgrader_spec.rb +6 -0
  372. data/spec/unit/network/http/connection_spec.rb +1 -1
  373. data/spec/unit/network/http/factory_spec.rb +28 -35
  374. data/spec/unit/parser/compiler_spec.rb +0 -8
  375. data/spec/unit/parser/environment_compiler_spec.rb +36 -0
  376. data/spec/unit/parser/functions/create_resources_spec.rb +9 -0
  377. data/spec/unit/parser/functions/inline_template_spec.rb +7 -0
  378. data/spec/unit/parser/functions/realize_spec.rb +9 -0
  379. data/spec/unit/parser/functions/tag_spec.rb +7 -0
  380. data/spec/unit/parser/functions/tagged_spec.rb +25 -0
  381. data/spec/unit/parser/functions/template_spec.rb +8 -0
  382. data/spec/unit/parser/scope_spec.rb +19 -0
  383. data/spec/unit/pops/evaluator/conditionals_spec.rb +1 -1
  384. data/spec/unit/pops/loaders/loader_spec.rb +516 -0
  385. data/spec/unit/pops/loaders/loaders_spec.rb +11 -0
  386. data/spec/unit/pops/loaders/module_loaders_spec.rb +43 -0
  387. data/spec/unit/pops/loaders/static_loader_spec.rb +15 -7
  388. data/spec/unit/pops/model/model_spec.rb +5 -0
  389. data/spec/unit/pops/parser/lexer2_spec.rb +15 -0
  390. data/spec/unit/pops/parser/locator_spec.rb +20 -0
  391. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +33 -0
  392. data/spec/unit/pops/parser/parse_calls_spec.rb +28 -0
  393. data/spec/unit/pops/parser/parse_conditionals_spec.rb +12 -0
  394. data/spec/unit/pops/parser/parse_plan_spec.rb +48 -0
  395. data/spec/unit/pops/serialization/packer_spec.rb +8 -0
  396. data/spec/unit/pops/serialization/serialization_spec.rb +30 -0
  397. data/spec/unit/pops/serialization/to_from_hr_spec.rb +31 -0
  398. data/spec/unit/pops/types/error_spec.rb +207 -0
  399. data/spec/unit/pops/types/p_init_type_spec.rb +98 -0
  400. data/spec/unit/pops/types/p_object_type_spec.rb +275 -10
  401. data/spec/unit/pops/types/p_uri_type_spec.rb +191 -0
  402. data/spec/unit/pops/types/ruby_generator_spec.rb +82 -44
  403. data/spec/unit/pops/types/task_spec.rb +353 -0
  404. data/spec/unit/pops/types/type_calculator_spec.rb +76 -5
  405. data/spec/unit/pops/types/type_formatter_spec.rb +31 -13
  406. data/spec/unit/pops/types/type_parser_spec.rb +13 -1
  407. data/spec/unit/pops/types/types_spec.rb +60 -0
  408. data/spec/unit/pops/validator/validator_spec.rb +76 -0
  409. data/spec/unit/provider/group/groupadd_spec.rb +77 -1
  410. data/spec/unit/provider/group/pw_spec.rb +4 -4
  411. data/spec/unit/provider/group/windows_adsi_spec.rb +22 -79
  412. data/spec/unit/provider/mount_spec.rb +18 -5
  413. data/spec/unit/provider/nameservice_spec.rb +5 -5
  414. data/spec/unit/provider/package/dnf_spec.rb +2 -2
  415. data/spec/unit/provider/package/gem_spec.rb +1 -1
  416. data/spec/unit/provider/package/pkg_spec.rb +3 -0
  417. data/spec/unit/provider/package/yum_spec.rb +40 -0
  418. data/spec/unit/provider/service/launchd_spec.rb +2 -1
  419. data/spec/unit/provider/service/redhat_spec.rb +5 -0
  420. data/spec/unit/provider/service/systemd_spec.rb +1 -1
  421. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  422. data/spec/unit/provider/user/openbsd_spec.rb +2 -2
  423. data/spec/unit/provider/user/pw_spec.rb +14 -14
  424. data/spec/unit/provider/user/user_role_add_spec.rb +19 -2
  425. data/spec/unit/provider/user/useradd_spec.rb +188 -22
  426. data/spec/unit/provider/user/windows_adsi_spec.rb +4 -4
  427. data/spec/unit/provider/zfs/zfs_spec.rb +55 -1
  428. data/spec/unit/provider_spec.rb +48 -0
  429. data/spec/unit/puppet_pal_2pec.rb +1005 -0
  430. data/spec/unit/puppet_pal_spec.rb +11 -0
  431. data/spec/unit/settings/ini_file_spec.rb +313 -2
  432. data/spec/unit/ssl/certificate_request_spec.rb +42 -1
  433. data/spec/unit/ssl/certificate_revocation_list_spec.rb +2 -1
  434. data/spec/unit/transaction/report_spec.rb +1 -0
  435. data/spec/unit/transaction_spec.rb +112 -21
  436. data/spec/unit/type/file/checksum_spec.rb +20 -0
  437. data/spec/unit/type/file_spec.rb +8 -0
  438. data/spec/unit/type/group_spec.rb +8 -0
  439. data/spec/unit/type/k5login_spec.rb +22 -1
  440. data/spec/unit/type/scheduled_task_spec.rb +15 -0
  441. data/spec/unit/type/user_spec.rb +11 -1
  442. data/spec/unit/type/yumrepo_spec.rb +5 -0
  443. data/spec/unit/util/checksums_spec.rb +3 -3
  444. data/spec/unit/util/log/destinations_spec.rb +14 -0
  445. data/spec/unit/util/network_device/cisco/device_spec.rb +1 -1
  446. data/spec/unit/util/plist_spec.rb +3 -3
  447. data/spec/unit/util/windows/adsi_spec.rb +27 -31
  448. data/spec/unit/util/windows/sid_spec.rb +15 -86
  449. data/spec/unit/util_spec.rb +17 -3
  450. data/tasks/manpages.rake +1 -1
  451. metadata +216 -178
  452. data/lib/puppet/bindings.rb +0 -148
  453. data/lib/puppet/configurer/downloader_factory.rb +0 -44
  454. data/spec/unit/configurer/downloader_factory_spec.rb +0 -129
@@ -0,0 +1,1005 @@
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
3
+ require 'puppet_spec/files'
4
+
5
+ describe 'Puppet Pal' do
6
+ # before { skip("Puppet::Pal is not available on Ruby 1.9.3") if RUBY_VERSION == '1.9.3' }
7
+
8
+ # Require here since it will not work on RUBY < 2.0.0
9
+ require 'puppet_pal'
10
+
11
+ include PuppetSpec::Files
12
+
13
+ let(:testing_env) do
14
+ {
15
+ 'pal_env' => {
16
+ 'functions' => functions,
17
+ 'lib' => { 'puppet' => lib_puppet },
18
+ 'manifests' => manifests,
19
+ 'modules' => modules,
20
+ 'plans' => plans,
21
+ 'tasks' => tasks,
22
+ 'types' => types,
23
+ },
24
+ 'other_env1' => { 'modules' => {} },
25
+ 'other_env2' => { 'modules' => {} },
26
+ }
27
+ end
28
+
29
+ let(:functions) { {} }
30
+ let(:manifests) { {} }
31
+ let(:modules) { {} }
32
+ let(:plans) { {} }
33
+ let(:lib_puppet) { {} }
34
+ let(:tasks) { {} }
35
+ let(:types) { {} }
36
+
37
+ let(:environments_dir) { Puppet[:environmentpath] }
38
+
39
+ let(:testing_env_dir) do
40
+ dir_contained_in(environments_dir, testing_env)
41
+ env_dir = File.join(environments_dir, 'pal_env')
42
+ PuppetSpec::Files.record_tmp(env_dir)
43
+ PuppetSpec::Files.record_tmp(File.join(environments_dir, 'other_env1'))
44
+ PuppetSpec::Files.record_tmp(File.join(environments_dir, 'other_env2'))
45
+ env_dir
46
+ end
47
+
48
+ let(:modules_dir) { File.join(testing_env_dir, 'modules') }
49
+
50
+ # Without any facts - this speeds up the tests that do not require $facts to have any values
51
+ let(:node_facts) { Hash.new }
52
+
53
+ # TODO: to be used in examples for running in an existing env
54
+ # let(:env) { Puppet::Node::Environment.create(:testing, [modules_dir]) }
55
+
56
+ context 'in general - without code in modules or env' do
57
+ let(:modulepath) { [] }
58
+
59
+ context 'deprecated PAL API methods work and' do
60
+ it '"evaluate_script_string" evaluates a code string in a given tmp environment' do
61
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
62
+ ctx.evaluate_script_string('1+2+3')
63
+ end
64
+ expect(result).to eq(6)
65
+ end
66
+
67
+ it '"evaluate_script_manifest" evaluates a manifest file in a given tmp environment' do
68
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
69
+ manifest = file_containing('testing.pp', "1+2+3+4")
70
+ ctx.evaluate_script_manifest(manifest)
71
+ end
72
+ expect(result).to eq(10)
73
+ end
74
+ end
75
+
76
+ context "with a script compiler" do
77
+ it 'errors if given both configured_by_env and manifest_file' do
78
+ expect {
79
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
80
+ ctx.with_script_compiler(configured_by_env: true, manifest_file: 'undef.pp') {|c| }
81
+ end
82
+ }.to raise_error(/manifest_file or code_string cannot be given when configured_by_env is true/)
83
+ end
84
+
85
+ it 'errors if given both configured_by_env and code_string' do
86
+ expect {
87
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
88
+ ctx.with_script_compiler(configured_by_env: true, code_string: 'undef') {|c| }
89
+ end
90
+ }.to raise_error(/manifest_file or code_string cannot be given when configured_by_env is true/)
91
+ end
92
+
93
+ context "evaluate_string method" do
94
+ it 'evaluates code string in a given tmp environment' do
95
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
96
+ ctx.with_script_compiler {|c| c.evaluate_string('1+2+3') }
97
+ end
98
+ expect(result).to eq(6)
99
+ end
100
+
101
+ it 'can be evaluated more than once in a given tmp environment - each in fresh compiler' do
102
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
103
+ expect( ctx.with_script_compiler {|c| c.evaluate_string('$a = 1+2+3')}).to eq(6)
104
+ expect { ctx.with_script_compiler {|c| c.evaluate_string('$a') }}.to raise_error(/Unknown variable: 'a'/)
105
+ end
106
+ end
107
+
108
+ it 'instantiates definitions in the given code string' do
109
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |pal|
110
+ pal.with_script_compiler do |compiler|
111
+ compiler.evaluate_string(<<-CODE)
112
+ function run_me() { "worked1" }
113
+ run_me()
114
+ CODE
115
+ end
116
+ end
117
+ expect(result).to eq('worked1')
118
+ end
119
+ end
120
+
121
+ context "evaluate_file method" do
122
+ it 'evaluates a manifest file in a given tmp environment' do
123
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
124
+ manifest = file_containing('testing.pp', "1+2+3+4")
125
+ ctx.with_script_compiler {|c| c.evaluate_file(manifest) }
126
+ end
127
+ expect(result).to eq(10)
128
+ end
129
+
130
+ it 'instantiates definitions in the given code string' do
131
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |pal|
132
+ pal.with_script_compiler do |compiler|
133
+ manifest = file_containing('testing.pp', (<<-CODE))
134
+ function run_me() { "worked1" }
135
+ run_me()
136
+ CODE
137
+ pal.with_script_compiler {|c| c.evaluate_file(manifest) }
138
+ end
139
+ end
140
+ expect(result).to eq('worked1')
141
+ end
142
+ end
143
+
144
+ context "variables are supported such that" do
145
+ it 'they can be set in any scope' do
146
+ vars = {'a'=> 10, 'x::y' => 20}
147
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts, variables: vars) do |ctx|
148
+ ctx.with_script_compiler {|c| c.evaluate_string("1+2+3+4+$a+$x::y")}
149
+ end
150
+ expect(result).to eq(40)
151
+ end
152
+
153
+ it 'an error is raised if a variable name is illegal' do
154
+ vars = {'_a::b'=> 10}
155
+ expect do
156
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts, variables: vars) do |ctx|
157
+ manifest = file_containing('testing.pp', "ok")
158
+ ctx.with_script_compiler {|c| c.evaluate_file(manifest) }
159
+ end
160
+ end.to raise_error(/has illegal name/)
161
+ end
162
+
163
+ it 'an error is raised if variable value is not RichData compliant' do
164
+ vars = {'a'=> ArgumentError.new("not rich data")}
165
+ expect do
166
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts, variables: vars) do |ctx|
167
+ ctx.with_script_compiler {|c| }
168
+ end
169
+ end.to raise_error(/has illegal type - got: ArgumentError/)
170
+ end
171
+
172
+ it 'variable given to script_compiler overrides those given for environment' do
173
+ vars = {'a'=> 10, 'x::y' => 20}
174
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts, variables: vars) do |ctx|
175
+ ctx.with_script_compiler(variables: {'x::y' => 40}) {|c| c.evaluate_string("1+2+3+4+$a+$x::y")}
176
+ end
177
+ expect(result).to eq(60)
178
+ end
179
+ end
180
+
181
+ context "functions are supported such that" do
182
+ it '"call_function" calls a function' do
183
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
184
+ manifest = file_containing('afunc.pp', "function myfunc($a) { $a * 2 } ")
185
+ ctx.with_script_compiler(manifest_file: manifest) {|c| c.call_function('myfunc', 6) }
186
+ end
187
+ expect(result).to eq(12)
188
+ end
189
+
190
+ it '"call_function" accepts a call with a ruby block' do
191
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
192
+ ctx.with_script_compiler {|c| c.call_function('with', 6) {|x| x * 2} }
193
+ end
194
+ expect(result).to eq(12)
195
+ end
196
+
197
+ it '"function_signature" returns a signature of a function' do
198
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
199
+ manifest = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
200
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
201
+ c.function_signature('myfunc')
202
+ end
203
+ end
204
+ expect(result.class).to eq(Puppet::Pal::FunctionSignature)
205
+ end
206
+
207
+ it '"FunctionSignature#callable_with?" returns boolean if function is callable with given argument values' do
208
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
209
+ manifest = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
210
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
211
+ signature = c.function_signature('myfunc')
212
+ [ signature.callable_with?([10]),
213
+ signature.callable_with?(['nope'])
214
+ ]
215
+ end
216
+ end
217
+ expect(result).to eq([true, false])
218
+ end
219
+
220
+ it '"FunctionSignature#callable_with?" calls a given lambda if there is an error' do
221
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
222
+ manifest = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
223
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
224
+ signature = c.function_signature('myfunc')
225
+ local_result = 'not yay'
226
+ signature.callable_with?(['nope']) {|error| local_result = error }
227
+ local_result
228
+ end
229
+ end
230
+ expect(result).to match(/'myfunc' parameter 'a' expects an Integer value, got String/)
231
+ end
232
+
233
+ it '"FunctionSignature#callable_with?" does not call a given lambda when there is no error' do
234
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
235
+ manifest = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
236
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
237
+ signature = c.function_signature('myfunc')
238
+ local_result = 'yay'
239
+ signature.callable_with?([10]) {|error| local_result = 'not yay' }
240
+ local_result
241
+ end
242
+ end
243
+ expect(result).to eq('yay')
244
+ end
245
+
246
+ it '"function_signature" gets the signatures from a ruby function with multiple dispatch' do
247
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
248
+ ctx.with_script_compiler {|c| c.function_signature('lookup') }
249
+ end
250
+ # check two different signatures of the lookup function
251
+ expect(result.callable_with?(['key'])).to eq(true)
252
+ expect(result.callable_with?(['key'], lambda() {|k| })).to eq(true)
253
+ end
254
+
255
+ it '"function_signature" returns nil if function is not found' do
256
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
257
+ ctx.with_script_compiler {|c| c.function_signature('no_where_to_be_found') }
258
+ end
259
+ expect(result).to eq(nil)
260
+ end
261
+
262
+ it '"FunctionSignature#callables" returns an array of callables' do
263
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
264
+ manifest = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
265
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
266
+ c.function_signature('myfunc').callables
267
+ end
268
+ end
269
+ expect(result.class).to eq(Array)
270
+ expect(result.all? {|c| c.is_a?(Puppet::Pops::Types::PCallableType)}).to eq(true)
271
+ end
272
+
273
+ it '"list_functions" returns an array with all function names that can be loaded' do
274
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
275
+ ctx.with_script_compiler {|c| c.list_functions() }
276
+ end
277
+ expect(result.is_a?(Array)).to eq(true)
278
+ expect(result.all? {|s| s.is_a?(Puppet::Pops::Loader::TypedName) }).to eq(true)
279
+ # there are certainly more than 30 functions in puppet - (56 when writing this, but some refactoring
280
+ # may take place, so don't want an exact number here - jsut make sure it found "all of them"
281
+ expect(result.count).to be > 30
282
+ end
283
+
284
+ it '"list_functions" filters on name based on a given regexp' do
285
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
286
+ ctx.with_script_compiler {|c| c.list_functions(/epp/) }
287
+ end
288
+ expect(result.is_a?(Array)).to eq(true)
289
+ expect(result.all? {|s| s.is_a?(Puppet::Pops::Loader::TypedName) }).to eq(true)
290
+ # there are two functions currently that have 'epp' in their name
291
+ expect(result.count).to eq(2)
292
+ end
293
+
294
+ end
295
+
296
+ context 'supports plans such that' do
297
+ it '"plan_signature" returns the signatures of a plan' do
298
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
299
+ manifest = file_containing('afunc.pp', "plan myplan(Integer $a) { } ")
300
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
301
+ signature = c.plan_signature('myplan')
302
+ [ signature.callable_with?({'a' => 10}),
303
+ signature.callable_with?({'a' => 'nope'})
304
+ ]
305
+ end
306
+ end
307
+ expect(result).to eq([true, false])
308
+ end
309
+
310
+ it 'a PlanSignature.callable_with? calls a given lambda with any errors as a formatted string' do
311
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
312
+ manifest = file_containing('afunc.pp', "plan myplan(Integer $a, Integer $b) { } ")
313
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
314
+ signature = c.plan_signature('myplan')
315
+ local_result = nil
316
+ signature.callable_with?({'a' => 'nope'}) {|errors| local_result = errors }
317
+ local_result
318
+ end
319
+ end
320
+ # Note that errors are indented one space and on separate lines
321
+ #
322
+ expect(result).to eq(" parameter 'a' expects an Integer value, got String\n expects a value for parameter 'b'")
323
+ end
324
+
325
+ it 'a PlanSignature.callable_with? does not call a given lambda if there are no errors' do
326
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
327
+ manifest = file_containing('afunc.pp', "plan myplan(Integer $a) { } ")
328
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
329
+ signature = c.plan_signature('myplan')
330
+ local_result = 'yay'
331
+ signature.callable_with?({'a' => 1}) {|errors| local_result = 'not yay' }
332
+ local_result
333
+ end
334
+ end
335
+ expect(result).to eq('yay')
336
+ end
337
+
338
+ it '"plan_signature" returns nil if plan is not found' do
339
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
340
+ ctx.with_script_compiler {|c| c.plan_signature('no_where_to_be_found') }
341
+ end
342
+ expect(result).to be(nil)
343
+ end
344
+
345
+ it '"PlanSignature#params_type" returns a map of all parameters and their types' do
346
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
347
+ manifest = file_containing('afunc.pp', "plan myplan(Integer $a, String $b) { } ")
348
+ ctx.with_script_compiler(manifest_file: manifest) do |c|
349
+ c.plan_signature('myplan').params_type
350
+ end
351
+ end
352
+ expect(result.class).to eq(Puppet::Pops::Types::PStructType)
353
+ expect(result.to_s).to eq("Struct[{'a' => Integer, 'b' => String}]")
354
+ end
355
+ end
356
+
357
+ context 'supports puppet data types such that' do
358
+ it '"type" parses and returns a Type from a string specification' do
359
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
360
+ manifest = file_containing('main.pp', "type MyType = Float")
361
+ ctx.with_script_compiler(manifest_file: manifest) {|c| c.type('Variant[Integer, Boolean, MyType]') }
362
+ end
363
+ expect(result.is_a?(Puppet::Pops::Types::PVariantType)).to eq(true)
364
+ expect(result.types.size).to eq(3)
365
+ expect(result.instance?(3.14)).to eq(true)
366
+ end
367
+
368
+ it '"create" creates a new object from a puppet data type and args' do
369
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
370
+ ctx.with_script_compiler { |c| c.create(Puppet::Pops::Types::PIntegerType::DEFAULT, '0x10') }
371
+ end
372
+ expect(result).to eq(16)
373
+ end
374
+
375
+ it '"create" creates a new object from puppet data type in string form and args' do
376
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
377
+ ctx.with_script_compiler { |c| c.create('Integer', '010') }
378
+ end
379
+ expect(result).to eq(8)
380
+ end
381
+ end
382
+ end
383
+
384
+ context 'supports parsing such that' do
385
+ it '"parse_string" parses a puppet language string' do
386
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
387
+ ctx.with_script_compiler { |c| c.parse_string('$a = 10') }
388
+ end
389
+ expect(result.class).to eq(Puppet::Pops::Model::Program)
390
+ end
391
+
392
+ { nil => Puppet::Error,
393
+ '0xWAT' => Puppet::ParseErrorWithIssue,
394
+ '$0 = 1' => Puppet::ParseErrorWithIssue,
395
+ 'else 32' => Puppet::ParseErrorWithIssue,
396
+ }.each_pair do |input, error_class|
397
+ it "'parse_string' raises an error for invalid input: '#{input}'" do
398
+ expect {
399
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
400
+ ctx.with_script_compiler { |c| c.parse_string(input) }
401
+ end
402
+ }.to raise_error(error_class)
403
+ end
404
+ end
405
+
406
+ it '"parse_file" parses a puppet language string' do
407
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
408
+ manifest = file_containing('main.pp', "$a = 10")
409
+ ctx.with_script_compiler { |c| c.parse_file(manifest) }
410
+ end
411
+ expect(result.class).to eq(Puppet::Pops::Model::Program)
412
+ end
413
+
414
+ it "'parse_file' raises an error for invalid input: 'else 32'" do
415
+ expect {
416
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
417
+ manifest = file_containing('main.pp', "else 32")
418
+ ctx.with_script_compiler { |c| c.parse_file(manifest) }
419
+ end
420
+ }.to raise_error(Puppet::ParseErrorWithIssue)
421
+ end
422
+
423
+ it "'parse_file' raises an error for invalid input, file is not a string" do
424
+ expect {
425
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
426
+ ctx.with_script_compiler { |c| c.parse_file(42) }
427
+ end
428
+ }.to raise_error(Puppet::Error)
429
+ end
430
+
431
+ it 'the "evaluate" method evaluates the parsed AST' do
432
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
433
+ ctx.with_script_compiler { |c| c.evaluate(c.parse_string('10 + 20')) }
434
+ end
435
+ expect(result).to eq(30)
436
+ end
437
+
438
+ it 'the "evaluate" method instantiates definitions when given a Program' do
439
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
440
+ ctx.with_script_compiler { |c| c.evaluate(c.parse_string('function foo() { "yay"}; foo()')) }
441
+ end
442
+ expect(result).to eq('yay')
443
+ end
444
+
445
+ it 'the "evaluate" method does not instantiates definitions when given ast other than Program' do
446
+ expect do
447
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
448
+ ctx.with_script_compiler do |c|
449
+ program= c.parse_string('function foo() { "yay"}; foo()')
450
+ c.evaluate(program.body)
451
+ end
452
+ end
453
+ end.to raise_error(/Unknown function: 'foo'/)
454
+ end
455
+
456
+ it 'the "evaluate_literal" method evaluates AST being a representation of a literal value' do
457
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
458
+ ctx.with_script_compiler { |c| c.evaluate_literal(c.parse_string('{10 => "hello"}')) }
459
+ end
460
+ expect(result).to eq({10 => 'hello'})
461
+ end
462
+
463
+ it 'the "evaluate_literal" method errors if ast is not representing a literal value' do
464
+ expect do
465
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
466
+ ctx.with_script_compiler { |c| c.evaluate_literal(c.parse_string('{10+1 => "hello"}')) }
467
+ end
468
+ end.to raise_error(/does not represent a literal value/)
469
+ end
470
+
471
+ it 'the "evaluate_literal" method errors if ast contains definitions' do
472
+ expect do
473
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do | ctx|
474
+ ctx.with_script_compiler { |c| c.evaluate_literal(c.parse_string('function foo() { }; 42')) }
475
+ end
476
+ end.to raise_error(/does not represent a literal value/)
477
+ end
478
+
479
+ end
480
+ end
481
+
482
+ context 'with code in modules and env' do
483
+ let(:modulepath) { [modules_dir] }
484
+
485
+ let(:metadata_json_a) {
486
+ {
487
+ 'name' => 'example/a',
488
+ 'version' => '0.1.0',
489
+ 'source' => 'git@github.com/example/example-a.git',
490
+ 'dependencies' => [{'name' => 'c', 'version_range' => '>=0.1.0'}],
491
+ 'author' => 'Bob the Builder',
492
+ 'license' => 'Apache-2.0'
493
+ }
494
+ }
495
+
496
+ let(:metadata_json_b) {
497
+ {
498
+ 'name' => 'example/b',
499
+ 'version' => '0.1.0',
500
+ 'source' => 'git@github.com/example/example-b.git',
501
+ 'dependencies' => [{'name' => 'c', 'version_range' => '>=0.1.0'}],
502
+ 'author' => 'Bob the Builder',
503
+ 'license' => 'Apache-2.0'
504
+ }
505
+ }
506
+
507
+ let(:metadata_json_c) {
508
+ {
509
+ 'name' => 'example/c',
510
+ 'version' => '0.1.0',
511
+ 'source' => 'git@github.com/example/example-c.git',
512
+ 'dependencies' => [],
513
+ 'author' => 'Bob the Builder',
514
+ 'license' => 'Apache-2.0'
515
+ }
516
+ }
517
+
518
+ # TODO: there is something amiss with the metadata wrt dependencies - when metadata is present there is an error
519
+ # that dependencies could not be resolved. Metadata is therefore commented out.
520
+ # Dependency based visibility is probably something that we should remove...
521
+ let(:modules) {
522
+ {
523
+ 'a' => {
524
+ 'functions' => a_functions,
525
+ 'lib' => { 'puppet' => a_lib_puppet },
526
+ 'plans' => a_plans,
527
+ 'tasks' => a_tasks,
528
+ 'types' => a_types,
529
+ # 'metadata.json' => metadata_json_a.to_json
530
+ },
531
+ 'b' => {
532
+ 'functions' => b_functions,
533
+ 'lib' => b_lib,
534
+ 'plans' => b_plans,
535
+ 'tasks' => b_tasks,
536
+ 'types' => b_types,
537
+ # 'metadata.json' => metadata_json_b.to_json
538
+ },
539
+ 'c' => {
540
+ 'types' => c_types,
541
+ # 'metadata.json' => metadata_json_c.to_json
542
+ },
543
+ }
544
+ }
545
+
546
+ let(:a_plans) {
547
+ {
548
+ 'aplan.pp' => <<-PUPPET.unindent,
549
+ plan a::aplan() { 'a::aplan value' }
550
+ PUPPET
551
+ }
552
+ }
553
+
554
+ let(:a_types) {
555
+ {
556
+ 'atype.pp' => <<-PUPPET.unindent,
557
+ type A::Atype = Integer
558
+ PUPPET
559
+ }
560
+ }
561
+
562
+ let(:a_tasks) {
563
+ {
564
+ 'atask' => '',
565
+ }
566
+ }
567
+
568
+ let(:a_functions) {
569
+ {
570
+ 'afunc.pp' => 'function a::afunc() { "a::afunc value" }',
571
+ }
572
+ }
573
+
574
+ let(:a_lib_puppet) {
575
+ {
576
+ 'functions' => {
577
+ 'a' => {
578
+ 'arubyfunc.rb' => <<-RUBY.unindent,
579
+ require 'stuff/something'
580
+ Puppet::Functions.create_function(:'a::arubyfunc') do
581
+ def arubyfunc
582
+ Stuff::SOMETHING
583
+ end
584
+ end
585
+ RUBY
586
+ 'myscriptcompilerfunc.rb' => <<-RUBY.unindent,
587
+ Puppet::Functions.create_function(:'a::myscriptcompilerfunc', Puppet::Functions::InternalFunction) do
588
+ dispatch :myscriptcompilerfunc do
589
+ script_compiler_param
590
+ param 'String',:name
591
+ end
592
+
593
+ def myscriptcompilerfunc(script_compiler, name)
594
+ script_compiler.is_a?(Puppet::Pal::ScriptCompiler) ? name : 'no go'
595
+ end
596
+ end
597
+ RUBY
598
+ }
599
+ }
600
+ }
601
+ }
602
+
603
+ let(:b_plans) {
604
+ {
605
+ 'aplan.pp' => <<-PUPPET.unindent,
606
+ plan b::aplan() {}
607
+ PUPPET
608
+ }
609
+ }
610
+
611
+ let(:b_types) {
612
+ {
613
+ 'atype.pp' => <<-PUPPET.unindent,
614
+ type B::Atype = Integer
615
+ PUPPET
616
+ }
617
+ }
618
+
619
+ let(:b_tasks) {
620
+ {
621
+ 'atask' => "# doing exactly nothing\n",
622
+ 'atask.json' => <<-JSONTEXT.unindent
623
+ {
624
+ "description": "test task b::atask",
625
+ "input_method": "stdin",
626
+ "parameters": {
627
+ "string_param": {
628
+ "description": "A string parameter",
629
+ "type": "String[1]"
630
+ },
631
+ "int_param": {
632
+ "description": "An integer parameter",
633
+ "type": "Integer"
634
+ }
635
+ }
636
+ }
637
+ JSONTEXT
638
+ }
639
+ }
640
+
641
+ let(:b_functions) {
642
+ {
643
+ 'afunc.pp' => 'function b::afunc() {}',
644
+ }
645
+ }
646
+
647
+ let(:b_lib) {
648
+ {
649
+ 'puppet' => b_lib_puppet,
650
+ 'stuff' => {
651
+ 'something.rb' => "module Stuff; SOMETHING = 'something'; end"
652
+ }
653
+ }
654
+ }
655
+
656
+ let(:b_lib_puppet) {
657
+ {
658
+ 'functions' => {
659
+ 'b' => {
660
+ 'arubyfunc.rb' => "Puppet::Functions.create_function(:'b::arubyfunc') { def arubyfunc; 'arubyfunc_value'; end }",
661
+ }
662
+ }
663
+ }
664
+ }
665
+
666
+ let(:c_types) {
667
+ {
668
+ 'atype.pp' => <<-PUPPET.unindent,
669
+ type C::Atype = Integer
670
+ PUPPET
671
+ }
672
+ }
673
+ context 'configured as temporary environment such that' do
674
+ it 'modules are available' do
675
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
676
+ ctx.with_script_compiler {|c| c.evaluate_string('a::afunc()') }
677
+ end
678
+ expect(result).to eq("a::afunc value")
679
+ end
680
+
681
+ it 'libs in a given "modulepath" are added to the Ruby $LOAD_PATH' do
682
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
683
+ ctx.with_script_compiler {|c| c.evaluate_string('a::arubyfunc()') }
684
+ end
685
+ expect(result).to eql('something')
686
+ end
687
+
688
+ it 'errors if a block is not given to in_tmp_environment' do
689
+ expect do
690
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts)
691
+ end.to raise_error(/A block must be given to 'in_tmp_environment/)
692
+ end
693
+
694
+ it 'errors if an env_name is given and is not a String[1]' do |ctx|
695
+ expect do
696
+ Puppet::Pal.in_tmp_environment('', modulepath: modulepath, facts: node_facts) { |ctx| }
697
+ end.to raise_error(/temporary environment name has wrong type/)
698
+
699
+ expect do
700
+ Puppet::Pal.in_tmp_environment(32, modulepath: modulepath, facts: node_facts) { |ctx| }
701
+ end.to raise_error(/temporary environment name has wrong type/)
702
+ end
703
+
704
+ { 'a hash' => {'a' => 'hm'},
705
+ 'an integer' => 32,
706
+ 'separated strings' => 'dir1;dir2',
707
+ 'empty string in array' => ['']
708
+ }.each_pair do |what, value|
709
+ it "errors if modulepath is #{what}" do
710
+ expect do
711
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: value, facts: node_facts) { |ctx| }
712
+ end.to raise_error(/modulepath has wrong type/)
713
+ end
714
+ end
715
+
716
+ context 'facts are supported such that' do
717
+ it 'they are obtained if they are not given' do
718
+ testing_env_dir # creates the structure
719
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath ) do |ctx|
720
+ ctx.with_script_compiler {|c| c.evaluate_string("$facts =~ Hash and $facts[puppetversion] == '#{Puppet.version}'") }
721
+ end
722
+ expect(result).to eq(true)
723
+ end
724
+
725
+ it 'can be given as a hash when creating the environment' do
726
+ testing_env_dir # creates the structure
727
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: { 'myfact' => 42 }) do |ctx|
728
+ ctx.with_script_compiler {|c| c.evaluate_string("$facts =~ Hash and $facts[myfact] == 42") }
729
+ end
730
+ expect(result).to eq(true)
731
+ end
732
+
733
+ it 'can be overridden with a hash when creating a script compiler' do
734
+ testing_env_dir # creates the structure
735
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: { 'myfact' => 42 }) do |ctx|
736
+ ctx.with_script_compiler(facts: { 'myfact' => 43 }) {|c| c.evaluate_string("$facts =~ Hash and $facts[myfact] == 43") }
737
+ end
738
+ expect(result).to eq(true)
739
+ end
740
+ end
741
+
742
+ context 'supports tasks such that' do
743
+ it '"task_signature" returns the signatures of a generic task' do
744
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
745
+ ctx.with_script_compiler do |c|
746
+ signature = c.task_signature('a::atask')
747
+ [ signature.runnable_with?('whatever' => 10),
748
+ signature.runnable_with?('anything_goes' => 'foo')
749
+ ]
750
+ end
751
+ end
752
+ expect(result).to eq([true, true])
753
+ end
754
+
755
+ it '"TaskSignature#runnable_with?" calls a given lambda if there is an error in a generic task' do
756
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
757
+ ctx.with_script_compiler do |c|
758
+ signature = c.task_signature('a::atask')
759
+ local_result = 'not yay'
760
+ signature.runnable_with?('string_param' => /not data/) {|error| local_result = error }
761
+ local_result
762
+ end
763
+ end
764
+ expect(result).to match(/Task a::atask:\s+entry 'string_param' expects a Data value, got Regexp/m)
765
+ end
766
+
767
+ it '"task_signature" returns the signatures of a task defined with metadata' do
768
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
769
+ ctx.with_script_compiler do |c|
770
+ signature = c.task_signature('b::atask')
771
+ [ signature.runnable_with?('string_param' => 'foo', 'int_param' => 10),
772
+ signature.runnable_with?('anything_goes' => 'foo'),
773
+ signature.task_hash['name'],
774
+ signature.task_hash['parameters']['string_param']['description'],
775
+ signature.task.description,
776
+ signature.task.parameters['int_param']['type'],
777
+ ]
778
+ end
779
+ end
780
+ expect(result).to eq([true, false, 'b::atask', 'A string parameter', 'test task b::atask', Puppet::Pops::Types::PIntegerType::DEFAULT])
781
+ end
782
+
783
+ it '"TaskSignature#runnable_with?" calls a given lambda if there is an error' do
784
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
785
+ ctx.with_script_compiler do |c|
786
+ signature = c.task_signature('b::atask')
787
+ local_result = 'not yay'
788
+ signature.runnable_with?('string_param' => 10) {|error| local_result = error }
789
+ local_result
790
+ end
791
+ end
792
+ expect(result).to match(/Task b::atask:\s+parameter 'string_param' expects a String value, got Integer/m)
793
+ end
794
+
795
+ it '"task_signature" returns nil if task is not found' do
796
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
797
+ ctx.with_script_compiler {|c| c.task_signature('no_where_to_be_found') }
798
+ end
799
+ expect(result).to be(nil)
800
+ end
801
+
802
+ it '"list_tasks" returns an array with all tasks that can be loaded' do
803
+ testing_env_dir # creates the structure
804
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
805
+ ctx.with_script_compiler {|c| c.list_tasks() }
806
+ end
807
+ expect(result.is_a?(Array)).to eq(true)
808
+ expect(result.all? {|s| s.is_a?(Puppet::Pops::Loader::TypedName) }).to eq(true)
809
+ expect(result.map {|tn| tn.name}).to contain_exactly('a::atask', 'b::atask')
810
+ end
811
+
812
+ it '"list_tasks" filters on name based on a given regexp' do
813
+ testing_env_dir # creates the structure
814
+ result = Puppet::Pal.in_tmp_environment('pal_env', modulepath: modulepath, facts: node_facts) do |ctx|
815
+ ctx.with_script_compiler {|c| c.list_tasks(/^a::/) }
816
+ end
817
+ expect(result.is_a?(Array)).to eq(true)
818
+ expect(result.all? {|s| s.is_a?(Puppet::Pops::Loader::TypedName) }).to eq(true)
819
+ expect(result.map {|tn| tn.name}).to eq(['a::atask'])
820
+ end
821
+ end
822
+
823
+ end
824
+
825
+ context 'configured as an existing given environment directory such that' do
826
+ it 'modules in it are available from its "modules" directory' do
827
+ result = Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir, facts: node_facts) do |ctx|
828
+ ctx.with_script_compiler {|c| c.evaluate_string('a::afunc()') }
829
+ end
830
+ expect(result).to eq("a::afunc value")
831
+ end
832
+
833
+ it 'libs in a given "modulepath" are added to the Ruby $LOAD_PATH' do
834
+ result = Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir, facts: node_facts) do |ctx|
835
+ ctx.with_script_compiler {|c| c.evaluate_string('a::arubyfunc()') }
836
+ end
837
+ expect(result).to eql('something')
838
+ end
839
+
840
+ it 'a given "modulepath" overrides the default' do
841
+ expect do
842
+ result = Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir, modulepath: [], facts: node_facts) do |ctx|
843
+ ctx.with_script_compiler {|c| c.evaluate_string('a::afunc()') }
844
+ end
845
+ end.to raise_error(/Unknown function: 'a::afunc'/)
846
+ end
847
+
848
+ it 'a "pre_modulepath" is prepended and a "post_modulepath" is appended to the effective modulepath' do
849
+ other_modules1 = File.join(environments_dir, 'other_env1/modules')
850
+ other_modules2 = File.join(environments_dir, 'other_env2/modules')
851
+ result = Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir,
852
+ pre_modulepath: [other_modules1],
853
+ post_modulepath: [other_modules2],
854
+ facts: node_facts
855
+ ) do |ctx|
856
+ the_modulepath = Puppet.lookup(:environments).get('pal_env').modulepath
857
+ the_modulepath[0] == other_modules1 && the_modulepath[-1] == other_modules2
858
+ end
859
+ expect(result).to be(true)
860
+ end
861
+
862
+ it 'can set variables in any scope' do
863
+ vars = {'a'=> 10, 'x::y' => 20}
864
+ result = Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir, facts: node_facts, variables: vars) do |ctx|
865
+ ctx.with_script_compiler { |c| c.evaluate_string("1+2+3+4+$a+$x::y") }
866
+ end
867
+ expect(result).to eq(40)
868
+ end
869
+
870
+ it 'errors in a meaningful way when a non existing env name is given' do
871
+ testing_env_dir # creates the structure
872
+ expect do
873
+ Puppet::Pal.in_environment('blah_env', env_dir: testing_env_dir.chop, facts: node_facts) { |ctx| }
874
+ end.to raise_error(/The environment directory '.*' does not exist/)
875
+ end
876
+
877
+ it 'errors if an env_name is given and is not a String[1]' do |ctx|
878
+ expect do
879
+ Puppet::Pal.in_environment('', env_dir: testing_env_dir, facts: node_facts) { |ctx| }
880
+ end.to raise_error(/env_name has wrong type/)
881
+
882
+ expect do
883
+ Puppet::Pal.in_environment(32, env_dir: testing_env_dir, facts: node_facts) { |ctx| }
884
+ end.to raise_error(/env_name has wrong type/)
885
+ end
886
+
887
+ { 'a hash' => {'a' => 'hm'},
888
+ 'an integer' => 32,
889
+ 'separated strings' => 'dir1;dir2',
890
+ 'empty string in array' => ['']
891
+ }.each_pair do |what, value|
892
+ it "errors if modulepath is #{what}" do
893
+ expect do
894
+ Puppet::Pal.in_environment('pal_env', env_dir: testing_env_dir, modulepath: {'a' => 'hm'}, facts: node_facts) { |ctx| }
895
+ Puppet::Pal.in_tmp_environment('pal_env', modulepath: value, facts: node_facts) { |ctx| }
896
+ end.to raise_error(/modulepath has wrong type/)
897
+ end
898
+ end
899
+
900
+ it 'errors if env_dir and envpath are both given' do
901
+ testing_env_dir # creates the structure
902
+ expect do
903
+ Puppet::Pal.in_environment('blah_env', env_dir: testing_env_dir, envpath: environments_dir, facts: node_facts) { |ctx| }
904
+ end.to raise_error(/Cannot use 'env_dir' and 'envpath' at the same time/)
905
+ end
906
+ end
907
+
908
+ context 'configured as existing given envpath such that' do
909
+ it 'modules in it are available from its "modules" directory' do
910
+ testing_env_dir # creates the structure
911
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, facts: node_facts) do |ctx|
912
+ ctx.with_script_compiler { |c| c.evaluate_string('a::afunc()') }
913
+ end
914
+ expect(result).to eq("a::afunc value")
915
+ end
916
+
917
+ it 'a given "modulepath" overrides the default' do
918
+ testing_env_dir # creates the structure
919
+ expect do
920
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, modulepath: [], facts: node_facts) do |ctx|
921
+ ctx.with_script_compiler { |c| c.evaluate_string('a::afunc()') }
922
+ end
923
+ end.to raise_error(/Unknown function: 'a::afunc'/)
924
+ end
925
+
926
+ it 'a "pre_modulepath" is prepended and a "post_modulepath" is appended to the effective modulepath' do
927
+ testing_env_dir # creates the structure
928
+ other_modules1 = File.join(environments_dir, 'other_env1/modules')
929
+ other_modules2 = File.join(environments_dir, 'other_env2/modules')
930
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir,
931
+ pre_modulepath: [other_modules1],
932
+ post_modulepath: [other_modules2],
933
+ facts: node_facts
934
+ ) do |ctx|
935
+ the_modulepath = Puppet.lookup(:environments).get('pal_env').modulepath
936
+ the_modulepath[0] == other_modules1 && the_modulepath[-1] == other_modules2
937
+ end
938
+ expect(result).to be(true)
939
+ end
940
+
941
+ it 'the envpath can have multiple entries - that are searched for the given env' do
942
+ testing_env_dir # creates the structure
943
+ several_dirs = "/tmp/nowhere/to/be/found:#{environments_dir}"
944
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, facts: node_facts) do |ctx|
945
+ ctx.with_script_compiler {|c| c.evaluate_string('a::afunc()') }
946
+ end
947
+ expect(result).to eq("a::afunc value")
948
+ end
949
+
950
+ it 'errors in a meaningful way when a non existing env name is given' do
951
+ testing_env_dir # creates the structure
952
+ expect do
953
+ Puppet::Pal.in_environment('blah_env', envpath: environments_dir, facts: node_facts) { |ctx| }
954
+ end.to raise_error(/No directory found for the environment 'blah_env' on the path '.*'/)
955
+ end
956
+
957
+ it 'errors if a block is not given to in_environment' do
958
+ expect do
959
+ Puppet::Pal.in_environment('blah_env', envpath: environments_dir, facts: node_facts)
960
+ end.to raise_error(/A block must be given to 'in_environment/)
961
+ end
962
+
963
+ it 'errors if envpath is something other than a string' do
964
+ testing_env_dir # creates the structure
965
+ expect do
966
+ Puppet::Pal.in_environment('blah_env', envpath: '', facts: node_facts) { |ctx| }
967
+ end.to raise_error(/envpath has wrong type/)
968
+
969
+ expect do
970
+ Puppet::Pal.in_environment('blah_env', envpath: [environments_dir], facts: node_facts) { |ctx| }
971
+ end.to raise_error(/envpath has wrong type/)
972
+ end
973
+
974
+ context 'with a script compiler' do
975
+ it 'uses configured manifest_file if configured_by_env is true and Puppet[:code] is unset' do
976
+ testing_env_dir # creates the structure
977
+ Puppet[:manifest] = file_containing('afunc.pp', "function myfunc(Integer $a) { $a * 2 } ")
978
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, facts: node_facts) do |ctx|
979
+ ctx.with_script_compiler(configured_by_env: true) {|c| c.call_function('myfunc', 4)}
980
+ end
981
+ expect(result).to eql(8)
982
+ end
983
+
984
+ it 'uses Puppet[:code] if configured_by_env is true and Puppet[:code] is set' do
985
+ testing_env_dir # creates the structure
986
+ Puppet[:manifest] = file_containing('amanifest.pp', "$a = 20")
987
+ Puppet[:code] = '$a = 40'
988
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, facts: node_facts) do |ctx|
989
+ ctx.with_script_compiler(configured_by_env: true) {|c| c.evaluate_string('$a')}
990
+ end
991
+ expect(result).to eql(40)
992
+ end
993
+
994
+ it 'makes the pal ScriptCompiler available as script_compiler_param to Function dispatcher' do
995
+ testing_env_dir # creates the structure
996
+ Puppet[:manifest] = file_containing('noop.pp', "undef")
997
+ result = Puppet::Pal.in_environment('pal_env', envpath: environments_dir, facts: node_facts) do |ctx|
998
+ ctx.with_script_compiler(configured_by_env: true) {|c| c.call_function('a::myscriptcompilerfunc', 'go')}
999
+ end
1000
+ expect(result).to eql('go')
1001
+ end
1002
+ end
1003
+ end
1004
+ end
1005
+ end