puppet 4.7.1 → 4.8.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 (276) hide show
  1. data/Gemfile +0 -3
  2. data/MAINTAINERS +76 -0
  3. data/README.md +0 -6
  4. data/Rakefile +2 -2
  5. data/lib/puppet/agent.rb +3 -3
  6. data/lib/puppet/application/apply.rb +1 -1
  7. data/lib/puppet/configurer.rb +2 -2
  8. data/lib/puppet/data_providers.rb +1 -0
  9. data/lib/puppet/data_providers/data_adapter.rb +1 -0
  10. data/lib/puppet/data_providers/data_function_support.rb +1 -0
  11. data/lib/puppet/data_providers/function_env_data_provider.rb +1 -0
  12. data/lib/puppet/data_providers/function_module_data_provider.rb +1 -0
  13. data/lib/puppet/data_providers/hiera_config.rb +1 -0
  14. data/lib/puppet/data_providers/hiera_env_data_provider.rb +1 -0
  15. data/lib/puppet/data_providers/hiera_interpolate.rb +1 -0
  16. data/lib/puppet/data_providers/hiera_module_data_provider.rb +1 -0
  17. data/lib/puppet/data_providers/hiera_support.rb +1 -2
  18. data/lib/puppet/data_providers/json_data_provider_factory.rb +2 -0
  19. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -0
  20. data/lib/puppet/defaults.rb +20 -1
  21. data/lib/puppet/environments.rb +5 -2
  22. data/lib/puppet/face/catalog.rb +1 -1
  23. data/lib/puppet/face/epp.rb +57 -11
  24. data/lib/puppet/face/module/install.rb +6 -6
  25. data/lib/puppet/functions.rb +23 -24
  26. data/lib/puppet/functions/alert.rb +14 -0
  27. data/lib/puppet/functions/binary_file.rb +25 -0
  28. data/lib/puppet/functions/break.rb +22 -0
  29. data/lib/puppet/functions/contain.rb +33 -0
  30. data/lib/puppet/functions/crit.rb +14 -0
  31. data/lib/puppet/functions/debug.rb +14 -0
  32. data/lib/puppet/functions/emerg.rb +14 -0
  33. data/lib/puppet/functions/epp.rb +1 -1
  34. data/lib/puppet/functions/err.rb +14 -0
  35. data/lib/puppet/functions/find_file.rb +31 -0
  36. data/lib/puppet/functions/include.rb +21 -0
  37. data/lib/puppet/functions/info.rb +14 -0
  38. data/lib/puppet/functions/new.rb +1 -1
  39. data/lib/puppet/functions/next.rb +23 -0
  40. data/lib/puppet/functions/notice.rb +14 -0
  41. data/lib/puppet/functions/regsubst.rb +12 -16
  42. data/lib/puppet/functions/require.rb +37 -0
  43. data/lib/puppet/functions/return.rb +22 -0
  44. data/lib/puppet/functions/strftime.rb +35 -0
  45. data/lib/puppet/functions/warning.rb +14 -0
  46. data/lib/puppet/generate/models/type/type.rb +4 -0
  47. data/lib/puppet/generate/templates/type/pcore.erb +2 -1
  48. data/lib/puppet/indirector/face.rb +6 -1
  49. data/lib/puppet/network/http/error.rb +2 -2
  50. data/lib/puppet/network/http/handler.rb +2 -2
  51. data/lib/puppet/node/environment.rb +11 -0
  52. data/lib/puppet/parser/ast.rb +5 -0
  53. data/lib/puppet/parser/ast/pops_bridge.rb +17 -4
  54. data/lib/puppet/parser/compiler.rb +29 -1
  55. data/lib/puppet/parser/functions.rb +6 -0
  56. data/lib/puppet/parser/functions/assert_type.rb +1 -1
  57. data/lib/puppet/parser/functions/binary_file.rb +24 -0
  58. data/lib/puppet/parser/functions/break.rb +39 -0
  59. data/lib/puppet/parser/functions/contain.rb +7 -15
  60. data/lib/puppet/parser/functions/defined.rb +2 -2
  61. data/lib/puppet/parser/functions/dig.rb +1 -1
  62. data/lib/puppet/parser/functions/each.rb +1 -1
  63. data/lib/puppet/parser/functions/epp.rb +2 -2
  64. data/lib/puppet/parser/functions/filter.rb +1 -1
  65. data/lib/puppet/parser/functions/find_file.rb +28 -0
  66. data/lib/puppet/parser/functions/hiera.rb +4 -4
  67. data/lib/puppet/parser/functions/hiera_array.rb +1 -1
  68. data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
  69. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  70. data/lib/puppet/parser/functions/include.rb +4 -8
  71. data/lib/puppet/parser/functions/inline_epp.rb +1 -1
  72. data/lib/puppet/parser/functions/lest.rb +1 -1
  73. data/lib/puppet/parser/functions/lookup.rb +4 -2
  74. data/lib/puppet/parser/functions/map.rb +1 -1
  75. data/lib/puppet/parser/functions/match.rb +1 -1
  76. data/lib/puppet/parser/functions/new.rb +414 -18
  77. data/lib/puppet/parser/functions/next.rb +38 -0
  78. data/lib/puppet/parser/functions/reduce.rb +1 -1
  79. data/lib/puppet/parser/functions/regsubst.rb +4 -2
  80. data/lib/puppet/parser/functions/require.rb +4 -27
  81. data/lib/puppet/parser/functions/return.rb +71 -0
  82. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  83. data/lib/puppet/parser/functions/scanf.rb +13 -8
  84. data/lib/puppet/parser/functions/slice.rb +1 -1
  85. data/lib/puppet/parser/functions/split.rb +1 -1
  86. data/lib/puppet/parser/functions/step.rb +1 -1
  87. data/lib/puppet/parser/functions/strftime.rb +185 -0
  88. data/lib/puppet/parser/functions/then.rb +1 -1
  89. data/lib/puppet/parser/functions/type.rb +1 -1
  90. data/lib/puppet/parser/functions/with.rb +3 -3
  91. data/lib/puppet/parser/resource.rb +8 -5
  92. data/lib/puppet/parser/scope.rb +1 -1
  93. data/lib/puppet/plugins/configuration.rb +8 -0
  94. data/lib/puppet/plugins/data_providers.rb +1 -0
  95. data/lib/puppet/plugins/data_providers/data_provider.rb +7 -28
  96. data/lib/puppet/plugins/data_providers/registry.rb +1 -0
  97. data/lib/puppet/pops.rb +4 -0
  98. data/lib/puppet/pops/evaluator/access_operator.rb +36 -5
  99. data/lib/puppet/pops/evaluator/closure.rb +81 -12
  100. data/lib/puppet/pops/evaluator/compare_operator.rb +24 -1
  101. data/lib/puppet/pops/evaluator/evaluator_impl.rb +29 -5
  102. data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +1 -1
  103. data/lib/puppet/pops/evaluator/runtime3_converter.rb +53 -62
  104. data/lib/puppet/pops/evaluator/runtime3_support.rb +15 -6
  105. data/lib/puppet/pops/functions/dispatch.rb +9 -2
  106. data/lib/puppet/pops/functions/dispatcher.rb +3 -1
  107. data/lib/puppet/pops/functions/function.rb +19 -2
  108. data/lib/puppet/pops/issues.rb +9 -0
  109. data/lib/puppet/pops/label_provider.rb +2 -2
  110. data/lib/puppet/pops/loader/loader.rb +17 -0
  111. data/lib/puppet/pops/loader/static_loader.rb +0 -41
  112. data/lib/puppet/pops/lookup.rb +12 -0
  113. data/lib/puppet/pops/lookup/context.rb +86 -0
  114. data/lib/puppet/pops/lookup/explainer.rb +46 -6
  115. data/lib/puppet/pops/lookup/invocation.rb +19 -0
  116. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  117. data/lib/puppet/pops/model/factory.rb +20 -8
  118. data/lib/puppet/pops/model/model_label_provider.rb +3 -0
  119. data/lib/puppet/pops/model/model_meta.rb +2 -0
  120. data/lib/puppet/pops/model/model_tree_dumper.rb +14 -0
  121. data/lib/puppet/pops/parser/egrammar.ra +11 -6
  122. data/lib/puppet/pops/parser/eparser.rb +1112 -1086
  123. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  124. data/lib/puppet/pops/pcore.rb +1 -0
  125. data/lib/puppet/pops/puppet_stack.rb +3 -3
  126. data/lib/puppet/pops/resource/param.rb +5 -1
  127. data/lib/puppet/pops/resource/resource_type_impl.rb +8 -4
  128. data/lib/puppet/pops/resource/resource_type_set.pcore +1 -0
  129. data/lib/puppet/pops/serialization/abstract_reader.rb +19 -2
  130. data/lib/puppet/pops/serialization/abstract_writer.rb +16 -3
  131. data/lib/puppet/pops/serialization/deserializer.rb +5 -1
  132. data/lib/puppet/pops/serialization/extension.rb +2 -0
  133. data/lib/puppet/pops/serialization/json.rb +76 -26
  134. data/lib/puppet/pops/serialization/serializer.rb +5 -1
  135. data/lib/puppet/pops/serialization/time_factory.rb +2 -1
  136. data/lib/puppet/pops/time/timespan.rb +718 -0
  137. data/lib/puppet/pops/time/timestamp.rb +148 -0
  138. data/lib/puppet/pops/types/p_binary_type.rb +220 -0
  139. data/lib/puppet/pops/types/p_object_type.rb +12 -6
  140. data/lib/puppet/pops/types/p_sensitive_type.rb +5 -1
  141. data/lib/puppet/pops/types/p_timespan_type.rb +141 -0
  142. data/lib/puppet/pops/types/p_timestamp_type.rb +69 -0
  143. data/lib/puppet/pops/types/string_converter.rb +62 -0
  144. data/lib/puppet/pops/types/type_asserter.rb +1 -1
  145. data/lib/puppet/pops/types/type_calculator.rb +17 -3
  146. data/lib/puppet/pops/types/type_factory.rb +35 -1
  147. data/lib/puppet/pops/types/type_formatter.rb +64 -11
  148. data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -61
  149. data/lib/puppet/pops/types/type_parser.rb +18 -4
  150. data/lib/puppet/pops/types/types.rb +98 -63
  151. data/lib/puppet/pops/validation.rb +9 -1
  152. data/lib/puppet/pops/validation/checker4_0.rb +7 -0
  153. data/lib/puppet/property.rb +1 -1
  154. data/lib/puppet/provider.rb +3 -6
  155. data/lib/puppet/provider/mcx/mcxcontent.rb +1 -1
  156. data/lib/puppet/provider/mount/parsed.rb +18 -4
  157. data/lib/puppet/provider/nameservice/directoryservice.rb +15 -7
  158. data/lib/puppet/provider/package/gem.rb +6 -1
  159. data/lib/puppet/provider/package/pip.rb +0 -1
  160. data/lib/puppet/provider/package/pkg.rb +5 -1
  161. data/lib/puppet/provider/package/pkgng.rb +1 -1
  162. data/lib/puppet/provider/package/yum.rb +10 -0
  163. data/lib/puppet/provider/service/launchd.rb +1 -0
  164. data/lib/puppet/provider/user/directoryservice.rb +6 -6
  165. data/lib/puppet/provider/yumrepo/inifile.rb +1 -1
  166. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  167. data/lib/puppet/resource.rb +54 -12
  168. data/lib/puppet/resource/capability_finder.rb +15 -9
  169. data/lib/puppet/resource/catalog.rb +25 -6
  170. data/lib/puppet/resource/type.rb +3 -1
  171. data/lib/puppet/settings.rb +1 -1
  172. data/lib/puppet/settings/environment_conf.rb +12 -4
  173. data/lib/puppet/syntax_checkers/base64.rb +41 -0
  174. data/lib/puppet/syntax_checkers/json.rb +0 -2
  175. data/lib/puppet/transaction.rb +6 -0
  176. data/lib/puppet/transaction/additional_resource_generator.rb +5 -0
  177. data/lib/puppet/transaction/report.rb +7 -2
  178. data/lib/puppet/type.rb +2 -1
  179. data/lib/puppet/type/file/checksum.rb +1 -0
  180. data/lib/puppet/type/file/content.rb +4 -4
  181. data/lib/puppet/type/mount.rb +44 -0
  182. data/lib/puppet/type/ssh_authorized_key.rb +1 -1
  183. data/lib/puppet/type/tidy.rb +3 -0
  184. data/lib/puppet/type/user.rb +12 -6
  185. data/lib/puppet/util/log.rb +25 -0
  186. data/lib/puppet/util/plist.rb +8 -3
  187. data/lib/puppet/version.rb +1 -1
  188. data/lib/puppet_x.rb +7 -1
  189. data/spec/integration/application/apply_spec.rb +118 -0
  190. data/spec/integration/parser/compiler_spec.rb +28 -0
  191. data/spec/integration/parser/pcore_resource_spec.rb +40 -3
  192. data/spec/integration/provider/mount_spec.rb +2 -1
  193. data/spec/integration/util/windows/principal_spec.rb +2 -2
  194. data/spec/integration/util/windows/registry_spec.rb +4 -4
  195. data/spec/lib/puppet_spec/compiler.rb +5 -1
  196. data/spec/lib/puppet_spec/unindent.rb +5 -0
  197. data/spec/shared_contexts/types_setup.rb +6 -0
  198. data/spec/shared_examples/rhel_package_provider.rb +16 -0
  199. data/spec/spec_helper.rb +1 -0
  200. data/spec/unit/agent_spec.rb +11 -0
  201. data/spec/unit/application/lookup_spec.rb +94 -3
  202. data/spec/unit/capability_spec.rb +22 -0
  203. data/spec/unit/configurer_spec.rb +8 -0
  204. data/spec/unit/face/epp_face_spec.rb +22 -3
  205. data/spec/unit/functions/assert_type_spec.rb +3 -3
  206. data/spec/unit/functions/binary_file_spec.rb +46 -0
  207. data/spec/unit/functions/break_spec.rb +89 -0
  208. data/spec/unit/{parser/functions → functions}/contain_spec.rb +68 -3
  209. data/spec/unit/functions/find_file_spec.rb +69 -0
  210. data/spec/unit/functions/include_spec.rb +175 -0
  211. data/spec/unit/functions/logging_spec.rb +54 -0
  212. data/spec/unit/functions/lookup_spec.rb +3 -3
  213. data/spec/unit/functions/new_spec.rb +105 -5
  214. data/spec/unit/functions/next_spec.rb +93 -0
  215. data/spec/unit/functions/require_spec.rb +83 -0
  216. data/spec/unit/functions/return_spec.rb +105 -0
  217. data/spec/unit/{parser/functions → functions}/shared.rb +14 -11
  218. data/spec/unit/functions/strftime_spec.rb +152 -0
  219. data/spec/unit/functions4_spec.rb +22 -0
  220. data/spec/unit/indirector/face_spec.rb +10 -2
  221. data/spec/unit/network/http/error_spec.rb +1 -2
  222. data/spec/unit/network/http/handler_spec.rb +6 -5
  223. data/spec/unit/parser/functions/hiera_array_spec.rb +1 -1
  224. data/spec/unit/parser/functions/hiera_hash_spec.rb +1 -1
  225. data/spec/unit/parser/functions/hiera_include_spec.rb +1 -1
  226. data/spec/unit/parser/functions/hiera_spec.rb +1 -1
  227. data/spec/unit/parser/functions/lookup_spec.rb +1 -1
  228. data/spec/unit/parser/functions/regsubst_spec.rb +1 -1
  229. data/spec/unit/parser/functions/split_spec.rb +1 -1
  230. data/spec/unit/pops/evaluator/access_ops_spec.rb +81 -1
  231. data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +170 -0
  232. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +29 -4
  233. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +112 -4
  234. data/spec/unit/pops/loaders/dependency_loader_spec.rb +12 -0
  235. data/spec/unit/pops/loaders/static_loader_spec.rb +0 -26
  236. data/spec/unit/pops/lookup/context_spec.rb +149 -0
  237. data/spec/unit/pops/parser/parse_functions_spec.rb +19 -0
  238. data/spec/unit/pops/parser/parse_lambda_spec.rb +19 -0
  239. data/spec/unit/pops/puppet_stack_spec.rb +1 -1
  240. data/spec/unit/pops/resource/resource_type_impl_spec.rb +74 -0
  241. data/spec/unit/pops/serialization/packer_spec.rb +34 -14
  242. data/spec/unit/pops/serialization/serialization_spec.rb +67 -5
  243. data/spec/unit/pops/time/timespan_spec.rb +121 -0
  244. data/spec/unit/pops/types/p_binary_type_spec.rb +243 -0
  245. data/spec/unit/pops/types/p_object_type_spec.rb +7 -7
  246. data/spec/unit/pops/types/p_sensitive_type_spec.rb +1 -1
  247. data/spec/unit/pops/types/p_timespan_type_spec.rb +273 -0
  248. data/spec/unit/pops/types/p_timestamp_type_spec.rb +311 -0
  249. data/spec/unit/pops/types/p_type_set_type_spec.rb +13 -13
  250. data/spec/unit/pops/types/ruby_generator_spec.rb +12 -12
  251. data/spec/unit/pops/types/string_converter_spec.rb +89 -0
  252. data/spec/unit/pops/types/type_asserter_spec.rb +3 -3
  253. data/spec/unit/pops/types/type_calculator_spec.rb +113 -5
  254. data/spec/unit/pops/types/type_formatter_spec.rb +40 -0
  255. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +49 -38
  256. data/spec/unit/pops/types/type_parser_spec.rb +87 -4
  257. data/spec/unit/pops/types/types_spec.rb +1 -1
  258. data/spec/unit/pops/validator/validator_spec.rb +23 -0
  259. data/spec/unit/provider/mount/parsed_spec.rb +47 -29
  260. data/spec/unit/provider/package/pkg_spec.rb +109 -99
  261. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -0
  262. data/spec/unit/provider/user/aix_spec.rb +1 -1
  263. data/spec/unit/provider/user/directoryservice_spec.rb +101 -30
  264. data/spec/unit/resource/capability_finder_spec.rb +29 -7
  265. data/spec/unit/resource/catalog_spec.rb +127 -0
  266. data/spec/unit/ssl/certificate_request_spec.rb +1 -1
  267. data/spec/unit/transaction/additional_resource_generator_spec.rb +30 -0
  268. data/spec/unit/transaction/persistence_spec.rb +1 -6
  269. data/spec/unit/transaction/report_spec.rb +23 -0
  270. data/spec/unit/transaction_spec.rb +38 -0
  271. data/spec/unit/type/mount_spec.rb +5 -0
  272. data/spec/unit/util/plist_spec.rb +14 -2
  273. metadata +71 -12
  274. data/spec/integration/parser/functions/require_spec.rb +0 -43
  275. data/spec/unit/parser/functions/include_spec.rb +0 -55
  276. data/spec/unit/parser/functions/require_spec.rb +0 -68
