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
@@ -178,6 +178,38 @@ end
178
178
  expect(s.string(f.iterator(f.integer))).to eq('Iterator[Integer]')
179
179
  end
180
180
 
181
+ it "should yield 'Timespan' for PTimespanType" do
182
+ expect(s.string(f.timespan())).to eq('Timespan')
183
+ end
184
+
185
+ it "should yield 'Timespan[{hours => 1}] for PTimespanType[Timespan]" do
186
+ expect(s.string(f.timespan({'hours' => 1}))).to eq("Timespan['0-01:00:00.0']")
187
+ end
188
+
189
+ it "should yield 'Timespan[default, {hours => 2}] for PTimespanType[nil, Timespan]" do
190
+ expect(s.string(f.timespan(nil, {'hours' => 2}))).to eq("Timespan[default, '0-02:00:00.0']")
191
+ end
192
+
193
+ it "should yield 'Timespan[{hours => 1}, {hours => 2}] for PTimespanType[Timespan, Timespan]" do
194
+ expect(s.string(f.timespan({'hours' => 1}, {'hours' => 2}))).to eq("Timespan['0-01:00:00.0', '0-02:00:00.0']")
195
+ end
196
+
197
+ it "should yield 'Timestamp' for PTimestampType" do
198
+ expect(s.string(f.timestamp())).to eq('Timestamp')
199
+ end
200
+
201
+ it "should yield 'Timestamp['2016-09-05T13:00:00.000 UTC'] for PTimestampType[Timestamp]" do
202
+ expect(s.string(f.timestamp('2016-09-05T13:00:00.000 UTC'))).to eq("Timestamp['2016-09-05T13:00:00.000 UTC']")
203
+ end
204
+
205
+ it "should yield 'Timestamp[default, '2016-09-05T13:00:00.000 UTC'] for PTimestampType[nil, Timestamp]" do
206
+ expect(s.string(f.timestamp(nil, '2016-09-05T13:00:00.000 UTC'))).to eq("Timestamp[default, '2016-09-05T13:00:00.000 UTC']")
207
+ end
208
+
209
+ it "should yield 'Timestamp['2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC'] for PTimestampType[Timestamp, Timestamp]" do
210
+ expect(s.string(f.timestamp('2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC'))).to eq("Timestamp['2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC']")
211
+ end
212
+
181
213
  it "should yield 'Tuple[Integer]' for PTupleType[PIntegerType]" do
182
214
  expect(s.string(f.tuple([f.integer]))).to eq('Tuple[Integer]')
183
215
  end
@@ -269,10 +301,18 @@ end
269
301
  expect(s.string(f.callable)).to eql('Callable[0, 0]')
270
302
  end
271
303
 
304
+ it "should yield 'Callable[[0,0],rt]' for callable without params but with return type" do
305
+ expect(s.string(f.callable([], Float))).to eql('Callable[[0, 0], Float]')
306
+ end
307
+
272
308
  it "should yield 'Callable[t,t]' for callable with typed parameters" do
273
309
  expect(s.string(f.callable(String, Integer))).to eql('Callable[String, Integer]')
274
310
  end
275
311
 
312
+ it "should yield 'Callable[[t,t],rt]' for callable with typed parameters and return type" do
313
+ expect(s.string(f.callable([String, Integer], Float))).to eql('Callable[[String, Integer], Float]')
314
+ end
315
+
276
316
  it "should yield 'Callable[t,min,max]' for callable with size constraint (infinite max)" do
277
317
  expect(s.string(f.callable(String, 0))).to eql('Callable[String, 0, default]')
278
318
  end
@@ -112,84 +112,95 @@ describe 'the type mismatch describer' do
112
112
  /parameter 'evars' expects a match for EVariants = Enum\['a', 'b', 'c', 'd'\], got 'n'/))
113
113
  end
114
114
 
