puppet 4.0.0 → 4.1.0

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

Potentially problematic release.


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

Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -46,7 +46,7 @@ describe 'Puppet::Pops::Impl::EvaluatorImpl' do
46
46
  end
47
47
 
48
48
  it "can not change a variable value in same scope" do
49
- expect { evaluate_l(block(var('a').set(10), var('a').set(20))) }.to raise_error(/Cannot reassign variable a/)
49
+ expect { evaluate_l(block(var('a').set(10), var('a').set(20))) }.to raise_error(/Cannot reassign variable '\$a'/)
50
50
  end
51
51
 
52
52
  context "access to numeric variables" do
@@ -62,19 +62,19 @@ describe "Puppet::Pops::IssueReporter" do
62
62
  end
63
63
 
64
64
  it "emits warnings if told to emit them" do
65
- Puppet.expects(:warning).twice.with(regexp_matches(/warning1|deprecation1/))
65
+ Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
66
66
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
67
67
  end
68
68
 
69
69
  it "does not emit warnings if not told to emit them" do
70
- Puppet.expects(:warning).never
70
+ Puppet::Log.expects(:create).never
71
71
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, {})
72
72
  end
73
73
 
74
74
  it "emits no warnings if :max_warnings is 0" do
75
75
  acceptor.accept( warning(2) )
76
76
  Puppet[:max_warnings] = 0
77
- Puppet.expects(:warning).once.with(regexp_matches(/deprecation1/))
77
+ Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/deprecation1/)))
78
78
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
79
79
  end
80
80
 
@@ -82,20 +82,20 @@ describe "Puppet::Pops::IssueReporter" do
82
82
  acceptor.accept( warning(2) )
83
83
  acceptor.accept( warning(3) )
84
84
  Puppet[:max_warnings] = 1
85
- Puppet.expects(:warning).twice.with(regexp_matches(/warning1|deprecation1/))
85
+ Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
86
86
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
87
87
  end
88
88
 
89
89
  it "does not emit more deprecations warnings than the max deprecation warnings" do
90
90
  acceptor.accept( deprecation(2) )
91
91
  Puppet[:max_deprecations] = 0
92
- Puppet.expects(:warning).once.with(regexp_matches(/warning1/))
92
+ Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/warning1/)))
93
93
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
94
94
  end
95
95
 
96
96
  it "does not emit deprecation warnings, but does emit regular warnings if disable_warnings includes deprecations" do
97
97
  Puppet[:disable_warnings] = 'deprecations'
98
- Puppet.expects(:warning).once.with(regexp_matches(/warning1/))
98
+ Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/warning1/)))
99
99
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
100
100
  end
101
101
  end
@@ -103,7 +103,7 @@ describe "Puppet::Pops::IssueReporter" do
103
103
  context "given errors" do
104
104
  it "logs nothing, but raises the given :message if :emit_errors is repressing error logging" do
105
105
  acceptor.accept( error(1) )
106
- Puppet.expects(:err).never
106
+ Puppet::Log.expects(:create).never
107
107
  expect do
108
108
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_errors => false, :message => 'special'})
109
109
  end.to raise_error(Puppet::ParseError, 'special')
@@ -111,7 +111,7 @@ describe "Puppet::Pops::IssueReporter" do
111
111
 
112
112
  it "prefixes :message if a single error is raised" do
113
113
  acceptor.accept( error(1) )
114
- Puppet.expects(:err).never
114
+ Puppet::Log.expects(:create).never
115
115
  expect do
116
116
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :message => 'special'})
117
117
  end.to raise_error(Puppet::ParseError, /special error1/)
@@ -119,7 +119,7 @@ describe "Puppet::Pops::IssueReporter" do
119
119
 
120
120
  it "logs nothing and raises immediately if there is only one error" do
121
121
  acceptor.accept( error(1) )
122
- Puppet.expects(:err).never
122
+ Puppet::Log.expects(:create).never
123
123
  expect do
124
124
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
125
125
  end.to raise_error(Puppet::ParseError, /error1/)
@@ -129,7 +129,7 @@ describe "Puppet::Pops::IssueReporter" do
129
129
  acceptor.accept( error(1) )
130
130
  acceptor.accept( error(2) )
