puppet 7.1.0 → 7.3.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +15 -13
  3. data/lib/puppet/application.rb +10 -6
  4. data/lib/puppet/application/agent.rb +1 -0
  5. data/lib/puppet/application/apply.rb +3 -2
  6. data/lib/puppet/application/device.rb +1 -0
  7. data/lib/puppet/application/script.rb +1 -0
  8. data/lib/puppet/configurer.rb +16 -3
  9. data/lib/puppet/defaults.rb +5 -14
  10. data/lib/puppet/face/facts.rb +15 -1
  11. data/lib/puppet/file_serving/configuration/parser.rb +5 -2
  12. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  13. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  14. data/lib/puppet/network/formats.rb +67 -0
  15. data/lib/puppet/parser/ast/leaf.rb +3 -2
  16. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  17. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  18. data/lib/puppet/provider/package/apt.rb +4 -0
  19. data/lib/puppet/reference/configuration.rb +6 -5
  20. data/lib/puppet/settings.rb +33 -28
  21. data/lib/puppet/settings/alias_setting.rb +37 -0
  22. data/lib/puppet/util/autoload.rb +1 -8
  23. data/lib/puppet/util/posix.rb +1 -1
  24. data/lib/puppet/version.rb +1 -1
  25. data/locales/puppet.pot +157 -141
  26. data/man/man5/puppet.conf.5 +6 -6
  27. data/man/man8/puppet-agent.8 +2 -2
  28. data/man/man8/puppet-apply.8 +2 -2
  29. data/man/man8/puppet-catalog.8 +1 -1
  30. data/man/man8/puppet-config.8 +1 -1
  31. data/man/man8/puppet-describe.8 +1 -1
  32. data/man/man8/puppet-device.8 +2 -2
  33. data/man/man8/puppet-doc.8 +1 -1
  34. data/man/man8/puppet-epp.8 +1 -1
  35. data/man/man8/puppet-facts.8 +5 -2
  36. data/man/man8/puppet-filebucket.8 +1 -1
  37. data/man/man8/puppet-generate.8 +1 -1
  38. data/man/man8/puppet-help.8 +1 -1
  39. data/man/man8/puppet-lookup.8 +1 -1
  40. data/man/man8/puppet-module.8 +1 -1
  41. data/man/man8/puppet-node.8 +1 -1
  42. data/man/man8/puppet-parser.8 +1 -1
  43. data/man/man8/puppet-plugin.8 +1 -1
  44. data/man/man8/puppet-report.8 +1 -1
  45. data/man/man8/puppet-resource.8 +1 -1
  46. data/man/man8/puppet-script.8 +2 -2
  47. data/man/man8/puppet-ssl.8 +1 -1
  48. data/man/man8/puppet.8 +2 -2
  49. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  50. data/spec/integration/application/agent_spec.rb +127 -3
  51. data/spec/integration/application/apply_spec.rb +19 -0
  52. data/spec/integration/defaults_spec.rb +0 -7
  53. data/spec/integration/indirector/file_content/file_server_spec.rb +0 -2
  54. data/spec/integration/indirector/file_metadata/file_server_spec.rb +0 -2
  55. data/spec/integration/resource/type_collection_spec.rb +2 -6
  56. data/spec/integration/transaction_spec.rb +4 -9
  57. data/spec/integration/util/windows/adsi_spec.rb +3 -1
  58. data/spec/integration/util/windows/registry_spec.rb +0 -10
  59. data/spec/spec_helper.rb +1 -4
  60. data/spec/unit/agent_spec.rb +8 -6
  61. data/spec/unit/application/agent_spec.rb +0 -1
  62. data/spec/unit/application/filebucket_spec.rb +0 -2
  63. data/spec/unit/application_spec.rb +17 -9
  64. data/spec/unit/confine/feature_spec.rb +1 -1
  65. data/spec/unit/confine_spec.rb +8 -2
  66. data/spec/unit/face/node_spec.rb +0 -11
  67. data/spec/unit/file_serving/configuration/parser_spec.rb +8 -1
  68. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  69. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  70. data/spec/unit/forge/module_release_spec.rb +2 -7
  71. data/spec/unit/indirector/face_spec.rb +0 -1
  72. data/spec/unit/indirector/facts/facter_spec.rb +11 -5
  73. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  74. data/spec/unit/indirector/indirection_spec.rb +8 -12
  75. data/spec/unit/indirector_spec.rb +2 -2
  76. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  77. data/spec/unit/network/formats_spec.rb +41 -0
  78. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -4
  79. data/spec/unit/parser/compiler_spec.rb +3 -19
  80. data/spec/unit/parser/resource_spec.rb +14 -8
  81. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  82. data/spec/unit/property_spec.rb +1 -0
  83. data/spec/unit/provider/nameservice_spec.rb +66 -65
  84. data/spec/unit/provider/package/apt_spec.rb +4 -8
  85. data/spec/unit/provider/package/base_spec.rb +6 -5
  86. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  87. data/spec/unit/provider/package/pip_spec.rb +6 -11
  88. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  89. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  90. data/spec/unit/provider_spec.rb +6 -8
  91. data/spec/unit/resource/type_spec.rb +1 -1
  92. data/spec/unit/resource_spec.rb +11 -10
  93. data/spec/unit/settings_spec.rb +13 -6
  94. data/spec/unit/ssl/base_spec.rb +0 -1
  95. data/spec/unit/ssl/ssl_provider_spec.rb +5 -2
  96. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  97. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  98. data/spec/unit/transaction_spec.rb +13 -4
  99. data/spec/unit/type/file/content_spec.rb +0 -1
  100. data/spec/unit/type/file/selinux_spec.rb +0 -2
  101. data/spec/unit/type/file_spec.rb +0 -6
  102. data/spec/unit/type/group_spec.rb +13 -6
  103. data/spec/unit/type/resources_spec.rb +7 -7
  104. data/spec/unit/type/service_spec.rb +1 -1
  105. data/spec/unit/type/tidy_spec.rb +0 -1
  106. data/spec/unit/type_spec.rb +2 -2
  107. data/spec/unit/util/at_fork_spec.rb +2 -2
  108. data/spec/unit/util/autoload_spec.rb +5 -1
  109. data/spec/unit/util/backups_spec.rb +1 -2
  110. data/spec/unit/util/execution_spec.rb +15 -11
  111. data/spec/unit/util/inifile_spec.rb +6 -14
  112. data/spec/unit/util/log_spec.rb +8 -7
  113. data/spec/unit/util/logging_spec.rb +3 -3
  114. data/spec/unit/util/posix_spec.rb +16 -10
  115. data/spec/unit/util/selinux_spec.rb +76 -52
  116. data/spec/unit/util/suidmanager_spec.rb +44 -41
  117. data/spec/unit/util_spec.rb +13 -6
  118. metadata +7 -2