@@ -1,41 +1,44 @@
1
- shared_examples_for 'all functions transforming relative to absolute names' do |func_method|
2
-
3
- it 'transforms relative names to absolute' do
4
- @scope.compiler.expects(:evaluate_classes).with(["::myclass"], @scope, false)
5
- @scope.send(func_method, ["myclass"])
1
+ shared_examples_for 'all functions transforming relative to absolute names' do |func_name|
2
+ before(:each) do
3
+ # mock that the class 'myclass' exists which are needed for the 'require' functions
4
+ # as it checks the existence of the required class
5
+ @klass = stub 'class', :name => "myclass"
6
+ @scope.environment.known_resource_types.stubs(:find_hostclass).returns(@klass)
7
+ @resource = Puppet::Parser::Resource.new(:file, "/my/file", :scope => @scope, :source => "source")
8
+ @scope.stubs(:resource).returns @resource
6
9
  end
7
10
 
8
11
  it 'accepts a Class[name] type' do
9
12
  @scope.compiler.expects(:evaluate_classes).with(["::myclass"], @scope, false)
10
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.host_class('myclass')])
13
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.host_class('myclass')])
11
14
  end
12
15
 
13
16
  it 'accepts a Resource[class, name] type' do
14
17
  @scope.compiler.expects(:evaluate_classes).with(["::myclass"], @scope, false)