131
131
  Puppet[:max_errors] = 0
132
- Puppet.expects(:err).never
132
+ Puppet::Log.expects(:create).never
133
133
  expect do
134
134
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
135
135
  end.to raise_error(Puppet::ParseError, /error1/)
@@ -138,7 +138,7 @@ describe "Puppet::Pops::IssueReporter" do
138
138
  it "logs the :message if there is more than one allowed error" do
139
139
  acceptor.accept( error(1) )
140
140
  acceptor.accept( error(2) )
141
- Puppet.expects(:err).times(3).with(regexp_matches(/error1|error2|special/))
141
+ Puppet::Log.expects(:create).times(3).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2|special/)))
142
142
  expect do
143
143
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :message => 'special'})
144
144
  end.to raise_error(Puppet::ParseError, /Giving up/)
@@ -149,7 +149,7 @@ describe "Puppet::Pops::IssueReporter" do
149
149
  acceptor.accept( error(2) )
150
150
  acceptor.accept( error(3) )
151
151
  Puppet[:max_errors] = 2
152
- Puppet.expects(:err).times(2).with(regexp_matches(/error1|error2/))
152
+ Puppet::Log.expects(:create).times(2).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2/)))
153
153
  expect do
154
154
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
155
155
  end.to raise_error(Puppet::ParseError, /3 errors.*Giving up/)
@@ -160,7 +160,7 @@ describe "Puppet::Pops::IssueReporter" do
160
160
  acceptor.accept( error(2) )
161
161
  acceptor.accept( error(3) )
162
162
  Puppet[:max_errors] = 4
163
- Puppet.expects(:err).times(3).with(regexp_matches(/error[123]/))
163
+ Puppet::Log.expects(:create).times(3).with(has_entries(:level => :err, :message => regexp_matches(/error[123]/)))
164
164
  expect do
165
165
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
166
166
  end.to raise_error(Puppet::ParseError, /3 errors.*Giving up/)
@@ -170,7 +170,7 @@ describe "Puppet::Pops::IssueReporter" do
170
170
  acceptor.accept( error(1) )
171
171
  acceptor.accept( error(2) )
172
172
  Puppet[:disable_warnings] = 'deprecations'
173
- Puppet.expects(:err).times(2).with(regexp_matches(/error1|error2/))
173
+ Puppet::Log.expects(:create).times(2).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2/)))
174
174
  expect do
175
175
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
176
176
  end.to raise_error(Puppet::ParseError, /Giving up/)
@@ -186,8 +186,8 @@ describe "Puppet::Pops::IssueReporter" do
186
186
  acceptor.accept( error(3) )
187
187
  acceptor.accept( deprecation(1) )
188
188
  Puppet[:max_errors] = 2
189
- Puppet.expects(:warning).twice.with(regexp_matches(/warning1|deprecation1/))
190
- Puppet.expects(:err).times(2).with(regexp_matches(/error[123]/))
189
+ Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
190
+ Puppet::Log.expects(:create).twice.with(has_entries(:level => :err, :message => regexp_matches(/error[123]/)))
191
191
  expect do
192
192
  Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
193
193
  end.to raise_error(Puppet::ParseError, /3 errors.*2 warnings.*Giving up/)
@@ -27,6 +27,7 @@ describe 'loaders' do
27
27
  include PuppetSpec::Files
28
28
 
29
29
  let(:module_without_metadata) { File.join(config_dir('wo_metadata_module'), 'modules') }
30
+ let(:module_without_lib) { File.join(config_dir('module_no_lib'), 'modules') }
30
31
  let(:mix_4x_and_3x_functions) { config_dir('mix_4x_and_3x_functions') }
31
32
  let(:module_with_metadata) { File.join(config_dir('single_module'), 'modules') }
32
33
  let(:dependent_modules_with_metadata) { config_dir('dependent_modules_with_metadata') }
@@ -49,70 +50,138 @@ describe 'loaders' do
49
50
  expect(loaders.private_environment_loader().to_s).to eql("(DependencyLoader 'environment' [])")
50
51
  end
51
52
 