@@ -5,22 +5,40 @@ require 'puppet/indirector/file_bucket_file/file'
5
5
  require 'puppet/indirector/file_bucket_file/rest'
6
6
 
7
7
  describe Puppet::FileBucketFile::Selector do
8
+ let(:model) { Puppet::FileBucket::File.new('') }
9
+ let(:indirection) { Puppet::FileBucket::File.indirection }
10
+ let(:terminus) { indirection.terminus(:selector) }
11
+
8
12
  %w[head find save search destroy].each do |method|
9
13
  describe "##{method}" do
10
14
  it "should proxy to rest terminus for https requests" do
11
- request = double('request', :protocol => 'https')
15
+ key = "https://example.com/path/to/file"
12
16
 
13
- expect_any_instance_of(Puppet::FileBucketFile::Rest).to receive(method).with(request)
17
+ expect(indirection.terminus(:rest)).to receive(method)
14
18
 
15
- subject.send(method, request)
19
+ if method == 'save'
20
+ terminus.send(method, indirection.request(method, key, model))
21
+ else
22
+ terminus.send(method, indirection.request(method, key, nil))
23
+ end
16
24
  end
17
25
 
18
26
  it "should proxy to file terminus for other requests" do
19
- request = double('request', :protocol => 'file')
20
-
21
- expect_any_instance_of(Puppet::FileBucketFile::File).to receive(method).with(request)
22
-
23
- subject.send(method, request)
27
+ key = "file:///path/to/file"
28
+
29
+ case method
30
+ when 'save'
31
+ expect(indirection.terminus(:file)).to receive(method)
32
+ terminus.send(method, indirection.request(method, key, model))
33
+ when 'find', 'head'
34
+ expect(indirection.terminus(:file)).to receive(method)
35
+ terminus.send(method, indirection.request(method, key, nil))
36
+ else
37
+ # file terminus doesn't implement search or destroy
38
+ expect {
39
+ terminus.send(method, indirection.request(method, key, nil))
40
+ }.to raise_error(NoMethodError)
41
+ end
24
42
  end
25
43
  end
26
44
  end
@@ -178,29 +178,25 @@ describe Puppet::Indirector::Indirection do
178
178
 
179
179
  describe "creates a request" do
180
180
  it "should create it with its name as the request's indirection name" do
181
- expect(Puppet::Indirector::Request).to receive(:new).with(@indirection.name, anything, anything)
182
- @indirection.request(:funtest, "yayness")
181
+ expect(@indirection.request(:funtest, "yayness", nil).indirection_name).to eq(@indirection.name)
183
182
  end
184
183
 
185
184
  it "should require a method and key" do
186
- expect(Puppet::Indirector::Request).to receive(:new).with(anything, :funtest, "yayness")
187
- @indirection.request(:funtest, "yayness")
185
+ request = @indirection.request(:funtest, "yayness", nil)
186
+ expect(request.method).to eq(:funtest)
187
+ expect(request.key).to eq("yayness")
188
188
  end
189
189
 
190
190
  it "should support optional arguments" do
191
- expect(Puppet::Indirector::Request).to receive(:new).with(anything, anything, anything, {:one => :two})
192
- @indirection.request(:funtest, "yayness", :one => :two)
191
+ expect(@indirection.request(:funtest, "yayness", nil, :one => :two).options).to eq(:one => :two)
193
192
  end
194
193
 
