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
@@ -26,18 +26,20 @@ describe 'when calling' do
26
26
  expect(hiera.call(scope, 'key')).to eql('foo_result')
27
27
  end
28
28
 
29
- it 'should propagate optional default' do
30
- dflt = 'the_default'
31
- Hiera.any_instance.expects(:lookup).with { |*args| expect(args[1]).to be(dflt) }.returns('foo_result')
32
- expect(hiera.call(scope, 'key', dflt)).to eql('foo_result')
33
- end
34
-
35
29
  it 'should propagate optional override' do
36
30
  ovr = 'the_override'
37
31
  Hiera.any_instance.expects(:lookup).with { |*args| expect(args[3]).to be(ovr) }.returns('foo_result')
38
32
  expect(hiera.call(scope, 'key', nil, ovr)).to eql('foo_result')
39
33
  end
40
34
 
35
+ it 'should return default value nil when key is not found' do
36
+ expect(hiera.call(scope, 'foo', nil)).to be_nil
37
+ end
38
+
39
+ it "should return default value '' when key is not found" do
40
+ expect(hiera.call(scope, 'foo', '')).to eq('')
41
+ end
42
+
41
43
  it 'should use default block' do
42
44
  #expect(hiera.call(scope, 'foo', lambda_1(scope, loader) { |k| "default for key '#{k}'" })).to eql("default for key 'foo'")
43
45
  expect(hiera.call(scope, 'foo') { |k| "default for key '#{k}'" }).to eql("default for key 'foo'")
@@ -66,6 +66,10 @@ describe 'the regsubst function' do
66
66
  it 'should accept Type[Regexp]' do
67
67
  expect(regsubst('abc', type_parser.parse("Regexp['b']"), '_')).to eql('a_c')
68
68
  end
69
+
70
+ it 'should treat Regexp as Regexp[//]' do
71
+ expect(regsubst('abc', type_parser.parse("Regexp"), '_', 'G')).to eql('_a_b_c_')
72
+ end
69
73
  end
70
74
 
71
75
  context 'when using an array target' do
@@ -43,4 +43,12 @@ describe 'the split function' do
43
43
  it 'should handle pattern in Regexp Type form' do
44
44
  expect(split('a,b',type_parser.parse('Regexp[/,/]'))).to eql(['a', 'b'])
45
45
  end
46
+
47
+ it 'should handle pattern in Regexp Type form with empty regular expression' do
48
+ expect(split('ab',type_parser.parse('Regexp[//]'))).to eql(['a', 'b'])
49
+ end
50
+
51
+ it 'should handle pattern in Regexp Type form with missing regular expression' do
52
+ expect(split('ab',type_parser.parse('Regexp'))).to eql(['a', 'b'])
53
+ end
46
54
  end
@@ -177,7 +177,7 @@ actual:
177
177
  end
178
178
 
179
179
  it 'an error includes optional indicators and count for last element when defined via dispatch' do
180
- f = create_function_with_optionals_and_varargs_via_dispatch()
180
+ f = create_function_with_optionals_and_repeated_via_dispatch()
181
181
  # TODO: Bogus parameters, not yet used
182
182
  func = f.new(:closure_scope, :loader)
183
183
  expect(func.is_a?(Puppet::Functions::Function)).to be_truthy
@@ -191,6 +191,39 @@ actual:
191
191
  min(Integer) - arg count {1}")
192
192
  end
193
193
 