52
- it 'can load a function using a qualified or unqualified name from a module with metadata' do
53
- loaders = Puppet::Pops::Loaders.new(environment_for(module_with_metadata))
54
- modulea_loader = loaders.public_loader_for_module('modulea')
53
+ context 'when loading from a module' do
54
+ it 'loads a ruby function using a qualified or unqualified name' do
55
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_with_metadata))
56
+ modulea_loader = loaders.public_loader_for_module('modulea')
55
57
 
56
- unqualified_function = modulea_loader.load_typed(typed_name(:function, 'rb_func_a')).value
57
- qualified_function = modulea_loader.load_typed(typed_name(:function, 'modulea::rb_func_a')).value
58
+ unqualified_function = modulea_loader.load_typed(typed_name(:function, 'rb_func_a')).value
59
+ qualified_function = modulea_loader.load_typed(typed_name(:function, 'modulea::rb_func_a')).value
58
60
 
59
- expect(unqualified_function).to be_a(Puppet::Functions::Function)
60
- expect(qualified_function).to be_a(Puppet::Functions::Function)
61
- expect(unqualified_function.class.name).to eq('rb_func_a')
62
- expect(qualified_function.class.name).to eq('modulea::rb_func_a')
63
- end
61
+ expect(unqualified_function).to be_a(Puppet::Functions::Function)
62
+ expect(qualified_function).to be_a(Puppet::Functions::Function)
63
+ expect(unqualified_function.class.name).to eq('rb_func_a')
64
+ expect(qualified_function.class.name).to eq('modulea::rb_func_a')
65
+ end
64
66
 
65
- it 'can load a function with a qualified name from module without metadata' do
66
- loaders = Puppet::Pops::Loaders.new(environment_for(module_without_metadata))
67
+ it 'loads a puppet function using a qualified name in module' do
68
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_with_metadata))
69
+ modulea_loader = loaders.public_loader_for_module('modulea')
67
70
 
68
- moduleb_loader = loaders.public_loader_for_module('moduleb')
69
- function = moduleb_loader.load_typed(typed_name(:function, 'moduleb::rb_func_b')).value
71
+ qualified_function = modulea_loader.load_typed(typed_name(:function, 'modulea::hello')).value
70
72
 
71
- expect(function).to be_a(Puppet::Functions::Function)
72
- expect(function.class.name).to eq('moduleb::rb_func_b')
73
- end
73
+ expect(qualified_function).to be_a(Puppet::Functions::Function)
74
+ expect(qualified_function.class.name).to eq('modulea::hello')
75
+ end
74
76
 
75
- it 'cannot load an unqualified function from a module without metadata' do
76
- loaders = Puppet::Pops::Loaders.new(environment_for(module_without_metadata))
77
+ it 'loads a puppet function from a module without a lib directory' do
78
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_without_lib))
79
+ modulea_loader = loaders.public_loader_for_module('modulea')
77
80
 
78
- moduleb_loader = loaders.public_loader_for_module('moduleb')
81
+ qualified_function = modulea_loader.load_typed(typed_name(:function, 'modulea::hello')).value
79
82
 
80
- expect(moduleb_loader.load_typed(typed_name(:function, 'rb_func_b'))).to be_nil
81
- end
83
+ expect(qualified_function).to be_a(Puppet::Functions::Function)
84
+ expect(qualified_function.class.name).to eq('modulea::hello')
85
+ end
82
86
 
83
- it 'makes all other modules visible to a module without metadata' do
84
- env = environment_for(module_with_metadata, module_without_metadata)
85
- loaders = Puppet::Pops::Loaders.new(env)
87
+ it 'loads a puppet function in a sub namespace of module' do
88
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_with_metadata))
89
+ modulea_loader = loaders.public_loader_for_module('modulea')
86
90
 
87
- moduleb_loader = loaders.private_loader_for_module('moduleb')
88
- function = moduleb_loader.load_typed(typed_name(:function, 'moduleb::rb_func_b')).value
91
+ qualified_function = modulea_loader.load_typed(typed_name(:function, 'modulea::subspace::hello')).value
89
92
 