115
+ it "will not generalize a string that doesn't match an enum in a function call" do
116
+ code = <<-CODE
117
+ function check_enums(Enum[a,b] $arg) {}
118
+ check_enums('c')
119
+ CODE
120
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
121
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got 'c'/))
122
+ end
123
+
124
+ it "will not disclose a Sensitive that doesn't match an enum in a function call" do
125
+ code = <<-CODE
126
+ function check_enums(Enum[a,b] $arg) {}
127
+ check_enums(Sensitive('c'))
128
+ CODE
129
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
130
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got Sensitive/))
131
+ end
132
+
133
+ it "will not generalize a string that doesn't match an enum in a define call" do
134
+ code = <<-CODE
135
+ define check_enums(Enum[a,b] $arg) {}
136
+ check_enums { x: arg => 'c' }
137
+ CODE
138
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
139
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got 'c'/))
140
+ end
141
+
142
+ it "will not disclose a Sensitive that doesn't match an enum in a define call" do
143
+ code = <<-CODE
144
+ define check_enums(Enum[a,b] $arg) {}
145
+ check_enums { x: arg => Sensitive('c') }
146
+ CODE
147
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
148
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got Sensitive/))
149
+ end
150
+
115
151
  context 'when reporting a mismatch between' do
116
- let(:parser) { TypeParser.new }
152
+ let(:parser) { TypeParser.singleton }
117
153
  let(:subject) { TypeMismatchDescriber.singleton }
118
154
 
119
155
  context 'hash and struct' do
120
156
  it 'reports a size mismatch when hash has unlimited size' do
121
157
  expected = parser.parse('Struct[{a=>Integer,b=>Integer}]')
122
158
  actual = parser.parse('Hash[String,Integer]')
123
- expect(subject.describe_mismatch('', expected, actual)).to eq('expected size to be 2, got unlimited')
159
+ expect(subject.describe_mismatch('', expected, actual)).to eq('expects size to be 2, got unlimited')
124
160
  end
125
161
 
126
162
  it 'reports a size mismatch when hash has specified but incorrect size' do
127
163
  expected = parser.parse('Struct[{a=>Integer,b=>Integer}]')
128
164
  actual = parser.parse('Hash[String,Integer,1,1]')
129
- expect(subject.describe_mismatch('', expected, actual)).to eq('expected size to be 2, got 1')
165
+ expect(subject.describe_mismatch('', expected, actual)).to eq('expects size to be 2, got 1')
130
166
  end
131
167
 
132
168
  it 'reports a full type mismatch when size is correct but hash value type is incorrect' do
133
169
  expected = parser.parse('Struct[{a=>Integer,b=>String}]')
134
170
  actual = parser.parse('Hash[String,Integer,2,2]')
135
- expect(subject.describe_mismatch('', expected, actual)).to eq("expected a Struct[{'a' => Integer, 'b' => String}] value, got Hash[String, Integer]")
171
+ expect(subject.describe_mismatch('', expected, actual)).to eq("expects a Struct[{'a' => Integer, 'b' => String}] value, got Hash[String, Integer]")
136
172
  end
137
173
  end
138
- end
139
174
 
140
- context 'when using present tense' do
141
- let(:parser) { TypeParser.singleton }
142
- let(:subject) { TypeMismatchDescriber.singleton }
143
175
  it 'reports a missing parameter as "has no parameter"' do
144
176
  t = parser.parse('Struct[{a=>String}]')
145
- expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false, :present) }.to raise_error(Puppet::Error, "v: has no parameter named 'b'")
177
+ expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false) }.to raise_error(Puppet::Error, "v: has no parameter named 'b'")
146
178
  end
147
179
 
148
180
  it 'reports a missing value as "expects a value"' do
149
181
  t = parser.parse('Struct[{a=>String,b=>String}]')
150
- expect { subject.validate_parameters('v', t, {'a'=>'a'}, false, :present) }.to raise_error(Puppet::Error, "v: expects a value for parameter 'b'")
182
+ expect { subject.validate_parameters('v', t, {'a'=>'a'}, false) }.to raise_error(Puppet::Error, "v: expects a value for parameter 'b'")
151
183
  end
152
184
 
153
185
  it 'reports a missing block as "expects a block"' do
154
186
  callable = parser.parse('Callable[String,String,Callable]')
155
187
  args_tuple = parser.parse('Tuple[String,String]')
156
188
  dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], 'block', nil, nil, false)
157
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :present)).to eq("'function' expects a block")
189
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' expects a block")
158
190
  end
159
191
 
160
192
  it 'reports an unexpected block as "does not expect a block"' do
161
193
  callable = parser.parse('Callable[String,String]')
162
194
  args_tuple = parser.parse('Tuple[String,String,Callable]')
163
195
  dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], nil, nil, nil, false)