194
+ it 'can create optional repeated parameter' do
195
+ f = create_function_with_repeated
196
+ func = f.new(:closure_scope, :loader)
197
+ expect(func.call({})).to eql(0)
198
+ expect(func.call({}, 1)).to eql(1)
199
+ expect(func.call({}, 1, 2)).to eql(2)
200
+
201
+ f = create_function_with_optional_repeated
202
+ func = f.new(:closure_scope, :loader)
203
+ expect(func.call({})).to eql(0)
204
+ expect(func.call({}, 1)).to eql(1)
205
+ expect(func.call({}, 1, 2)).to eql(2)
206
+ end
207
+
208
+ it 'can create required repeated parameter' do
209
+ f = create_function_with_required_repeated
210
+ func = f.new(:closure_scope, :loader)
211
+ expect(func.call({}, 1)).to eql(1)
212
+ expect(func.call({}, 1, 2)).to eql(2)
213
+ expect { func.call({}) }.to raise_error(ArgumentError,
214
+ "function 'count_args' called with mis-matched arguments
215
+ expected:
216
+ count_args(Any c{1,}) - arg count {1,}
217
+ actual:
218
+ count_args(Undef{0}) - arg count {0}")
219
+ end
220
+
221
+ it 'can create scope_param followed by repeated parameter' do
222
+ f = create_function_with_scope_param_required_repeat
223
+ func = f.new(:closure_scope, :loader)
224
+ expect(func.call({}, 'yay', 1,2,3)).to eql([{}, 'yay',1,2,3])
225
+ end
226
+
194
227
  it 'a function can use inexact argument mapping' do
195
228
  f = create_function_with_inexact_dispatch
196
229
  func = f.new(:closure_scope, :loader)
@@ -213,6 +246,10 @@ actual:
213
246
  expect { create_function_with_rq_after_opt }.to raise_error(ArgumentError, 'A required parameter cannot be added after an optional parameter')
214
247
  end
215
248
 
249
+ it 'a function can not be created with required repeated parameters declared after optional ones' do
250
+ expect { create_function_with_rq_repeated_after_opt }.to raise_error(ArgumentError, 'A required repeated parameter cannot be added after an optional parameter')
251
+ end
252
+
216
253
  it 'an error is raised with reference to multiple methods when called with mis-matched arguments' do
217
254
  f = create_min_function_class_disptaching_to_two_methods()
218
255
  # TODO: Bogus parameters, not yet used
@@ -553,7 +590,7 @@ actual:
553
590
  end
554
591
  end
555
592
 
556
- def create_function_with_optionals_and_varargs_via_dispatch
593
+ def create_function_with_optionals_and_repeated_via_dispatch
557
594
  f = Puppet::Functions.create_function('min') do
558
595
  dispatch :min do
559
596
  param 'Numeric', :x
@@ -568,6 +605,39 @@ actual:
568
605
  end
569
606
  end
570
607
 
608
+ def create_function_with_repeated
609
+ f = Puppet::Functions.create_function('count_args') do
610
+ dispatch :count_args do
611
+ repeated_param 'Any', :c
612
+ end
613
+ def count_args(*c)
614
+ c.size
615
+ end
616
+ end
617
+ end
618
+
619
+ def create_function_with_optional_repeated
620
+ f = Puppet::Functions.create_function('count_args') do
621
+ dispatch :count_args do
622
+ optional_repeated_param 'Any', :c
623
+ end
624
+ def count_args(*c)
625
+ c.size
626
+ end
627
+ end
628
+ end
629
+
630
+ def create_function_with_required_repeated
631
+ f = Puppet::Functions.create_function('count_args') do
632
+ dispatch :count_args do
633
+ required_repeated_param 'Any', :c
634
+ end
635
+ def count_args(*c)
636
+ c.size
637
+ end
638
+ end
639
+ end
640
+
571
641
  def create_function_with_inexact_dispatch
572
642
  f = Puppet::Functions.create_function('t1') do
573
643
  dispatch :t1 do
@@ -598,6 +668,18 @@ actual:
598
668
  end
599
669
  end
600
670
 
671
+ def create_function_with_rq_repeated_after_opt
672
+ f = Puppet::Functions.create_function('t1') do
673
+ dispatch :t1 do
674
+ optional_param 'Numeric', :x
675
+ required_repeated_param 'Numeric', :y
676
+ end
677
+ def t1(x, *y)
678
+ x
679
+ end
680
+ end
681
+ end
682
+
601
683
  def create_function_with_param_after_repeated
602
684
  f = Puppet::Functions.create_function('t1') do
603
685
  dispatch :t1 do
@@ -682,6 +764,19 @@ actual:
682
764
  end
683
765
  end
684
766
 
767
+ def create_function_with_scope_param_required_repeat
768
+ f = Puppet::Functions.create_function('test', Puppet::Functions::InternalFunction) do
769
+ dispatch :test do
770
+ scope_param
771
+ param 'Any', :extra
772
+ repeated_param 'Any', :the_block
773
+ end
774
+ def test(scope, *args)
775
+ [scope, *args]
776
+ end
777
+ end
778
+ end
779
+
685
780
  def create_function_with_required_block_given_type
686
781
  f = Puppet::Functions.create_function('test') do
687
782
  dispatch :test do
@@ -43,6 +43,13 @@ describe Puppet::Node::Facts::Facter do
43
43
  @facter.find(@request)
44
44
  end
45
45
 
46
+ it 'should add the puppetversion fact' do
47
+ reset = sequence 'reset'
48
+ Facter.expects(:reset).in_sequence(reset)
49
+ Facter.expects(:add).with(:puppetversion)
50
+ @facter.find(@request)
51
+ end
52
+
46
53
  it 'should include external facts when feature is present' do
47
54
  reset = sequence 'reset'
48
55
  Puppet.features.stubs(:external_facts?).returns true
@@ -219,6 +219,12 @@ describe Puppet::Node, "when merging facts" do
219
219
  expect(@node.parameters["two"]).to eq("b")
220
220
  end
221
221
 
222
+ it "warns when a parameter value is not updated" do
223
+ @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
224
+ Puppet.expects(:warning).with('The node parameter \'one\' for node \'testnode\' was already set to \'a\'. It could not be set to \'b\'')
225
+ @node.merge "one" => "b"
226
+ end
227
+
222
228
  it "accepts arbitrary parameters to merge into its parameters" do
223
229
  @node = Puppet::Node.new("testnode", :parameters => {"one" => "a"})
224
230
  @node.merge "two" => "three"
@@ -15,7 +15,7 @@ describe "the 'file' function" do
15
15
 
16
16
  def with_file_content(content)
17
17
  path = tmpfile('file-function')
18
- file = File.new(path, 'w')
18
+ file = File.new(path, 'wb')
19
19
  file.sync = true
20
20
  file.print content
21
21
  yield path
@@ -27,6 +27,12 @@ describe "the 'file' function" do
27
27
  end
28
28
  end
29
29
 
30
+ it "should read a file keeping line endings intact" do
31
+ with_file_content("file content\r\n") do |name|
32
+ expect(scope.function_file([name])).to eq("file content\r\n")
33
+ end
34
+ end
35
+
30
36
  it "should read a file from a module path" do
31
37
  with_file_content('file content') do |name|
32
38
  mod = mock 'module'
@@ -82,7 +82,7 @@ describe "the template function" do
82
82
  end
83
83
 
84
84
  def eval_template(content)
85
- File.stubs(:read).with("template").returns(content)
85
+ Puppet::FileSystem.stubs(:read_preserve_line_endings).with("template").returns(content)
86
86
  Puppet::Parser::Files.stubs(:find_template).returns("template")
87
87
  scope.function_template(['template'])
88
88
  end
@@ -192,7 +192,7 @@ describe Puppet::Parser::Scope do
192
192
  @scope["var"] = "childval"
193
193
  expect {
194
194
  @scope["var"] = "change"
195
- }.to raise_error(Puppet::Error, "Cannot reassign variable var")
195
+ }.to raise_error(Puppet::Error, "Cannot reassign variable '$var'")
196
196
  end
