puppet 4.9.4 → 4.10.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.
- checksums.yaml +7 -0
- data/Rakefile +6 -0
- data/ext/project_data.yaml +2 -2
- data/lib/hiera/puppet_function.rb +1 -1
- data/lib/puppet.rb +1 -0
- data/lib/puppet/application.rb +14 -0
- data/lib/puppet/application/inspect.rb +3 -0
- data/lib/puppet/defaults.rb +12 -2
- data/lib/puppet/etc.rb +125 -0
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/functions.rb +49 -4
- data/lib/puppet/functions/eyaml_lookup_key.rb +12 -3
- data/lib/puppet/functions/hocon_data.rb +9 -0
- data/lib/puppet/functions/json_data.rb +9 -0
- data/lib/puppet/functions/yaml_data.rb +9 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +69 -22
- data/lib/puppet/indirector/key/file.rb +2 -1
- data/lib/puppet/indirector/ssl_file.rb +24 -3
- data/lib/puppet/module.rb +28 -22
- data/lib/puppet/network/http/compression.rb +2 -1
- data/lib/puppet/parser/compiler.rb +15 -38
- data/lib/puppet/parser/functions/hiera.rb +1 -1
- data/lib/puppet/parser/functions/hiera_array.rb +1 -1
- data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
- data/lib/puppet/parser/functions/hiera_include.rb +1 -1
- data/lib/puppet/parser/scope.rb +59 -17
- data/lib/puppet/pops/evaluator/callable_signature.rb +7 -0
- data/lib/puppet/pops/functions/dispatch.rb +18 -5
- data/lib/puppet/pops/functions/dispatcher.rb +7 -13
- data/lib/puppet/pops/issue_reporter.rb +1 -1
- data/lib/puppet/pops/issues.rb +84 -0
- data/lib/puppet/pops/loader/base_loader.rb +13 -5
- data/lib/puppet/pops/lookup/configured_data_provider.rb +8 -2
- data/lib/puppet/pops/lookup/data_dig_function_provider.rb +109 -19
- data/lib/puppet/pops/lookup/data_hash_function_provider.rb +19 -4
- data/lib/puppet/pops/lookup/data_provider.rb +43 -29
- data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
- data/lib/puppet/pops/lookup/explainer.rb +1 -0
- data/lib/puppet/pops/lookup/function_provider.rb +36 -11
- data/lib/puppet/pops/lookup/global_data_provider.rb +18 -5
- data/lib/puppet/pops/lookup/hiera_config.rb +203 -84
- data/lib/puppet/pops/lookup/interpolation.rb +21 -6
- data/lib/puppet/pops/lookup/invocation.rb +14 -9
- data/lib/puppet/pops/lookup/location_resolver.rb +27 -0
- data/lib/puppet/pops/lookup/lookup_adapter.rb +59 -6
- data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +9 -77
- data/lib/puppet/pops/lookup/module_data_provider.rb +27 -4
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +3 -3
- data/lib/puppet/pops/types/p_object_type.rb +4 -6
- data/lib/puppet/pops/types/ruby_generator.rb +2 -2
- data/lib/puppet/pops/types/type_asserter.rb +3 -3
- data/lib/puppet/pops/types/type_mismatch_describer.rb +25 -7
- data/lib/puppet/pops/types/types.rb +20 -29
- data/lib/puppet/provider/exec.rb +4 -2
- data/lib/puppet/provider/nameservice.rb +8 -8
- data/lib/puppet/provider/selmodule/semodule.rb +20 -16
- data/lib/puppet/provider/service/src.rb +39 -39
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/aix.rb +7 -2
- data/lib/puppet/settings.rb +30 -17
- data/lib/puppet/ssl/base.rb +14 -1
- data/lib/puppet/ssl/certificate_authority.rb +4 -2
- data/lib/puppet/ssl/configuration.rb +4 -1
- data/lib/puppet/ssl/inventory.rb +10 -3
- data/lib/puppet/ssl/key.rb +7 -3
- data/lib/puppet/test/test_helper.rb +3 -0
- data/lib/puppet/type.rb +13 -1
- data/lib/puppet/type/exec.rb +16 -1
- data/lib/puppet/type/group.rb +17 -11
- data/lib/puppet/type/user.rb +3 -1
- data/lib/puppet/util.rb +1 -0
- data/lib/puppet/util/character_encoding.rb +95 -0
- data/lib/puppet/util/execution.rb +9 -6
- data/lib/puppet/util/reference.rb +4 -2
- data/lib/puppet/util/windows/file.rb +5 -1
- data/lib/puppet/version.rb +6 -2
- data/locales/config.yaml +1 -1
- data/locales/puppet.pot +18 -4
- data/spec/integration/ssl/autosign_spec.rb +18 -3
- data/spec/integration/ssl/key_spec.rb +104 -0
- data/spec/integration/type/user_spec.rb +13 -6
- data/spec/spec_helper.rb +7 -0
- data/spec/unit/application/inspect_spec.rb +9 -2
- data/spec/unit/data_providers/function_data_provider_spec.rb +2 -2
- data/spec/unit/etc_spec.rb +234 -0
- data/spec/unit/face/certificate_spec.rb +10 -2
- data/spec/unit/functions/dig_spec.rb +1 -1
- data/spec/unit/functions/hiera_spec.rb +40 -1
- data/spec/unit/functions/lookup_fixture_spec.rb +10 -10
- data/spec/unit/functions/lookup_spec.rb +1217 -357
- data/spec/unit/functions4_spec.rb +37 -1
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +33 -2
- data/spec/unit/indirector/key/file_spec.rb +1 -1
- data/spec/unit/indirector/ssl_file_spec.rb +3 -3
- data/spec/unit/module_spec.rb +52 -59
- data/spec/unit/network/http/compression_spec.rb +39 -8
- data/spec/unit/parser/compiler_spec.rb +14 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +21 -3
- data/spec/unit/pops/loaders/module_loaders_spec.rb +61 -0
- data/spec/unit/pops/lookup/context_spec.rb +56 -8
- data/spec/unit/pops/lookup/lookup_spec.rb +32 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +8 -0
- data/spec/unit/pops/types/ruby_generator_spec.rb +48 -0
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -3
- data/spec/unit/pops/types/types_spec.rb +6 -7
- data/spec/unit/provider/nameservice_spec.rb +12 -12
- data/spec/unit/provider/package/pkg_spec.rb +2 -0
- data/spec/unit/provider/service/src_spec.rb +5 -0
- data/spec/unit/ssl/base_spec.rb +9 -0
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -2
- data/spec/unit/ssl/certificate_request_attributes_spec.rb +6 -0
- data/spec/unit/ssl/certificate_request_spec.rb +1 -1
- data/spec/unit/ssl/certificate_spec.rb +1 -1
- data/spec/unit/ssl/configuration_spec.rb +11 -2
- data/spec/unit/ssl/inventory_spec.rb +27 -3
- data/spec/unit/ssl/key_spec.rb +7 -7
- data/spec/unit/type/exec_spec.rb +41 -4
- data/spec/unit/type/file_spec.rb +4 -1
- data/spec/unit/util/character_encoding_spec.rb +88 -0
- data/spec/unit/util/execution_spec.rb +12 -0
- data/spec/unit/version_spec.rb +4 -0
- metadata +3803 -3808
- data/tasks/i18n.rake +0 -20
@@ -237,6 +237,22 @@ describe 'the 4x function api' do
|
|
237
237
|
rejected: parameter 's1' expects a String value, got Integer")
|
238
238
|
end
|
239
239
|
|
240
|
+
context 'an argument_mismatch handler' do
|
241
|
+
let(:func) { create_function_with_mismatch_handler.new(:closure_scope, :loader) }
|
242
|
+
|
243
|
+
it 'is called on matching arguments' do
|
244
|
+
expect { func.call({}, '1') }.to raise_error(ArgumentError, "'test' It's not OK to pass a string")
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'is not called unless arguments are matching' do
|
248
|
+
expect { func.call({}, '1', 3) }.to raise_error(ArgumentError, "'test' expects 1 argument, got 2")
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'is not included in a signature mismatch description' do
|
252
|
+
expect { func.call({}, 2.3) }.to raise_error { |e| expect(e.message).not_to match(/String/) }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
240
256
|
context 'can use injection' do
|
241
257
|
before :all do
|
242
258
|
injector = Puppet::Pops::Binder::Injector.create('test') do
|
@@ -474,7 +490,7 @@ describe 'the 4x function api' do
|
|
474
490
|
# evaluate a puppet call
|
475
491
|
source = "testing::test(10) |$x| { $x+1 }"
|
476
492
|
program = parser.parse_string(source, __FILE__)
|
477
|
-
Puppet::Pops::Adapters::LoaderAdapter.expects(:loader_for_model_object).returns(the_loader)
|
493
|
+
Puppet::Pops::Adapters::LoaderAdapter.expects(:loader_for_model_object).at_least_once.returns(the_loader)
|
478
494
|
expect(parser.evaluate(scope, program)).to eql(11)
|
479
495
|
end
|
480
496
|
end
|
@@ -962,6 +978,26 @@ describe 'the 4x function api' do
|
|
962
978
|
end
|
963
979
|
end
|
964
980
|
|
981
|
+
def create_function_with_mismatch_handler
|
982
|
+
f = Puppet::Functions.create_function('test') do
|
983
|
+
dispatch :test do
|
984
|
+
param 'Integer', :x
|
985
|
+
end
|
986
|
+
|
987
|
+
argument_mismatch :on_error do
|
988
|
+
param 'String', :x
|
989
|
+
end
|
990
|
+
|
991
|
+
def test(x)
|
992
|
+
yield(5,x) if block_given?
|
993
|
+
end
|
994
|
+
|
995
|
+
def on_error(x)
|
996
|
+
"It's not OK to pass a string"
|
997
|
+
end
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
|
965
1001
|
def type_alias_t(name, type_string)
|
966
1002
|
type_expr = Puppet::Pops::Parser::EvaluatingParser.new.parse_string(type_string).current
|
967
1003
|
Puppet::Pops::Types::TypeFactory.type_alias(name, type_expr)
|
@@ -52,11 +52,42 @@ describe Puppet::FileBucketFile::File, :uses_checksums => true do
|
|
52
52
|
0x2f94cc40,0x15a12deb,0xdc15f4a3,0x490786bb,
|
53
53
|
0x6d658673,0xa4341f7d,0x8fd75920,0xefd18d5a].pack("I" * 16)
|
54
54
|
|
55
|
-
save_bucket_file(first_contents, "/foo/bar")
|
55
|
+
checksum_value = save_bucket_file(first_contents, "/foo/bar")
|
56
56
|
|
57
|
+
# We expect Puppet to log an error with the path to the file
|
58
|
+
Puppet.expects(:err).with(regexp_matches(/Unable to verify existing FileBucket backup at '#{Puppet[:bucketdir]}.*#{checksum_value}\/contents'/))
|
59
|
+
|
60
|
+
# But the exception should not contain it
|
57
61
|
expect do
|
58
62
|
save_bucket_file(collision_contents, "/foo/bar")
|
59
|
-
end.to raise_error(Puppet::FileBucket::BucketError,
|
63
|
+
end.to raise_error(Puppet::FileBucket::BucketError, /\AExisting backup and new file have different content but same checksum, {md5}#{checksum_value}\. Verify existing backup and remove if incorrect\.\Z/)
|
64
|
+
end
|
65
|
+
|
66
|
+
# See PUP-1334
|
67
|
+
context "when the contents file exists but is corrupted and does not match the expected checksum" do
|
68
|
+
let(:original_contents) { "a file that will get corrupted" }
|
69
|
+
let(:bucket_file) { Puppet::FileBucket::File.new(original_contents) }
|
70
|
+
let(:contents_file) { "#{Puppet[:bucketdir]}/8/e/6/4/f/8/5/d/8e64f85dd54a412f65edabcafe44d491/contents" }
|
71
|
+
|
72
|
+
before(:each) do
|
73
|
+
# Ensure we're starting with a clean slate - no pre-existing backup
|
74
|
+
Puppet::FileSystem.unlink(contents_file) if Puppet::FileSystem.exist?(contents_file)
|
75
|
+
# Create initial "correct" backup
|
76
|
+
Puppet::FileBucket::File.indirection.save(bucket_file)
|
77
|
+
# Modify the contents file so that it no longer matches the SHA, simulating a corrupt backup
|
78
|
+
Puppet::FileSystem.unlink(contents_file) # bucket_files are read-only
|
79
|
+
Puppet::Util.replace_file(contents_file, 0600) { |fh| fh.puts "now with corrupted content" }
|
80
|
+
end
|
81
|
+
|
82
|
+
it "issues a warning that the backup will be overwritten" do
|
83
|
+
Puppet.expects(:warning).with(regexp_matches(/Existing backup does not match its expected sum, #{bucket_file.checksum}/))
|
84
|
+
Puppet::FileBucket::File.indirection.save(bucket_file)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "overwrites the existing contents file (backup)" do
|
88
|
+
Puppet::FileBucket::File.indirection.save(bucket_file)
|
89
|
+
expect(Puppet::FileSystem.read(contents_file)).to eq(original_contents)
|
90
|
+
end
|
60
91
|
end
|
61
92
|
|
62
93
|
describe "when supplying a path" do
|
@@ -66,7 +66,7 @@ describe Puppet::SSL::Key::File do
|
|
66
66
|
it "should save the public key when saving the private key" do
|
67
67
|
fh = StringIO.new
|
68
68
|
|
69
|
-
Puppet.settings.setting(:publickeydir).expects(:open_file).with(@public_key_path, 'w').yields fh
|
69
|
+
Puppet.settings.setting(:publickeydir).expects(:open_file).with(@public_key_path, 'w:ASCII').yields fh
|
70
70
|
Puppet.settings.setting(:privatekeydir).stubs(:open_file)
|
71
71
|
@public_key.expects(:to_pem).returns "my pem"
|
72
72
|
|
@@ -221,7 +221,7 @@ describe Puppet::Indirector::SslFile do
|
|
221
221
|
@searcher.class.store_in @setting
|
222
222
|
fh = mock 'filehandle'
|
223
223
|
fh.stubs :print
|
224
|
-
Puppet.settings.setting(@setting).expects(:open_file).with(@certpath, 'w').yields fh
|
224
|
+
Puppet.settings.setting(@setting).expects(:open_file).with(@certpath, 'w:ASCII').yields fh
|
225
225
|
|
226
226
|
@searcher.save(@request)
|
227
227
|
end
|
@@ -233,7 +233,7 @@ describe Puppet::Indirector::SslFile do
|
|
233
233
|
|
234
234
|
fh = mock 'filehandle'
|
235
235
|
fh.stubs :print
|
236
|
-
Puppet.settings.setting(@setting).expects(:open).with('w').yields fh
|
236
|
+
Puppet.settings.setting(@setting).expects(:open).with('w:ASCII').yields fh
|
237
237
|
@searcher.save(@request)
|
238
238
|
end
|
239
239
|
end
|
@@ -246,7 +246,7 @@ describe Puppet::Indirector::SslFile do
|
|
246
246
|
|
247
247
|
fh = mock 'filehandle'
|
248
248
|
fh.stubs :print
|
249
|
-
Puppet.settings.setting(:cakey).expects(:open).with('w').yields fh
|
249
|
+
Puppet.settings.setting(:cakey).expects(:open).with('w:ASCII').yields fh
|
250
250
|
@searcher.stubs(:ca?).returns true
|
251
251
|
@searcher.save(@request)
|
252
252
|
end
|
data/spec/unit/module_spec.rb
CHANGED
@@ -170,7 +170,6 @@ describe Puppet::Module do
|
|
170
170
|
|
171
171
|
it "should list modules that are missing" do
|
172
172
|
metadata_file = "#{@modpath}/needy/metadata.json"
|
173
|
-
Puppet::FileSystem.expects(:exist?).with(metadata_file).returns true
|
174
173
|
mod = PuppetSpec::Modules.create(
|
175
174
|
'needy',
|
176
175
|
@modpath,
|
@@ -196,7 +195,6 @@ describe Puppet::Module do
|
|
196
195
|
|
197
196
|
it "should list modules that are missing and have invalid names" do
|
198
197
|
metadata_file = "#{@modpath}/needy/metadata.json"
|
199
|
-
Puppet::FileSystem.expects(:exist?).with(metadata_file).returns true
|
200
198
|
mod = PuppetSpec::Modules.create(
|
201
199
|
'needy',
|
202
200
|
@modpath,
|
@@ -305,7 +303,6 @@ describe Puppet::Module do
|
|
305
303
|
env = Puppet::Node::Environment.create(:testing, [@modpath])
|
306
304
|
|
307
305
|
metadata_file = "#{@modpath}/foobar/metadata.json"
|
308
|
-
Puppet::FileSystem.expects(:exist?).with(metadata_file).times(3).returns true
|
309
306
|
mod = PuppetSpec::Modules.create(
|
310
307
|
'foobar',
|
311
308
|
@modpath,
|
@@ -364,10 +361,6 @@ describe Puppet::Module do
|
|
364
361
|
it "should only list unmet dependencies" do
|
365
362
|
env = Puppet::Node::Environment.create(:testing, [@modpath])
|
366
363
|
|
367
|
-
[name, 'satisfied'].each do |mod_name|
|
368
|
-
metadata_file = "#{@modpath}/#{mod_name}/metadata.json"
|
369
|
-
Puppet::FileSystem.expects(:exist?).with(metadata_file).twice.returns true
|
370
|
-
end
|
371
364
|
mod = PuppetSpec::Modules.create(
|
372
365
|
name,
|
373
366
|
@modpath,
|
@@ -588,60 +581,70 @@ end
|
|
588
581
|
|
589
582
|
describe Puppet::Module do
|
590
583
|
include PuppetSpec::Files
|
591
|
-
|
592
|
-
|
593
|
-
|
584
|
+
|
585
|
+
let!(:modpath) do
|
586
|
+
path = tmpdir('modpath')
|
587
|
+
PuppetSpec::Modules.create('mymod', path)
|
588
|
+
path
|
594
589
|
end
|
595
590
|
|
591
|
+
let!(:mymodpath) { File.join(modpath, 'mymod') }
|
592
|
+
|
593
|
+
let!(:mymod_metadata) { File.join(mymodpath, 'metadata.json') }
|
594
|
+
|
595
|
+
let(:mymod) { Puppet::Module.new('mymod', mymodpath, nil) }
|
596
|
+
|
596
597
|
it "should use 'License' in its current path as its metadata file" do
|
597
|
-
expect(
|
598
|
+
expect(mymod.license_file).to eq("#{modpath}/mymod/License")
|
598
599
|
end
|
599
600
|
|
600
601
|
it "should cache the license file" do
|
601
|
-
|
602
|
-
|
603
|
-
|
602
|
+
mymod.expects(:path).once.returns nil
|
603
|
+
mymod.license_file
|
604
|
+
mymod.license_file
|
604
605
|
end
|
605
606
|
|
606
607
|
it "should use 'metadata.json' in its current path as its metadata file" do
|
607
|
-
expect(
|
608
|
+
expect(mymod_metadata).to eq("#{modpath}/mymod/metadata.json")
|
609
|
+
end
|
610
|
+
|
611
|
+
it "should not have metadata if it has a metadata file and its data is valid but empty json hash" do
|
612
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns "{}"
|
613
|
+
|
614
|
+
expect(mymod).not_to be_has_metadata
|
608
615
|
end
|
609
616
|
|
610
|
-
it "should have metadata if it has a metadata file and its data is
|
611
|
-
|
612
|
-
File.stubs(:read).with(@module.metadata_file, {:encoding => 'utf-8'}).returns "{\"foo\" : \"bar\"}"
|
617
|
+
it "should not have metadata if it has a metadata file and its data is empty" do
|
618
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns ""
|
613
619
|
|
614
|
-
expect(
|
620
|
+
expect(mymod).not_to be_has_metadata
|
615
621
|
end
|
616
622
|
|
617
|
-
it "should not have metadata if has a metadata file and its data is
|
618
|
-
|
619
|
-
|
620
|
-
expect(@module).not_to be_has_metadata
|
623
|
+
it "should not have metadata if has a metadata file and its data is invalid" do
|
624
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns "This is some invalid json.\n"
|
625
|
+
expect(mymod).not_to be_has_metadata
|
621
626
|
end
|
622
627
|
|
623
628
|
it "should know if it is missing a metadata file" do
|
624
|
-
|
629
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).raises(Errno::ENOENT)
|
625
630
|
|
626
|
-
expect(
|
631
|
+
expect(mymod).not_to be_has_metadata
|
627
632
|
end
|
628
633
|
|
629
634
|
it "should be able to parse its metadata file" do
|
630
|
-
expect(
|
635
|
+
expect(mymod).to respond_to(:load_metadata)
|
631
636
|
end
|
632
637
|
|
633
638
|
it "should parse its metadata file on initialization if it is present" do
|
634
|
-
Puppet::Module.any_instance.expects(:has_metadata?).returns true
|
635
639
|
Puppet::Module.any_instance.expects(:load_metadata)
|
636
640
|
|
637
641
|
Puppet::Module.new("yay", "/path", mock("env"))
|
638
642
|
end
|
639
643
|
|
640
644
|
it "should tolerate failure to parse" do
|
641
|
-
|
642
|
-
File.stubs(:read).with(@module.metadata_file, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
645
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
643
646
|
|
644
|
-
expect(
|
647
|
+
expect(mymod.has_metadata?).to be_falsey
|
645
648
|
end
|
646
649
|
|
647
650
|
describe 'when --strict is warning' do
|
@@ -650,10 +653,9 @@ describe Puppet::Module do
|
|
650
653
|
end
|
651
654
|
|
652
655
|
it "should warn about a failure to parse" do
|
653
|
-
|
654
|
-
File.stubs(:read).with(@module.metadata_file, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
656
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
655
657
|
|
656
|
-
expect(
|
658
|
+
expect(mymod.has_metadata?).to be_falsey
|
657
659
|
expect(@logs).to have_matching_log(/mymod has an invalid and unparsable metadata\.json file/)
|
658
660
|
end
|
659
661
|
end
|
@@ -664,10 +666,9 @@ describe Puppet::Module do
|
|
664
666
|
end
|
665
667
|
|
666
668
|
it "should warn about a failure to parse" do
|
667
|
-
|
668
|
-
File.stubs(:read).with(@module.metadata_file, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
669
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
669
670
|
|
670
|
-
expect(
|
671
|
+
expect(mymod.has_metadata?).to be_falsey
|
671
672
|
expect(@logs).to have_matching_log(/mymod has an invalid and unparsable metadata\.json file.*/)
|
672
673
|
end
|
673
674
|
end
|
@@ -678,47 +679,39 @@ describe Puppet::Module do
|
|
678
679
|
end
|
679
680
|
|
680
681
|
it "should fail on a failure to parse" do
|
681
|
-
|
682
|
-
File.stubs(:read).with(@module.metadata_file, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
682
|
+
File.stubs(:read).with(mymod_metadata, {:encoding => 'utf-8'}).returns(my_fixture('trailing-comma.json'))
|
683
683
|
|
684
684
|
expect do
|
685
|
-
expect(
|
685
|
+
expect(mymod.has_metadata?).to be_falsey
|
686
686
|
end.to raise_error(/mymod has an invalid and unparsable metadata\.json file/)
|
687
687
|
end
|
688
688
|
end
|
689
689
|
|
690
690
|
def a_module_with_metadata(data)
|
691
|
-
|
692
|
-
|
693
|
-
mod = Puppet::Module.new("foo", "/path", mock("env"))
|
694
|
-
mod.stubs(:metadata_file).returns "/my/file"
|
695
|
-
File.stubs(:read).with("/my/file", {:encoding => 'utf-8'}).returns text
|
696
|
-
mod
|
691
|
+
File.stubs(:read).with("/path/metadata.json", {:encoding => 'utf-8'}).returns data.to_pson
|
692
|
+
Puppet::Module.new("foo", "/path", mock("env"))
|
697
693
|
end
|
698
694
|
|
699
695
|
describe "when loading the metadata file" do
|
700
|
-
|
701
|
-
|
696
|
+
let(:data) do
|
697
|
+
{
|
702
698
|
:license => "GPL2",
|
703
699
|
:author => "luke",
|
704
700
|
:version => "1.0",
|
705
701
|
:source => "http://foo/",
|
706
702
|
:dependencies => []
|
707
703
|
}
|
708
|
-
@module = a_module_with_metadata(@data)
|
709
704
|
end
|
710
705
|
|
711
706
|
%w{source author version license}.each do |attr|
|
712
707
|
it "should set #{attr} if present in the metadata file" do
|
713
|
-
|
714
|
-
expect(
|
708
|
+
mod = a_module_with_metadata(data)
|
709
|
+
expect(mod.send(attr)).to eq(data[attr.to_sym])
|
715
710
|
end
|
716
711
|
|
717
712
|
it "should fail if #{attr} is not present in the metadata file" do
|
718
|
-
|
719
|
-
|
720
|
-
File.stubs(:read).with("/my/file", {:encoding => 'utf-8'}).returns @text
|
721
|
-
expect { @module.load_metadata }.to raise_error(
|
713
|
+
data.delete(attr.to_sym)
|
714
|
+
expect { a_module_with_metadata(data) }.to raise_error(
|
722
715
|
Puppet::Module::MissingMetadata,
|
723
716
|
"No #{attr} module metadata provided for foo"
|
724
717
|
)
|
@@ -742,8 +735,8 @@ describe Puppet::Module do
|
|
742
735
|
EOF
|
743
736
|
end
|
744
737
|
|
738
|
+
Puppet::Module.any_instance.stubs(:metadata_file).returns metadata_json
|
745
739
|
mod = Puppet::Module.new('foo', '/path', mock('env'))
|
746
|
-
mod.stubs(:metadata_file).returns metadata_json
|
747
740
|
|
748
741
|
mod.load_metadata
|
749
742
|
expect(mod.author).to eq(rune_utf8)
|
@@ -773,17 +766,17 @@ describe Puppet::Module do
|
|
773
766
|
end
|
774
767
|
|
775
768
|
it "should know what other modules require it" do
|
776
|
-
env = Puppet::Node::Environment.create(:testing, [
|
769
|
+
env = Puppet::Node::Environment.create(:testing, [modpath])
|
777
770
|
|
778
771
|
dependable = PuppetSpec::Modules.create(
|
779
772
|
'dependable',
|
780
|
-
|
773
|
+
modpath,
|
781
774
|
:metadata => {:author => 'puppetlabs'},
|
782
775
|
:environment => env
|
783
776
|
)
|
784
777
|
PuppetSpec::Modules.create(
|
785
778
|
'needy',
|
786
|
-
|
779
|
+
modpath,
|
787
780
|
:metadata => {
|
788
781
|
:author => 'beggar',
|
789
782
|
:dependencies => [{
|
@@ -795,7 +788,7 @@ describe Puppet::Module do
|
|
795
788
|
)
|
796
789
|
PuppetSpec::Modules.create(
|
797
790
|
'wantit',
|
798
|
-
|
791
|
+
modpath,
|
799
792
|
:metadata => {
|
800
793
|
:author => 'spoiled',
|
801
794
|
:dependencies => [{
|
@@ -86,17 +86,48 @@ describe "http compression" do
|
|
86
86
|
expect(@uncompressor.uncompress_body(@response)).to eq("uncompresseddata")
|
87
87
|
end
|
88
88
|
|
89
|
-
|
90
|
-
|
89
|
+
context "with 'gzip' content-encoding" do
|
90
|
+
it "should use a GzipReader" do
|
91
|
+
@response.stubs(:[]).with('content-encoding').returns('gzip')
|
91
92
|
|
92
|
-
|
93
|
-
|
93
|
+
io = stub 'io'
|
94
|
+
StringIO.expects(:new).with("mydata").returns io
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
96
|
+
reader = stub 'gzip reader'
|
97
|
+
Zlib::GzipReader.expects(:new).with(io, :encoding => Encoding::BINARY).returns(reader)
|
98
|
+
reader.expects(:read).returns "uncompresseddata"
|
98
99
|
|
99
|
-
|
100
|
+
expect(@uncompressor.uncompress_body(@response)).to eq("uncompresseddata")
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should correctly decompress PSON containing UTF-8 in Binary Encoding" do
|
104
|
+
# Simulate a compressed response body containing PSON containing UTF-8
|
105
|
+
# using different UTF-8 widths:
|
106
|
+
|
107
|
+
# \u06ff - ۿ - http://www.fileformat.info/info/unicode/char/06ff/index.htm - 0xDB 0xBF / 219 191
|
108
|
+
# \u16A0 - ᚠ - http://www.fileformat.info/info/unicode/char/16A0/index.htm - 0xE1 0x9A 0xA0 / 225 154 160
|
109
|
+
# \u{2070E} - 𠜎 - http://www.fileformat.info/info/unicode/char/2070E/index.htm - 0xF0 0xA0 0x9C 0x8E / 240 160 156 142
|
110
|
+
|
111
|
+
pson = "foo\u06ff\u16A0\u{2070E}".to_pson # unicode expression eqivalent of "foo\xDB\xBF\xE1\x9A\xA0\xF0\xA0\x9C\x8E\" per above
|
112
|
+
writer = Zlib::GzipWriter.new(StringIO.new)
|
113
|
+
writer.write(pson)
|
114
|
+
compressed_body = writer.close.string
|
115
|
+
|
116
|
+
begin
|
117
|
+
default_external = Encoding.default_external
|
118
|
+
Encoding.default_external = Encoding::ISO_8859_1
|
119
|
+
|
120
|
+
@response.stubs(:[]).with('content-encoding').returns('gzip')
|
121
|
+
@response.stubs(:body).returns(compressed_body)
|
122
|
+
|
123
|
+
uncompressed = @uncompressor.uncompress_body(@response)
|
124
|
+
# By default Zlib::GzipReader decompresses into Encoding.default_external, and we want to ensure our result is BINARY too
|
125
|
+
expect(uncompressed.encoding).to eq(Encoding::BINARY)
|
126
|
+
expect(uncompressed).to eq("\"foo\xDB\xBF\xE1\x9A\xA0\xF0\xA0\x9C\x8E\"".force_encoding(Encoding::BINARY))
|
127
|
+
ensure
|
128
|
+
Encoding.default_external = default_external
|
129
|
+
end
|
130
|
+
end
|
100
131
|
end
|
101
132
|
end
|
102
133
|
|
@@ -109,6 +109,20 @@ describe Puppet::Parser::Compiler do
|
|
109
109
|
|
110
110
|
describe "when initializing" do
|
111
111
|
|
112
|
+
it 'should not create the settings class more than once' do
|
113
|
+
logs = []
|
114
|
+
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
115
|
+
Puppet[:code] = 'undef'
|
116
|
+
@compiler.compile
|
117
|
+
|
118
|
+
@compiler = Puppet::Parser::Compiler.new(@node)
|
119
|
+
Puppet[:code] = 'undef'
|
120
|
+
@compiler.compile
|
121
|
+
end
|
122
|
+
warnings = logs.select { |log| log.level == :warning }.map { |log| log.message }
|
123
|
+
expect(warnings).not_to include(/Class 'settings' is already defined/)
|
124
|
+
end
|
125
|
+
|
112
126
|
it "should set its node attribute" do
|
113
127
|
expect(@compiler.node).to equal(@node)
|
114
128
|
end
|