90
- expect(function.call({})).to eql("I am modulea::rb_func_a() + I am moduleb::rb_func_b()")
93
+ expect(qualified_function).to be_a(Puppet::Functions::Function)
94
+ expect(qualified_function.class.name).to eq('modulea::subspace::hello')
95
+ end
96
+
97
+ it 'loader does not add namespace if not given' do
98
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_without_metadata))
99
+
100
+ moduleb_loader = loaders.public_loader_for_module('moduleb')
101
+
102
+ expect(moduleb_loader.load_typed(typed_name(:function, 'rb_func_b'))).to be_nil
103
+ end
104
+
105
+ it 'loader allows loading a function more than once' do
106
+ env = environment_for(dependent_modules_with_metadata)
107
+ loaders = Puppet::Pops::Loaders.new(env)
108
+
109
+ moduleb_loader = loaders.private_loader_for_module('user')
110
+ function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
111
+ expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
112
+
113
+ function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
114
+ expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
115
+ end
116
+ end
117
+
118
+ context 'when loading from a module with metadata' do
119
+ it 'all dependent modules are visible' do
120
+ env = environment_for(dependent_modules_with_metadata)
121
+ loaders = Puppet::Pops::Loaders.new(env)
122
+
123
+ moduleb_loader = loaders.private_loader_for_module('user')
124
+ function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
125
+ expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
126
+ end
91
127
  end
92
128
 
93
- it 'makes dependent modules visible to a module with metadata' do
94
- env = environment_for(dependent_modules_with_metadata)
95
- loaders = Puppet::Pops::Loaders.new(env)
129
+ context 'when loading from a module without metadata' do
130
+ it 'loads a ruby function with a qualified name' do
131
+ loaders = Puppet::Pops::Loaders.new(environment_for(module_without_metadata))
96
132
 
97
- moduleb_loader = loaders.private_loader_for_module('user')
98
- function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
133
+ moduleb_loader = loaders.public_loader_for_module('moduleb')
134
+ function = moduleb_loader.load_typed(typed_name(:function, 'moduleb::rb_func_b')).value
135
+
136
+ expect(function).to be_a(Puppet::Functions::Function)
137
+ expect(function.class.name).to eq('moduleb::rb_func_b')
138
+ end
99
139
 
100
- expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
140
+
141
+ it 'all other modules are visible' do
142
+ env = environment_for(module_with_metadata, module_without_metadata)
143
+ loaders = Puppet::Pops::Loaders.new(env)
144
+
145
+ moduleb_loader = loaders.private_loader_for_module('moduleb')
146
+ function = moduleb_loader.load_typed(typed_name(:function, 'moduleb::rb_func_b')).value
147
+
148
+ expect(function.call({})).to eql("I am modulea::rb_func_a() + I am moduleb::rb_func_b()")
149
+ end
101
150
  end
102
151
 
103
- context 'with scope' do
152
+ context 'when calling' do
104
153
  let(:env) { environment_for(mix_4x_and_3x_functions) }
105
154
  let(:scope) { Puppet::Parser::Compiler.new(Puppet::Node.new("test", :environment => env)).newscope(nil) }
106
155
  let(:loader) { Puppet::Pops::Loaders.new(env).private_loader_for_module('user') }
107
156
 
108
- it 'can call 3x function in dependent module from a 4x function' do
157
+ it 'a 3x function in dependent module can be called from a 4x function' do
109
158
  Puppet.override({ :current_environment => scope.environment, :global_scope => scope }) do
110
159
  function = loader.load_typed(typed_name(:function, 'user::caller')).value
111
160
  expect(function.call(scope)).to eql("usee::callee() got 'first' - usee::callee() got 'second'")
112
161
  end
113
162
  end
114
163
 