197
197
 
198
198
  it "should be able to detect when variables are not set" do
@@ -305,7 +305,7 @@ describe Puppet::Parser::Scope do
305
305
  @scope.setvar("var", "1", :append => true)
306
306
  }.to raise_error(
307
307
  Puppet::ParseError,
308
- "Cannot append, variable var is defined in this scope"
308
+ "Cannot append, variable '$var' is defined in this scope"
309
309
  )
310
310
  end
311
311
 
@@ -94,7 +94,7 @@ describe Puppet::Parser::TemplateWrapper do
94
94
  Puppet::Parser::Files.stubs(:find_template).
95
95
  with(name, anything()).
96
96
  returns(full_name)
97
- File.stubs(:read).with(full_name).returns(contents)
97
+ Puppet::FileSystem.stubs(:read_preserve_line_endings).with(full_name).returns(contents)
98
98
 
99
99
  full_name
100
100
  end
@@ -400,6 +400,25 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
400
400
  expect {evaluate(expr)}.to raise_error(/Resource not found: File\['x'\]/)
401
401
  end
402
402
 
403
+ # NotUndef Type
404
+ #
405
+ it 'produces a NotUndef instance' do
406
+ type_expr = fqr('NotUndef')
407
+ expect(evaluate(type_expr)).to eql(Puppet::Pops::Types::TypeFactory.not_undef())
408
+ end
409
+
410
+ it 'produces a NotUndef instance with contained type' do
411
+ type_expr = fqr('NotUndef')[fqr('Integer')]
412
+ tf = Puppet::Pops::Types::TypeFactory
413
+ expect(evaluate(type_expr)).to eql(tf.not_undef(tf.integer))
414
+ end
415
+
416
+ it 'produces a NotUndef instance with String type when given a literal String' do
417
+ type_expr = fqr('NotUndef')[literal('hey')]
418
+ tf = Puppet::Pops::Types::TypeFactory
419
+ expect(evaluate(type_expr)).to eql(tf.not_undef(tf.string('hey')))
420
+ end
421
+
403
422
  # Type Type