195
194
  it "should not pass options if none are supplied" do
196
- expect(Puppet::Indirector::Request).to receive(:new).with(anything, anything, anything)
197
- @indirection.request(:funtest, "yayness")
195
+ expect(@indirection.request(:funtest, "yayness", nil).options).to eq({})
198
196
  end
199
197
 
200
198
  it "should return the request" do
201
- request = double('request')
202
- expect(Puppet::Indirector::Request).to receive(:new).and_return(request)
203
- expect(@indirection.request(:funtest, "yayness")).to equal(request)
199
+ expect(@indirection.request(:funtest, "yayness", nil)).to be_a(Puppet::Indirector::Request)
204
200
  end
205
201
  end
206
202
 
@@ -833,7 +829,7 @@ describe Puppet::Indirector::Indirection do
833
829
  end
834
830
 
835
831
  it "should not create a terminus instance until one is actually needed" do
836
- expect(Puppet::Indirector).not_to receive(:terminus)
832
+ expect(@indirection).not_to receive(:terminus)
837
833
  Puppet::Indirector::Indirection.new(double('model'), :lazytest)
838
834
  end
839
835
 
@@ -112,8 +112,8 @@ describe Puppet::Indirector, "when registering an indirection" do
112
112
  end
113
113
 
114
114
  it "should pass any provided options to the indirection during initialization" do
115
- expect(Puppet::Indirector::Indirection).to receive(:new).with(@thingie, :first, {:some => :options, :indirected_class => 'Thingie'})
116
- @indirection = @thingie.indirects :first, :some => :options
115
+ expect(Puppet::Indirector::Indirection).to receive(:new).with(@thingie, :first, {:doc => 'some docs', :indirected_class => 'Thingie'})
116
+ @indirection = @thingie.indirects :first, :doc => 'some docs'
117
117
  end
118
118
 
119
119
  it "should extend the class to handle serialization" do
@@ -247,6 +247,21 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
247
247
  expect(subject).to include :result => :success
248
248
  graph_should_include 'pmtacceptance-mysql', nil => v('0.8.0')
249
249
  end
250
+
251
+ context 'with an already installed dependency' do
252
+ before { preinstall('pmtacceptance-stdlib', '2.6.0') }
253
+
254
+ def options
255
+ super.merge(:version => '0.7.0')
256
+ end
257
+
258
+ it 'installs given version without errors and does not change version of dependency' do
259
+ expect(subject).to include :result => :success
260
+ graph_should_include 'pmtacceptance-mysql', nil => v('0.7.0')
261
+ expect(subject[:error]).to be_nil
262
+ graph_should_include 'pmtacceptance-stdlib', v('2.6.0') => v('2.6.0')
263
+ end
264
+ end
250
265
  end
251
266
 
252
267
  context 'with a --version that cannot satisfy' do
@@ -258,6 +273,20 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
258
273
  expect(subject).to include :result => :failure
259
274
  end
260
275
 
276
+ it 'prints a detailed error containing the modules that would not be satisfied' do
277
+ graph = double(SemanticPuppet::Dependency::Graph, :modules => ['pmtacceptance-mysql'])
278
+ exception = SemanticPuppet::Dependency::UnsatisfiableGraph.new(graph)
279
+ allow(exception).to receive(:respond_to?).and_return(true)
280
+ allow(exception).to receive(:unsatisfied).and_return('pmtacceptance-mysql')
281
+ allow(SemanticPuppet::Dependency).to receive(:resolve).and_raise(exception)
282
+
283
+ expect(subject[:error]).to include(:multiline)
284
+ expect(subject[:error][:multiline]).to include("Could not install module 'pmtacceptance-mysql' (> 1.0.0)")
285
+ expect(subject[:error][:multiline]).to include("The requested version cannot satisfy one or more of the following installed modules:")
286
+ expect(subject[:error][:multiline]).to include("pmtacceptance-keystone, expects 'pmtacceptance-mysql': >=0.6.1 <1.0.0")
287
+ expect(subject[:error][:multiline]).to include("Use `puppet module install 'pmtacceptance-mysql' --ignore-dependencies` to install only this module")
288
+ end
289
+
261
290
  context 'with --ignore-dependencies' do
262
291
  def options
263
292
  super.merge(:ignore_dependencies => true)
@@ -278,6 +307,43 @@ describe Puppet::ModuleTool::Applications::Installer, :unless => RUBY_PLATFORM =
278
307
  graph_should_include 'pmtacceptance-mysql', nil => v('2.1.0')
279
308
  end
280
309
  end