115
- it 'can call 3x function and propagate caller scope from a 4x function' do
164
+ it 'a 3x function in dependent module can be called from a puppet function' do
165
+ Puppet.override({ :current_environment => scope.environment, :global_scope => scope }) do
166
+ function = loader.load_typed(typed_name(:function, 'user::puppetcaller')).value
167
+ expect(function.call(scope)).to eql("usee::callee() got 'first' - usee::callee() got 'second'")
168
+ end
169
+ end
170
+
171
+ it 'a 4x function can be called from a puppet function' do
172
+ Puppet.override({ :current_environment => scope.environment, :global_scope => scope }) do
173
+ function = loader.load_typed(typed_name(:function, 'user::puppetcaller4')).value
174
+ expect(function.call(scope)).to eql("usee::callee() got 'first' - usee::callee() got 'second'")
175
+ end
176
+ end
177
+ it 'a puppet function can be called from a 4x function' do
178
+ Puppet.override({ :current_environment => scope.environment, :global_scope => scope }) do
179
+ function = loader.load_typed(typed_name(:function, 'user::callingpuppet')).value
180
+ expect(function.call(scope)).to eql("Did you call to say you love me?")
181
+ end
182
+ end
183
+
184
+ it 'a 3x function can be called with caller scope propagated from a 4x function' do
116
185
  Puppet.override({ :current_environment => scope.environment, :global_scope => scope }) do
117
186
  function = loader.load_typed(typed_name(:function, 'user::caller_ws')).value
118
187
  expect(function.call(scope, 'passed in scope')).to eql("usee::callee_ws() got 'passed in scope'")
@@ -120,17 +189,6 @@ describe 'loaders' do
120
189
  end
121
190
  end
122
191
 
123
- it 'can load a function more than once from modules' do
124
- env = environment_for(dependent_modules_with_metadata)
125
- loaders = Puppet::Pops::Loaders.new(env)
126
-
127
- moduleb_loader = loaders.private_loader_for_module('user')
128
- function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
129
- expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
130
-
131
- function = moduleb_loader.load_typed(typed_name(:function, 'user::caller')).value
132
- expect(function.call({})).to eql("usee::callee() was told 'passed value' + I am user::caller()")
133
- end
134
192
 
135
193
  def environment_for(*module_paths)
136
194
  Puppet::Node::Environment.create(:'*test*', module_paths)
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ require 'puppet/pops'
4
+ require 'puppet/pops/evaluator/evaluator_impl'
5
+ require 'puppet/loaders'
6
+ require 'puppet_spec/pops'
7
+ require 'puppet_spec/scope'
8
+ require 'puppet/parser/e4_parser_adapter'
9
+
10
+ describe 'Puppet::Pops::MigrationMigrationChecker' do
11
+ include PuppetSpec::Pops
12
+ include PuppetSpec::Scope
13
+ before(:each) do
14
+ Puppet[:strict_variables] = true
15
+
16
+ # Puppetx cannot be loaded until the correct parser has been set (injector is turned off otherwise)
17
+ require 'puppet_x'
18
+
19
+ # Tests needs a known configuration of node/scope/compiler since it parses and evaluates
20
+ # snippets as the compiler will evaluate them, butwithout the overhead of compiling a complete
21
+ # catalog for each tested expression.
22
+ #
23
+ @parser = Puppet::Pops::Parser::EvaluatingParser.new
24
+ @node = Puppet::Node.new('node.example.com')
25
+ @node.environment = Puppet::Node::Environment.create(:testing, [])
26
+ @compiler = Puppet::Parser::Compiler.new(@node)
27
+ @scope = Puppet::Parser::Scope.new(@compiler)
28
+ @scope.source = Puppet::Resource::Type.new(:node, 'node.example.com')
29
+ @scope.parent = @compiler.topscope
30
+ end
31
+
32
+ let(:scope) { @scope }
33
+
34
+ describe "when there is no MigrationChecker in the PuppetContext" do
35
+ it "a null implementation of the MigrationChecker gets created (once per impl that needs one)" do
36
+ migration_checker = Puppet::Pops::Migration::MigrationChecker.new()
37
+ Puppet::Pops::Migration::MigrationChecker.expects(:new).at_least_once.returns(migration_checker)
38
+ expect(Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "1", __FILE__)).to eq(1)
39
+ Puppet::Pops::Migration::MigrationChecker.unstub(:new)
40
+ end
41
+ end
42
+
43
+ describe "when there is a MigrationChecker in the Puppet Context" do
44
+ it "does not create any MigrationChecker instances when parsing and evaluating" do
45
+ migration_checker = mock()
46
+ Puppet::Pops::Migration::MigrationChecker.expects(:new).never
47
+ Puppet.override({:migration_checker => migration_checker}, "test-context") do
48
+ Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "true", __FILE__)
49
+ end
50
+ Puppet::Pops::Migration::MigrationChecker.unstub(:new)
51
+ end
52
+ end
53
+ end
@@ -234,6 +234,19 @@ describe 'Lexer2' do
234
234
  '"a${y::_x}"' => [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
235
235
  [:VARIABLE, 'y::_x', {:line => 1, :pos=>5, :length=>5 }],
236
236
  [:DQPOST, '', {:line => 1, :pos=>11, :length=>1 }]],