404
423
  #
405
424
  it 'creates a Type instance when applied to a Type' do
@@ -71,6 +71,9 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
71
71
  "[1,2,3] != [1,2,3]" => false,
72
72
  "[1,2,3][2]" => 3,
73
73
  "[1,2,3] + [4,5]" => [1,2,3,4,5],
74
+ "[1,2,3, *[4,5]]" => [1,2,3,4,5],
75
+ "[1,2,3, (*[4,5])]" => [1,2,3,4,5],
76
+ "[1,2,3, ((*[4,5]))]" => [1,2,3,4,5],
74
77
  "[1,2,3] + [[4,5]]" => [1,2,3,[4,5]],
75
78
  "[1,2,3] + 4" => [1,2,3,4],
76
79
  "[1,2,3] << [4,5]" => [1,2,3,[4,5]],
@@ -219,6 +222,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
219
222
  "$x = Pattern['a.*'] a =~ $x" => true,
220
223
  "1 =~ Integer" => true,
221
224
  "1 !~ Integer" => false,
225
+ "undef =~ NotUndef" => false,
226
+ "undef !~ NotUndef" => true,
222
227
  "[1,2,3] =~ Array[Integer[1,10]]" => true,
223
228
  }.each do |source, result|
224
229
  it "should parse and evaluate the expression '#{source}' to #{result}" do
@@ -300,7 +305,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
300
305
  end
301
306
 
302
307
  {
303
- 'Any' => ['Data', 'Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Collection',
308
+ 'Any' => ['NotUndef', 'Data', 'Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Collection',
304
309
  'Array', 'Hash', 'CatalogEntry', 'Resource', 'Class', 'Undef', 'File', 'NotYetKnownResourceType'],
305
310
 
306
311
  # Note, Data > Collection is false (so not included)
@@ -430,18 +435,31 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
430
435
  "$a = 5; $a" => 5,
431
436
  "$a = 5; $b = 6; $a" => 5,
432
437
  "$a = $b = 5; $a == $b" => true,
438
+ "[$a] = 1 $a" => 1,
439
+ "[$a] = [1] $a" => 1,
440
+ "[$a, $b] = [1,2] $a+$b" => 3,
441
+ "[$a, [$b, $c]] = [1,[2, 3]] $a+$b+$c" => 6,
442
+ "[$a] = {a => 1} $a" => 1,
443
+ "[$a, $b] = {a=>1,b=>2} $a+$b" => 3,
444
+ "[$a, [$b, $c]] = {a=>1,[b,c] =>{b=>2, c=>3}} $a+$b+$c" => 6,
433
445
  }.each do |source, result|
434
446
  it "should parse and evaluate the expression '#{source}' to #{result}" do
435
447
  expect(parser.evaluate_string(scope, source, __FILE__)).to eq(result)
436
448
  end
437
449
  end
438
450
 
439
- {
440
- "[a,b,c] = [1,2,3]" => /attempt to assign to 'an Array Expression'/,
441
- "[a,b,c] = {b=>2,c=>3,a=>1}" => /attempt to assign to 'an Array Expression'/,
442
- }.each do |source, result|
443
- it "should parse and evaluate the expression '#{source}' to error with #{result}" do
444
- expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(Puppet::ParseError, result)
451
+ [
452
+ "[a,b,c] = [1,2,3]",
453
+ "[a,b,c] = {b=>2,c=>3,a=>1}",
454
+ "[$a, $b] = 1",
455
+ "[$a, $b] = [1,2,3]",
456
+ "[$a, [$b,$c]] = [1,[2]]",
457
+ "[$a, [$b,$c]] = [1,[2,3,4]]",
458
+ "[$a, $b] = {a=>1}",
459
+ "[$a, [$b, $c]] = {a=>1, b =>{b=>2, c=>3}}",
460
+ ].each do |source|
461
+ it "should parse and evaluate the expression '#{source}' to error" do
462
+ expect { parser.evaluate_string(scope, source, __FILE__)}.to raise_error(Puppet::ParseError)
445
463
  end
446
464
  end
447
465
  end
@@ -456,6 +474,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
456
474
  "unless false {5}" => 5,
457
475
  "unless true {5}" => nil,
458
476
  "unless true {2} else {5}" => 5,
477
+ "unless true {} else {5}" => 5,
459
478
  "$a = if true {5} $a" => 5,
460
479
  "$a = if false {5} $a" => nil,
461
480
  "$a = if false {2} else {5} $a" => 5,
@@ -493,12 +512,31 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
493
512
  "case ringo {
494
513
  *[paul, john, ringo, george] : { 'beatle' } }" => 'beatle',