164
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :present)).to eq("'function' does not expect a block")
165
- end
166
- end
167
-
168
- context 'when using past tense' do
169
- let(:parser) { TypeParser.singleton }
170
- let(:subject) { TypeMismatchDescriber.singleton }
171
- it 'reports a missing parameter as "did not have a parameter"' do
172
- t = parser.parse('Struct[{a=>String}]')
173
- expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false, :past) }.to raise_error(Puppet::Error, "v: did not have a parameter named 'b'")
174
- end
175
-
176
- it 'reports a missing value as "expected a value"' do
177
- t = parser.parse('Struct[{a=>String,b=>String}]')
178
- expect { subject.validate_parameters('v', t, {'a'=>'a'}, false, :past) }.to raise_error(Puppet::Error, "v: expected a value for parameter 'b'")
179
- end
180
-
181
- it 'reports a missing block as "expected a block"' do
182
- callable = parser.parse('Callable[String,String,Callable]')
183
- args_tuple = parser.parse('Tuple[String,String]')
184
- dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], 'block', nil, nil, false)
185
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :past)).to eq("'function' expected a block")
196
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' does not expect a block")
186
197
  end
187
198
 
188
- it 'reports an unexpected block as "did not expect a block"' do
189
- callable = parser.parse('Callable[String,String]')
190
- args_tuple = parser.parse('Tuple[String,String,Callable]')
191
- dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], nil, nil, nil, false)
192
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :past)).to eq("'function' did not expect a block")
199
+ it 'reports a block return type mismatch' do
200
+ callable = parser.parse('Callable[[0,0,Callable[ [0,0],String]],Undef]')
201
+ args_tuple = parser.parse('Tuple[Callable[[0,0],Integer]]')
202
+ dispatch = Functions::Dispatch.new(callable, 'foo', [], 'block', nil, nil, false)
203
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' block return expects a String value, got Integer")
193
204
  end
194
205
  end
195
206
  end
@@ -111,6 +111,16 @@ describe TypeParser do
111
111
  expect(the_type_parsed_from(opt_t)).to be_the_type(opt_t)
112
112
  end
113
113
 
114
+ it "parses timespan type" do
115
+ timespan_t = types.timespan
116
+ expect(the_type_parsed_from(timespan_t)).to be_the_type(timespan_t)
117
+ end
118
+
119
+ it "parses timestamp type" do
120
+ timestamp_t = types.timestamp
121
+ expect(the_type_parsed_from(timestamp_t)).to be_the_type(timestamp_t)
122
+ end
123
+
114
124
  it "parses tuple type" do
115
125
  tuple_t = types.tuple([Integer, String])
116
126
  expect(the_type_parsed_from(tuple_t)).to be_the_type(tuple_t)
@@ -248,6 +258,38 @@ describe TypeParser do
248
258
  expect(parser.parse("Collection[1,2]")).to be_the_type(types.collection(types.range(1,2)))
249
259
  end
250
260
 
261
+ it 'parses a timespan type' do
262
+ expect(parser.parse("Timespan")).to be_the_type(types.timespan)
263
+ end
264
+
265
+ it 'parses a timespan type with a lower bound' do
266
+ expect(parser.parse("Timespan[{hours => 3}]")).to be_the_type(types.timespan({'hours' => 3}))
267
+ end
268
+
269
+ it 'parses a timespan type with an upper bound' do
270
+ expect(parser.parse("Timespan[default, {hours => 9}]")).to be_the_type(types.timespan(nil, {'hours' => 9}))
271
+ end
272
+
273
+ it 'parses a timespan type with both lower and upper bounds' do
274
+ expect(parser.parse("Timespan[{hours => 3}, {hours => 9}]")).to be_the_type(types.timespan({'hours' => 3}, {'hours' => 9}))
275
+ end
276
+
277
+ it 'parses a timestamp type' do
278
+ expect(parser.parse("Timestamp")).to be_the_type(types.timestamp)
279
+ end
280
+
281
+ it 'parses a timestamp type with a lower bound' do
282
+ expect(parser.parse("Timestamp['2014-12-12T13:14:15 CET']")).to be_the_type(types.timestamp('2014-12-12T13:14:15 CET'))
283
+ end
284
+
285
+ it 'parses a timestamp type with an upper bound' do
286
+ expect(parser.parse("Timestamp[default, '2014-12-12T13:14:15 CET']")).to be_the_type(types.timestamp(nil, '2014-12-12T13:14:15 CET'))
287
+ end
288
+
289
+ it 'parses a timestamp type with both lower and upper bounds' do
290
+ expect(parser.parse("Timestamp['2014-12-12T13:14:15 CET', '2016-08-23T17:50:00 CET']")).to be_the_type(types.timestamp('2014-12-12T13:14:15 CET', '2016-08-23T17:50:00 CET'))
291
+ end
292
+
251
293
  it 'parses a type type' do