310
+
311
+ context 'with an already installed dependency' do
312
+ let(:graph) {
313
+ double(SemanticPuppet::Dependency::Graph,
314
+ :dependencies => {
315
+ 'pmtacceptance-mysql' => {
316
+ :version => '2.1.0'
317
+ }
318
+ },
319
+ :modules => ['pmtacceptance-mysql'],
320
+ :unsatisfied => 'pmtacceptance-stdlib'
321
+ )
322
+ }
323
+
324
+ let(:unsatisfiable_graph_exception) { SemanticPuppet::Dependency::UnsatisfiableGraph.new(graph) }
325
+
326
+ before do
327
+ allow(SemanticPuppet::Dependency).to receive(:resolve).and_raise(unsatisfiable_graph_exception)
328
+ allow(unsatisfiable_graph_exception).to receive(:respond_to?).and_return(true)
329
+ allow(unsatisfiable_graph_exception).to receive(:unsatisfied).and_return(graph.unsatisfied)
330
+
331
+ preinstall('pmtacceptance-stdlib', '2.6.0')
332
+ end
333
+
334
+ def options
335
+ super.merge(:version => '2.1.0')
336
+ end
337
+
338
+ it 'fails to install and outputs a multiline error containing the versions, expectations and workaround' do
339
+ expect(subject).to include :result => :failure
340
+ expect(subject[:error]).to include(:multiline)
341
+ expect(subject[:error][:multiline]).to include("Could not install module 'pmtacceptance-mysql' (v2.1.0)")
342
+ expect(subject[:error][:multiline]).to include("The requested version cannot satisfy one or more of the following installed modules:")
343
+ expect(subject[:error][:multiline]).to include("pmtacceptance-stdlib, installed: 2.6.0, expected: >= 2.2.1")
344
+ expect(subject[:error][:multiline]).to include("Use `puppet module install 'pmtacceptance-mysql' --ignore-dependencies` to install only this module")
345
+ end
346
+ end
281
347
  end
282
348
  end
283
349
 
@@ -534,4 +534,45 @@ EOT
534
534
  end
535
535
  end
536
536
  end
537
+
538
+ describe ":flat format" do
539
+ let(:flat) { Puppet::Network::FormatHandler.format(:flat) }
540
+
541
+ it "should include a flat format" do
542
+ expect(flat).to be_an_instance_of Puppet::Network::Format
543
+ end
544
+
545
+ [:intern, :intern_multiple].each do |method|
546
+ it "should not implement #{method}" do
547
+ expect { flat.send(method, String, 'blah') }.to raise_error NotImplementedError
548
+ end
549
+ end
550
+
551
+ context "when rendering arrays" do
552
+ {
553
+ [] => "",
554
+ [1, 2] => "0=1\n1=2\n",
555
+ ["one"] => "0=one\n",
556
+ [{"one" => 1}, {"two" => 2}] => "0.one=1\n1.two=2\n",
557
+ [['something', 'for'], ['the', 'test']] => "0=[\"something\", \"for\"]\n1=[\"the\", \"test\"]\n"
558
+ }.each_pair do |input, output|
559
+ it "should render #{input.inspect} as one item per line" do
560
+ expect(flat.render(input)).to eq(output)
561
+ end
562
+ end
563
+ end
564
+
565
+ context "when rendering hashes" do
566
+ {
567
+ {} => "",
568
+ {1 => 2} => "1=2\n",
569
+ {"one" => "two"} => "one=two\n",
570
+ {[1,2] => 3, [2,3] => 5, [3,4] => 7} => "[1, 2]=3\n[2, 3]=5\n[3, 4]=7\n",
571
+ }.each_pair do |input, output|
572
+ it "should render #{input.inspect}" do
573
+ expect(flat.render(input)).to eq(output)
574
+ end
575
+ end
576
+ end
577
+ end
537
578
  end
@@ -24,10 +24,6 @@ describe Puppet::Network::HTTP::API::IndirectedRoutes do
24
24
  let(:env_loaders) { Puppet::Environments::Static.new(environment) }
25
25
  let(:params) { { :environment => "env" } }
26
26
 
27
- before do
28
- allow(handler).to receive(:handler).and_return("foo")
29
- end
30
-
31
27
  around do |example|
32
28
  Puppet.override(:environments => env_loaders) do
33
29
  example.run
@@ -240,20 +240,9 @@ describe Puppet::Parser::Compiler do
240
240
  end
241
241
 
242
242
  describe "when compiling" do
243
- def compile_methods
244
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
245
- :finish, :store, :extract, :evaluate_relationships]
246
- end
247
-
248
- # Stub all of the main compile methods except the ones we're specifically interested in.
249
- def compile_stub(*except)
250
- (compile_methods - except).each { |m| allow(@compiler).to receive(m) }
251
- end
252
-
253
243
  it "should set node parameters as variables in the top scope" do
254
244
  params = {"a" => "b", "c" => "d"}
255
245
  allow(@node).to receive(:parameters).and_return(params)
256
- compile_stub(:set_node_parameters)
257
246
  @compiler.compile
258
247
  expect(@compiler.topscope['a']).to eq("b")
259
248
  expect(@compiler.topscope['c']).to eq("d")
@@ -262,13 +251,11 @@ describe Puppet::Parser::Compiler do
262
251
  it "should set node parameters that are of Symbol type as String variables in the top scope" do
263
252
  params = {"a" => :b}
264
253
  allow(@node).to receive(:parameters).and_return(params)
265
- compile_stub(:set_node_parameters)
266
254
  @compiler.compile
267
255
  expect(@compiler.topscope['a']).to eq("b")
268
256
  end
269
257
 
270
258
  it "should set the node's environment as a string variable in top scope" do