495
514
 
515
+ "case ringo {
516
+ (*[paul, john, ringo, george]) : { 'beatle' } }" => 'beatle',
517
+
496
518
  "case undef {
497
519
  undef : { 'yes' } }" => 'yes',
498
520
 
499
521
  "case undef {
500
522
  *undef : { 'no' }
501
523
  default :{ 'yes' }}" => 'yes',
524
+
525
+ "case [green, 2, whatever] {
526
+ [/ee/, Integer[0,10], default] : { 'yes' }
527
+ default :{ 'no' }}" => 'yes',
528
+
529
+ "case [green, 2, whatever] {
530
+ default :{ 'no' }
531
+ [/ee/, Integer[0,10], default] : { 'yes' }}" => 'yes',
532
+
533
+ "case {a=>1, b=>2, whatever=>3, extra => ignored} {
534
+ { a => Integer[0,5],
535
+ b => Integer[0,5],
536
+ whatever => default
537
+ } : { 'yes' }
538
+ default : { 'no' }}" => 'yes',
539
+
502
540
  }.each do |source, result|
503
541
  it "should parse and evaluate the expression '#{source}' to #{result}" do
504
542
  expect(parser.evaluate_string(scope, source, __FILE__)).to eq(result)
@@ -515,8 +553,22 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
515
553
  "'banana' ? { /.*(ana).*/ => $1 }" => 'ana',
516
554
  "[2] ? { Array[String] => yes, Array => yes}" => 'yes',
517
555
  "ringo ? *[paul, john, ringo, george] => 'beatle'" => 'beatle',
556
+ "ringo ? (*[paul, john, ringo, george]) => 'beatle'"=> 'beatle',
518
557
  "undef ? undef => 'yes'" => 'yes',
519
558
  "undef ? {*undef => 'no', default => 'yes'}" => 'yes',
559
+
560
+ "[green, 2, whatever] ? {
561
+ [/ee/, Integer[0,10], default
562
+ ] => 'yes',
563
+ default => 'no'}" => 'yes',
564
+
565
+ "{a=>1, b=>2, whatever=>3, extra => ignored} ?
566
+ {{ a => Integer[0,5],
567
+ b => Integer[0,5],
568
+ whatever => default
569
+ } => 'yes',
570
+ default => 'no' }" => 'yes',
571
+
520
572
  }.each do |source, result|
521
573
  it "should parse and evaluate the expression '#{source}' to #{result}" do
522
574
  expect(parser.evaluate_string(scope, source, __FILE__)).to eq(result)
@@ -683,6 +735,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
683
735
  "'abc'[x]" => "The value 'x' cannot be converted to Numeric",
684
736
  "'abc'[1.0]" => "A String[] cannot use Float where Integer is expected",
685
737
  "'abc'[1,2,3]" => "String supports [] with one or two arguments. Got 3",
738
+ "NotUndef[0]" => 'NotUndef-Type[] argument must be a Type or a String. Got Fixnum',
739
+ "NotUndef[a,b]" => 'NotUndef-Type[] accepts 0 to 1 arguments. Got 2',
686
740
  "Resource[0]" => 'First argument to Resource[] must be a resource type or a String. Got Integer',
687
741
  "Resource[a, 0]" => 'Error creating type specialization of a Resource-Type, Cannot use Integer where a resource title String is expected',
688
742
  "File[0]" => 'Error creating type specialization of a File-Type, Cannot use Integer where a resource title String is expected',