252
294
  expect(parser.parse("Type[Integer]")).to be_the_type(types.type_type(types.integer))
253
295
  end
@@ -257,25 +299,57 @@ describe TypeParser do
257
299
  end
258
300
 
259
301
  it 'parses a callable type' do
260
- expect(parser.parse("Callable")).to be_the_type(types.all_callables())
302
+ t = parser.parse("Callable")
303
+ expect(t).to be_the_type(types.all_callables())
304
+ expect(t.return_type).to be_nil
261
305
  end
262
306
 
263
307
  it 'parses a parameterized callable type' do
264
- expect(parser.parse("Callable[String, Integer]")).to be_the_type(types.callable(String, Integer))
308
+ t = parser.parse("Callable[String, Integer]")
309
+ expect(t).to be_the_type(types.callable(String, Integer))
310
+ expect(t.return_type).to be_nil
265
311
  end
266
312
 
267
313
  it 'parses a parameterized callable type with min/max' do
268
- expect(parser.parse("Callable[String, Integer, 1, default]")).to be_the_type(types.callable(String, Integer, 1, :default))
314
+ t = parser.parse("Callable[String, Integer, 1, default]")
315
+ expect(t).to be_the_type(types.callable(String, Integer, 1, :default))
316
+ expect(t.return_type).to be_nil
269
317
  end
270
318
 
271
319
  it 'parses a parameterized callable type with block' do
272
- expect(parser.parse("Callable[String, Callable[Boolean]]")).to be_the_type(types.callable(String, types.callable(true)))
320
+ t = parser.parse("Callable[String, Callable[Boolean]]")
321
+ expect(t).to be_the_type(types.callable(String, types.callable(true)))
322
+ expect(t.return_type).to be_nil
323
+ end
324
+
325
+ it 'parses a callable with no parameters and return type' do
326
+ expect(parser.parse("Callable[[],Float]")).to be_the_type(types.callable([],Float))
327
+ end
328
+
329
+ it 'parses a parameterized callable type with return type' do
330
+ expect(parser.parse("Callable[[String, Integer],Float]")).to be_the_type(types.callable([String, Integer],Float))
331
+ end
332
+
333
+ it 'parses a parameterized callable type with min/max and return type' do
334
+ expect(parser.parse("Callable[[String, Integer, 1, default],Float]")).to be_the_type(types.callable([String, Integer, 1, :default], Float))
335
+ end
336
+
337
+ it 'parses a parameterized callable type with block and return type' do
338
+ expect(parser.parse("Callable[[String, Callable[Boolean]],Float]")).to be_the_type(types.callable([String, types.callable(true)], Float))
273
339
  end
274
340
 
275
341
  it 'parses a parameterized callable type with 0 min/max' do
276
342
  t = parser.parse("Callable[0,0]")
277
343
  expect(t).to be_the_type(types.callable(0,0))
278
344
  expect(t.param_types.types).to be_empty
345
+ expect(t.return_type).to be_nil
346
+ end
347
+
348
+ it 'parses a parameterized callable type with 0 min/max and return_type' do
349
+ t = parser.parse("Callable[[0,0],Float]")
350
+ expect(t).to be_the_type(types.callable([0,0],Float))
351
+ expect(t.param_types.types).to be_empty
352
+ expect(t.return_type).to be_the_type(types.float)
279
353
  end
280
354
 
281
355
  it 'parses a parameterized callable type with >0 min/max' do
@@ -283,6 +357,15 @@ describe TypeParser do
283
357
  expect(t).to be_the_type(types.callable(0,1))
284
358
  # Contains a Unit type to indicate "called with what you accept"
285
359
  expect(t.param_types.types[0]).to be_the_type(PUnitType.new())
360
+ expect(t.return_type).to be_nil
361
+ end
362
+
363
+ it 'parses a parameterized callable type with >0 min/max and a return type' do
364
+ t = parser.parse("Callable[[0,1],Float]")
365
+ expect(t).to be_the_type(types.callable([0,1], Float))
366
+ # Contains a Unit type to indicate "called with what you accept"
367
+ expect(t.param_types.types[0]).to be_the_type(PUnitType.new())
368
+ expect(t.return_type).to be_the_type(types.float)
286
369
  end