15
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.resource('class', 'myclass')])
18
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.resource('class', 'myclass')])
16
19
  end
17
20
 
18
21
  it 'raises and error for unspecific Class' do
19
22
  expect {
20
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.host_class()])
23
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.host_class()])
21
24
  }.to raise_error(ArgumentError, /Cannot use an unspecific Class\[\] Type/)
22
25
  end
23
26
 
24
27
  it 'raises and error for Resource that is not of class type' do
25
28
  expect {
26
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.resource('file')])
29
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.resource('file')])
27
30
  }.to raise_error(ArgumentError, /Cannot use a Resource\[File\] where a Resource\['class', name\] is expected/)
28
31
  end
29
32
 
30
33
  it 'raises and error for Resource that is unspecific' do
31
34
  expect {
32
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.resource()])
35
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.resource()])
33
36
  }.to raise_error(ArgumentError, /Cannot use an unspecific Resource\[\] where a Resource\['class', name\] is expected/)
34
37
  end
35
38
 
36
39
  it 'raises and error for Resource[class] that is unspecific' do
37
40
  expect {
38
- @scope.send(func_method, [Puppet::Pops::Types::TypeFactory.resource('class')])
41
+ @scope.call_function(func_name, [Puppet::Pops::Types::TypeFactory.resource('class')])
39
42
  }.to raise_error(ArgumentError, /Cannot use an unspecific Resource\['class'\] where a Resource\['class', name\] is expected/)