271
- compile_stub(:set_node_parameters)
272
259
  @node.merge({'wat' => 'this is how the sausage is made'})
273
260
  @compiler.compile
274
261
  expect(@compiler.topscope['environment']).to eq("testing")
@@ -276,7 +263,6 @@ describe Puppet::Parser::Compiler do
276
263
  end
277
264
 
278
265
  it "sets the environment based on node.environment instead of the parameters" do
279
- compile_stub(:set_node_parameters)
280
266
  @node.parameters['environment'] = "Not actually #{@node.environment.name}"
281
267
 
282
268
  @compiler.compile
@@ -286,23 +272,21 @@ describe Puppet::Parser::Compiler do
286
272
  it "should set the client and server versions on the catalog" do
287
273
  params = {"clientversion" => "2", "serverversion" => "3"}
288
274
  allow(@node).to receive(:parameters).and_return(params)
289
- compile_stub(:set_node_parameters)
290
275
  @compiler.compile
291
276
  expect(@compiler.catalog.client_version).to eq("2")
292
277
  expect(@compiler.catalog.server_version).to eq("3")
293
278
  end
294
279
 
295
280
  it "should evaluate the main class if it exists" do
296
- compile_stub(:evaluate_main)
297
281
  main_class = @known_resource_types.add Puppet::Resource::Type.new(:hostclass, "")
282
+ @compiler.topscope.source = main_class
283
+
298
284
  expect(main_class).to receive(:evaluate_code).with(be_a(Puppet::Parser::Resource))
299
- expect(@compiler.topscope).to receive(:source=).with(main_class)
300
285
 
301
286
  @compiler.compile
302
287
  end
303
288
 
304
289
  it "should create a new, empty 'main' if no main class exists" do
305
- compile_stub(:evaluate_main)
306
290
  @compiler.compile
307
291
  expect(@known_resource_types.find_hostclass("")).to be_instance_of(Puppet::Resource::Type)
308
292
  end
@@ -325,7 +309,7 @@ describe Puppet::Parser::Compiler do
325
309
  @compiler.add_collection(colls[0])
326
310
  @compiler.add_collection(colls[1])
327
311
 
328
- compile_stub(:evaluate_generators)
312
+ allow(@compiler).to receive(:fail_on_unevaluated)
329
313
  @compiler.compile
330
314
  end
331
315
 
@@ -418,22 +418,27 @@ describe Puppet::Parser::Resource do
418
418
  end
419
419
 
420
420
  describe "when merging overrides" do
421
+ def resource_type(name)
422
+ double(name, :child_of? => false)
423
+ end
424
+
421
425
  before do
422
- @source = "source1"
426
+ @source = resource_type("source1")
423
427
  @resource = mkresource :source => @source
424
428
  @override = mkresource :source => @source
425
429
  end
426
430
 
427
431
  it "should fail when the override was not created by a parent class" do
428
- @override.source = "source2"
429
- expect(@override.source).to receive(:child_of?).with("source1").and_return(false)
432
+ @override.source = resource_type("source2")
433
+ expect(@override.source).to receive(:child_of?).with(@source).and_return(false)
430
434
  expect { @resource.merge(@override) }.to raise_error(Puppet::ParseError)
431
435
  end
432
436
 
433
437
  it "should succeed when the override was created in the current scope" do
434
- @resource.source = "source3"
438
+ @source3 = resource_type("source3")
439
+ @resource.source = @source3
435
440
  @override.source = @resource.source
436
- expect(@override.source).not_to receive(:child_of?).with("source3")
441
+ expect(@override.source).not_to receive(:child_of?).with(@source3)
437
442
  params = {:a => :b, :c => :d}
438
443
  expect(@override).to receive(:parameters).and_return(params)
439
444
  expect(@resource).to receive(:override_parameter).with(:b)
@@ -442,9 +447,10 @@ describe Puppet::Parser::Resource do
442
447
  end
443
448
 
444
449
  it "should succeed when a parent class created the override" do
445
- @resource.source = "source3"
446
- @override.source = "source4"
447
- expect(@override.source).to receive(:child_of?).with("source3").and_return(true)
450
+ @source3 = resource_type("source3")
451
+ @resource.source = @source3
452
+ @override.source = resource_type("source4")
453
+ expect(@override.source).to receive(:child_of?).with(@source3).and_return(true)
448
454
  params = {:a => :b, :c => :d}
449
455
  expect(@override).to receive(:parameters).and_return(params)
450
456
  expect(@resource).to receive(:override_parameter).with(:b)
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'puppet_spec/compiler'
3
+
4
+ describe Puppet::Pops::Evaluator::DeferredResolver do
5
+ include PuppetSpec::Compiler
6
+
7
+ let(:environment) { Puppet::Node::Environment.create(:testing, []) }
8
+ let(:facts) { Puppet::Node::Facts.new('node.example.com') }
9
+
10
+ it 'resolves deferred values in a catalog' do
11
+ catalog = compile_to_catalog(<<~END)
12
+ notify { "deferred":
13
+ message => Deferred("join", [[1,2,3], ":"])
14
+ }
15
+ END
16
+ described_class.resolve_and_replace(facts, catalog)
17
+
18
+ expect(catalog.resource(:notify, 'deferred')[:message]).to eq('1:2:3')
19
+ end
20
+ end
@@ -5,6 +5,7 @@ Puppet::Type.newtype(:property_test) do
5
5
  newparam(:name, isnamevar: true)
