puppet 3.4.3 → 3.5.0.rc1

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 (811) hide show
  1. data/CONTRIBUTING.md +6 -6
  2. data/Gemfile +22 -16
  3. data/LICENSE +1 -1
  4. data/README.md +33 -11
  5. data/Rakefile +1 -1
  6. data/conf/auth.conf +4 -0
  7. data/ext/build_defaults.yaml +1 -1
  8. data/ext/debian/control +6 -6
  9. data/ext/ips/transforms +1 -1
  10. data/ext/nagios/naggen +1 -1
  11. data/ext/project_data.yaml +21 -1
  12. data/ext/puppet-test +3 -3
  13. data/ext/redhat/puppet.spec.erb +28 -2
  14. data/ext/suse/puppet.spec +1 -1
  15. data/ext/upload_facts.rb +1 -1
  16. data/ext/windows/service/daemon.rb +99 -20
  17. data/lib/hiera_puppet.rb +2 -2
  18. data/lib/puppet.rb +68 -5
  19. data/lib/puppet/agent.rb +5 -1
  20. data/lib/puppet/application.rb +20 -11
  21. data/lib/puppet/application/agent.rb +1 -1
  22. data/lib/puppet/application/apply.rb +61 -41
  23. data/lib/puppet/application/cert.rb +3 -3
  24. data/lib/puppet/application/device.rb +7 -8
  25. data/lib/puppet/application/doc.rb +1 -1
  26. data/lib/puppet/application/filebucket.rb +3 -3
  27. data/lib/puppet/application/kick.rb +2 -2
  28. data/lib/puppet/application/master.rb +1 -1
  29. data/lib/puppet/application/queue.rb +9 -9
  30. data/lib/puppet/application/resource.rb +2 -2
  31. data/lib/puppet/bindings.rb +6 -6
  32. data/lib/puppet/configurer.rb +17 -14
  33. data/lib/puppet/configurer/fact_handler.rb +1 -1
  34. data/lib/puppet/confine/any.rb +26 -0
  35. data/lib/puppet/confine/exists.rb +1 -1
  36. data/lib/puppet/confiner.rb +1 -0
  37. data/lib/puppet/context.rb +55 -0
  38. data/lib/puppet/context/trusted_information.rb +56 -0
  39. data/lib/puppet/defaults.rb +97 -26
  40. data/lib/puppet/environments.rb +187 -0
  41. data/lib/puppet/error.rb +2 -1
  42. data/lib/puppet/external/pson/common.rb +1 -1
  43. data/lib/puppet/external/pson/pure/generator.rb +1 -1
  44. data/lib/puppet/external/pson/pure/parser.rb +1 -1
  45. data/lib/puppet/face/config.rb +73 -15
  46. data/lib/puppet/face/file/store.rb +1 -1
  47. data/lib/puppet/face/help.rb +2 -1
  48. data/lib/puppet/face/help/action.erb +1 -0
  49. data/lib/puppet/face/help/face.erb +1 -0
  50. data/lib/puppet/face/help/global.erb +1 -0
  51. data/lib/puppet/face/help/man.erb +9 -8
  52. data/lib/puppet/face/module/list.rb +13 -7
  53. data/lib/puppet/face/node/clean.rb +2 -2
  54. data/lib/puppet/face/parser.rb +11 -5
  55. data/lib/puppet/face/status.rb +1 -1
  56. data/lib/puppet/feature/external_facts.rb +2 -2
  57. data/lib/puppet/feature/libuser.rb +1 -1
  58. data/lib/puppet/feature/msgpack.rb +2 -0
  59. data/lib/puppet/feature/rails.rb +2 -2
  60. data/lib/puppet/file_bucket/dipper.rb +9 -9
  61. data/lib/puppet/file_bucket/file.rb +9 -5
  62. data/lib/puppet/file_serving/base.rb +1 -1
  63. data/lib/puppet/file_serving/configuration.rb +1 -1
  64. data/lib/puppet/file_serving/configuration/parser.rb +3 -3
  65. data/lib/puppet/file_serving/content.rb +2 -2
  66. data/lib/puppet/file_serving/fileset.rb +4 -4
  67. data/lib/puppet/file_serving/metadata.rb +69 -15
  68. data/lib/puppet/file_serving/mount/file.rb +1 -1
  69. data/lib/puppet/file_system.rb +361 -1
  70. data/lib/puppet/file_system/file18.rb +3 -3
  71. data/lib/puppet/file_system/file19.rb +3 -3
  72. data/lib/puppet/file_system/file19windows.rb +18 -23
  73. data/lib/puppet/file_system/file_impl.rb +145 -0
  74. data/lib/puppet/file_system/memory_file.rb +23 -9
  75. data/lib/puppet/file_system/memory_impl.rb +64 -0
  76. data/lib/puppet/forge.rb +4 -3
  77. data/lib/puppet/forge/repository.rb +0 -1
  78. data/lib/puppet/graph/relationship_graph.rb +7 -7
  79. data/lib/puppet/indirector.rb +1 -0
  80. data/lib/puppet/indirector/catalog/compiler.rb +3 -30
  81. data/lib/puppet/indirector/catalog/msgpack.rb +6 -0
  82. data/lib/puppet/indirector/catalog/static_compiler.rb +3 -7
  83. data/lib/puppet/indirector/data_binding/hiera.rb +1 -1
  84. data/lib/puppet/indirector/direct_file_server.rb +2 -2
  85. data/lib/puppet/indirector/exec.rb +1 -1
  86. data/lib/puppet/indirector/face.rb +3 -2
  87. data/lib/puppet/indirector/facts/facter.rb +1 -1
  88. data/lib/puppet/indirector/file_bucket_file/file.rb +25 -15
  89. data/lib/puppet/indirector/file_metadata/file.rb +1 -1
  90. data/lib/puppet/indirector/file_server.rb +1 -1
  91. data/lib/puppet/indirector/indirection.rb +1 -1
  92. data/lib/puppet/indirector/json.rb +4 -4
  93. data/lib/puppet/indirector/key/file.rb +8 -5
  94. data/lib/puppet/indirector/ldap.rb +1 -1
  95. data/lib/puppet/indirector/memory.rb +4 -0
  96. data/lib/puppet/indirector/msgpack.rb +82 -0
  97. data/lib/puppet/indirector/node/exec.rb +1 -1
  98. data/lib/puppet/indirector/node/ldap.rb +3 -3
  99. data/lib/puppet/indirector/node/msgpack.rb +7 -0
  100. data/lib/puppet/indirector/node/yaml.rb +15 -0
  101. data/lib/puppet/indirector/queue.rb +3 -2
  102. data/lib/puppet/indirector/report/msgpack.rb +11 -0
  103. data/lib/puppet/indirector/request.rb +17 -20
  104. data/lib/puppet/indirector/resource/rest.rb +1 -1
  105. data/lib/puppet/indirector/resource_type/parser.rb +3 -13
  106. data/lib/puppet/indirector/rest.rb +6 -7
  107. data/lib/puppet/indirector/ssl_file.rb +7 -7
  108. data/lib/puppet/indirector/yaml.rb +9 -13
  109. data/lib/puppet/metatype/manager.rb +12 -7
  110. data/lib/puppet/module.rb +14 -9
  111. data/lib/puppet/module_tool.rb +21 -26
  112. data/lib/puppet/module_tool/applications/application.rb +1 -1
  113. data/lib/puppet/module_tool/applications/generator.rb +2 -1
  114. data/lib/puppet/module_tool/applications/installer.rb +9 -4
  115. data/lib/puppet/module_tool/applications/uninstaller.rb +10 -7
  116. data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  117. data/lib/puppet/module_tool/applications/upgrader.rb +11 -8
  118. data/lib/puppet/module_tool/checksums.rb +1 -1
  119. data/lib/puppet/module_tool/contents_description.rb +2 -0
  120. data/lib/puppet/module_tool/dependency.rb +4 -5
  121. data/lib/puppet/module_tool/errors.rb +2 -0
  122. data/lib/puppet/module_tool/install_directory.rb +3 -0
  123. data/lib/puppet/module_tool/metadata.rb +3 -5
  124. data/lib/puppet/module_tool/modulefile.rb +3 -0
  125. data/lib/puppet/module_tool/shared_behaviors.rb +6 -1
  126. data/lib/puppet/module_tool/skeleton.rb +3 -0
  127. data/lib/puppet/module_tool/tar.rb +3 -0
  128. data/lib/puppet/network/auth_config_parser.rb +1 -1
  129. data/lib/puppet/network/authconfig.rb +5 -2
  130. data/lib/puppet/network/authentication.rb +7 -2
  131. data/lib/puppet/network/authorization.rb +2 -2
  132. data/lib/puppet/network/format_support.rb +4 -0
  133. data/lib/puppet/network/formats.rb +9 -14
  134. data/lib/puppet/network/http.rb +11 -0
  135. data/lib/puppet/network/http/api.rb +0 -2
  136. data/lib/puppet/network/http/api/v1.rb +146 -11
  137. data/lib/puppet/network/http/api/v2.rb +32 -0
  138. data/lib/puppet/network/http/api/v2/authorization.rb +13 -0
  139. data/lib/puppet/network/http/api/v2/environments.rb +21 -0
  140. data/lib/puppet/network/http/connection.rb +94 -37
  141. data/lib/puppet/network/http/error.rb +69 -0
  142. data/lib/puppet/network/http/handler.rb +28 -196
  143. data/lib/puppet/network/http/issues.rb +9 -0
  144. data/lib/puppet/network/http/memory_response.rb +13 -0
  145. data/lib/puppet/network/http/rack/rest.rb +10 -18
  146. data/lib/puppet/network/http/request.rb +56 -0
  147. data/lib/puppet/network/http/response.rb +11 -0
  148. data/lib/puppet/network/http/route.rb +91 -0
  149. data/lib/puppet/network/http/webrick.rb +1 -1
  150. data/lib/puppet/network/http/webrick/rest.rb +7 -12
  151. data/lib/puppet/network/http_pool.rb +3 -3
  152. data/lib/puppet/network/rights.rb +4 -4
  153. data/lib/puppet/node.rb +23 -14
  154. data/lib/puppet/node/environment.rb +149 -125
  155. data/lib/puppet/node/facts.rb +6 -5
  156. data/lib/puppet/parameter.rb +1 -1
  157. data/lib/puppet/parser/ast.rb +1 -1
  158. data/lib/puppet/parser/ast/block_expression.rb +1 -6
  159. data/lib/puppet/parser/ast/collexpr.rb +54 -2
  160. data/lib/puppet/parser/ast/lambda.rb +9 -0
  161. data/lib/puppet/parser/ast/leaf.rb +15 -0
  162. data/lib/puppet/parser/ast/pops_bridge.rb +168 -0
  163. data/lib/puppet/parser/code_merger.rb +13 -0
  164. data/lib/puppet/parser/collector.rb +1 -1
  165. data/lib/puppet/parser/compiler.rb +28 -30
  166. data/lib/puppet/parser/e4_parser_adapter.rb +81 -0
  167. data/lib/puppet/parser/e_parser_adapter.rb +0 -1
  168. data/lib/puppet/parser/files.rb +12 -7
  169. data/lib/puppet/parser/functions.rb +36 -29
  170. data/lib/puppet/parser/functions/collect.rb +1 -1
  171. data/lib/puppet/parser/functions/defined.rb +40 -16
  172. data/lib/puppet/parser/functions/each.rb +55 -41
  173. data/lib/puppet/parser/functions/epp.rb +41 -0
  174. data/lib/puppet/parser/functions/extlookup.rb +2 -2
  175. data/lib/puppet/parser/functions/file.rb +1 -1
  176. data/lib/puppet/parser/functions/filter.rb +68 -16
  177. data/lib/puppet/parser/functions/generate.rb +1 -1
  178. data/lib/puppet/parser/functions/include.rb +3 -2
  179. data/lib/puppet/parser/functions/inline_epp.rb +79 -0
  180. data/lib/puppet/parser/functions/inline_template.rb +1 -1
  181. data/lib/puppet/parser/functions/lookup.rb +127 -27
  182. data/lib/puppet/parser/functions/map.rb +64 -12
  183. data/lib/puppet/parser/functions/reduce.rb +40 -16
  184. data/lib/puppet/parser/functions/select.rb +1 -1
  185. data/lib/puppet/parser/functions/slice.rb +42 -23
  186. data/lib/puppet/parser/grammar.ra +3 -0
  187. data/lib/puppet/parser/lexer.rb +10 -9
  188. data/lib/puppet/parser/parser.rb +15 -12
  189. data/lib/puppet/parser/parser_factory.rb +26 -1
  190. data/lib/puppet/parser/parser_support.rb +13 -4
  191. data/lib/puppet/parser/resource.rb +1 -1
  192. data/lib/puppet/parser/scope.rb +246 -97
  193. data/lib/puppet/parser/templatewrapper.rb +1 -1
  194. data/lib/puppet/parser/type_loader.rb +13 -2
  195. data/lib/puppet/pops.rb +15 -1
  196. data/lib/puppet/pops/adapters.rb +64 -32
  197. data/lib/puppet/pops/binder/binder.rb +122 -150
  198. data/lib/puppet/pops/binder/binder_issues.rb +1 -21
  199. data/lib/puppet/pops/binder/bindings_checker.rb +0 -20
  200. data/lib/puppet/pops/binder/bindings_composer.rb +4 -70
  201. data/lib/puppet/pops/binder/bindings_factory.rb +16 -58
  202. data/lib/puppet/pops/binder/bindings_label_provider.rb +0 -3
  203. data/lib/puppet/pops/binder/bindings_loader.rb +13 -4
  204. data/lib/puppet/pops/binder/bindings_model.rb +17 -31
  205. data/lib/puppet/pops/binder/bindings_model_dumper.rb +2 -20
  206. data/lib/puppet/pops/binder/config/binder_config.rb +8 -40
  207. data/lib/puppet/pops/binder/config/binder_config_checker.rb +2 -43
  208. data/lib/puppet/pops/binder/config/issues.rb +1 -21
  209. data/lib/puppet/pops/binder/injector.rb +86 -7
  210. data/lib/puppet/pops/binder/injector_entry.rb +6 -2
  211. data/lib/puppet/pops/binder/key_factory.rb +7 -1
  212. data/lib/puppet/pops/binder/lookup.rb +191 -0
  213. data/lib/puppet/pops/binder/producers.rb +5 -5
  214. data/lib/puppet/pops/binder/scheme_handler/symbolic_scheme.rb +2 -3
  215. data/lib/puppet/pops/binder/system_bindings.rb +4 -16
  216. data/lib/puppet/pops/containment.rb +72 -5
  217. data/lib/puppet/pops/evaluator/access_operator.rb +548 -0
  218. data/lib/puppet/pops/evaluator/closure.rb +57 -0
  219. data/lib/puppet/pops/evaluator/compare_operator.rb +168 -0
  220. data/lib/puppet/pops/evaluator/epp_evaluator.rb +87 -0
  221. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1069 -0
  222. data/lib/puppet/pops/evaluator/external_syntax_support.rb +49 -0
  223. data/lib/puppet/pops/evaluator/relationship_operator.rb +156 -0
  224. data/lib/puppet/pops/evaluator/runtime3_support.rb +489 -0
  225. data/lib/puppet/pops/issue_reporter.rb +8 -4
  226. data/lib/puppet/pops/issues.rb +199 -4
  227. data/lib/puppet/pops/label_provider.rb +5 -0
  228. data/lib/puppet/pops/model/ast_transformer.rb +55 -31
  229. data/lib/puppet/pops/model/ast_tree_dumper.rb +9 -1
  230. data/lib/puppet/pops/model/factory.rb +265 -111
  231. data/lib/puppet/pops/model/model.rb +179 -140
  232. data/lib/puppet/pops/model/model_label_provider.rb +38 -9
  233. data/lib/puppet/pops/model/model_tree_dumper.rb +38 -13
  234. data/lib/puppet/pops/parser/code_merger.rb +17 -0
  235. data/lib/puppet/pops/parser/egrammar.ra +110 -61
  236. data/lib/puppet/pops/parser/eparser.rb +1415 -1092
  237. data/lib/puppet/pops/parser/epp_parser.rb +51 -0
  238. data/lib/puppet/pops/parser/epp_support.rb +247 -0
  239. data/lib/puppet/pops/parser/evaluating_parser.rb +53 -15
  240. data/lib/puppet/pops/parser/heredoc_support.rb +139 -0
  241. data/lib/puppet/pops/parser/interpolation_support.rb +227 -0
  242. data/lib/puppet/pops/parser/lexer.rb +83 -192
  243. data/lib/puppet/pops/parser/lexer2.rb +684 -0
  244. data/lib/puppet/pops/parser/lexer_support.rb +107 -0
  245. data/lib/puppet/pops/parser/locatable.rb +23 -0
  246. data/lib/puppet/pops/parser/locator.rb +291 -0
  247. data/lib/puppet/pops/parser/makefile +1 -8
  248. data/lib/puppet/pops/parser/parser_support.rb +76 -48
  249. data/lib/puppet/pops/parser/slurp_support.rb +95 -0
  250. data/lib/puppet/pops/patterns.rb +13 -4
  251. data/lib/puppet/pops/types/class_loader.rb +2 -2
  252. data/lib/puppet/pops/types/enumeration.rb +34 -0
  253. data/lib/puppet/pops/types/type_calculator.rb +983 -58
  254. data/lib/puppet/pops/types/type_factory.rb +203 -15
  255. data/lib/puppet/pops/types/type_parser.rb +355 -12
  256. data/lib/puppet/pops/types/types.rb +314 -24
  257. data/lib/puppet/pops/utils.rb +23 -7
  258. data/lib/puppet/pops/validation.rb +14 -8
  259. data/lib/puppet/pops/validation/checker3_1.rb +17 -12
  260. data/lib/puppet/pops/validation/checker4_0.rb +514 -0
  261. data/lib/puppet/pops/validation/validator_factory_4_0.rb +31 -0
  262. data/lib/puppet/pops/visitor.rb +146 -4
  263. data/lib/puppet/property.rb +1 -1
  264. data/lib/puppet/property/ensure.rb +1 -1
  265. data/lib/puppet/provider.rb +47 -26
  266. data/lib/puppet/provider/aixobject.rb +3 -3
  267. data/lib/puppet/provider/augeas/augeas.rb +11 -11
  268. data/lib/puppet/provider/cron/crontab.rb +10 -1
  269. data/lib/puppet/provider/exec.rb +1 -1
  270. data/lib/puppet/provider/exec/posix.rb +1 -1
  271. data/lib/puppet/provider/exec/windows.rb +1 -1
  272. data/lib/puppet/provider/file/posix.rb +2 -2
  273. data/lib/puppet/provider/file/windows.rb +15 -9
  274. data/lib/puppet/provider/group/aix.rb +2 -2
  275. data/lib/puppet/provider/macauthorization/macauthorization.rb +3 -3
  276. data/lib/puppet/provider/mount.rb +7 -0
  277. data/lib/puppet/provider/mount/parsed.rb +0 -1
  278. data/lib/puppet/provider/naginator.rb +1 -1
  279. data/lib/puppet/provider/nameservice.rb +3 -3
  280. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
  281. data/lib/puppet/provider/package/aix.rb +1 -1
  282. data/lib/puppet/provider/package/appdmg.rb +1 -4
  283. data/lib/puppet/provider/package/apple.rb +1 -1
  284. data/lib/puppet/provider/package/apt.rb +1 -1
  285. data/lib/puppet/provider/package/blastwave.rb +1 -1
  286. data/lib/puppet/provider/package/fink.rb +1 -1
  287. data/lib/puppet/provider/package/gem.rb +3 -3
  288. data/lib/puppet/provider/package/openbsd.rb +6 -4
  289. data/lib/puppet/provider/package/pacman.rb +58 -5
  290. data/lib/puppet/provider/package/pip.rb +2 -2
  291. data/lib/puppet/provider/package/pkgdmg.rb +25 -10
  292. data/lib/puppet/provider/package/pkgin.rb +48 -23
  293. data/lib/puppet/provider/package/pkgutil.rb +1 -1
  294. data/lib/puppet/provider/package/ports.rb +1 -1
  295. data/lib/puppet/provider/package/portupgrade.rb +7 -7
  296. data/lib/puppet/provider/package/rpm.rb +16 -8
  297. data/lib/puppet/provider/package/windows.rb +1 -1
  298. data/lib/puppet/provider/package/windows/package.rb +1 -1
  299. data/lib/puppet/provider/parsedfile.rb +1 -1
  300. data/lib/puppet/provider/selboolean/getsetsebool.rb +1 -1
  301. data/lib/puppet/provider/selmodule/semodule.rb +5 -5
  302. data/lib/puppet/provider/service/base.rb +1 -1
  303. data/lib/puppet/provider/service/bsd.rb +3 -3
  304. data/lib/puppet/provider/service/daemontools.rb +20 -20
  305. data/lib/puppet/provider/service/debian.rb +1 -1
  306. data/lib/puppet/provider/service/freebsd.rb +3 -3
  307. data/lib/puppet/provider/service/gentoo.rb +2 -2
  308. data/lib/puppet/provider/service/init.rb +5 -5
  309. data/lib/puppet/provider/service/launchd.rb +4 -4
  310. data/lib/puppet/provider/service/redhat.rb +2 -2
  311. data/lib/puppet/provider/service/runit.rb +4 -4
  312. data/lib/puppet/provider/service/service.rb +3 -4
  313. data/lib/puppet/provider/service/smf.rb +1 -1
  314. data/lib/puppet/provider/service/src.rb +3 -3
  315. data/lib/puppet/provider/service/systemd.rb +4 -4
  316. data/lib/puppet/provider/service/upstart.rb +22 -7
  317. data/lib/puppet/provider/service/windows.rb +7 -7
  318. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +3 -3
  319. data/lib/puppet/provider/user/aix.rb +5 -5
  320. data/lib/puppet/provider/user/directoryservice.rb +8 -5
  321. data/lib/puppet/provider/user/ldap.rb +1 -1
  322. data/lib/puppet/provider/user/pw.rb +1 -1
  323. data/lib/puppet/provider/user/user_role_add.rb +2 -2
  324. data/lib/puppet/provider/user/useradd.rb +19 -5
  325. data/lib/puppet/provider/yumrepo/inifile.rb +187 -0
  326. data/lib/puppet/provider/zone/solaris.rb +4 -4
  327. data/lib/puppet/rails.rb +16 -11
  328. data/lib/puppet/rails/benchmark.rb +1 -1
  329. data/lib/puppet/rails/resource.rb +5 -1
  330. data/lib/puppet/reference/configuration.rb +1 -1
  331. data/lib/puppet/reference/report.rb +1 -1
  332. data/lib/puppet/relationship.rb +10 -5
  333. data/lib/puppet/reports/http.rb +8 -2
  334. data/lib/puppet/reports/rrdgraph.rb +1 -1
  335. data/lib/puppet/reports/store.rb +3 -3
  336. data/lib/puppet/reports/tagmail.rb +4 -4
  337. data/lib/puppet/resource.rb +37 -44
  338. data/lib/puppet/resource/catalog.rb +18 -20
  339. data/lib/puppet/resource/status.rb +7 -6
  340. data/lib/puppet/resource/type.rb +6 -5
  341. data/lib/puppet/resource/type_collection.rb +2 -2
  342. data/lib/puppet/run.rb +9 -8
  343. data/lib/puppet/settings.rb +395 -244
  344. data/lib/puppet/settings/base_setting.rb +10 -4
  345. data/lib/puppet/settings/config_file.rb +81 -44
  346. data/lib/puppet/settings/directory_setting.rb +1 -2
  347. data/lib/puppet/settings/file_setting.rb +12 -5
  348. data/lib/puppet/settings/ini_file.rb +171 -0
  349. data/lib/puppet/ssl/base.rb +4 -0
  350. data/lib/puppet/ssl/certificate_authority.rb +16 -11
  351. data/lib/puppet/ssl/certificate_authority/interface.rb +3 -2
  352. data/lib/puppet/ssl/certificate_factory.rb +50 -5
  353. data/lib/puppet/ssl/certificate_request.rb +2 -2
  354. data/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
  355. data/lib/puppet/ssl/certificate_revocation_list.rb +3 -1
  356. data/lib/puppet/ssl/host.rb +9 -8
  357. data/lib/puppet/ssl/inventory.rb +1 -1
  358. data/lib/puppet/ssl/key.rb +1 -1
  359. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  360. data/lib/puppet/status.rb +8 -7
  361. data/lib/puppet/test/test_helper.rb +35 -4
  362. data/lib/puppet/transaction/event.rb +6 -5
  363. data/lib/puppet/transaction/report.rb +10 -10
  364. data/lib/puppet/type.rb +1 -3
  365. data/lib/puppet/type/augeas.rb +2 -1
  366. data/lib/puppet/type/cron.rb +41 -11
  367. data/lib/puppet/type/exec.rb +5 -5
  368. data/lib/puppet/type/file.rb +42 -4
  369. data/lib/puppet/type/file/content.rb +5 -6
  370. data/lib/puppet/type/file/ensure.rb +3 -3
  371. data/lib/puppet/type/file/source.rb +12 -6
  372. data/lib/puppet/type/file/target.rb +5 -5
  373. data/lib/puppet/type/k5login.rb +4 -4
  374. data/lib/puppet/type/mount.rb +1 -1
  375. data/lib/puppet/type/package.rb +79 -3
  376. data/lib/puppet/type/resources.rb +34 -5
  377. data/lib/puppet/type/selboolean.rb +1 -1
  378. data/lib/puppet/type/selmodule.rb +1 -1
  379. data/lib/puppet/type/ssh_authorized_key.rb +2 -1
  380. data/lib/puppet/type/sshkey.rb +2 -1
  381. data/lib/puppet/type/tidy.rb +1 -1
  382. data/lib/puppet/type/user.rb +4 -1
  383. data/lib/puppet/type/yumrepo.rb +219 -344
  384. data/lib/puppet/type/zone.rb +15 -5
  385. data/lib/puppet/util.rb +14 -13
  386. data/lib/puppet/util/adsi.rb +19 -3
  387. data/lib/puppet/util/autoload.rb +27 -24
  388. data/lib/puppet/util/backups.rb +6 -6
  389. data/lib/puppet/util/checksums.rb +2 -2
  390. data/lib/puppet/util/classgen.rb +1 -1
  391. data/lib/puppet/util/colors.rb +4 -12
  392. data/lib/puppet/util/command_line.rb +2 -2
  393. data/lib/puppet/util/command_line/trollop.rb +3 -3
  394. data/lib/puppet/util/docs.rb +2 -2
  395. data/lib/puppet/util/errors.rb +8 -1
  396. data/lib/puppet/util/execution.rb +12 -5
  397. data/lib/puppet/util/filetype.rb +5 -5
  398. data/lib/puppet/util/inifile.rb +19 -4
  399. data/lib/puppet/util/instrumentation/data.rb +5 -0
  400. data/lib/puppet/util/instrumentation/indirection_probe.rb +6 -1
  401. data/lib/puppet/util/instrumentation/listener.rb +6 -1
  402. data/lib/puppet/util/json_lockfile.rb +4 -1
  403. data/lib/puppet/util/ldap/connection.rb +1 -1
  404. data/lib/puppet/util/lockfile.rb +10 -6
  405. data/lib/puppet/util/log.rb +6 -1
  406. data/lib/puppet/util/log/destinations.rb +2 -2
  407. data/lib/puppet/util/metric.rb +9 -4
  408. data/lib/puppet/util/nagios_maker.rb +26 -1
  409. data/lib/puppet/util/network_device.rb +1 -1
  410. data/lib/puppet/util/network_device/config.rb +1 -1
  411. data/lib/puppet/util/network_device/transport/ssh.rb +3 -3
  412. data/lib/puppet/util/plugins.rb +1 -1
  413. data/lib/puppet/util/profiler.rb +13 -1
  414. data/lib/puppet/util/pson.rb +1 -1
  415. data/lib/puppet/util/queue/stomp.rb +2 -2
  416. data/lib/puppet/util/rdoc.rb +1 -1
  417. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
  418. data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +19 -19
  419. data/lib/puppet/util/reference.rb +1 -1
  420. data/lib/puppet/util/resource_template.rb +1 -1
  421. data/lib/puppet/util/retryaction.rb +1 -1
  422. data/lib/puppet/util/selinux.rb +2 -2
  423. data/lib/puppet/util/storage.rb +3 -3
  424. data/lib/puppet/util/symbolic_file_mode.rb +1 -1
  425. data/lib/puppet/util/tag_set.rb +15 -3
  426. data/lib/puppet/util/tagging.rb +12 -17
  427. data/lib/puppet/util/watched_file.rb +1 -1
  428. data/lib/puppet/util/watcher.rb +1 -1
  429. data/lib/puppet/util/windows/error.rb +2 -2
  430. data/lib/puppet/util/windows/file.rb +20 -4
  431. data/lib/puppet/util/windows/registry.rb +2 -2
  432. data/lib/puppet/vendor/safe_yaml/CHANGES.md +1 -1
  433. data/lib/puppet/version.rb +1 -1
  434. data/lib/puppetx.rb +1 -21
  435. data/lib/puppetx/puppet/syntax_checker.rb +1 -1
  436. data/lib/puppetx/puppetlabs/syntax_checkers/json.rb +9 -11
  437. data/spec/fixtures/integration/node/environment/sitedir/00_a.pp +2 -0
  438. data/spec/fixtures/integration/node/environment/sitedir/01_b.pp +6 -0
  439. data/spec/fixtures/{unit/pops/binder/hiera2/yaml_backend/empty/common.yaml → integration/node/environment/sitedir/03_empty.pp} +0 -0
  440. data/spec/fixtures/integration/node/environment/sitedir/04_include.pp +2 -0
  441. data/spec/fixtures/integration/provider/cron/crontab/purged +8 -0
  442. data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +1 -1
  443. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/binder_config.yaml +3 -12
  444. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/lib/puppet/bindings/confdirtest.rb +10 -0
  445. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome2/lib/puppet/bindings/awesome2/default.rb +20 -0
  446. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/{awesome/lib/puppetx/awesome → awesome2/lib/puppetx/awesome2}/echo_scheme_handler.rb +2 -2
  447. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/lib/puppet/bindings/bad/default.rb +5 -0
  448. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/lib/puppet/bindings/good/default.rb +6 -0
  449. data/spec/fixtures/unit/pops/binder/config/binder_config/ok/binder_config.yaml +2 -2
  450. data/spec/fixtures/unit/provider/service/systemd/{list_units → list_units_services} +0 -1
  451. data/spec/integration/agent/logging_spec.rb +1 -1
  452. data/spec/integration/application/apply_spec.rb +78 -3
  453. data/spec/integration/application/doc_spec.rb +3 -2
  454. data/spec/integration/configurer_spec.rb +5 -3
  455. data/spec/integration/directory_environments_spec.rb +50 -0
  456. data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
  457. data/spec/integration/indirector/file_content/file_server_spec.rb +4 -5
  458. data/spec/integration/network/authconfig_spec.rb +4 -4
  459. data/spec/integration/network/formats_spec.rb +1 -1
  460. data/spec/integration/node/environment_spec.rb +67 -15
  461. data/spec/integration/node/facts_spec.rb +1 -1
  462. data/spec/integration/node_spec.rb +1 -1
  463. data/spec/integration/parser/catalog_spec.rb +100 -60
  464. data/spec/integration/parser/compiler_spec.rb +102 -13
  465. data/spec/integration/parser/future_compiler_spec.rb +416 -0
  466. data/spec/integration/parser/parser_spec.rb +44 -105
  467. data/spec/integration/parser/scope_spec.rb +614 -528
  468. data/spec/integration/provider/cron/crontab_spec.rb +21 -0
  469. data/spec/integration/provider/mount_spec.rb +15 -2
  470. data/spec/integration/resource/catalog_spec.rb +1 -1
  471. data/spec/integration/resource/type_collection_spec.rb +3 -4
  472. data/spec/integration/ssl/autosign_spec.rb +1 -1
  473. data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -1
  474. data/spec/integration/ssl/host_spec.rb +1 -1
  475. data/spec/integration/transaction_spec.rb +13 -13
  476. data/spec/integration/type/exec_spec.rb +2 -2
  477. data/spec/integration/type/file_spec.rb +114 -41
  478. data/spec/integration/type/nagios_spec.rb +80 -0
  479. data/spec/integration/type/tidy_spec.rb +2 -2
  480. data/spec/integration/util/execution_spec.rb +17 -0
  481. data/spec/integration/util/rdoc/parser_spec.rb +1 -1
  482. data/spec/integration/util/settings_spec.rb +1 -1
  483. data/spec/integration/util/windows/security_spec.rb +27 -2
  484. data/spec/lib/matchers/include.rb +27 -0
  485. data/spec/lib/matchers/include_spec.rb +32 -0
  486. data/spec/lib/matchers/json.rb +135 -79
  487. data/spec/lib/matchers/match_tokens2.rb +74 -0
  488. data/spec/lib/matchers/resource.rb +35 -0
  489. data/spec/lib/puppet/indirector/indirector_testing/memory.rb +7 -0
  490. data/spec/lib/puppet/indirector/indirector_testing/msgpack.rb +6 -0
  491. data/spec/lib/puppet/indirector_testing.rb +12 -2
  492. data/spec/lib/puppet_spec/files.rb +1 -0
  493. data/spec/lib/puppet_spec/matchers.rb +5 -0
  494. data/spec/lib/puppet_spec/modules.rb +1 -1
  495. data/spec/lib/puppet_spec/scope.rb +14 -0
  496. data/spec/shared_behaviours/file_server_terminus.rb +2 -2
  497. data/spec/spec_helper.rb +47 -17
  498. data/spec/unit/agent_spec.rb +8 -1
  499. data/spec/unit/application/agent_spec.rb +5 -4
  500. data/spec/unit/application/apply_spec.rb +34 -15
  501. data/spec/unit/application/device_spec.rb +27 -32
  502. data/spec/unit/application/doc_spec.rb +4 -4
  503. data/spec/unit/application/filebucket_spec.rb +1 -1
  504. data/spec/unit/application/master_spec.rb +2 -2
  505. data/spec/unit/application_spec.rb +1 -1
  506. data/spec/unit/configurer/downloader_spec.rb +1 -1
  507. data/spec/unit/configurer/fact_handler_spec.rb +5 -16
  508. data/spec/unit/configurer_spec.rb +2 -2
  509. data/spec/unit/confine/exists_spec.rb +5 -5
  510. data/spec/unit/context/trusted_information_spec.rb +124 -0
  511. data/spec/unit/context_spec.rb +74 -0
  512. data/spec/unit/environments_spec.rb +126 -0
  513. data/spec/unit/face/config_spec.rb +31 -16
  514. data/spec/unit/face/module/build_spec.rb +1 -0
  515. data/spec/unit/face/module/install_spec.rb +21 -104
  516. data/spec/unit/face/module/list_spec.rb +52 -36
  517. data/spec/unit/face/module/uninstall_spec.rb +18 -25
  518. data/spec/unit/face/parser_spec.rb +39 -23
  519. data/spec/unit/file_bucket/dipper_spec.rb +2 -2
  520. data/spec/unit/file_serving/base_spec.rb +9 -13
  521. data/spec/unit/file_serving/configuration/parser_spec.rb +8 -2
  522. data/spec/unit/file_serving/configuration_spec.rb +7 -7
  523. data/spec/unit/file_serving/content_spec.rb +7 -12
  524. data/spec/unit/file_serving/fileset_spec.rb +49 -53
  525. data/spec/unit/file_serving/metadata_spec.rb +83 -32
  526. data/spec/unit/file_serving/mount/file_spec.rb +10 -10
  527. data/spec/unit/file_system/tempfile_spec.rb +3 -3
  528. data/spec/unit/file_system_spec.rb +508 -0
  529. data/spec/unit/forge/errors_spec.rb +1 -1
  530. data/spec/unit/forge/repository_spec.rb +1 -3
  531. data/spec/unit/hiera/scope_spec.rb +6 -2
  532. data/spec/unit/hiera_puppet_spec.rb +13 -6
  533. data/spec/unit/indirector/catalog/msgpack_spec.rb +12 -0
  534. data/spec/unit/indirector/catalog/static_compiler_spec.rb +42 -11
  535. data/spec/unit/indirector/direct_file_server_spec.rb +6 -6
  536. data/spec/unit/indirector/facts/facter_spec.rb +5 -5
  537. data/spec/unit/indirector/file_bucket_file/file_spec.rb +4 -4
  538. data/spec/unit/indirector/file_metadata/file_spec.rb +2 -2
  539. data/spec/unit/indirector/file_server_spec.rb +4 -4
  540. data/spec/unit/indirector/json_spec.rb +6 -6
  541. data/spec/unit/indirector/key/file_spec.rb +8 -8
  542. data/spec/unit/indirector/msgpack_spec.rb +191 -0
  543. data/spec/unit/indirector/node/active_record_spec.rb +1 -1
  544. data/spec/unit/indirector/node/ldap_spec.rb +16 -7
  545. data/spec/unit/indirector/node/msgpack_spec.rb +24 -0
  546. data/spec/unit/indirector/node/plain_spec.rb +1 -1
  547. data/spec/unit/indirector/queue_spec.rb +1 -1
  548. data/spec/unit/indirector/report/msgpack_spec.rb +28 -0
  549. data/spec/unit/indirector/request_spec.rb +16 -8
  550. data/spec/unit/indirector/rest_spec.rb +0 -4
  551. data/spec/unit/indirector/ssl_file_spec.rb +12 -11
  552. data/spec/unit/indirector/yaml_spec.rb +4 -4
  553. data/spec/unit/man_spec.rb +32 -0
  554. data/spec/unit/module_spec.rb +60 -46
  555. data/spec/unit/module_tool/applications/checksummer_spec.rb +1 -1
  556. data/spec/unit/module_tool/applications/installer_spec.rb +53 -16
  557. data/spec/unit/module_tool/applications/uninstaller_spec.rb +26 -25
  558. data/spec/unit/module_tool/tar_spec.rb +1 -1
  559. data/spec/unit/module_tool_spec.rb +17 -90
  560. data/spec/unit/network/authconfig_spec.rb +3 -4
  561. data/spec/unit/network/authentication_spec.rb +20 -6
  562. data/spec/unit/network/authorization_spec.rb +11 -1
  563. data/spec/unit/network/formats_spec.rb +32 -9
  564. data/spec/unit/network/http/api/v1_spec.rb +365 -62
  565. data/spec/unit/network/http/api/v2/authorization_spec.rb +57 -0
  566. data/spec/unit/network/http/api/v2/environments_spec.rb +42 -0
  567. data/spec/unit/network/http/api/v2_spec.rb +14 -0
  568. data/spec/unit/network/http/connection_spec.rb +39 -5
  569. data/spec/unit/network/http/error_spec.rb +30 -0
  570. data/spec/unit/network/http/handler_spec.rb +69 -419
  571. data/spec/unit/network/http/rack/rest_spec.rb +20 -28
  572. data/spec/unit/network/http/route_spec.rb +75 -0
  573. data/spec/unit/network/http/webrick/rest_spec.rb +21 -58
  574. data/spec/unit/network/http_pool_spec.rb +3 -3
  575. data/spec/unit/network/rights_spec.rb +2 -2
  576. data/spec/unit/node/environment_spec.rb +108 -89
  577. data/spec/unit/node/facts_spec.rb +5 -12
  578. data/spec/unit/node_spec.rb +22 -22
  579. data/spec/unit/parser/ast/collection_spec.rb +1 -1
  580. data/spec/unit/parser/ast/leaf_spec.rb +2 -0
  581. data/spec/unit/parser/ast/resource_spec.rb +1 -1
  582. data/spec/unit/parser/compiler_spec.rb +5 -3
  583. data/spec/unit/parser/files_spec.rb +40 -50
  584. data/spec/unit/parser/functions/defined_spec.rb +80 -18
  585. data/spec/unit/parser/functions/epp_spec.rb +88 -0
  586. data/spec/unit/parser/functions/fqdn_rand_spec.rb +4 -1
  587. data/spec/unit/parser/functions/generate_spec.rb +6 -2
  588. data/spec/unit/parser/functions/hiera_array_spec.rb +5 -2
  589. data/spec/unit/parser/functions/hiera_hash_spec.rb +4 -1
  590. data/spec/unit/parser/functions/hiera_include_spec.rb +6 -3
  591. data/spec/unit/parser/functions/hiera_spec.rb +5 -2
  592. data/spec/unit/parser/functions/include_spec.rb +0 -1
  593. data/spec/unit/parser/functions/inline_epp_spec.rb +82 -0
  594. data/spec/unit/parser/functions/lookup_spec.rb +66 -16
  595. data/spec/unit/parser/functions_spec.rb +25 -91
  596. data/spec/unit/parser/lexer_spec.rb +1 -1
  597. data/spec/unit/parser/methods/filter_spec.rb +56 -0
  598. data/spec/unit/parser/methods/map_spec.rb +94 -5
  599. data/spec/unit/parser/methods/reduce_spec.rb +10 -0
  600. data/spec/unit/parser/methods/shared.rb +2 -18
  601. data/spec/unit/parser/methods/slice_spec.rb +39 -1
  602. data/spec/unit/parser/parser_spec.rb +14 -10
  603. data/spec/unit/parser/resource_spec.rb +3 -9
  604. data/spec/unit/parser/scope_spec.rb +81 -78
  605. data/spec/unit/parser/type_loader_spec.rb +0 -4
  606. data/spec/unit/pops/benchmark_spec.rb +142 -0
  607. data/spec/unit/pops/binder/binder_spec.rb +15 -34
  608. data/spec/unit/pops/binder/bindings_checker_spec.rb +0 -41
  609. data/spec/unit/pops/binder/bindings_composer_spec.rb +6 -31
  610. data/spec/unit/pops/binder/config/binder_config_spec.rb +5 -18
  611. data/spec/unit/pops/binder/injector_spec.rb +76 -81
  612. data/spec/unit/pops/evaluator/access_ops_spec.rb +376 -0
  613. data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +77 -0
  614. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +103 -0
  615. data/spec/unit/pops/evaluator/collections_ops_spec.rb +111 -0
  616. data/spec/unit/pops/evaluator/comparison_ops_spec.rb +256 -0
  617. data/spec/unit/pops/evaluator/conditionals_spec.rb +190 -0
  618. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +1045 -0
  619. data/spec/unit/pops/evaluator/evaluator_rspec_helper.rb +75 -0
  620. data/spec/unit/pops/evaluator/logical_ops_spec.rb +90 -0
  621. data/spec/unit/pops/evaluator/string_interpolation_spec.rb +44 -0
  622. data/spec/unit/pops/evaluator/variables_spec.rb +194 -0
  623. data/spec/unit/pops/factory_spec.rb +6 -29
  624. data/spec/unit/pops/issues_spec.rb +1 -1
  625. data/spec/unit/pops/model/ast_transformer_spec.rb +6 -9
  626. data/spec/unit/pops/model/model_spec.rb +2 -2
  627. data/spec/unit/pops/parser/epp_parser_spec.rb +86 -0
  628. data/spec/unit/pops/parser/evaluating_parser_spec.rb +4 -2
  629. data/spec/unit/pops/parser/lexer2_spec.rb +428 -0
  630. data/spec/unit/pops/parser/lexer_spec.rb +25 -86
  631. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +29 -4
  632. data/spec/unit/pops/parser/parse_calls_spec.rb +10 -6
  633. data/spec/unit/pops/parser/parse_conditionals_spec.rb +0 -9
  634. data/spec/unit/pops/parser/parse_containers_spec.rb +43 -12
  635. data/spec/unit/pops/parser/parse_heredoc_spec.rb +73 -0
  636. data/spec/unit/pops/parser/parse_resource_spec.rb +14 -0
  637. data/spec/unit/pops/parser/parser_spec.rb +3 -1
  638. data/spec/unit/pops/transformer/transform_basic_expressions_spec.rb +4 -4
  639. data/spec/unit/pops/transformer/transform_calls_spec.rb +41 -6
  640. data/spec/unit/pops/transformer/transform_conditionals_spec.rb +0 -9
  641. data/spec/unit/pops/transformer/transform_containers_spec.rb +12 -4
  642. data/spec/unit/pops/types/enumeration_spec.rb +50 -0
  643. data/spec/unit/pops/types/type_calculator_spec.rb +1171 -196
  644. data/spec/unit/pops/types/type_factory_spec.rb +108 -4
  645. data/spec/unit/pops/types/type_parser_spec.rb +114 -10
  646. data/spec/unit/pops/validator/validator_spec.rb +36 -1
  647. data/spec/unit/provider/augeas/augeas_spec.rb +39 -16
  648. data/spec/unit/provider/cron/parsed_spec.rb +27 -31
  649. data/spec/unit/provider/file/posix_spec.rb +2 -2
  650. data/spec/unit/provider/group/windows_adsi_spec.rb +1 -0
  651. data/spec/unit/provider/mount_spec.rb +12 -1
  652. data/spec/unit/provider/nameservice/directoryservice_spec.rb +3 -3
  653. data/spec/unit/provider/package/apt_spec.rb +1 -1
  654. data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
  655. data/spec/unit/provider/package/gem_spec.rb +12 -0
  656. data/spec/unit/provider/package/msi_spec.rb +4 -0
  657. data/spec/unit/provider/package/openbsd_spec.rb +10 -10
  658. data/spec/unit/provider/package/pacman_spec.rb +36 -7
  659. data/spec/unit/provider/package/pkgin_spec.rb +57 -55
  660. data/spec/unit/provider/package/rpm_spec.rb +51 -6
  661. data/spec/unit/provider/service/base_spec.rb +4 -4
  662. data/spec/unit/provider/service/daemontools_spec.rb +8 -13
  663. data/spec/unit/provider/service/freebsd_spec.rb +3 -3
  664. data/spec/unit/provider/service/gentoo_spec.rb +24 -24
  665. data/spec/unit/provider/service/init_spec.rb +15 -15
  666. data/spec/unit/provider/service/openbsd_spec.rb +16 -16
  667. data/spec/unit/provider/service/openrc_spec.rb +20 -20
  668. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  669. data/spec/unit/provider/service/runit_spec.rb +5 -8
  670. data/spec/unit/provider/service/src_spec.rb +4 -4
  671. data/spec/unit/provider/service/systemd_spec.rb +24 -14
  672. data/spec/unit/provider/service/upstart_spec.rb +12 -4
  673. data/spec/unit/provider/service/windows_spec.rb +1 -1
  674. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +21 -23
  675. data/spec/unit/provider/user/directoryservice_spec.rb +7 -7
  676. data/spec/unit/provider/user/useradd_spec.rb +43 -15
  677. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
  678. data/spec/unit/provider/yumrepo/inifile_spec.rb +105 -0
  679. data/spec/unit/provider/zone/solaris_spec.rb +1 -1
  680. data/spec/unit/provider_spec.rb +120 -62
  681. data/spec/unit/rails/host_spec.rb +1 -1
  682. data/spec/unit/rails/param_value_spec.rb +4 -0
  683. data/spec/unit/relationship_spec.rb +4 -4
  684. data/spec/unit/reports/http_spec.rb +14 -3
  685. data/spec/unit/reports/rrdgraph_spec.rb +0 -1
  686. data/spec/unit/reports/store_spec.rb +2 -2
  687. data/spec/unit/resource/catalog_spec.rb +17 -29
  688. data/spec/unit/resource/status_spec.rb +1 -1
  689. data/spec/unit/resource/type_collection_spec.rb +28 -47
  690. data/spec/unit/resource/type_spec.rb +12 -23
  691. data/spec/unit/resource_spec.rb +54 -93
  692. data/spec/unit/run_spec.rb +3 -3
  693. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  694. data/spec/unit/settings/config_file_spec.rb +68 -15
  695. data/spec/unit/settings/file_setting_spec.rb +2 -2
  696. data/spec/unit/settings/ini_file_spec.rb +184 -0
  697. data/spec/unit/settings_spec.rb +137 -79
  698. data/spec/unit/ssl/certificate_authority/interface_spec.rb +3 -1
  699. data/spec/unit/ssl/certificate_authority_spec.rb +11 -9
  700. data/spec/unit/ssl/certificate_factory_spec.rb +19 -4
  701. data/spec/unit/ssl/certificate_request_attributes_spec.rb +1 -1
  702. data/spec/unit/ssl/certificate_revocation_list_spec.rb +101 -72
  703. data/spec/unit/ssl/host_spec.rb +8 -20
  704. data/spec/unit/ssl/inventory_spec.rb +2 -2
  705. data/spec/unit/ssl/key_spec.rb +4 -4
  706. data/spec/unit/status_spec.rb +6 -4
  707. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -11
  708. data/spec/unit/transaction/event_spec.rb +2 -2
  709. data/spec/unit/transaction/report_spec.rb +24 -15
  710. data/spec/unit/transaction/resource_harness_spec.rb +1 -1
  711. data/spec/unit/type/cron_spec.rb +39 -1
  712. data/spec/unit/type/file/content_spec.rb +4 -5
  713. data/spec/unit/type/file/ctime_spec.rb +1 -1
  714. data/spec/unit/type/file/mode_spec.rb +5 -4
  715. data/spec/unit/type/file/mtime_spec.rb +1 -1
  716. data/spec/unit/type/file/source_spec.rb +30 -7
  717. data/spec/unit/type/file_spec.rb +8 -8
  718. data/spec/unit/type/k5login_spec.rb +3 -3
  719. data/spec/unit/type/nagios_spec.rb +6 -0
  720. data/spec/unit/type/package/package_settings_spec.rb +135 -0
  721. data/spec/unit/type/package_spec.rb +13 -1
  722. data/spec/unit/type/resources_spec.rb +155 -0
  723. data/spec/unit/type/service_spec.rb +3 -3
  724. data/spec/unit/type/ssh_authorized_key_spec.rb +96 -93
  725. data/spec/unit/type/sshkey_spec.rb +39 -30
  726. data/spec/unit/type/tidy_spec.rb +19 -12
  727. data/spec/unit/type/user_spec.rb +47 -2
  728. data/spec/unit/type/whit_spec.rb +2 -2
  729. data/spec/unit/type/yumrepo_spec.rb +32 -177
  730. data/spec/unit/type/zone_spec.rb +2 -2
  731. data/spec/unit/type_spec.rb +11 -0
  732. data/spec/unit/util/adsi_spec.rb +48 -1
  733. data/spec/unit/util/autoload_spec.rb +24 -39
  734. data/spec/unit/util/backups_spec.rb +25 -28
  735. data/spec/unit/util/checksums_spec.rb +1 -3
  736. data/spec/unit/util/colors_spec.rb +14 -0
  737. data/spec/unit/util/docs_spec.rb +9 -0
  738. data/spec/unit/util/execution_spec.rb +1 -1
  739. data/spec/unit/util/filetype_spec.rb +7 -7
  740. data/spec/unit/util/instrumentation/data_spec.rb +3 -1
  741. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +2 -0
  742. data/spec/unit/util/instrumentation/listener_spec.rb +3 -2
  743. data/spec/unit/util/json_lockfile_spec.rb +25 -4
  744. data/spec/unit/util/lockfile_spec.rb +49 -7
  745. data/spec/unit/util/log/destinations_spec.rb +1 -0
  746. data/spec/unit/util/log_spec.rb +1 -1
  747. data/spec/unit/util/metric_spec.rb +1 -1
  748. data/spec/unit/util/pidlock_spec.rb +6 -6
  749. data/spec/unit/util/pson_spec.rb +2 -2
  750. data/spec/unit/util/rdoc/parser_spec.rb +32 -29
  751. data/spec/unit/util/resource_template_spec.rb +3 -3
  752. data/spec/unit/util/selinux_spec.rb +5 -5
  753. data/spec/unit/util/storage_spec.rb +4 -4
  754. data/spec/unit/util/tag_set_spec.rb +1 -1
  755. data/spec/unit/util/watcher_spec.rb +1 -4
  756. data/spec/unit/util/yaml_spec.rb +2 -2
  757. data/spec/unit/util_spec.rb +7 -7
  758. data/tasks/benchmark.rake +0 -1
  759. data/tasks/parallel.rake +408 -0
  760. data/tasks/yard.rake +59 -0
  761. metadata +2889 -2782
  762. checksums.yaml +0 -7
  763. data/README_DEVELOPER.md +0 -809
  764. data/lib/puppet/file_system/file.rb +0 -271
  765. data/lib/puppet/network/http/rack/httphandler.rb +0 -13
  766. data/lib/puppet/pops/binder/hiera2.rb +0 -10
  767. data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +0 -148
  768. data/lib/puppet/pops/binder/hiera2/config.rb +0 -69
  769. data/lib/puppet/pops/binder/hiera2/config_checker.rb +0 -68
  770. data/lib/puppet/pops/binder/hiera2/diagnostic_producer.rb +0 -36
  771. data/lib/puppet/pops/binder/hiera2/issues.rb +0 -67
  772. data/lib/puppet/pops/binder/hiera2/json_backend.rb +0 -18
  773. data/lib/puppet/pops/binder/hiera2/yaml_backend.rb +0 -21
  774. data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +0 -67
  775. data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +0 -92
  776. data/lib/puppet/pops/parser/grammar.ra +0 -746
  777. data/lib/puppet/provider/port/parsed.rb +0 -173
  778. data/lib/puppet/type/port.rb +0 -119
  779. data/lib/puppetx/puppet/hiera2_backend.rb +0 -31
  780. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/binder_config.yaml +0 -18
  781. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/hiera.yaml +0 -8
  782. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/common.yaml +0 -1
  783. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/hiera.yaml +0 -10
  784. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/common.yaml +0 -1
  785. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/hiera.yaml +0 -11
  786. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/localhost.yaml +0 -1
  787. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/common.yaml +0 -3
  788. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/hiera.yaml +0 -13
  789. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppet/bindings/awesome/default.rb +0 -4
  790. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_backend.rb +0 -11
  791. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/localhost.yaml +0 -1
  792. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/common.yaml +0 -3
  793. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/hiera_config.yaml +0 -9
  794. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/common.yaml +0 -2
  795. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/hiera.yaml +0 -11
  796. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/hiera.yaml +0 -9
  797. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.json +0 -9
  798. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.yaml +0 -5
  799. data/spec/fixtures/unit/pops/binder/hiera2/config/bad_syntax/hiera.yaml +0 -10
  800. data/spec/fixtures/unit/pops/binder/hiera2/config/malformed_hierarchy/hiera.yaml +0 -8
  801. data/spec/fixtures/unit/pops/binder/hiera2/config/missing/foo.txt +0 -1
  802. data/spec/fixtures/unit/pops/binder/hiera2/config/no_backends/hiera.yaml +0 -7
  803. data/spec/fixtures/unit/pops/binder/hiera2/config/no_hierarchy/hiera.yaml +0 -4
  804. data/spec/fixtures/unit/pops/binder/hiera2/config/not_a_hash/hiera.yaml +0 -2
  805. data/spec/fixtures/unit/pops/binder/hiera2/config/ok/hiera.yaml +0 -8
  806. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/invalid/common.yaml +0 -1
  807. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/ok/common.yaml +0 -2
  808. data/spec/unit/file_system/file_spec.rb +0 -486
  809. data/spec/unit/pops/binder/hiera2/bindings_provider_spec.rb +0 -74
  810. data/spec/unit/pops/binder/hiera2/config_spec.rb +0 -61
  811. data/spec/unit/pops/binder/hiera2/yaml_backend_spec.rb +0 -33