237
+
238
+ '"a${_x[1]}"' => [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
239
+ [:VARIABLE, '_x', {:line => 1, :pos=>5, :length=>2 }],
240
+ [:LBRACK, '[', {:line => 1, :pos=>7, :length=>1 }],
241
+ [:NUMBER, '1', {:line => 1, :pos=>8, :length=>1 }],
242
+ [:RBRACK, ']', {:line => 1, :pos=>9, :length=>1 }],
243
+ [:DQPOST, '', {:line => 1, :pos=>11, :length=>1 }]],
244
+
245
+ '"a${_x.foo}"'=> [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
246
+ [:VARIABLE, '_x', {:line => 1, :pos=>5, :length=>2 }],
247
+ [:DOT, '.', {:line => 1, :pos=>7, :length=>1 }],
248
+ [:NAME, 'foo', {:line => 1, :pos=>8, :length=>3 }],
249
+ [:DQPOST, '', {:line => 1, :pos=>12, :length=>1 }]],
237
250
  }.each do |source, expected|
238
251
  it "should lex an interpolated variable 'x' from #{source}" do
239
252
  expect(tokens_scanned_from(source)).to match_tokens2(*expected)
@@ -361,6 +374,63 @@ describe 'Lexer2' do
361
374
  [:DQPOST, " After"]
362
375
  )
363
376
  end
377
+
378
+ context 'with bad syntax' do
379
+ def expect_issue(code, issue)
380
+ expect { tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
381
+ expect(e.issue_code).to be(issue.issue_code)
382
+ }
383
+ end
384
+
385
+ it 'detects and reports HEREDOC_UNCLOSED_PARENTHESIS' do
386
+ code = <<-CODE
387
+ @(END:syntax/t
388
+ Text
389
+ |- END
390
+ CODE
391
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_UNCLOSED_PARENTHESIS)
392
+ end
393
+
394
+ it 'detects and reports HEREDOC_WITHOUT_END_TAGGED_LINE' do
395
+ code = <<-CODE
396
+ @(END:syntax/t)
397
+ Text
398
+ CODE
399
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_WITHOUT_END_TAGGED_LINE)
400
+ end
401
+
402
+ it 'detects and reports HEREDOC_INVALID_ESCAPE' do
403
+ code = <<-CODE
404
+ @(END:syntax/x)
405
+ Text
406
+ |- END
407
+ CODE
408
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_INVALID_ESCAPE)
409
+ end
410
+
411
+ it 'detects and reports HEREDOC_INVALID_SYNTAX' do
412
+ code = <<-CODE
413
+ @(END:syntax/t/p)
414
+ Text
415
+ |- END
416
+ CODE
417
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_INVALID_SYNTAX)
418
+ end
419
+
420
+ it 'detects and reports HEREDOC_WITHOUT_TEXT' do
421
+ code = '@(END:syntax/t)'
422
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_WITHOUT_TEXT)
423
+ end
424
+
425
+ it 'detects and reports HEREDOC_MULTIPLE_AT_ESCAPES' do
426
+ code = <<-CODE
427
+ @(END:syntax/tst)
428
+ Tex\\tt\\n
429
+ |- END
430
+ CODE
431
+ expect_issue(code, Puppet::Pops::Issues::HEREDOC_MULTIPLE_AT_ESCAPES)
432
+ end
433
+ end
364
434
  end
365
435
 
366
436
  context 'when dealing with multi byte characters' do
@@ -371,6 +441,12 @@ describe 'Lexer2' do
371
441
  # >= Ruby 1.9.3 reports \u