6
6
  end
7
7
  Puppet::Type.type(:property_test).provide(:property_test) do
8
+ attr_accessor :foo
8
9
  end
9
10
 
10
11
  describe Puppet::Property do
@@ -3,11 +3,28 @@ require 'puppet/provider/nameservice'
3
3
  require 'puppet/etc'
4
4
  require 'puppet_spec/character_encoding'
5
5
 
6
+ Puppet::Type.newtype(:nameservice_dummytype) do
7
+ newparam(:name)
8
+ ensurable
9
+ newproperty(:foo)
10
+ newproperty(:bar)
11
+ end
12
+
13
+ Puppet::Type.type(:nameservice_dummytype).provide(:nameservice_dummyprovider, parent: Puppet::Provider::NameService) do
14
+ def posixmethod(param)
15
+ param
16
+ end
17
+
18
+ def modifycmd(param, value)
19
+ []
20
+ end
21
+ end
22
+
6
23
  describe Puppet::Provider::NameService do
7
24
 
8
25
  before :each do
9
- described_class.initvars
10
- described_class.resource_type = faketype
26
+ provider.class.initvars
27
+ provider.class.resource_type = faketype
11
28
  end
12
29
 
13
30
  # These are values getpwent might give you
@@ -41,16 +58,12 @@ describe Puppet::Provider::NameService do
41
58
  # The provider sometimes relies on @resource for valid properties so let's
42
59
  # create a fake type with properties that match our fake struct.
43
60
  let :faketype do
44
- Puppet::Type.newtype(:nameservice_dummytype) do
45
- newparam(:name)
46
- ensurable
47
- newproperty(:foo)
48
- newproperty(:bar)
49
- end
61
+ Puppet::Type.type(:nameservice_dummytype)
50
62
  end
51
63
 
52
64
  let :provider do
53
- described_class.new(:name => 'bob', :foo => 'fooval', :bar => 'barval')
65
+ Puppet::Type.type(:nameservice_dummytype).provider(:nameservice_dummyprovider)
66
+ .new(:name => 'bob', :foo => 'fooval', :bar => 'barval')
54
67
  end
55
68
 
56
69
  let :resource do
@@ -91,61 +104,61 @@ describe Puppet::Provider::NameService do
91
104
 
92
105
  describe "#options" do
93
106
  it "should add options for a valid property" do
94
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
95
- described_class.options :bar, :key3 => 'val3'
96
- expect(described_class.option(:foo, :key1)).to eq('val1')
97
- expect(described_class.option(:foo, :key2)).to eq('val2')
98
- expect(described_class.option(:bar, :key3)).to eq('val3')
107
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
108
+ provider.class.options :bar, :key3 => 'val3'
109
+ expect(provider.class.option(:foo, :key1)).to eq('val1')
110
+ expect(provider.class.option(:foo, :key2)).to eq('val2')
111
+ expect(provider.class.option(:bar, :key3)).to eq('val3')
99
112
  end
100
113
 
101
114
  it "should raise an error for an invalid property" do
102
- expect { described_class.options :baz, :key1 => 'val1' }.to raise_error(
115
+ expect { provider.class.options :baz, :key1 => 'val1' }.to raise_error(
103
116
  Puppet::Error, 'baz is not a valid attribute for nameservice_dummytype')
104
117
  end
105
118
  end
106
119
 
107
120
  describe "#option" do
108
121
  it "should return the correct value" do
109
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
110
- expect(described_class.option(:foo, :key2)).to eq('val2')
122
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
123
+ expect(provider.class.option(:foo, :key2)).to eq('val2')
111
124
  end
112
125
 
113
126
  it "should symbolize the name first" do
114
- described_class.options :foo, :key1 => 'val1', :key2 => 'val2'
115
- expect(described_class.option('foo', :key2)).to eq('val2')
127
+ provider.class.options :foo, :key1 => 'val1', :key2 => 'val2'
128
+ expect(provider.class.option('foo', :key2)).to eq('val2')
116
129
  end
117
130
 
118
131
  it "should return nil if no option has been specified earlier" do
119
- expect(described_class.option(:foo, :key2)).to be_nil
132
+ expect(provider.class.option(:foo, :key2)).to be_nil
120
133
  end
121
134
 
122
135
  it "should return nil if no option for that property has been specified earlier" do
123
- described_class.options :bar, :key2 => 'val2'
124
- expect(described_class.option(:foo, :key2)).to be_nil
136
+ provider.class.options :bar, :key2 => 'val2'
137
+ expect(provider.class.option(:foo, :key2)).to be_nil
125
138
  end
126
139
 
127
140
  it "should return nil if no matching key can be found for that property" do
128
- described_class.options :foo, :key3 => 'val2'
129
- expect(described_class.option(:foo, :key2)).to be_nil
141
+ provider.class.options :foo, :key3 => 'val2'
142
+ expect(provider.class.option(:foo, :key2)).to be_nil
130
143
  end
131
144
  end
132
145
 
133
146
  describe "#section" do
134
147
  it "should raise an error if resource_type has not been set" do
135
- expect(described_class).to receive(:resource_type).and_return(nil)
136
- expect { described_class.section }.to raise_error Puppet::Error, 'Cannot determine Etc section without a resource type'
148
+ expect(provider.class).to receive(:resource_type).and_return(nil)
149
+ expect { provider.class.section }.to raise_error Puppet::Error, 'Cannot determine Etc section without a resource type'
137
150
  end
138
151
 
139
152
  # the return values are hard coded so I am using types that actually make
140
153
  # use of the nameservice provider
141
154
  it "should return pw for users" do
142
- described_class.resource_type = Puppet::Type.type(:user)
143
- expect(described_class.section).to eq('pw')
155
+ provider.class.resource_type = Puppet::Type.type(:user)
156
+ expect(provider.class.section).to eq('pw')
144
157
  end
145
158
 
146
159
  it "should return gr for groups" do
147
- described_class.resource_type = Puppet::Type.type(:group)
148
- expect(described_class.section).to eq('gr')
160
+ provider.class.resource_type = Puppet::Type.type(:group)
161
+ expect(provider.class.section).to eq('gr')
149
162
  end
150
163
  end
151
164
 
@@ -156,7 +169,7 @@ describe Puppet::Provider::NameService do
156
169
  # encoding
157
170
  allow(Etc).to receive(:getpwent).and_return(*utf_8_mixed_users)
158
171
  result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::UTF_8) do