287
370
 
288
371
  it 'parses all known literals' do
@@ -440,7 +440,7 @@ describe 'Puppet Type System' do
440
440
  type Foo = Variant[Foo,String,Integer]
441
441
  assert_type(Foo, /x/)
442
442
  CODE
443
- expect { eval_and_collect_notices(code) }.to raise_error(/expected a value of type String or Integer, got Regexp/)
443
+ expect { eval_and_collect_notices(code) }.to raise_error(/expects a value of type String or Integer, got Regexp/)
444
444
  end
445
445
 
446
446
  it 'will handle a scalar correctly in combinations of nested aliased variants' do
@@ -440,6 +440,29 @@ describe "validating 4x" do
440
440
  end
441
441
  end
442
442
 
443
+ context 'that are functions' do
444
+ it 'accepts typed parameters' do
445
+ source = <<-CODE
446
+ function f(Integer $a) { $a }
447
+ CODE
448
+ expect(validate(parse(source))).not_to have_any_issues
449
+ end
450
+
451
+ it 'accepts return types' do
452
+ source = <<-CODE
453
+ function f() >> Integer { 42 }
454
+ CODE
455
+ expect(validate(parse(source))).not_to have_any_issues
456
+ end
457
+
458
+ it 'accepts block with return types' do
459
+ source = <<-CODE
460
+ map([1,2]) |Integer $x| >> Integer { $x + 3 }
461
+ CODE
462
+ expect(validate(parse(source))).not_to have_any_issues
463
+ end
464
+ end
465
+
443
466
  context 'that are type mappings' do
444
467
  it 'accepts a valid type mapping expression' do
445
468
  source = <<-CODE
@@ -115,6 +115,7 @@ FSTAB
115
115
  describe "mountinstances" do
116
116
  it "should get name from mountoutput found on Solaris" do
117
117
  Facter.stubs(:value).with(:osfamily).returns 'Solaris'
118
+ Facter.stubs(:value).with(:kernel).returns 'SunOS'
118
119
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('solaris.mount')))
119
120
  mounts = described_class.mountinstances
120
121
  expect(mounts.size).to eq(6)
@@ -128,6 +129,7 @@ FSTAB
128
129
 
129
130
  it "should get name from mountoutput found on HP-UX" do
130
131
  Facter.stubs(:value).with(:osfamily).returns 'HP-UX'
132
+ Facter.stubs(:value).with(:kernel).returns 'HP-UX'
131
133
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('hpux.mount')))
132
134
  mounts = described_class.mountinstances
133
135
  expect(mounts.size).to eq(17)
@@ -150,32 +152,35 @@ FSTAB
150
152
  expect(mounts[16]).to eq({ :name => '/ghost', :mounted => :yes })
151
153
  end
152
154
 
153
- it "should get name from mountoutput found on Darwin" do
155
+ it "should get name and mount options from mountoutput found on Darwin" do
154
156
  Facter.stubs(:value).with(:osfamily).returns 'Darwin'
157
+ Facter.stubs(:value).with(:kernel).returns 'Darwin'
155
158
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('darwin.mount')))
156
159
  mounts = described_class.mountinstances
157
160
  expect(mounts.size).to eq(6)
158
- expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
159
- expect(mounts[1]).to eq({ :name => '/dev', :mounted => :yes })
160
- expect(mounts[2]).to eq({ :name => '/net', :mounted => :yes })
161
- expect(mounts[3]).to eq({ :name => '/home', :mounted => :yes })
162
- expect(mounts[4]).to eq({ :name => '/usr', :mounted => :yes })
163
- expect(mounts[5]).to eq({ :name => '/ghost', :mounted => :yes })
161
+ expect(mounts[0]).to eq({ :name => '/', :mounted => :yes, :live_options=>"hfs, local, journaled"})
162
+ expect(mounts[1]).to eq({ :name => '/dev', :mounted => :yes, :live_options=>"devfs, local, nobrowse"})
163
+ expect(mounts[2]).to eq({ :name => '/net', :mounted => :yes, :live_options=>"autofs, nosuid, automounted, nobrowse"})
164
+ expect(mounts[3]).to eq({ :name => '/home', :mounted => :yes, :mounted=>:yes, :live_options=>"autofs, automounted, nobrowse"})
165
+ expect(mounts[4]).to eq({ :name => '/usr', :mounted => :yes, :mounted=>:yes, :live_options=>"hfs, local, journaled"})
166
+ expect(mounts[5]).to eq({ :name => '/ghost', :mounted => :yes, :live_options => "hfs, local, journaled"})
164
167
  end