@@ -0,0 +1,190 @@
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
3
+ require 'puppet/pops'
4
+ require 'puppet/pops/evaluator/evaluator_impl'
5
+
6
+ # relative to this spec file (./) does not work as this file is loaded by rspec
7
+ require File.join(File.dirname(__FILE__), '/evaluator_rspec_helper')
8
+
9
+ # This file contains testing of Conditionals, if, case, unless, selector
10
+ #
11
+ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
12
+ include EvaluatorRspecHelper
13
+
14
+ context "When the evaluator evaluates" do
15
+ context "an if expression" do
16
+ it 'should output the expected result when dumped' do
17
+ dump(IF(literal(true), literal(2), literal(5))).should == unindent(<<-TEXT
18
+ (if true
19
+ (then 2)
20
+ (else 5))
21
+ TEXT
22
+ )
23
+ end
24
+
25
+ it 'if true {5} == 5' do
26
+ evaluate(IF(literal(true), literal(5))).should == 5
27
+ end
28
+
29
+ it 'if false {5} == nil' do
30
+ evaluate(IF(literal(false), literal(5))).should == nil
31
+ end
32
+
33
+ it 'if false {2} else {5} == 5' do
34
+ evaluate(IF(literal(false), literal(2), literal(5))).should == 5
35
+ end
36
+
37
+ it 'if false {2} elsif true {5} == 5' do
38
+ evaluate(IF(literal(false), literal(2), IF(literal(true), literal(5)))).should == 5
39
+ end
40
+
41
+ it 'if false {2} elsif false {5} == nil' do
42
+ evaluate(IF(literal(false), literal(2), IF(literal(false), literal(5)))).should == nil
43
+ end
44
+ end
45
+
46
+ context "an unless expression" do
47
+ it 'should output the expected result when dumped' do
48
+ dump(UNLESS(literal(true), literal(2), literal(5))).should == unindent(<<-TEXT
49
+ (unless true
50
+ (then 2)
51
+ (else 5))
52
+ TEXT
53
+ )
54
+ end
55
+
56
+ it 'unless false {5} == 5' do
57
+ evaluate(UNLESS(literal(false), literal(5))).should == 5
58
+ end
59
+
60
+ it 'unless true {5} == nil' do
61
+ evaluate(UNLESS(literal(true), literal(5))).should == nil
62
+ end
63
+
64
+ it 'unless true {2} else {5} == 5' do
65
+ evaluate(UNLESS(literal(true), literal(2), literal(5))).should == 5
66
+ end
67
+
68
+ it 'unless true {2} elsif true {5} == 5' do
69
+ # not supported by concrete syntax
70
+ evaluate(UNLESS(literal(true), literal(2), IF(literal(true), literal(5)))).should == 5
71
+ end
72
+
73
+ it 'unless true {2} elsif false {5} == nil' do
74
+ # not supported by concrete syntax
75
+ evaluate(UNLESS(literal(true), literal(2), IF(literal(false), literal(5)))).should == nil
76
+ end
77
+ end
78
+
79
+ context "a case expression" do
80
+ it 'should output the expected result when dumped' do
81
+ dump(CASE(literal(2),
82
+ WHEN(literal(1), literal('wat')),
83
+ WHEN([literal(2), literal(3)], literal('w00t'))
84
+ )).should == unindent(<<-TEXT
85
+ (case 2
86
+ (when (1) (then 'wat'))
87
+ (when (2 3) (then 'w00t')))
88
+ TEXT
89
+ )
90
+ dump(CASE(literal(2),
91
+ WHEN(literal(1), literal('wat')),
92
+ WHEN([literal(2), literal(3)], literal('w00t'))
93
+ ).default(literal(4))).should == unindent(<<-TEXT
94
+ (case 2
95
+ (when (1) (then 'wat'))
96
+ (when (2 3) (then 'w00t'))
97
+ (when (:default) (then 4)))
98
+ TEXT
99
+ )
100
+ end
101
+
102
+ it "case 1 { 1 : { 'w00t'} } == 'w00t'" do
103
+ evaluate(CASE(literal(1), WHEN(literal(1), literal('w00t')))).should == 'w00t'
104
+ end
105
+
106
+ it "case 2 { 1,2,3 : { 'w00t'} } == 'w00t'" do
107
+ evaluate(CASE(literal(2), WHEN([literal(1), literal(2), literal(3)], literal('w00t')))).should == 'w00t'
108
+ end
109
+
110
+ it "case 2 { 1,3 : {'wat'} 2: { 'w00t'} } == 'w00t'" do
111
+ evaluate(CASE(literal(2),
112
+ WHEN([literal(1), literal(3)], literal('wat')),
113
+ WHEN(literal(2), literal('w00t')))).should == 'w00t'
114
+ end
115
+
116
+ it "case 2 { 1,3 : {'wat'} 5: { 'wat'} default: {'w00t'}} == 'w00t'" do
117
+ evaluate(CASE(literal(2),
118
+ WHEN([literal(1), literal(3)], literal('wat')),
119
+ WHEN(literal(5), literal('wat'))).default(literal('w00t'))
120
+ ).should == 'w00t'
121
+ end
122
+
123
+ it "case 2 { 1,3 : {'wat'} 5: { 'wat'} } == nil" do
124
+ evaluate(CASE(literal(2),
125
+ WHEN([literal(1), literal(3)], literal('wat')),
126
+ WHEN(literal(5), literal('wat')))
127
+ ).should == nil
128
+ end
129
+
130
+ it "case 'banana' { 1,3 : {'wat'} /.*ana.*/: { 'w00t'} } == w00t" do
131
+ evaluate(CASE(literal('banana'),
132
+ WHEN([literal(1), literal(3)], literal('wat')),
133
+ WHEN(literal(/.*ana.*/), literal('w00t')))
134
+ ).should == 'w00t'
135
+ end
136
+
137
+ context "with regular expressions" do
138
+ it "should set numeric variables from the match" do
139
+ evaluate(CASE(literal('banana'),
140
+ WHEN([literal(1), literal(3)], literal('wat')),
141
+ WHEN(literal(/.*(ana).*/), var(1)))
142
+ ).should == 'ana'
143
+ end
144
+ end
145
+ end
146
+
147
+ context "select expressions" do
148
+ it 'should output the expected result when dumped' do
149
+ dump(literal(2).select(
150
+ MAP(literal(1), literal('wat')),
151
+ MAP(literal(2), literal('w00t'))
152
+ )).should == "(? 2 (1 => 'wat') (2 => 'w00t'))"
153
+ end
154
+
155
+ it "1 ? {1 => 'w00t'} == 'w00t'" do
156
+ evaluate(literal(1).select(MAP(literal(1), literal('w00t')))).should == 'w00t'
157
+ end
158
+
159
+ it "2 ? {1 => 'wat', 2 => 'w00t'} == 'w00t'" do
160
+ evaluate(literal(2).select(
161
+ MAP(literal(1), literal('wat')),
162
+ MAP(literal(2), literal('w00t'))
163
+ )).should == 'w00t'
164
+ end
165
+
166
+ it "3 ? {1 => 'wat', 2 => 'wat', default => 'w00t'} == 'w00t'" do
167
+ evaluate(literal(3).select(
168
+ MAP(literal(1), literal('wat')),
169
+ MAP(literal(2), literal('wat')),
170
+ MAP(literal(:default), literal('w00t'))
171
+ )).should == 'w00t'
172
+ end
173
+
174
+ it "3 ? {1 => 'wat', default => 'w00t', 3 => 'wat'} == 'w00t'" do
175
+ evaluate(literal(3).select(
176
+ MAP(literal(1), literal('wat')),
177
+ MAP(literal(:default), literal('w00t')),
178
+ MAP(literal(2), literal('wat'))
179
+ )).should == 'w00t'
180
+ end
181
+
182
+ it "should set numerical variables from match" do
183
+ evaluate(literal('banana').select(
184
+ MAP(literal(1), literal('wat')),
185
+ MAP(literal(/.*(ana).*/), var(1))
186
+ )).should == 'ana'
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,1045 @@
1
+ require 'spec_helper'
2
+
3
+ require 'puppet/pops'
4
+ require 'puppet/pops/evaluator/evaluator_impl'
5
+ require 'puppet_spec/pops'
6
+ require 'puppet_spec/scope'
7
+ require 'puppet/parser/e4_parser_adapter'
8
+
9
+
10
+ # relative to this spec file (./) does not work as this file is loaded by rspec
11
+ #require File.join(File.dirname(__FILE__), '/evaluator_rspec_helper')
12
+
13
+ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
14
+ include PuppetSpec::Pops
15
+ include PuppetSpec::Scope
16
+ before(:each) do
17
+ Puppet[:strict_variables] = true
18
+
19
+ # These must be set since the is 3x logic that triggers on these even if the tests are explicit
20
+ # about selection of parser and evaluator
21
+ #
22
+ Puppet[:parser] = 'future'
23
+ Puppet[:evaluator] = 'future'
24
+ # Puppetx cannot be loaded until the correct parser has been set (injector is turned off otherwise)
25
+ require 'puppetx'
26
+ end
27
+
28
+ let(:parser) { Puppet::Pops::Parser::EvaluatingParser::Transitional.new }
29
+ let(:node) { 'node.example.com' }
30
+ let(:scope) { s = create_test_scope_for_node(node); s }
31
+ types = Puppet::Pops::Types::TypeFactory
32
+
33
+ context "When evaluator evaluates literals" do
34
+ {
35
+ "1" => 1,
36
+ "010" => 8,
37
+ "0x10" => 16,
38
+ "3.14" => 3.14,
39
+ "0.314e1" => 3.14,
40
+ "31.4e-1" => 3.14,
41
+ "'1'" => '1',
42
+ "'banana'" => 'banana',
43
+ '"banana"' => 'banana',
44
+ "banana" => 'banana',
45
+ "banana::split" => 'banana::split',
46
+ "false" => false,
47
+ "true" => true,
48
+ "Array" => types.array_of_data(),
49
+ "/.*/" => /.*/
50
+ }.each do |source, result|
51
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
52
+ parser.evaluate_string(scope, source, __FILE__).should == result
53
+ end
54
+ end
55
+ end
56
+
57
+ context "When the evaluator evaluates Lists and Hashes" do
58
+ {
59
+ "[]" => [],
60
+ "[1,2,3]" => [1,2,3],
61
+ "[1,[2.0, 2.1, [2.2]],[3.0, 3.1]]" => [1,[2.0, 2.1, [2.2]],[3.0, 3.1]],
62
+ "[2 + 2]" => [4],
63
+ "[1,2,3] == [1,2,3]" => true,
64
+ "[1,2,3] != [2,3,4]" => true,
65
+ "[1,2,3] == [2,2,3]" => false,
66
+ "[1,2,3] != [1,2,3]" => false,
67
+ "[1,2,3][2]" => 3,
68
+ "[1,2,3] + [4,5]" => [1,2,3,4,5],
69
+ "[1,2,3] + [[4,5]]" => [1,2,3,[4,5]],
70
+ "[1,2,3] + 4" => [1,2,3,4],
71
+ "[1,2,3] << [4,5]" => [1,2,3,[4,5]],
72
+ "[1,2,3] << {'a' => 1, 'b'=>2}" => [1,2,3,{'a' => 1, 'b'=>2}],
73
+ "[1,2,3] << 4" => [1,2,3,4],
74
+ "[1,2,3,4] - [2,3]" => [1,4],
75
+ "[1,2,3,4] - [2,5]" => [1,3,4],
76
+ "[1,2,3,4] - 2" => [1,3,4],
77
+ "[1,2,3,[2],4] - 2" => [1,3,[2],4],
78
+ "[1,2,3,[2,3],4] - [[2,3]]" => [1,2,3,4],
79
+ "[1,2,3,3,2,4,2,3] - [2,3]" => [1,4],
80
+ "[1,2,3,['a',1],['b',2]] - {'a' => 1, 'b'=>2}" => [1,2,3],
81
+ "[1,2,3,{'a'=>1,'b'=>2}] - [{'a' => 1, 'b'=>2}]" => [1,2,3],
82
+ }.each do |source, result|
83
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
84
+ parser.evaluate_string(scope, source, __FILE__).should == result
85
+ end
86
+ end
87
+
88
+ {
89
+ "[1,2,3] + {'a' => 1, 'b'=>2}" => [1,2,3,['a',1],['b',2]],
90
+ }.each do |source, result|
91
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
92
+ # This test must be done with match_array since the order of the hash
93
+ # is undefined and Ruby 1.8.7 and 1.9.3 produce different results.
94
+ expect(parser.evaluate_string(scope, source, __FILE__)).to match_array(result)
95
+ end
96
+ end
97
+
98
+ {
99
+ "[1,2,3][a]" => :error,
100
+ }.each do |source, result|
101
+ it "should parse and raise error for '#{source}'" do
102
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
103
+ end
104
+ end
105
+
106
+ {
107
+ "{}" => {},
108
+ "{'a'=>1,'b'=>2}" => {'a'=>1,'b'=>2},
109
+ "{'a'=>1,'b'=>{'x'=>2.1,'y'=>2.2}}" => {'a'=>1,'b'=>{'x'=>2.1,'y'=>2.2}},
110
+ "{'a'=> 2 + 2}" => {'a'=> 4},
111
+ "{'a'=> 1, 'b'=>2} == {'a'=> 1, 'b'=>2}" => true,
112
+ "{'a'=> 1, 'b'=>2} != {'x'=> 1, 'b'=>2}" => true,
113
+ "{'a'=> 1, 'b'=>2} == {'a'=> 2, 'b'=>3}" => false,
114
+ "{'a'=> 1, 'b'=>2} != {'a'=> 1, 'b'=>2}" => false,
115
+ "{a => 1, b => 2}[b]" => 2,
116
+ "{2+2 => sum, b => 2}[4]" => 'sum',
117
+ "{'a'=>1, 'b'=>2} + {'c'=>3}" => {'a'=>1,'b'=>2,'c'=>3},
118
+ "{'a'=>1, 'b'=>2} + {'b'=>3}" => {'a'=>1,'b'=>3},
119
+ "{'a'=>1, 'b'=>2} + ['c', 3, 'b', 3]" => {'a'=>1,'b'=>3, 'c'=>3},
120
+ "{'a'=>1, 'b'=>2} + [['c', 3], ['b', 3]]" => {'a'=>1,'b'=>3, 'c'=>3},
121
+ "{'a'=>1, 'b'=>2} - {'b' => 3}" => {'a'=>1},
122
+ "{'a'=>1, 'b'=>2, 'c'=>3} - ['b', 'c']" => {'a'=>1},
123
+ "{'a'=>1, 'b'=>2, 'c'=>3} - 'c'" => {'a'=>1, 'b'=>2},
124
+ }.each do |source, result|
125
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
126
+ parser.evaluate_string(scope, source, __FILE__).should == result
127
+ end
128
+ end
129
+
130
+ {
131
+ "{'a' => 1, 'b'=>2} << 1" => :error,
132
+ }.each do |source, result|
133
+ it "should parse and raise error for '#{source}'" do
134
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
135
+ end
136
+ end
137
+ end
138
+
139
+ context "When the evaluator perform comparisons" do
140
+ {
141
+ "'a' == 'a'" => true,
142
+ "'a' == 'b'" => false,
143
+ "'a' != 'a'" => false,
144
+ "'a' != 'b'" => true,
145
+ "'a' < 'b' " => true,
146
+ "'a' < 'a' " => false,
147
+ "'b' < 'a' " => false,
148
+ "'a' <= 'b'" => true,
149
+ "'a' <= 'a'" => true,
150
+ "'b' <= 'a'" => false,
151
+ "'a' > 'b' " => false,
152
+ "'a' > 'a' " => false,
153
+ "'b' > 'a' " => true,
154
+ "'a' >= 'b'" => false,
155
+ "'a' >= 'a'" => true,
156
+ "'b' >= 'a'" => true,
157
+ "'a' == 'A'" => true,
158
+ "'a' != 'A'" => false,
159
+ "'a' > 'A'" => false,
160
+ "'a' >= 'A'" => true,
161
+ "'A' < 'a'" => false,
162
+ "'A' <= 'a'" => true,
163
+ "1 == 1" => true,
164
+ "1 == 2" => false,
165
+ "1 != 1" => false,
166
+ "1 != 2" => true,
167
+ "1 < 2 " => true,
168
+ "1 < 1 " => false,
169
+ "2 < 1 " => false,
170
+ "1 <= 2" => true,
171
+ "1 <= 1" => true,
172
+ "2 <= 1" => false,
173
+ "1 > 2 " => false,
174
+ "1 > 1 " => false,
175
+ "2 > 1 " => true,
176
+ "1 >= 2" => false,
177
+ "1 >= 1" => true,
178
+ "2 >= 1" => true,
179
+ "1 == 1.0 " => true,
180
+ "1 < 1.1 " => true,
181
+ "'1' < 1.1" => true,
182
+ "1.0 == 1 " => true,
183
+ "1.0 < 2 " => true,
184
+ "'1.0' < 1.1" => true,
185
+ "'1.0' < 'a'" => true,
186
+ "'1.0' < '' " => true,
187
+ "'1.0' < ' '" => true,
188
+ "'a' > '1.0'" => true,
189
+ "/.*/ == /.*/ " => true,
190
+ "/.*/ != /a.*/" => true,
191
+ "true == true " => true,
192
+ "false == false" => true,
193
+ "true == false" => false,
194
+ }.each do |source, result|
195
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
196
+ parser.evaluate_string(scope, source, __FILE__).should == result
197
+ end
198
+ end
199
+
200
+ {
201
+ "'a' =~ /.*/" => true,
202
+ "'a' =~ '.*'" => true,
203
+ "/.*/ != /a.*/" => true,
204
+ "'a' !~ /b.*/" => true,
205
+ "'a' !~ 'b.*'" => true,
206
+ '$x = a; a =~ "$x.*"' => true,
207
+ "a =~ Pattern['a.*']" => true,
208
+ "a =~ Regexp['a.*']" => true,
209
+ "$x = /a.*/ a =~ $x" => true,
210
+ "$x = Pattern['a.*'] a =~ $x" => true,
211
+ "1 =~ Integer" => true,
212
+ "1 !~ Integer" => false,
213
+ "[1,2,3] =~ Array[Integer[1,10]]" => true,
214
+ }.each do |source, result|
215
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
216
+ parser.evaluate_string(scope, source, __FILE__).should == result
217
+ end
218
+ end
219
+
220
+ {
221
+ "666 =~ /6/" => :error,
222
+ "[a] =~ /a/" => :error,
223
+ "{a=>1} =~ /a/" => :error,
224
+ "/a/ =~ /a/" => :error,
225
+ "Array =~ /A/" => :error,
226
+ }.each do |source, result|
227
+ it "should parse and raise error for '#{source}'" do
228
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
229
+ end
230
+ end
231
+
232
+ {
233
+ "1 in [1,2,3]" => true,
234
+ "4 in [1,2,3]" => false,
235
+ "a in {x=>1, a=>2}" => true,
236
+ "z in {x=>1, a=>2}" => false,
237
+ "ana in bananas" => true,
238
+ "xxx in bananas" => false,
239
+ "/ana/ in bananas" => true,
240
+ "/xxx/ in bananas" => false,
241
+ "ANA in bananas" => false, # ANA is a type, not a String
242
+ "'ANA' in bananas" => true,
243
+ "ana in 'BANANAS'" => true,
244
+ "/ana/ in 'BANANAS'" => false,
245
+ "/ANA/ in 'BANANAS'" => true,
246
+ "xxx in 'BANANAS'" => false,
247
+ "[2,3] in [1,[2,3],4]" => true,
248
+ "[2,4] in [1,[2,3],4]" => false,
249
+ "[a,b] in ['A',['A','B'],'C']" => true,
250
+ "[x,y] in ['A',['A','B'],'C']" => false,
251
+ "a in {a=>1}" => true,
252
+ "x in {a=>1}" => false,
253
+ "'A' in {a=>1}" => true,
254
+ "'X' in {a=>1}" => false,
255
+ "a in {'A'=>1}" => true,
256
+ "x in {'A'=>1}" => false,
257
+ "/xxx/ in {'aaaxxxbbb'=>1}" => true,
258
+ "/yyy/ in {'aaaxxxbbb'=>1}" => false,
259
+ "15 in [1, 0xf]" => true,
260
+ "15 in [1, '0xf']" => true,
261
+ "'15' in [1, 0xf]" => true,
262
+ "15 in [1, 115]" => false,
263
+ "1 in [11, '111']" => false,
264
+ "'1' in [11, '111']" => false,
265
+ "Array[Integer] in [2, 3]" => false,
266
+ "Array[Integer] in [2, [3, 4]]" => true,
267
+ "Array[Integer] in [2, [a, 4]]" => false,
268
+ "Integer in { 2 =>'a'}" => true,
269
+ "Integer[5,10] in [1,5,3]" => true,
270
+ "Integer[5,10] in [1,2,3]" => false,
271
+ "Integer in {'a'=>'a'}" => false,
272
+ "Integer in {'a'=>1}" => false,
273
+ }.each do |source, result|
274
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
275
+ parser.evaluate_string(scope, source, __FILE__).should == result
276
+ end
277
+ end
278
+
279
+ {
280
+ 'Object' => ['Data', 'Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Collection',
281
+ 'Array', 'Hash', 'CatalogEntry', 'Resource', 'Class', 'Undef', 'File', 'NotYetKnownResourceType'],
282
+
283
+ # Note, Data > Collection is false (so not included)
284
+ 'Data' => ['Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Array', 'Hash',],
285
+ 'Scalar' => ['Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern'],
286
+ 'Numeric' => ['Integer', 'Float'],
287
+ 'CatalogEntry' => ['Class', 'Resource', 'File', 'NotYetKnownResourceType'],
288
+ 'Integer[1,10]' => ['Integer[2,3]'],
289
+ }.each do |general, specials|
290
+ specials.each do |special |
291
+ it "should compute that #{general} > #{special}" do
292
+ parser.evaluate_string(scope, "#{general} > #{special}", __FILE__).should == true
293
+ end
294
+ it "should compute that #{special} < #{general}" do
295
+ parser.evaluate_string(scope, "#{special} < #{general}", __FILE__).should == true
296
+ end
297
+ it "should compute that #{general} != #{special}" do
298
+ parser.evaluate_string(scope, "#{special} != #{general}", __FILE__).should == true
299
+ end
300
+ end
301
+ end
302
+
303
+ {
304
+ 'Integer[1,10] > Integer[2,3]' => true,
305
+ 'Integer[1,10] == Integer[2,3]' => false,
306
+ 'Integer[1,10] > Integer[0,5]' => false,
307
+ 'Integer[1,10] > Integer[1,10]' => false,
308
+ 'Integer[1,10] >= Integer[1,10]' => true,
309
+ 'Integer[1,10] == Integer[1,10]' => true,
310
+ }.each do |source, result|
311
+ it "should parse and evaluate the integer range comparison expression '#{source}' to #{result}" do
312
+ parser.evaluate_string(scope, source, __FILE__).should == result
313
+ end
314
+ end
315
+
316
+ end
317
+
318
+ context "When the evaluator performs arithmetic" do
319
+ context "on Integers" do
320
+ { "2+2" => 4,
321
+ "2 + 2" => 4,
322
+ "7 - 3" => 4,
323
+ "6 * 3" => 18,
324
+ "6 / 3" => 2,
325
+ "6 % 3" => 0,
326
+ "10 % 3" => 1,
327
+ "-(6/3)" => -2,
328
+ "-6/3 " => -2,
329
+ "8 >> 1" => 4,
330
+ "8 << 1" => 16,
331
+ }.each do |source, result|
332
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
333
+ parser.evaluate_string(scope, source, __FILE__).should == result
334
+ end
335
+ end
336
+
337
+ context "on Floats" do
338
+ {
339
+ "2.2 + 2.2" => 4.4,
340
+ "7.7 - 3.3" => 4.4,
341
+ "6.1 * 3.1" => 18.91,
342
+ "6.6 / 3.3" => 2.0,
343
+ "-(6.0/3.0)" => -2.0,
344
+ "-6.0/3.0 " => -2.0,
345
+ }.each do |source, result|
346
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
347
+ parser.evaluate_string(scope, source, __FILE__).should == result
348
+ end
349
+ end
350
+
351
+ {
352
+ "3.14 << 2" => :error,
353
+ "3.14 >> 2" => :error,
354
+ "6.6 % 3.3" => 0.0,
355
+ "10.0 % 3.0" => 1.0,
356
+ }.each do |source, result|
357
+ it "should parse and raise error for '#{source}'" do
358
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
359
+ end
360
+ end
361
+ end
362
+
363
+ context "on strings requiring boxing to Numeric" do
364
+ {
365
+ "'2' + '2'" => 4,
366
+ "'2.2' + '2.2'" => 4.4,
367
+ "'0xF7' + '010'" => 0xFF,
368
+ "'0xF7' + '0x8'" => 0xFF,
369
+ "'0367' + '010'" => 0xFF,
370
+ "'012.3' + '010'" => 20.3,
371
+ }.each do |source, result|
372
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
373
+ parser.evaluate_string(scope, source, __FILE__).should == result
374
+ end
375
+ end
376
+
377
+ {
378
+ "'0888' + '010'" => :error,
379
+ "'0xWTF' + '010'" => :error,
380
+ "'0x12.3' + '010'" => :error,
381
+ "'0x12.3' + '010'" => :error,
382
+ }.each do |source, result|
383
+ it "should parse and raise error for '#{source}'" do
384
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
385
+ end
386
+ end
387
+ end
388
+ end
389
+ end # arithmetic
390
+
391
+ context "When the evaluator evaluates assignment" do
392
+ {
393
+ "$a = 5" => 5,
394
+ "$a = 5; $a" => 5,
395
+ "$a = 5; $b = 6; $a" => 5,
396
+ "$a = $b = 5; $a == $b" => true,
397
+ "$a = [1,2,3]; [x].map |$x| { $a += x; $a }" => [[1,2,3,'x']],
398
+ "$a = [a,x,c]; [x].map |$x| { $a -= x; $a }" => [['a','c']],
399
+ }.each do |source, result|
400
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
401
+ parser.evaluate_string(scope, source, __FILE__).should == result
402
+ end
403
+ end
404
+
405
+ {
406
+ "[a,b,c] = [1,2,3]; $a == 1 and $b == 2 and $c == 3" => :error,
407
+ "[a,b,c] = {b=>2,c=>3,a=>1}; $a == 1 and $b == 2 and $c == 3" => :error,
408
+ "$a = [1,2,3]; [x].collect |$x| { [a] += x; $a }" => :error,
409
+ "$a = [a,x,c]; [x].collect |$x| { [a] -= x; $a }" => :error,
410
+ }.each do |source, result|
411
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
412
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(Puppet::ParseError)
413
+ end
414
+ end
415
+ end
416
+
417
+ context "When the evaluator evaluates conditionals" do
418
+ {
419
+ "if true {5}" => 5,
420
+ "if false {5}" => nil,
421
+ "if false {2} else {5}" => 5,
422
+ "if false {2} elsif true {5}" => 5,
423
+ "if false {2} elsif false {5}" => nil,
424
+ "unless false {5}" => 5,
425
+ "unless true {5}" => nil,
426
+ "unless true {2} else {5}" => 5,
427
+ "$a = if true {5} $a" => 5,
428
+ "$a = if false {5} $a" => nil,
429
+ "$a = if false {2} else {5} $a" => 5,
430
+ "$a = if false {2} elsif true {5} $a" => 5,
431
+ "$a = if false {2} elsif false {5} $a" => nil,
432
+ "$a = unless false {5} $a" => 5,
433
+ "$a = unless true {5} $a" => nil,
434
+ "$a = unless true {2} else {5} $a" => 5,
435
+ }.each do |source, result|
436
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
437
+ parser.evaluate_string(scope, source, __FILE__).should == result
438
+ end
439
+ end
440
+
441
+ {
442
+ "case 1 { 1 : { yes } }" => 'yes',
443
+ "case 2 { 1,2,3 : { yes} }" => 'yes',
444
+ "case 2 { 1,3 : { no } 2: { yes} }" => 'yes',
445
+ "case 2 { 1,3 : { no } 5: { no } default: { yes }}" => 'yes',
446
+ "case 2 { 1,3 : { no } 5: { no } }" => nil,
447
+ "case 'banana' { 1,3 : { no } /.*ana.*/: { yes } }" => 'yes',
448
+ "case 'banana' { /.*(ana).*/: { $1 } }" => 'ana',
449
+ "case [1] { Array : { yes } }" => 'yes',
450
+ "case [1] {
451
+ Array[String] : { no }
452
+ Array[Integer]: { yes }
453
+ }" => 'yes',
454
+ "case 1 {
455
+ Integer : { yes }
456
+ Type[Integer] : { no } }" => 'yes',
457
+ "case Integer {
458
+ Integer : { no }
459
+ Type[Integer] : { yes } }" => 'yes',
460
+
461
+ }.each do |source, result|
462
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
463
+ parser.evaluate_string(scope, source, __FILE__).should == result
464
+ end
465
+ end
466
+
467
+ {
468
+ "2 ? { 1 => no, 2 => yes}" => 'yes',
469
+ "3 ? { 1 => no, 2 => no}" => nil,
470
+ "3 ? { 1 => no, 2 => no, default => yes }" => 'yes',
471
+ "3 ? { 1 => no, default => yes, 3 => no }" => 'yes',
472
+ "'banana' ? { /.*(ana).*/ => $1 }" => 'ana',
473
+ "[2] ? { Array[String] => yes, Array => yes}" => 'yes',
474
+ }.each do |source, result|
475
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
476
+ parser.evaluate_string(scope, source, __FILE__).should == result
477
+ end
478
+ end
479
+ end
480
+
481
+ context "When evaluator performs [] operations" do
482
+ {
483
+ "[1,2,3][0]" => 1,
484
+ "[1,2,3][2]" => 3,
485
+ "[1,2,3][3]" => nil,
486
+ "[1,2,3][-1]" => 3,
487
+ "[1,2,3][-2]" => 2,
488
+ "[1,2,3][-4]" => nil,
489
+ "[1,2,3,4][0,2]" => [1,2],
490
+ "[1,2,3,4][1,3]" => [2,3,4],
491
+ "[1,2,3,4][-2,2]" => [3,4],
492
+ "[1,2,3,4][-3,2]" => [2,3],
493
+ "[1,2,3,4][3,5]" => [4],
494
+ "[1,2,3,4][5,2]" => [],
495
+ "[1,2,3,4][0,-1]" => [1,2,3,4],
496
+ "[1,2,3,4][0,-2]" => [1,2,3],
497
+ "[1,2,3,4][0,-4]" => [1],
498
+ "[1,2,3,4][0,-5]" => [],
499
+ "[1,2,3,4][-5,2]" => [1],
500
+ "[1,2,3,4][-5,-3]" => [1,2],
501
+ "[1,2,3,4][-6,-3]" => [1,2],
502
+ "[1,2,3,4][2,-3]" => [],
503
+ }.each do |source, result|
504
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
505
+ parser.evaluate_string(scope, source, __FILE__).should == result
506
+ end
507
+ end
508
+
509
+ {
510
+ "{a=>1, b=>2, c=>3}[a]" => 1,
511
+ "{a=>1, b=>2, c=>3}[c]" => 3,
512
+ "{a=>1, b=>2, c=>3}[x]" => nil,
513
+ "{a=>1, b=>2, c=>3}[c,b]" => [3,2],
514
+ "{a=>1, b=>2, c=>3}[a,b,c]" => [1,2,3],
515
+ "{a=>{b=>{c=>'it works'}}}[a][b][c]" => 'it works',
516
+ "$a = {undef => 10} $a[free_lunch]" => nil,
517
+ "$a = {undef => 10} $a[undef]" => 10,
518
+ "$a = {undef => 10} $a[$a[free_lunch]]" => 10,
519
+ "$a = {} $a[free_lunch] == undef" => true,
520
+ }.each do |source, result|
521
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
522
+ parser.evaluate_string(scope, source, __FILE__).should == result
523
+ end
524
+ end
525
+
526
+ {
527
+ "'abc'[0]" => 'a',
528
+ "'abc'[2]" => 'c',
529
+ "'abc'[-1]" => 'c',
530
+ "'abc'[-2]" => 'b',
531
+ "'abc'[-3]" => 'a',
532
+ "'abc'[-4]" => '',
533
+ "'abc'[3]" => '',
534
+ "abc[0]" => 'a',
535
+ "abc[2]" => 'c',
536
+ "abc[-1]" => 'c',
537
+ "abc[-2]" => 'b',
538
+ "abc[-3]" => 'a',
539
+ "abc[-4]" => '',
540
+ "abc[3]" => '',
541
+ "'abcd'[0,2]" => 'ab',
542
+ "'abcd'[1,3]" => 'bcd',
543
+ "'abcd'[-2,2]" => 'cd',
544
+ "'abcd'[-3,2]" => 'bc',
545
+ "'abcd'[3,5]" => 'd',
546
+ "'abcd'[5,2]" => '',
547
+ "'abcd'[0,-1]" => 'abcd',
548
+ "'abcd'[0,-2]" => 'abc',
549
+ "'abcd'[0,-4]" => 'a',
550
+ "'abcd'[0,-5]" => '',
551
+ "'abcd'[-5,2]" => 'a',
552
+ "'abcd'[-5,-3]" => 'ab',
553
+ "'abcd'[-6,-3]" => 'ab',
554
+ "'abcd'[2,-3]" => '',
555
+ }.each do |source, result|
556
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
557
+ parser.evaluate_string(scope, source, __FILE__).should == result
558
+ end
559
+ end
560
+
561
+ # Type operations (full set tested by tests covering type calculator)
562
+ {
563
+ "Array[Integer]" => types.array_of(types.integer),
564
+ "Array[Integer,1]" => types.constrain_size(types.array_of(types.integer),1, :default),
565
+ "Array[Integer,1,2]" => types.constrain_size(types.array_of(types.integer),1, 2),
566
+ "Array[Integer,Integer[1,2]]" => types.constrain_size(types.array_of(types.integer),1, 2),
567
+ "Array[Integer,Integer[1]]" => types.constrain_size(types.array_of(types.integer),1, :default),
568
+ "Hash[Integer,Integer]" => types.hash_of(types.integer, types.integer),
569
+ "Hash[Integer,Integer,1]" => types.constrain_size(types.hash_of(types.integer, types.integer),1, :default),
570
+ "Hash[Integer,Integer,1,2]" => types.constrain_size(types.hash_of(types.integer, types.integer),1, 2),
571
+ "Hash[Integer,Integer,Integer[1,2]]" => types.constrain_size(types.hash_of(types.integer, types.integer),1, 2),
572
+ "Hash[Integer,Integer,Integer[1]]" => types.constrain_size(types.hash_of(types.integer, types.integer),1, :default),
573
+ "Resource[File]" => types.resource('File'),
574
+ "Resource['File']" => types.resource(types.resource('File')),
575
+ "File[foo]" => types.resource('file', 'foo'),
576
+ "File[foo, bar]" => [types.resource('file', 'foo'), types.resource('file', 'bar')],
577
+ "Pattern[a, /b/, Pattern[c], Regexp[d]]" => types.pattern('a', 'b', 'c', 'd'),
578
+ "String[1,2]" => types.constrain_size(types.string,1, 2),
579
+ "String[Integer[1,2]]" => types.constrain_size(types.string,1, 2),
580
+ "String[Integer[1]]" => types.constrain_size(types.string,1, :default),
581
+ }.each do |source, result|
582
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
583
+ parser.evaluate_string(scope, source, __FILE__).should == result
584
+ end
585
+ end
586
+
587
+ # LHS where [] not supported, and missing key(s)
588
+ {
589
+ "Array[]" => :error,
590
+ "'abc'[]" => :error,
591
+ "Resource[]" => :error,
592
+ "File[]" => :error,
593
+ "String[]" => :error,
594
+ "1[]" => :error,
595
+ "3.14[]" => :error,
596
+ "/.*/[]" => :error,
597
+ "$a=[1] $a[]" => :error,
598
+ }.each do |source, result|
599
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
600
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(/Syntax error/)
601
+ end
602
+ end
603
+
604
+ # Errors when wrong number/type of keys are used
605
+ {
606
+ "Array[0]" => 'Array-Type[] arguments must be types. Got Fixnum',
607
+ "Hash[0]" => 'Hash-Type[] arguments must be types. Got Fixnum',
608
+ "Hash[Integer, 0]" => 'Hash-Type[] arguments must be types. Got Fixnum',
609
+ "Array[Integer,1,2,3]" => 'Array-Type[] accepts 1 to 3 arguments. Got 4',
610
+ "Array[Integer,String]" => "A Type's size constraint arguments must be a single Integer type, or 1-2 integers (or default). Got a String-Type",
611
+ "Hash[Integer,String, 1,2,3]" => 'Hash-Type[] accepts 1 to 4 arguments. Got 5',
612
+ "'abc'[x]" => "The value 'x' cannot be converted to Numeric",
613
+ "'abc'[1.0]" => "A String[] cannot use Float where Integer is expected",
614
+ "'abc'[1,2,3]" => "String supports [] with one or two arguments. Got 3",
615
+ "Resource[0]" => 'First argument to Resource[] must be a resource type or a String. Got Fixnum',
616
+ "Resource[a, 0]" => 'Error creating type specialization of a Resource-Type, Cannot use Fixnum where String is expected',
617
+ "File[0]" => 'Error creating type specialization of a File-Type, Cannot use Fixnum where String is expected',
618
+ "String[a]" => "A Type's size constraint arguments must be a single Integer type, or 1-2 integers (or default). Got a String",
619
+ "Pattern[0]" => 'Error creating type specialization of a Pattern-Type, Cannot use Fixnum where String or Regexp or Pattern-Type or Regexp-Type is expected',
620
+ "Regexp[0]" => 'Error creating type specialization of a Regexp-Type, Cannot use Fixnum where String or Regexp is expected',
621
+ "Regexp[a,b]" => 'A Regexp-Type[] accepts 1 argument. Got 2',
622
+ "true[0]" => "Operator '[]' is not applicable to a Boolean",
623
+ "1[0]" => "Operator '[]' is not applicable to an Integer",
624
+ "3.14[0]" => "Operator '[]' is not applicable to a Float",
625
+ "/.*/[0]" => "Operator '[]' is not applicable to a Regexp",
626
+ "[1][a]" => "The value 'a' cannot be converted to Numeric",
627
+ "[1][0.0]" => "An Array[] cannot use Float where Integer is expected",
628
+ "[1]['0.0']" => "An Array[] cannot use Float where Integer is expected",
629
+ "[1,2][1, 0.0]" => "An Array[] cannot use Float where Integer is expected",
630
+ "[1,2][1.0, -1]" => "An Array[] cannot use Float where Integer is expected",
631
+ "[1,2][1, -1.0]" => "An Array[] cannot use Float where Integer is expected",
632
+ }.each do |source, result|
633
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
634
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(Regexp.new(Regexp.quote(result)))
635
+ end
636
+ end
637
+
638
+ context "on catalog types" do
639
+ it "[n] gets resource parameter [n]" do
640
+ source = "notify { 'hello': message=>'yo'} Notify[hello][message]"
641
+ parser.evaluate_string(scope, source, __FILE__).should == 'yo'
642
+ end
643
+
644
+ it "[n] gets class parameter [n]" do
645
+ source = "class wonka($produces='chocolate'){ }
646
+ include wonka
647
+ Class[wonka][produces]"
648
+
649
+ # This is more complicated since it needs to run like 3.x and do an import_ast
650
+ adapted_parser = Puppet::Parser::E4ParserAdapter.new
651
+ adapted_parser.file = __FILE__
652
+ ast = adapted_parser.parse(source)
653
+ scope.known_resource_types.import_ast(ast, '')
654
+ ast.code.safeevaluate(scope).should == 'chocolate'
655
+ end
656
+
657
+ # Resource default and override expressions and resource parameter access with []
658
+ {
659
+ "notify { id: message=>explicit} Notify[id][message]" => "explicit",
660
+ "Notify { message=>by_default} notify {foo:} Notify[foo][message]" => "by_default",
661
+ "notify {foo:} Notify[foo]{message =>by_override} Notify[foo][message]" => "by_override",
662
+ }.each do |source, result|
663
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
664
+ parser.evaluate_string(scope, source, __FILE__).should == result
665
+ end
666
+ end
667
+
668
+ # Resource default and override expressions and resource parameter access error conditions
669
+ {
670
+ "notify { xid: message=>explicit} Notify[id][message]" => /Resource not found/,
671
+ "notify { id: message=>explicit} Notify[id][mustard]" => /does not have a parameter called 'mustard'/,
672
+ }.each do |source, result|
673
+ it "should parse '#{source}' and raise error matching #{result}" do
674
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(result)
675
+ end
676
+ end
677
+
678
+ context 'with errors' do
679
+ { "Class['fail-whale']" => /Illegal name/,
680
+ "Class[0]" => /An Integer cannot be used where a String is expected/,
681
+ "Class[/.*/]" => /A Regexp cannot be used where a String is expected/,
682
+ "Class[4.1415]" => /A Float cannot be used where a String is expected/,
683
+ "Class[Integer]" => /An Integer-Type cannot be used where a String is expected/,
684
+ "Class[File['tmp']]" => /A File\['tmp'\] Resource-Reference cannot be used where a String is expected/,
685
+ }.each do | source, error_pattern|
686
+ it "an error is flagged for '#{source}'" do
687
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(error_pattern)
688
+ end
689
+ end
690
+ end
691
+ end
692
+ # end [] operations
693
+ end
694
+
695
+ context "When the evaluator performs boolean operations" do
696
+ {
697
+ "true and true" => true,
698
+ "false and true" => false,
699
+ "true and false" => false,
700
+ "false and false" => false,
701
+ "true or true" => true,
702
+ "false or true" => true,
703
+ "true or false" => true,
704
+ "false or false" => false,
705
+ "! true" => false,
706
+ "!! true" => true,
707
+ "!! false" => false,
708
+ "! 'x'" => false,
709
+ "! ''" => true,
710
+ "! undef" => true,
711
+ "! [a]" => false,
712
+ "! []" => false,
713
+ "! {a=>1}" => false,
714
+ "! {}" => false,
715
+ "true and false and '0xwtf' + 1" => false,
716
+ "false or true or '0xwtf' + 1" => true,
717
+ }.each do |source, result|
718
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
719
+ parser.evaluate_string(scope, source, __FILE__).should == result
720
+ end
721
+ end
722
+
723
+ {
724
+ "false || false || '0xwtf' + 1" => :error,
725
+ }.each do |source, result|
726
+ it "should parse and raise error for '#{source}'" do
727
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
728
+ end
729
+ end
730
+ end
731
+
732
+ context "When evaluator performs operations on literal undef" do
733
+ it "computes non existing hash lookup as undef" do
734
+ parser.evaluate_string(scope, "{a => 1}[b] == undef", __FILE__).should == true
735
+ parser.evaluate_string(scope, "undef == {a => 1}[b]", __FILE__).should == true
736
+ end
737
+ end
738
+
739
+ context "When evaluator performs calls" do
740
+ let(:populate) do
741
+ parser.evaluate_string(scope, "$a = 10 $b = [1,2,3]")
742
+ end
743
+
744
+ {
745
+ 'sprintf( "x%iy", $a )' => "x10y",
746
+ '"x%iy".sprintf( $a )' => "x10y",
747
+ '$b.reduce |$memo,$x| { $memo + $x }' => 6,
748
+ 'reduce($b) |$memo,$x| { $memo + $x }' => 6,
749
+ }.each do |source, result|
750
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
751
+ populate
752
+ parser.evaluate_string(scope, source, __FILE__).should == result
753
+ end
754
+ end
755
+
756
+ {
757
+ '"value is ${a*2} yo"' => :error,
758
+ }.each do |source, result|
759
+ it "should parse and raise error for '#{source}'" do
760
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
761
+ end
762
+ end
763
+ end
764
+
765
+ context "When evaluator performs string interpolation" do
766
+ let(:populate) do
767
+ parser.evaluate_string(scope, "$a = 10 $b = [1,2,3]")
768
+ end
769
+
770
+ {
771
+ '"value is $a yo"' => "value is 10 yo",
772
+ '"value is \$a yo"' => "value is $a yo",
773
+ '"value is ${a} yo"' => "value is 10 yo",
774
+ '"value is \${a} yo"' => "value is ${a} yo",
775
+ '"value is ${$a} yo"' => "value is 10 yo",
776
+ '"value is ${$a*2} yo"' => "value is 20 yo",
777
+ '"value is ${sprintf("x%iy",$a)} yo"' => "value is x10y yo",
778
+ '"value is ${"x%iy".sprintf($a)} yo"' => "value is x10y yo",
779
+ '"value is ${[1,2,3]} yo"' => "value is [1, 2, 3] yo",
780
+ '"value is ${/.*/} yo"' => "value is /.*/ yo",
781
+ '$x = undef "value is $x yo"' => "value is yo",
782
+ '$x = default "value is $x yo"' => "value is default yo",
783
+ '$x = Array[Integer] "value is $x yo"' => "value is Array[Integer] yo",
784
+ '"value is ${Array[Integer]} yo"' => "value is Array[Integer] yo",
785
+ }.each do |source, result|
786
+ it "should parse and evaluate the expression '#{source}' to #{result}" do
787
+ populate
788
+ parser.evaluate_string(scope, source, __FILE__).should == result
789
+ end
790
+ end
791
+
792
+ it "should parse and evaluate an interpolation of a hash" do
793
+ source = '"value is ${{a=>1,b=>2}} yo"'
794
+ # This test requires testing against two options because a hash to string
795
+ # produces a result that is unordered
796
+ hashstr = {'a' => 1, 'b' => 2}.to_s
797
+ alt_results = ["value is {a => 1, b => 2} yo", "value is {b => 2, a => 1} yo" ]
798
+ populate
799
+ parse_result = parser.evaluate_string(scope, source, __FILE__)
800
+ alt_results.include?(parse_result).should == true
801
+ end
802
+
803
+ {
804
+ '"value is ${a*2} yo"' => :error,
805
+ }.each do |source, result|
806
+ it "should parse and raise error for '#{source}'" do
807
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(Puppet::ParseError)
808
+ end
809
+ end
810
+ end
811
+
812
+ context "When evaluating variables" do
813
+ context "that are non existing an error is raised for" do
814
+ it "unqualified variable" do
815
+ expect { parser.evaluate_string(scope, "$quantum_gravity", __FILE__) }.to raise_error(/Unknown variable/)
816
+ end
817
+
818
+ it "qualified variable" do
819
+ expect { parser.evaluate_string(scope, "$quantum_gravity::graviton", __FILE__) }.to raise_error(/Unknown variable/)
820
+ end
821
+ end
822
+
823
+ it "a lex error should be raised for '$foo::::bar'" do
824
+ expect { parser.evaluate_string(scope, "$foo::::bar") }.to raise_error(Puppet::LexError, /Illegal fully qualified name at line 1:7/)
825
+ end
826
+
827
+ { '$a = $0' => nil,
828
+ '$a = $1' => nil,
829
+ }.each do |source, value|
830
+ it "it is ok to reference numeric unassigned variables '#{source}'" do
831
+ parser.evaluate_string(scope, source, __FILE__).should == value
832
+ end
833
+ end
834
+
835
+ { '$00 = 0' => /must be a decimal value/,
836
+ '$0xf = 0' => /must be a decimal value/,
837
+ '$0777 = 0' => /must be a decimal value/,
838
+ '$123a = 0' => /must be a decimal value/,
839
+ }.each do |source, error_pattern|
840
+ it "should raise an error for '#{source}'" do
841
+ expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(error_pattern)
842
+ end
843
+ end
844
+
845
+ context "an initial underscore in the last segment of a var name is allowed" do
846
+ { '$_a = 1' => 1,
847
+ '$__a = 1' => 1,
848
+ }.each do |source, value|
849
+ it "as in this example '#{source}'" do
850
+ parser.evaluate_string(scope, source, __FILE__).should == value
851
+ end
852
+ end
853
+ end
854
+ end
855
+
856
+ context "When evaluating relationships" do
857
+ it 'should form a relation with File[a] -> File[b]' do
858
+ source = "File[a] -> File[b]"
859
+ parser.evaluate_string(scope, source, __FILE__)
860
+ scope.compiler.should have_relationship(['File', 'a', '->', 'File', 'b'])
861
+ end
862
+
863
+ it 'should form a relation with resource -> resource' do
864
+ source = "notify{a:} -> notify{b:}"
865
+ parser.evaluate_string(scope, source, __FILE__)
866
+ scope.compiler.should have_relationship(['Notify', 'a', '->', 'Notify', 'b'])
867
+ end
868
+
869
+ it 'should form a relation with [File[a], File[b]] -> [File[x], File[y]]' do
870
+ source = "[File[a], File[b]] -> [File[x], File[y]]"
871
+ parser.evaluate_string(scope, source, __FILE__)
872
+ scope.compiler.should have_relationship(['File', 'a', '->', 'File', 'x'])
873
+ scope.compiler.should have_relationship(['File', 'b', '->', 'File', 'x'])
874
+ scope.compiler.should have_relationship(['File', 'a', '->', 'File', 'y'])
875
+ scope.compiler.should have_relationship(['File', 'b', '->', 'File', 'y'])
876
+ end
877
+
878
+ it 'should tolerate (eliminate) duplicates in operands' do
879
+ source = "[File[a], File[a]] -> File[x]"
880
+ parser.evaluate_string(scope, source, __FILE__)
881
+ scope.compiler.should have_relationship(['File', 'a', '->', 'File', 'x'])
882
+ scope.compiler.relationships.size.should == 1
883
+ end
884
+
885
+ it 'should form a relation with <-' do
886
+ source = "File[a] <- File[b]"
887
+ parser.evaluate_string(scope, source, __FILE__)
888
+ scope.compiler.should have_relationship(['File', 'b', '->', 'File', 'a'])
889
+ end
890
+
891
+ it 'should form a relation with <-' do
892
+ source = "File[a] <~ File[b]"
893
+ parser.evaluate_string(scope, source, __FILE__)
894
+ scope.compiler.should have_relationship(['File', 'b', '~>', 'File', 'a'])
895
+ end
896
+ end
897
+
898
+ context "When evaluating heredoc" do
899
+ it "evaluates plain heredoc" do
900
+ src = "@(END)\nThis is\nheredoc text\nEND\n"
901
+ parser.evaluate_string(scope, src).should == "This is\nheredoc text\n"
902
+ end
903
+
904
+ it "parses heredoc with margin" do
905
+ src = [
906
+ "@(END)",
907
+ " This is",
908
+ " heredoc text",
909
+ " | END",
910
+ ""
911
+ ].join("\n")
912
+ parser.evaluate_string(scope, src).should == "This is\nheredoc text\n"
913
+ end
914
+
915
+ it "parses heredoc with margin and right newline trim" do
916
+ src = [
917
+ "@(END)",
918
+ " This is",
919
+ " heredoc text",
920
+ " |- END",
921
+ ""
922
+ ].join("\n")
923
+ parser.evaluate_string(scope, src).should == "This is\nheredoc text"
924
+ end
925
+
926
+ it "parses escape specification" do
927
+ src = <<-CODE
928
+ @(END/t)
929
+ Tex\\tt\\n
930
+ |- END
931
+ CODE
932
+ parser.evaluate_string(scope, src).should == "Tex\tt\\n"
933
+ end
934
+
935
+ it "parses syntax checked specification" do
936
+ src = <<-CODE
937
+ @(END:json)
938
+ ["foo", "bar"]
939
+ |- END
940
+ CODE
941
+ parser.evaluate_string(scope, src).should == '["foo", "bar"]'
942
+ end
943
+
944
+ it "parses syntax checked specification with error and reports it" do
945
+ src = <<-CODE
946
+ @(END:json)
947
+ ['foo', "bar"]
948
+ |- END
949
+ CODE
950
+ expect { parser.evaluate_string(scope, src)}.to raise_error(/Cannot parse invalid JSON string/)
951
+ end
952
+
953
+ it "parses interpolated heredoc epression" do
954
+ src = <<-CODE
955
+ $name = 'Fjodor'
956
+ @("END")
957
+ Hello $name
958
+ |- END
959
+ CODE
960
+ parser.evaluate_string(scope, src).should == "Hello Fjodor"
961
+ end
962
+
963
+ end
964
+
965
+ context "Detailed Error messages are reported" do
966
+ it 'for illegal type references' do
967
+ source = '1+1 { "title": }'
968
+ # Error references position 5 at the opening '{'
969
+ # Set file to nil to make it easier to match with line number (no file name in output)
970
+ expect { parser.parse_string(source, nil) }.to raise_error(/Expression is not valid as a resource.*line 1:5/)
971
+ end
972
+
973
+ it 'for non r-value producing <| |>' do
974
+ expect { parser.parse_string("$a = File <| |>", nil) }.to raise_error(/A Virtual Query does not produce a value at line 1:6/)
975
+ end
976
+
977
+ it 'for non r-value producing <<| |>>' do
978
+ expect { parser.parse_string("$a = File <<| |>>", nil) }.to raise_error(/An Exported Query does not produce a value at line 1:6/)
979
+ end
980
+
981
+ it 'for non r-value producing define' do
982
+ Puppet.expects(:err).with("Invalid use of expression. A 'define' expression does not produce a value at line 1:6")
983
+ Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
984
+ expect { parser.parse_string("$a = define foo { }", nil) }.to raise_error(/2 errors/)
985
+ end
986
+
987
+ it 'for non r-value producing class' do
988
+ Puppet.expects(:err).with("Invalid use of expression. A Host Class Definition does not produce a value at line 1:6")
989
+ Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
990
+ expect { parser.parse_string("$a = class foo { }", nil) }.to raise_error(/2 errors/)
991
+ end
992
+
993
+ it 'for unclosed quote with indication of start position of string' do
994
+ source = <<-SOURCE.gsub(/^ {6}/,'')
995
+ $a = "xx
996
+ yyy
997
+ SOURCE
998
+ # first char after opening " reported as being in error.
999
+ expect { parser.parse_string(source) }.to raise_error(/Unclosed quote after '"' followed by 'xx\\nyy\.\.\.' at line 1:7/)
1000
+ end
1001
+
1002
+ it 'for multiple errors with a summary exception' do
1003
+ Puppet.expects(:err).with("Invalid use of expression. A Node Definition does not produce a value at line 1:6")
1004
+ Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
1005
+ expect { parser.parse_string("$a = node x { }",nil) }.to raise_error(/2 errors/)
1006
+ end
1007
+
1008
+ it 'for a bad hostname' do
1009
+ expect {
1010
+ parser.parse_string("node 'macbook+owned+by+name' { }", nil)
1011
+ }.to raise_error(/The hostname 'macbook\+owned\+by\+name' contains illegal characters.*at line 1:6/)
1012
+ end
1013
+
1014
+ it 'for a hostname with interpolation' do
1015
+ source = <<-SOURCE.gsub(/^ {6}/,'')
1016
+ $name = 'fred'
1017
+ node "macbook-owned-by$name" { }
1018
+ SOURCE
1019
+ expect {
1020
+ parser.parse_string(source, nil)
1021
+ }.to raise_error(/An interpolated expression is not allowed in a hostname of a node at line 2:23/)
1022
+ end
1023
+
1024
+ end
1025
+
1026
+ matcher :have_relationship do |expected|
1027
+ calc = Puppet::Pops::Types::TypeCalculator.new
1028
+
1029
+ match do |compiler|
1030
+ op_name = {'->' => :relationship, '~>' => :subscription}
1031
+ compiler.relationships.any? do | relation |
1032
+ relation.source.type == expected[0] &&
1033
+ relation.source.title == expected[1] &&
1034
+ relation.type == op_name[expected[2]] &&
1035
+ relation.target.type == expected[3] &&
1036
+ relation.target.title == expected[4]
1037
+ end
1038
+ end
1039
+
1040
+ failure_message_for_should do |actual|
1041
+ "Relationship #{expected[0]}[#{expected[1]}] #{expected[2]} #{expected[3]}[#{expected[4]}] but was unknown to compiler"
1042
+ end
1043
+ end
1044
+
1045
+ end