40
43
  end
41
44
 
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+ require 'puppet_spec/compiler'
3
+
4
+ describe 'the strftime function' do
5
+ include PuppetSpec::Compiler
6
+
7
+ def test_format(ctor_arg, format, expected)
8
+ expect(eval_and_collect_notices("notice(strftime(Timespan(#{ctor_arg}), '#{format}'))")).to eql(["#{expected}"])
9
+ end
10
+
11
+ context 'when applied to a Timespan' do
12
+ [
13
+ ['hours', 'H', 2],
14
+ ['minutes', 'M', 2],
15
+ ['seconds', 'S', 2],
16
+ ].each do |field, fmt, dflt_width|
17
+ ctor_arg = "{#{field}=>3}"
18
+ it "%#{fmt} width defaults to #{dflt_width}" do
19
+ test_format(ctor_arg, "%#{fmt}", sprintf("%0#{dflt_width}d", 3))
20
+ end
21
+
22
+ it "%_#{fmt} pads with space" do
23
+ test_format(ctor_arg, "%_#{fmt}", sprintf("% #{dflt_width}d", 3))
24
+ end
25
+
26
+ it "%-#{fmt} does not pad" do
27
+ test_format(ctor_arg, "%-#{fmt}", '3')
28
+ end
29
+
30
+ it "%10#{fmt} pads with zeroes to specified width" do
31
+ test_format(ctor_arg, "%10#{fmt}", sprintf("%010d", 3))
32
+ end
33
+
34
+ it "%_10#{fmt} pads with space to specified width" do
35
+ test_format(ctor_arg, "%_10#{fmt}", sprintf("% 10d", 3))
36
+ end
37
+
38
+ it "%-10#{fmt} does not pad even if width is specified" do
39
+ test_format(ctor_arg, "%-10#{fmt}", '3')
40
+ end
41
+ end
42
+
43
+ [
44
+ ['milliseconds', 'L', 3],
45
+ ['nanoseconds', 'N', 9],
46
+ ['milliseconds', '3N', 3],
47
+ ['microseconds', '6N', 6],
48
+ ['nanoseconds', '9N', 9],
49
+ ].each do |field, fmt, dflt_width|
50
+ ctor_arg = "{#{field}=>3000}"
51
+ it "%#{fmt} width defaults to #{dflt_width}" do
52
+ test_format(ctor_arg, "%#{fmt}", sprintf("%-#{dflt_width}d", 3000))
53
+ end
54
+
55
+ it "%_#{fmt} pads with space" do
56
+ test_format(ctor_arg, "%_#{fmt}", sprintf("%-#{dflt_width}d", 3000))
57
+ end
58
+
59
+ it "%-#{fmt} does not pad" do
60
+ test_format(ctor_arg, "%-#{fmt}", '3000')
61
+ end
62
+ end
63
+
64
+ it 'can use a format containing all format characters, flags, and widths' do
65
+ test_format("{string => '100-14:02:24.123456000', format => '%D-%H:%M:%S.%9N'}", '%_10D%%%03H:%-M:%S.%9N', ' 100%014:2:24.123456000')
66
+ end
67
+
68
+ it 'can format and strip excess zeroes from fragment using no-padding flag' do
69
+ test_format("{string => '100-14:02:24.123456000', format => '%D-%H:%M:%S.%N'}", '%D-%H:%M:%S.%-N', '100-14:02:24.123456')
70
+ end
71
+
72
+ it 'can format and replace excess zeroes with spaces from fragment using space-padding flag and default widht' do
73
+ test_format("{string => '100-14:02:24.123456000', format => '%D-%H:%M:%S.%N'}", '%D-%H:%M:%S.%_N', '100-14:02:24.123456 ')
74
+ end
75
+
76
+ it 'can format and replace excess zeroes with spaces from fragment using space-padding flag and specified width' do
77
+ test_format("{string => '100-14:02:24.123400000', format => '%D-%H:%M:%S.%N'}", '%D-%H:%M:%S.%_6N', '100-14:02:24.1234 ')
78
+ end
79
+
80
+ it 'can format and retain excess zeroes in fragment using default width' do
81
+ test_format("{string => '100-14:02:24.123400000', format => '%D-%H:%M:%S.%N'}", '%D-%H:%M:%S.%N', '100-14:02:24.123400000')
82
+ end
83
+
84
+ it 'can format and retain excess zeroes in fragment using specified width' do
85
+ test_format("{string => '100-14:02:24.123400000', format => '%D-%H:%M:%S.%N'}", '%D-%H:%M:%S.%6N', '100-14:02:24.123400')
86
+ end
87
+ end
88
+
89
+ def test_timestamp_format(ctor_arg, format, expected)
90
+ expect(eval_and_collect_notices("notice(strftime(Timestamp('#{ctor_arg}'), '#{format}'))")).to eql(["#{expected}"])
91
+ end
92
+
93
+ def test_timestamp_format_tz(ctor_arg, format, tz, expected)
94
+ expect(eval_and_collect_notices("notice(strftime(Timestamp('#{ctor_arg}'), '#{format}', '#{tz}'))")).to eql(["#{expected}"])
95
+ end
96
+
97
+ def collect_log(code, node = Puppet::Node.new('foonode'))
98
+ Puppet[:code] = code
99
+ compiler = Puppet::Parser::Compiler.new(node)
100
+ node.environment.check_for_reparse
101
+ logs = []
102
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
103
+ compiler.compile
104
+ end
105
+ logs
106
+ end
107
+
108
+ context 'when applied to a Timestamp' do
109
+ it 'can format a timestamp with a format pattern' do
110
+ test_timestamp_format('2016-09-23T13:14:15.123 UTC', '%Y-%m-%d %H:%M:%S.%L %z', '2016-09-23 13:14:15.123 +0000')
111
+ end
112
+
113
+ it 'can format a timestamp using a specific timezone' do
114
+ test_timestamp_format_tz('2016-09-23T13:14:15.123 UTC', '%Y-%m-%d %H:%M:%S.%L %z', 'EST', '2016-09-23 08:14:15.123 -0500')
115
+ end
116
+ end
117
+
118
+ context 'when used with dispatcher covering legacy stdlib API (String format, String timeszone = undef)' do
119
+ it 'produces the current time when used with one argument' do
120
+ before_eval = Time.now
121
+ notices = eval_and_collect_notices("notice(strftime('%F %T'))")
122
+ expect(notices).not_to be_empty
123
+ expect(notices[0]).to match(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\z/)
124
+ parsed_time = DateTime.strptime(notices[0], '%F %T').to_time
125
+ expect(Time.now.to_i >= parsed_time.to_i && parsed_time.to_i >= before_eval.to_i).to be_truthy
126
+ end
127
+
128
+ it 'emits a deprecation warning when used with one argument' do
129
+ log = collect_log("notice(strftime('%F %T'))")
130
+ warnings = log.select { |log_entry| log_entry.level == :warning }.map { |log_entry| log_entry.message }
131
+ expect(warnings).not_to be_empty
132
+ expect(warnings[0]).to match(/The argument signature \(String format, \[String timezone\]\) is deprecated for #strfime/)
133
+ end
134
+
135
+ it 'produces the current time formatted with specific timezone when used with two arguments' do
136
+ before_eval = Time.now
137
+ notices = eval_and_collect_notices("notice(strftime('%F %T %:z', 'EST'))")
138
+ expect(notices).not_to be_empty
139
+ expect(notices[0]).to match(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -05:00\z/)
140
+ parsed_time = DateTime.strptime(notices[0], '%F %T %z').to_time
141
+ expect(Time.now.to_i >= parsed_time.to_i && parsed_time.to_i >= before_eval.to_i).to be_truthy
142
+ end
143
+
144
+ it 'emits a deprecation warning when using legacy format with two arguments' do
145
+ log = collect_log("notice(strftime('%F %T', 'EST'))")
146
+ warnings = log.select { |log_entry| log_entry.level == :warning }.map { |log_entry| log_entry.message }
147
+ expect(warnings).not_to be_empty
148
+ expect(warnings[0]).to match(/The argument signature \(String format, \[String timezone\]\) is deprecated for #strfime/)
149
+ end
150
+ end
151
+ end
152
+
@@ -482,6 +482,27 @@ describe 'the 4x function api' do
482
482
  context 'can use a loader when parsing types in function dispatch, and' do
483
483
  let(:parser) { Puppet::Pops::Parser::EvaluatingParser.new }
484
484
 
485
+ it 'uses return_type to validate returned value' do
486
+ the_loader = loader()
487
+ here = get_binding(the_loader)
488
+ fc = eval(<<-CODE, here)
489
+ Puppet::Functions.create_function('testing::test') do
490
+ dispatch :test do
491
+ param 'Integer', :x
492
+ return_type 'String'
493
+ end
494
+ def test(x)
495
+ x
496
+ end
497
+ end
498
+ CODE
499
+ the_loader.add_function('testing::test', fc.new({}, the_loader))
500
+ program = parser.parse_string('testing::test(10)', __FILE__)
501
+ Puppet::Pops::Adapters::LoaderAdapter.expects(:loader_for_model_object).returns(the_loader)
502
+ expect { parser.evaluate({}, program) }.to raise_error(Puppet::Error,
503
+ /value returned from function 'test' has wrong type, expects a String value, got Integer/)
504
+ end
505
+
485
506
  it 'resolve a referenced Type alias' do
486
507
  the_loader = loader()
487
508
  the_loader.add_type('myalias', type_alias_t('MyAlias', 'Integer'))
@@ -490,6 +511,7 @@ describe 'the 4x function api' do
490
511
  Puppet::Functions.create_function('testing::test') do
491
512
  dispatch :test do
492
513
  param 'MyAlias', :x
514
+ return_type 'MyAlias'
493
515
  end
494
516
  def test(x)
495
517
  x
@@ -40,16 +40,24 @@ describe Puppet::Indirector::Face do
40
40
  end
41
41
 
42
42
  [:find, :search, :save, :destroy].each do |method|
43
+ def params(method, options)
44
+ if method == :save
45
+ [nil, options]
46
+ else
47
+ [options]
48
+ end
49
+ end
50
+
43
51
  it "should define a '#{method}' action" do
44
52
  expect(Puppet::Indirector::Face).to be_action(method)
45
53
  end
46
54
 
47
55
  it "should call the indirection method with options when the '#{method}' action is invoked" do
48
- subject.indirection.expects(method).with(:test, {})
56
+ subject.indirection.expects(method).with(:test, *params(method, {}))
49
57
  subject.send(method, :test)
50
58
  end
51
59
  it "should forward passed options" do
52
- subject.indirection.expects(method).with(:test, {'one'=>'1'})
60
+ subject.indirection.expects(method).with(:test, *params(method, {'one'=>'1'}))
53
61
  subject.send(method, :test, :extra => {'one'=>'1'})
54
62
  end
55
63
  end
@@ -15,7 +15,7 @@ describe Puppet::Network::HTTP::Error do
15
15
  end
16
16
 
17
17
  describe Puppet::Network::HTTP::Error::HTTPServerError do
18
- it "should serialize to JSON that matches the error schema and has a deprecated stacktrace property" do
18
+ it "should serialize to JSON that matches the error schema" do
19
19
  begin
20
20
  raise Exception, "a wild Exception appeared!"
21
21
  rescue Exception => e
@@ -24,7 +24,6 @@ describe Puppet::Network::HTTP::Error do
24
24
  error = Puppet::Network::HTTP::Error::HTTPServerError.new(culpable)
25
25
 
26
26
  expect(error.to_json).to validate_against('api/schemas/error.json')
27
- expect(error.to_json).to match(/The 'stacktrace' property is deprecated/)
28
27
  end
29
28
  end
30
29
 
@@ -76,8 +76,7 @@ describe Puppet::Network::HTTP::Handler do
76
76
 
77
77
  it "returns a structured error response when the server encounters an internal error" do
78
78
  error = StandardError.new("the sky is falling!")
79
- original_stacktrace = ['a.rb', 'b.rb']
80
- error.set_backtrace(original_stacktrace)
79
+ error.set_backtrace(['a.rb', 'b.rb'])
81
80
 
82
81
  handler = PuppetSpec::Handler.new(
83
82
  Puppet::Network::HTTP::Route.path(/.*/).get(lambda { |_, _| raise error}))
@@ -95,9 +94,11 @@ describe Puppet::Network::HTTP::Handler do
95
94
  expect(res[:content_type_header]).to eq("application/json")
96
95
  expect(res_body["issue_kind"]).to eq(Puppet::Network::HTTP::Issues::RUNTIME_ERROR.to_s)
97
96
  expect(res_body["message"]).to eq("Server Error: the sky is falling!")
98
- expect(res_body["stacktrace"].is_a?(Array) && !res_body["stacktrace"].empty?).to be_truthy
99
- expect(res_body["stacktrace"][0]).to match(/The 'stacktrace' property is deprecated/)
100
- expect(res_body["stacktrace"] & original_stacktrace).to be_empty
97
+
98
+ # Stactraces may contain sensitive information, returning them to API
99
+ # consumers is not a best practice. See
100
+ # https://tickets.puppetlabs.com/browse/PUP-6659
101
+ expect(res_body["stacktrace"]).to be_nil
101
102
  expect(res[:status]).to eq(500)
102
103
  end
103
104
 
@@ -7,6 +7,6 @@ describe 'Puppet::Parser::Functions#hiera_array' do
7
7
  let :scope do create_test_scope_for_node('foo') end
8
8
 
9
9
  it 'should raise an error since this function is converted to 4x API)' do
10
- expect { scope.function_hiera_array(['key']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
10
+ expect { scope.function_hiera_array(['key']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
11
11
  end
12
12
  end
@@ -7,6 +7,6 @@ describe 'Puppet::Parser::Functions#hiera_hash' do
7
7
  let :scope do create_test_scope_for_node('foo') end
8
8
 
9
9
  it 'should raise an error since this function is converted to 4x API)' do
10
- expect { scope.function_hiera_hash(['key']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
10
+ expect { scope.function_hiera_hash(['key']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
11
11
  end
12
12
  end
@@ -7,6 +7,6 @@ describe 'Puppet::Parser::Functions#hiera_include' do
7
7
  let :scope do create_test_scope_for_node('foo') end
8
8
 
9
9
  it 'should raise an error since this function is converted to 4x API)' do
10
- expect { scope.function_hiera_include(['key']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
10
+ expect { scope.function_hiera_include(['key']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
11
11
  end
12
12
  end
@@ -7,6 +7,6 @@ describe 'Puppet::Parser::Functions#hiera' do
7
7
  let :scope do create_test_scope_for_node('foo') end
8
8
 
9
9
  it 'should raise an error since this function is converted to 4x API)' do
10
- expect { scope.function_hiera(['key']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
10
+ expect { scope.function_hiera(['key']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
11
11
  end
12
12
  end
@@ -9,6 +9,6 @@ describe "lookup function" do
9
9
  let :scope do create_test_scope_for_node('foo') end
10
10
 
11
11
  it 'should raise an error since this function is converted to 4x API)' do
12
- expect { scope.function_lookup(['key']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
12
+ expect { scope.function_lookup(['key']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
13
13
  end
14
14
  end
@@ -19,6 +19,6 @@ describe "the regsubst function" do
19
19
  'b[an]*a',
20
20
  'coconut'
21
21
  ])
22
- end.to raise_error(Puppet::ParseError, /converted to 4x API/)
22
+ end.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
23
23
  end
24
24
  end
@@ -13,6 +13,6 @@ describe "the split function" do
13
13
  end
14
14
 
15
15
  it 'should raise a ParseError' do
16
- expect { @scope.function_split([ '130;236;254;10', ';']) }.to raise_error(Puppet::ParseError, /converted to 4x API/)
16
+ expect { @scope.function_split([ '130;236;254;10', ';']) }.to raise_error(Puppet::ParseError, /can only be called using the 4.x function API/)
17
17
  end
18
18
  end
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  require 'puppet/pops'
5
5
  require 'puppet/pops/evaluator/evaluator_impl'
6
6
  require 'puppet/pops/types/type_factory'
7
-
7
+ require 'base64'
8
8
 
9
9
  # relative to this spec file (./) does not work as this file is loaded by rspec
10
10
  require File.join(File.dirname(__FILE__), '/evaluator_rspec_helper')
@@ -20,6 +20,13 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
20
20
  Puppet::Pops::Types::TypeFactory.float_range(from, to)
21
21
  end
22
22
 
23
+ def binary(s)
24
+ # Note that the factory is not aware of Binary and cannot operate on a
25
+ # literal binary. Instead, it must create a call to Binary.new() with the base64 encoded
26
+ # string as an argument
27
+ CALL_NAMED(QREF("Binary"), true, [Base64.strict_encode64(s)])
28
+ end
29
+
23
30
  context 'The evaluator when operating on a String' do
24
31
  it 'can get a single character using a single key index to []' do
25
32
  expect(evaluate(literal('abc')[1])).to eql('b')
@@ -45,6 +52,31 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
45
52
  end
46
53
  end
47
54
 
55
+ context 'The evaluator when operating on a Binary' do
56
+ it 'can get a single character using a single key index to []' do
57
+ expect(evaluate(binary('abc')[1]).binary_buffer).to eql('b')
58
+ end
59
+
60
+ it 'can get the last character using the key -1 in []' do
61
+ expect(evaluate(binary('abc')[-1]).binary_buffer).to eql('c')
62
+ end
63
+
64
+ it 'can get a substring by giving two keys' do
65
+ expect(evaluate(binary('abcd')[1,2]).binary_buffer).to eql('bc')
66
+ # flattens keys
67
+ expect(evaluate(binary('abcd')[[1,2]]).binary_buffer).to eql('bc')
68
+ end
69
+
70
+ it 'produces empty string for a substring out of range' do
71
+ expect(evaluate(binary('abc')[100]).binary_buffer).to eql('')
72
+ end
73
+
74
+ it 'raises an error if arity is wrong for []' do
75
+ expect{evaluate(binary('abc')[])}.to raise_error(/String supports \[\] with one or two arguments\. Got 0/)
76
+ expect{evaluate(binary('abc')[1,2,3])}.to raise_error(/String supports \[\] with one or two arguments\. Got 3/)
77
+ end
78
+ end
79
+
48
80
  context 'The evaluator when operating on an Array' do
49
81
  it 'is tested with the correct assumptions' do
50
82
  expect(literal([1,2,3])[1].current.is_a?(Puppet::Pops::Model::AccessExpression)).to eql(true)
@@ -235,6 +267,40 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
235
267
  expect { evaluate(expr)}.to raise_error(/Array-Type\[\] arguments must be types/)
236
268
  end
237
269
 
270
+ # Timespan Type
271
+ #
272
+ it 'produdes a Timespan type with a lower bound' do
273
+ expr = fqr('Timespan')[{fqn('hours') => literal(3)}]
274
+ expect(evaluate(expr)).to be_the_type(types.timespan({'hours' => 3}))
275
+ end
276
+
277
+ it 'produdes a Timespan type with an upper bound' do
278
+ expr = fqr('Timespan')[literal(:default), {fqn('hours') => literal(9)}]
279
+ expect(evaluate(expr)).to be_the_type(types.timespan(nil, {'hours' => 9}))
280
+ end
281
+
282
+ it 'produdes a Timespan type with both lower and upper bounds' do
283
+ expr = fqr('Timespan')[{fqn('hours') => literal(3)}, {fqn('hours') => literal(9)}]
284
+ expect(evaluate(expr)).to be_the_type(types.timespan({'hours' => 3}, {'hours' => 9}))
285
+ end
286
+
287
+ # Timestamp Type
288
+ #
289
+ it 'produdes a Timestamp type with a lower bound' do
290
+ expr = fqr('Timestamp')[literal('2014-12-12T13:14:15 CET')]
291
+ expect(evaluate(expr)).to be_the_type(types.timestamp('2014-12-12T13:14:15 CET'))
292
+ end
293
+
294
+ it 'produdes a Timestamp type with an upper bound' do
295
+ expr = fqr('Timestamp')[literal(:default), literal('2016-08-23T17:50:00 CET')]
296
+ expect(evaluate(expr)).to be_the_type(types.timestamp(nil, '2016-08-23T17:50:00 CET'))
297
+ end
298
+
299
+ it 'produdes a Timestamp type with both lower and upper bounds' do
300
+ expr = fqr('Timestamp')[literal('2014-12-12T13:14:15 CET'), literal('2016-08-23T17:50:00 CET')]
301
+ expect(evaluate(expr)).to be_the_type(types.timestamp('2014-12-12T13:14:15 CET', '2016-08-23T17:50:00 CET'))
302
+ end
303
+
238
304
  # Tuple Type
239
305
  #
240
306
  it 'produces a Tuple[String] from the expression Tuple[String]' do
@@ -459,6 +525,20 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
459
525
  expect(evaluate(type_expr)).to eql(tf.ruby_type('String'))
460
526
  end
461
527
 
528
+ # Callable Type
529
+ #
530
+ it 'produces Callable instance without return type' do
531
+ type_expr = fqr('Callable')[fqr('String')]
532
+ tf = Puppet::Pops::Types::TypeFactory
533
+ expect(evaluate(type_expr)).to eql(tf.callable(String))
534
+ end
535
+
536
+ it 'produces Callable instance with parameters and return type' do
537
+ type_expr = fqr('Callable')[[fqr('String')], fqr('Integer')]
538
+ tf = Puppet::Pops::Types::TypeFactory
539
+ expect(evaluate(type_expr)).to eql(tf.callable([String], Integer))
540
+ end
541
+
462
542
  end
463
543
 
464
544
  matcher :be_the_type do |type|