165
168
 
166
- it "should get name from mountoutput found on Linux" do
169
+ it "should get name and mount options from mountoutput found on Linux" do
167
170
  Facter.stubs(:value).with(:osfamily).returns 'Gentoo'
171
+ Facter.stubs(:value).with(:kernel).returns 'Linux'
168
172
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('linux.mount')))
169
173
  mounts = described_class.mountinstances
170
- expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
171
- expect(mounts[1]).to eq({ :name => '/lib64/rc/init.d', :mounted => :yes })
172
- expect(mounts[2]).to eq({ :name => '/sys', :mounted => :yes })
173
- expect(mounts[3]).to eq({ :name => '/usr/portage', :mounted => :yes })
174
- expect(mounts[4]).to eq({ :name => '/ghost', :mounted => :yes })
174
+ expect(mounts[0]).to eq({ :name => '/', :mounted => :yes, :live_options=>"rw,noatime"})
175
+ expect(mounts[1]).to eq({ :name => '/lib64/rc/init.d', :mounted => :yes, :live_options => "rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755" })
176
+ expect(mounts[2]).to eq({ :name => '/sys', :mounted => :yes, :live_options => "rw,nosuid,nodev,noexec,relatime"})
177
+ expect(mounts[3]).to eq({ :name => '/usr/portage', :mounted => :yes, :live_options => "rw" })
178
+ expect(mounts[4]).to eq({ :name => '/ghost', :mounted => :yes, :live_options => "rw" })
175
179
  end
176
180
 
177
181
  it "should get name from mountoutput found on AIX" do
178
182
  Facter.stubs(:value).with(:osfamily).returns 'AIX'
183
+ Facter.stubs(:value).with(:kernel).returns 'AIX'
179
184
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('aix.mount')))
180
185
  mounts = described_class.mountinstances
181
186
  expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
@@ -224,29 +229,42 @@ FSTAB
224
229
  platform != 'solaris' or
225
230
  skip "We need to stub the operatingsystem fact at load time, but can't"
226
231
  end
227
-
228
- # Stub the mount output to our fixture.
229
- begin
230
- mount = my_fixture(platform + '.mount')
231
- described_class.stubs(:mountcmd).returns File.read(mount)
232
- rescue
233
- skip "is #{platform}.mount missing at this point?"
234
- end
235
-
236
- # Note: we have to stub default_target before creating resources
237
- # because it is used by Puppet::Type::Mount.new to populate the
238
- # :target property.
239
- described_class.stubs(:default_target).returns fstab
240
- @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
241
232
  end
242
233
 
243
234
  # Following mountpoint are present in all fstabs/mountoutputs
244
235
  describe "on other platforms than Solaris", :if => Facter.value(:osfamily) != 'Solaris' do
245
- it "should include unmounted resources" do
236
+ before :each do
237
+ # Stub the mount output to our fixture.
238
+ begin
239
+ mount = my_fixture(platform + '.mount')
240
+ described_class.stubs(:mountcmd).returns File.read(mount)
241
+ rescue
242
+ skip "is #{platform}.mount missing at this point?"
243
+ end
244
+
245
+ # Note: we have to stub default_target before creating resources
246
+ # because it is used by Puppet::Type::Mount.new to populate the
247
+ # :target property.
248
+ described_class.stubs(:default_target).returns fstab
249
+
250
+ platforms = {
251
+ 'linux' => ['Gentoo', 'Linux'],
252
+ 'freebsd' => ['BSD', 'BSD'],
253
+ 'openbsd' => ['BSD', 'BSD'],
254
+ 'netbsd' => ['BSd', 'BSD']
255
+ }
256
+ Facter.stubs(:value).with(:osfamily).returns(platforms[platform][0])
257
+ Facter.stubs(:value).with(:kernel).returns(platforms[platform][1])
258
+
259
+ @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
260
+ end
261
+
262
+ it "should include mounted resources" do
246
263
  expect(@retrieve).to include(:name => '/', :ensure => :mounted)
247
264
  end
248
265
 
249
- it "should include mounted resources" do
266
+ it "should include unmounted resources" do
267
+ @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
250
268
  expect(@retrieve).to include(:name => '/boot', :ensure => :unmounted)
251
269
  end
252
270