@@ -884,6 +938,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
884
938
  'sprintf( "x%iy", $a )' => "x10y",
885
939
  # unfolds
886
940
  'sprintf( *["x%iy", $a] )' => "x10y",
941
+ '( *["x%iy", $a] ).sprintf' => "x10y",
942
+ '((*["x%iy", $a])).sprintf' => "x10y",
887
943
  '"x%iy".sprintf( $a )' => "x10y",
888
944
  '$b.reduce |$memo,$x| { $memo + $x }' => 6,
889
945
  'reduce($b) |$memo,$x| { $memo + $x }' => 6,
@@ -1084,7 +1140,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
1084
1140
  end
1085
1141
 
1086
1142
  it "a lex error should be raised for '$foo::::bar'" do
1087
- expect { parser.evaluate_string(scope, "$foo::::bar") }.to raise_error(Puppet::LexError, /Illegal fully qualified name at line 1:7/)
1143
+ expect { parser.evaluate_string(scope, "$foo::::bar") }.to raise_error(Puppet::ParseErrorWithIssue, /Illegal fully qualified name at line 1:7/)
1088
1144
  end
1089
1145
 
1090
1146
  { '$a = $0' => nil,
@@ -1215,14 +1271,24 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
1215
1271
 
1216
1272
  it "parses interpolated heredoc expression" do
1217
1273
  src = <<-CODE
1218
- $name = 'Fjodor'
1274
+ $pname = 'Fjodor'
1219
1275
  @("END")
1220
- Hello $name
1276
+ Hello $pname
1221
1277
  |- END
1222
1278
  CODE
1223
1279
  expect(parser.evaluate_string(scope, src)).to eq("Hello Fjodor")
1224
1280
  end
1225
1281
 
1282
+ it "parses interpolated heredoc expression with escapes" do
1283
+ src = <<-CODE
1284
+ $name = 'Fjodor'
1285
+ @("END")
1286
+ Hello\\ \\$name
1287
+ |- END
1288
+ CODE
1289
+ expect(parser.evaluate_string(scope, src)).to eq("Hello\\ \\Fjodor")
1290
+ end
1291
+
1226
1292
  end
1227
1293
  context "Handles Deprecations and Discontinuations" do
1228
1294
  it 'of import statements' do
@@ -1251,14 +1317,14 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
1251
1317
  end
1252
1318
 
1253
1319
  it 'for non r-value producing define' do
1254
- Puppet.expects(:err).with("Invalid use of expression. A 'define' expression does not produce a value at line 1:6")
1255
- Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
1320
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => "Invalid use of expression. A 'define' expression does not produce a value", :line => 1, :pos => 6))
1321
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
1256
1322
  expect { parser.parse_string("$a = define foo { }", nil) }.to raise_error(/2 errors/)
1257
1323
  end
1258
1324
 
1259
1325
  it 'for non r-value producing class' do
1260
- Puppet.expects(:err).with("Invalid use of expression. A Host Class Definition does not produce a value at line 1:6")
1261
- Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
1326
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Invalid use of expression. A Host Class Definition does not produce a value', :line => 1, :pos => 6))
1327
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
1262
1328
  expect { parser.parse_string("$a = class foo { }", nil) }.to raise_error(/2 errors/)
1263
1329
  end
1264
1330
 
@@ -1272,8 +1338,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
1272
1338
  end
1273
1339
 
1274
1340
  it 'for multiple errors with a summary exception' do
1275
- Puppet.expects(:err).with("Invalid use of expression. A Node Definition does not produce a value at line 1:6")
1276
- Puppet.expects(:err).with("Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6")
1341
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Invalid use of expression. A Node Definition does not produce a value', :line => 1, :pos => 6))
1342
+ Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
1277
1343
  expect { parser.parse_string("$a = node x { }",nil) }.to raise_error(/2 errors/)
1278
1344
  end
1279
1345
 
@@ -1285,8 +1351,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
1285
1351
 
1286
1352
  it 'for a hostname with interpolation' do
1287
1353
  source = <<-SOURCE.gsub(/^ {6}/,'')
1288
- $name = 'fred'
1289
- node "macbook-owned-by$name" { }
1354
+ $pname = 'fred'
1355
+ node "macbook-owned-by$pname" { }
1290
1356
  SOURCE
1291
1357
  expect {
1292
1358
  parser.parse_string(source, nil)