159
- described_class.instances
172
+ provider.class.instances
160
173
  end
161
174
  expect(result.map(&:name)).to eq(
162
175
  [
@@ -171,7 +184,7 @@ describe Puppet::Provider::NameService do
171
184
  it "should have object names in their original encoding/bytes if they would not be valid UTF-8" do
172
185
  allow(Etc).to receive(:getpwent).and_return(*latin_1_mixed_users)
173
186
  result = PuppetSpec::CharacterEncoding.with_external_encoding(Encoding::ISO_8859_1) do
174
- described_class.instances
187
+ provider.class.instances
175
188
  end
176
189
  expect(result.map(&:name)).to eq(
177
190
  [
@@ -186,40 +199,40 @@ describe Puppet::Provider::NameService do
186
199
  it "should pass the Puppet::Etc :canonical_name Struct member to the constructor" do
187
200
  users = [ Struct::Passwd.new(invalid_utf_8_jose, invalid_utf_8_jose, 1002, 2000), nil ]
188
201
  allow(Etc).to receive(:getpwent).and_return(*users)
189
- expect(described_class).to receive(:new).with(:name => escaped_utf_8_jose, :canonical_name => invalid_utf_8_jose, :ensure => :present)
190
- described_class.instances
202
+ expect(provider.class).to receive(:new).with(:name => escaped_utf_8_jose, :canonical_name => invalid_utf_8_jose, :ensure => :present)
203
+ provider.class.instances
191
204
  end
192
205
  end
193
206
 
194
207
  describe "validate" do
195
208
  it "should pass if no check is registered at all" do
196
- expect { described_class.validate(:foo, 300) }.to_not raise_error
197
- expect { described_class.validate('foo', 300) }.to_not raise_error
209
+ expect { provider.class.validate(:foo, 300) }.to_not raise_error
210
+ expect { provider.class.validate('foo', 300) }.to_not raise_error
198
211
  end
199
212
 
200
213
  it "should pass if no check for that property is registered" do
201
- described_class.verify(:bar, 'Must be 100') { |val| val == 100 }
202
- expect { described_class.validate(:foo, 300) }.to_not raise_error
203
- expect { described_class.validate('foo', 300) }.to_not raise_error
214
+ provider.class.verify(:bar, 'Must be 100') { |val| val == 100 }
215
+ expect { provider.class.validate(:foo, 300) }.to_not raise_error
216
+ expect { provider.class.validate('foo', 300) }.to_not raise_error
204
217
  end
205
218
 
206
219
  it "should pass if the value is valid" do
207
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
208
- expect { described_class.validate(:foo, 100) }.to_not raise_error
209
- expect { described_class.validate('foo', 100) }.to_not raise_error
220
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
221
+ expect { provider.class.validate(:foo, 100) }.to_not raise_error
222
+ expect { provider.class.validate('foo', 100) }.to_not raise_error
210
223
  end
211
224
 
212
225
  it "should raise an error if the value is invalid" do
213
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
214
- expect { described_class.validate(:foo, 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
215
- expect { described_class.validate('foo', 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
226
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
227
+ expect { provider.class.validate(:foo, 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
228
+ expect { provider.class.validate('foo', 200) }.to raise_error(ArgumentError, 'Invalid value 200: Must be 100')
216
229
  end
217
230
  end
218
231
 
219
232
  describe "getinfo" do
220
233
  before :each do
221
234
  # with section=foo we'll call Etc.getfoonam instead of getpwnam or getgrnam
222
- allow(described_class).to receive(:section).and_return('foo')
235
+ allow(provider.class).to receive(:section).and_return('foo')
223
236
  resource # initialize the resource so our provider has a @resource instance variable
224
237
  end
225
238
 
@@ -239,13 +252,13 @@ describe Puppet::Provider::NameService do
239
252
  # overriding to UTF-8, in @canonical_name for querying that state on disk
240
253
  # again if needed
241
254
  it "should use the instance's @canonical_name to query the system" do
242
- provider_instance = described_class.new(:name => 'foo', :canonical_name => 'original_foo', :ensure => :present)
255
+ provider_instance = provider.class.new(:name => 'foo', :canonical_name => 'original_foo', :ensure => :present)
243
256
  expect(Puppet::Etc).to receive(:send).with(:getfoonam, 'original_foo')
244
257
  provider_instance.getinfo(true)
245
258
  end
246
259
 
247
260
  it "should use the instance's name instead of canonical_name if not supplied during instantiation" do
248
- provider_instance = described_class.new(:name => 'foo', :ensure => :present)
261
+ provider_instance = provider.class.new(:name => 'foo', :ensure => :present)
249
262
  expect(Puppet::Etc).to receive(:send).with(:getfoonam, 'foo')
250
263
  provider_instance.getinfo(true)
251
264
  end
@@ -253,16 +266,6 @@ describe Puppet::Provider::NameService do
253
266
 
254
267
  describe "info2hash" do
255
268
  it "should return a hash with all properties" do
256
- # we have to have an implementation of posixmethod which has to
257
- # convert a propertyname (e.g. comment) into a fieldname of our
258
- # Struct (e.g. gecos). I do not want to test posixmethod here so
259
- # let's fake an implementation which does not do any translation. We
260
- # expect two method invocations because info2hash calls the method
261
- # twice if the Struct responds to the propertyname (our fake Struct
262
- # provides values for :foo and :bar) TODO: Fix that
263
- expect(provider).to receive(:posixmethod).with(:foo).and_return(:foo).twice
264
- expect(provider).to receive(:posixmethod).with(:bar).and_return(:bar).twice
265
- expect(provider).to receive(:posixmethod).with(:ensure).and_return(:ensure)
266
269
  expect(provider.info2hash(fakeetcobject)).to eq({ :foo => 'fooval', :bar => 'barval' })
267
270
  end
268
271
  end
@@ -273,7 +276,7 @@ describe Puppet::Provider::NameService do
273
276
  end
274
277
 
275
278
  it "should return the munged value otherwise" do
276
- described_class.options(:foo, :munge => proc { |x| x*2 })
279
+ provider.class.options(:foo, :munge => proc { |x| x*2 })
277
280
  expect(provider.munge(:foo, 100)).to eq(200)
278
281
  end
279
282
  end
@@ -284,7 +287,7 @@ describe Puppet::Provider::NameService do
284
287
  end
285
288
 
286
289
  it "should return the unmunged value otherwise" do
287
- described_class.options(:foo, :unmunge => proc { |x| x/2 })
290
+ provider.class.options(:foo, :unmunge => proc { |x| x/2 })
288
291
  expect(provider.unmunge(:foo, 200)).to eq(100)
289
292
  end
290
293
  end
@@ -302,15 +305,13 @@ describe Puppet::Provider::NameService do
302
305
  end
303
306
 
304
307
  describe "get" do
305
- before(:each) {described_class.resource_type = faketype }
306
-
307
308
  it "should return the correct getinfo value" do
308
309
  expect(provider).to receive(:getinfo).with(false).and_return(:foo => 'fooval', :bar => 'barval')
309
310
  expect(provider.get(:bar)).to eq('barval')
310
311
  end
311
312
 
312
313
  it "should unmunge the value first" do
313
- described_class.options(:bar, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
314
+ provider.class.options(:bar, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
314
315
  expect(provider).to receive(:getinfo).with(false).and_return(:foo => 200, :bar => 500)
315
316
  expect(provider.get(:bar)).to eq(250)
316
317
  end
@@ -325,7 +326,7 @@ describe Puppet::Provider::NameService do
325
326
  describe "set" do
326
327
  before :each do
327
328
  resource # initialize resource so our provider has a @resource object
328
- described_class.verify(:foo, 'Must be 100') { |val| val == 100 }
329
+ provider.class.verify(:foo, 'Must be 100') { |val| val == 100 }
329
330
  end
330
331
 
331
332
  it "should raise an error on invalid values" do
@@ -339,7 +340,7 @@ describe Puppet::Provider::NameService do
339
340
  end
340
341
 
341
342
  it "should munge the value first" do
342
- described_class.options(:foo, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
343
+ provider.class.options(:foo, :munge => proc { |x| x*2}, :unmunge => proc {|x| x/2})
343
344
  expect(provider).to receive(:modifycmd).with(:foo, 200).and_return(['/bin/modify', '-f', '200' ])
344
345
  expect(provider).to receive(:execute).with(['/bin/modify', '-f', '200'], hash_including(custom_environment: {}))
345
346
  provider.set(:foo, 100)