372
442
  expect(tokens_scanned_from(code)).to match_tokens2([:STRING, "x\u2713y"])
373
443
  end
444
+ it 'should support unicode characters in long form' do
445
+ code = <<-CODE
446
+ "x\\u{1f452}y"
447
+ CODE
448
+ expect(tokens_scanned_from(code)).to match_tokens2([:STRING, "x\u{1f452}y"])
449
+ end
374
450
 
375
451
  it 'should not select LISTSTART token when preceded by multibyte chars' do
376
452
  # This test is sensitive to the number of multibyte characters and position of the expressions
@@ -482,6 +558,71 @@ describe 'Lexer2' do
482
558
  [:RENDER_STRING, "<% this is escaped epp %>\n"]
483
559
  )
484
560
  end
561
+
562
+ context 'with bad epp syntax' do
563
+ def expect_issue(code, issue)
564
+ expect { epp_tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
565
+ expect(e.issue_code).to be(issue.issue_code)
566
+ }
567
+ end
568
+
569
+ it 'detects and reports EPP_UNBALANCED_TAG' do
570
+ expect_issue('<% asf', Puppet::Pops::Issues::EPP_UNBALANCED_TAG)
571
+ end
572
+
573
+ it 'detects and reports EPP_UNBALANCED_COMMENT' do
574
+ expect_issue('<%# asf', Puppet::Pops::Issues::EPP_UNBALANCED_COMMENT)
575
+ end
576
+
577
+ it 'detects and reports EPP_UNBALANCED_EXPRESSION' do
578
+ expect_issue('asf <%', Puppet::Pops::Issues::EPP_UNBALANCED_EXPRESSION)
579
+ end
580
+ end
485
581
  end
486
- end
487
582
 
583
+ context 'when parsing bad code' do
584
+ def expect_issue(code, issue)
585
+ expect { tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) do |e|
586
+ expect(e.issue_code).to be(issue.issue_code)
587
+ end
588
+ end
589
+
590
+ it 'detects and reports issue ILLEGAL_CLASS_REFERENCE' do
591
+ expect_issue('A::3', Puppet::Pops::Issues::ILLEGAL_CLASS_REFERENCE)
592
+ end
593
+
594
+ it 'detects and reports issue ILLEGAL_FULLY_QUALIFIED_CLASS_REFERENCE' do
595
+ expect_issue('::A::3', Puppet::Pops::Issues::ILLEGAL_FULLY_QUALIFIED_CLASS_REFERENCE)
596
+ end
597
+
598
+ it 'detects and reports issue ILLEGAL_FULLY_QUALIFIED_NAME' do
599
+ expect_issue('::a::3', Puppet::Pops::Issues::ILLEGAL_FULLY_QUALIFIED_NAME)
600
+ end
601
+
602
+ it 'detects and reports issue ILLEGAL_NUMBER' do
603
+ expect_issue('3g', Puppet::Pops::Issues::ILLEGAL_NUMBER)
604
+ end
605
+
606
+ it 'detects and reports issue INVALID_HEX_NUMBER' do
607
+ expect_issue('0x3g', Puppet::Pops::Issues::INVALID_HEX_NUMBER)
608
+ end
609
+
610
+ it 'detects and reports issue INVALID_OCTAL_NUMBER' do
611
+ expect_issue('038', Puppet::Pops::Issues::INVALID_OCTAL_NUMBER)
612
+ end
613
+
614
+ it 'detects and reports issue INVALID_DECIMAL_NUMBER' do
615
+ expect_issue('4.3g', Puppet::Pops::Issues::INVALID_DECIMAL_NUMBER)
616
+ end
617
+
618
+ it 'detects and reports issue NO_INPUT_TO_LEXER' do
619
+ expect { Puppet::Pops::Parser::Lexer2.new.fullscan }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
620
+ expect(e.issue_code).to be(Puppet::Pops::Issues::NO_INPUT_TO_LEXER.issue_code)
621
+ }
622
+ end
623
+
624
+ it 'detects and reports issue UNCLOSED_QUOTE' do
625
+ expect_issue('"asd', Puppet::Pops::Issues::UNCLOSED_QUOTE)
626
+ end
627
+ end
628
+ end