puppet 7.12.1-universal-darwin → 7.13.1-universal-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -8
- data/ext/project_data.yaml +1 -1
- data/lib/puppet/application/lookup.rb +72 -24
- data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
- data/lib/puppet/defaults.rb +3 -1
- data/lib/puppet/file_serving/metadata.rb +3 -0
- data/lib/puppet/file_system/file_impl.rb +7 -7
- data/lib/puppet/file_system/jruby.rb +1 -1
- data/lib/puppet/file_system/path_pattern.rb +10 -15
- data/lib/puppet/file_system/uniquefile.rb +1 -1
- data/lib/puppet/file_system/windows.rb +4 -4
- data/lib/puppet/file_system.rb +1 -1
- data/lib/puppet/functions/versioncmp.rb +6 -2
- data/lib/puppet/graph/simple_graph.rb +2 -1
- data/lib/puppet/pops/parser/code_merger.rb +4 -4
- data/lib/puppet/pops/parser/egrammar.ra +2 -0
- data/lib/puppet/pops/parser/eparser.rb +574 -558
- data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
- data/lib/puppet/pops/validation/checker4_0.rb +7 -2
- data/lib/puppet/provider/service/init.rb +5 -4
- data/lib/puppet/ssl/verifier.rb +3 -1
- data/lib/puppet/transaction/persistence.rb +22 -12
- data/lib/puppet/type/file/data_sync.rb +1 -1
- data/lib/puppet/type/file/group.rb +8 -1
- data/lib/puppet/type/file/owner.rb +8 -1
- data/lib/puppet/type/user.rb +40 -38
- data/lib/puppet/util/json.rb +17 -0
- data/lib/puppet/util/log.rb +7 -2
- data/lib/puppet/util/monkey_patches.rb +26 -2
- data/lib/puppet/util/package.rb +25 -16
- data/lib/puppet/util/yaml.rb +11 -0
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet.rb +1 -0
- data/locales/puppet.pot +115 -93
- data/man/man5/puppet.conf.5 +10 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-lookup.8 +9 -6
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/forge/bacula.json +1 -1
- data/spec/integration/application/lookup_spec.rb +29 -6
- data/spec/integration/parser/pcore_resource_spec.rb +10 -0
- data/spec/shared_contexts/l10n.rb +5 -0
- data/spec/unit/application/lookup_spec.rb +131 -10
- data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
- data/spec/unit/file_system/uniquefile_spec.rb +7 -1
- data/spec/unit/file_system_spec.rb +34 -4
- data/spec/unit/forge/module_release_spec.rb +3 -3
- data/spec/unit/functions/versioncmp_spec.rb +40 -4
- data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
- data/spec/unit/pops/validator/validator_spec.rb +5 -0
- data/spec/unit/provider/service/gentoo_spec.rb +6 -5
- data/spec/unit/provider/service/init_spec.rb +15 -9
- data/spec/unit/provider/service/openwrt_spec.rb +21 -29
- data/spec/unit/provider/service/redhat_spec.rb +3 -2
- data/spec/unit/transaction/persistence_spec.rb +51 -0
- data/spec/unit/type/file/group_spec.rb +7 -0
- data/spec/unit/type/file/owner_spec.rb +7 -0
- data/spec/unit/type/user_spec.rb +0 -45
- data/spec/unit/util/json_spec.rb +126 -0
- data/spec/unit/util/yaml_spec.rb +37 -13
- metadata +14 -4
@@ -106,7 +106,7 @@ describe "egrammar parsing containers" do
|
|
106
106
|
|
107
107
|
context 'it should allow keywords as attribute names' do
|
108
108
|
['and', 'case', 'class', 'default', 'define', 'else', 'elsif', 'if', 'in', 'inherits', 'node', 'or',
|
109
|
-
'undef', 'unless', 'type', 'attr', 'function', 'private'].each do |keyword|
|
109
|
+
'undef', 'unless', 'type', 'attr', 'function', 'private', 'plan', 'apply'].each do |keyword|
|
110
110
|
it "such as #{keyword}" do
|
111
111
|
expect { parse("class x ($#{keyword}){} class { x: #{keyword} => 1 }") }.to_not raise_error
|
112
112
|
end
|
@@ -178,7 +178,7 @@ describe "egrammar parsing containers" do
|
|
178
178
|
|
179
179
|
context 'it should allow keywords as attribute names' do
|
180
180
|
['and', 'case', 'class', 'default', 'define', 'else', 'elsif', 'if', 'in', 'inherits', 'node', 'or',
|
181
|
-
'undef', 'unless', 'type', 'attr', 'function', 'private'].each do |keyword|
|
181
|
+
'undef', 'unless', 'type', 'attr', 'function', 'private', 'plan', 'apply'].each do |keyword|
|
182
182
|
it "such as #{keyword}" do
|
183
183
|
expect {parse("define x ($#{keyword}){} x { y: #{keyword} => 1 }")}.to_not raise_error
|
184
184
|
end
|
@@ -559,29 +559,6 @@ module Serialization
|
|
559
559
|
expect(warnings).to eql(["['key'] contains the special value default. It will be converted to the String 'default'"])
|
560
560
|
end
|
561
561
|
end
|
562
|
-
context 'and force_symbol set to true' do
|
563
|
-
let(:to_converter) { ToDataConverter.new(:rich_data => false, :force_symbol => true) }
|
564
|
-
|
565
|
-
it 'A Hash with Symbol values is converted to hash with Symbol values' do
|
566
|
-
val = { 'one' => :one, 'two' => :two }
|
567
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
568
|
-
|
569
|
-
# write and read methods does not work here as we cannot force Symbols in Json.
|
570
|
-
# and a hash with symbol values cannot be an instance of Types::TypeFactory.data.
|
571
|
-
# Using YAML for this instead
|
572
|
-
io.reopen
|
573
|
-
value = to_converter.convert(val)
|
574
|
-
io << [value].to_yaml
|
575
|
-
io.rewind
|
576
|
-
|
577
|
-
val2 = from_converter.convert(YAML::load(io.read)[0])
|
578
|
-
|
579
|
-
expect(val2).to be_a(Hash)
|
580
|
-
expect(val2).to eql({ 'one' => :one, 'two' => :two })
|
581
|
-
end
|
582
|
-
expect(warnings).to be_empty
|
583
|
-
end
|
584
|
-
end
|
585
562
|
end
|
586
563
|
|
587
564
|
context 'with rich_data is set to true' do
|
@@ -655,41 +632,6 @@ module Serialization
|
|
655
632
|
end.to raise_error(/Cannot create a Pcore::TimestampType from a Integer/)
|
656
633
|
end
|
657
634
|
end
|
658
|
-
|
659
|
-
context 'when data is unknown' do
|
660
|
-
let(:to_converter) { ToDataConverter.new(:message_prefix => 'Test Hash') }
|
661
|
-
let(:logs) { [] }
|
662
|
-
let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
|
663
|
-
let(:val) { Class.new }
|
664
|
-
|
665
|
-
context 'and :silence_warnings undefined or set to false' do
|
666
|
-
it 'convert the unknown data to string with warnings' do
|
667
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
668
|
-
write(val)
|
669
|
-
val2 = read
|
670
|
-
expect(val2).to be_a(String)
|
671
|
-
expect(val2).to match(/Class/)
|
672
|
-
end
|
673
|
-
expect(warnings).to eql([
|
674
|
-
"Test Hash contains a #{val.class} value. It will be converted to the String '#{val.to_s}'"])
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
context 'and :silence_warnings undefined or set to true' do
|
679
|
-
let(:to_converter) { ToDataConverter.new(:message_prefix => 'Test Hash', :silence_warnings => true) }
|
680
|
-
|
681
|
-
it 'convert the unknown data to string without warnings if silence_warnings set to true' do
|
682
|
-
val = Class.new
|
683
|
-
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
684
|
-
write(val)
|
685
|
-
val2 = read
|
686
|
-
expect(val2).to be_a(String)
|
687
|
-
expect(val2).to match(/Class/)
|
688
|
-
end
|
689
|
-
expect(warnings).to be_empty
|
690
|
-
end
|
691
|
-
end
|
692
|
-
end
|
693
635
|
end
|
694
636
|
end
|
695
637
|
end
|
@@ -414,6 +414,11 @@ describe "validating 4x" do
|
|
414
414
|
expect(acceptor.error_count).to eql(0)
|
415
415
|
end
|
416
416
|
|
417
|
+
it 'allows apply to be used as a resource attribute name' do
|
418
|
+
acceptor = validate(parse('apply("foo.example.com") { sometype { "resourcetitle": apply => "applyvalue" } }'))
|
419
|
+
expect(acceptor.error_count).to eql(0)
|
420
|
+
end
|
421
|
+
|
417
422
|
it 'accepts multiple arguments' do
|
418
423
|
acceptor = validate(parse('apply(["foo.example.com"], { "other" => "args" }) { }'))
|
419
424
|
expect(acceptor.error_count).to eql(0)
|
@@ -6,8 +6,8 @@ describe 'Puppet::Type::Service::Provider::Gentoo',
|
|
6
6
|
|
7
7
|
before :each do
|
8
8
|
allow(Puppet::Type.type(:service)).to receive(:defaultprovider).and_return(provider_class)
|
9
|
-
allow(
|
10
|
-
allow(
|
9
|
+
allow(Puppet::FileSystem).to receive(:file?).with('/sbin/rc-update').and_return(true)
|
10
|
+
allow(Puppet::FileSystem).to receive(:executable?).with('/sbin/rc-update').and_return(true)
|
11
11
|
allow(Facter).to receive(:value).with(:operatingsystem).and_return('Gentoo')
|
12
12
|
allow(Facter).to receive(:value).with(:osfamily).and_return('Gentoo')
|
13
13
|
|
@@ -52,13 +52,14 @@ describe 'Puppet::Type::Service::Provider::Gentoo',
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should get a list of services from /etc/init.d but exclude helper scripts" do
|
55
|
-
|
55
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
56
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
56
57
|
expect(Dir).to receive(:entries).with('/etc/init.d').and_return(initscripts)
|
57
58
|
(initscripts - helperscripts).each do |script|
|
58
|
-
expect(
|
59
|
+
expect(Puppet::FileSystem).to receive(:executable?).with("/etc/init.d/#{script}").and_return(true)
|
59
60
|
end
|
60
61
|
helperscripts.each do |script|
|
61
|
-
expect(
|
62
|
+
expect(Puppet::FileSystem).not_to receive(:executable?).with("/etc/init.d/#{script}")
|
62
63
|
end
|
63
64
|
|
64
65
|
allow(Puppet::FileSystem).to receive(:symlink?).and_return(false)
|
@@ -85,14 +85,20 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
85
85
|
@services = ['one', 'two', 'three', 'four', 'umountfs']
|
86
86
|
allow(Dir).to receive(:entries).and_call_original
|
87
87
|
allow(Dir).to receive(:entries).with('tmp').and_return(@services)
|
88
|
-
|
89
|
-
allow(
|
88
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
89
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('tmp').and_return(true)
|
90
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
90
91
|
end
|
91
92
|
|
92
93
|
it "should return instances for all services" do
|
93
94
|
expect(provider_class.instances.map(&:name)).to eq(@services)
|
94
95
|
end
|
95
96
|
|
97
|
+
it "should omit directories from the service list" do
|
98
|
+
expect(Puppet::FileSystem).to receive(:directory?).with('tmp/four').and_return(true)
|
99
|
+
expect(provider_class.instances.map(&:name)).to eq(@services - ['four'])
|
100
|
+
end
|
101
|
+
|
96
102
|
it "should omit an array of services from exclude list" do
|
97
103
|
exclude = ['two', 'four']
|
98
104
|
expect(provider_class.get_services(provider_class.defpath, exclude).map(&:name)).to eq(@services - exclude)
|
@@ -140,9 +146,9 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
140
146
|
|
141
147
|
describe "when checking valid paths" do
|
142
148
|
it "should discard paths that do not exist" do
|
143
|
-
expect(
|
149
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(paths[0]).and_return(false)
|
144
150
|
expect(Puppet::FileSystem).to receive(:exist?).with(paths[0]).and_return(false)
|
145
|
-
expect(
|
151
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(paths[1]).and_return(true)
|
146
152
|
|
147
153
|
expect(provider.paths).to eq([paths[1]])
|
148
154
|
end
|
@@ -150,7 +156,7 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
150
156
|
it "should discard paths that are not directories" do
|
151
157
|
paths.each do |path|
|
152
158
|
expect(Puppet::FileSystem).to receive(:exist?).with(path).and_return(true)
|
153
|
-
expect(
|
159
|
+
expect(Puppet::FileSystem).to receive(:directory?).with(path).and_return(false)
|
154
160
|
end
|
155
161
|
expect(provider.paths).to be_empty
|
156
162
|
end
|
@@ -158,7 +164,7 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
158
164
|
|
159
165
|
describe "when searching for the init script" do
|
160
166
|
before :each do
|
161
|
-
paths.each {|path| expect(
|
167
|
+
paths.each {|path| expect(Puppet::FileSystem).to receive(:directory?).with(path).and_return(true) }
|
162
168
|
end
|
163
169
|
|
164
170
|
it "should be able to find the init script in the service path" do
|
@@ -191,9 +197,9 @@ describe 'Puppet::Type::Service::Provider::Init',
|
|
191
197
|
|
192
198
|
describe "if the init script is present" do
|
193
199
|
before :each do
|
194
|
-
allow(
|
195
|
-
allow(
|
196
|
-
allow(
|
200
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
201
|
+
allow(Puppet::FileSystem).to receive(:directory?).with("/service/path").and_return(true)
|
202
|
+
allow(Puppet::FileSystem).to receive(:directory?).with("/alt/service/path").and_return(true)
|
197
203
|
allow(Puppet::FileSystem).to receive(:exist?).with("/service/path/myservice").and_return(true)
|
198
204
|
end
|
199
205
|
|
@@ -2,63 +2,56 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe 'Puppet::Type::Service::Provider::Openwrt',
|
4
4
|
unless: Puppet::Util::Platform.windows? || Puppet::Util::Platform.jruby? do
|
5
|
+
|
5
6
|
let(:provider_class) { Puppet::Type.type(:service).provider(:openwrt) }
|
6
7
|
|
7
8
|
let(:resource) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
resource
|
9
|
+
Puppet::Type.type(:service).new(
|
10
|
+
:name => 'myservice',
|
11
|
+
:path => '/etc/init.d',
|
12
|
+
:hasrestart => true,
|
13
|
+
)
|
14
14
|
end
|
15
15
|
|
16
16
|
let(:provider) do
|
17
17
|
provider = provider_class.new
|
18
|
-
|
19
|
-
|
18
|
+
provider.resource = resource
|
20
19
|
provider
|
21
20
|
end
|
22
21
|
|
23
22
|
before :each do
|
24
|
-
|
25
|
-
provider.resource = resource
|
26
|
-
|
27
|
-
allow(FileTest).to receive(:file?).with('/etc/rc.common').and_return(true)
|
28
|
-
allow(FileTest).to receive(:executable?).with('/etc/rc.common').and_return(true)
|
23
|
+
resource.provider = provider
|
29
24
|
|
30
25
|
# All OpenWrt tests operate on the init script directly. It must exist.
|
31
|
-
allow(
|
32
|
-
allow(
|
26
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
27
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
33
28
|
|
34
29
|
allow(Puppet::FileSystem).to receive(:exist?).with('/etc/init.d/myservice').and_return(true)
|
35
|
-
allow(
|
36
|
-
allow(
|
37
|
-
allow(
|
30
|
+
allow(Puppet::FileSystem).to receive(:file?).and_call_original
|
31
|
+
allow(Puppet::FileSystem).to receive(:file?).with('/etc/init.d/myservice').and_return(true)
|
32
|
+
allow(Puppet::FileSystem).to receive(:executable?).with('/etc/init.d/myservice').and_return(true)
|
38
33
|
end
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
expect(Facter).to receive(:value).with(:operatingsystem).and_return(operatingsystem)
|
35
|
+
it "should be the default provider on 'openwrt'" do
|
36
|
+
expect(Facter).to receive(:value).with(:operatingsystem).and_return('openwrt')
|
43
37
|
expect(provider_class.default?).to be_truthy
|
44
38
|
end
|
45
39
|
|
46
40
|
# test self.instances
|
47
41
|
describe "when getting all service instances" do
|
48
|
-
let(:services) {['dnsmasq', 'dropbear', 'firewall', 'led', 'puppet', 'uhttpd' ]}
|
42
|
+
let(:services) { ['dnsmasq', 'dropbear', 'firewall', 'led', 'puppet', 'uhttpd' ] }
|
49
43
|
|
50
44
|
before :each do
|
51
45
|
allow(Dir).to receive(:entries).and_call_original
|
52
46
|
allow(Dir).to receive(:entries).with('/etc/init.d').and_return(services)
|
53
|
-
allow(
|
54
|
-
allow(FileTest).to receive(:executable?).and_return(true)
|
47
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
55
48
|
end
|
56
49
|
|
57
50
|
it "should return instances for all services" do
|
58
51
|
services.each do |inst|
|
59
52
|
expect(provider_class).to receive(:new).with(hash_including(:name => inst, :path => '/etc/init.d')).and_return("#{inst}_instance")
|
60
53
|
end
|
61
|
-
results = services.collect {|x| "#{x}_instance"}
|
54
|
+
results = services.collect { |x| "#{x}_instance"}
|
62
55
|
expect(provider_class.instances).to eq(results)
|
63
56
|
end
|
64
57
|
end
|
@@ -82,14 +75,13 @@ describe 'Puppet::Type::Service::Provider::Openwrt',
|
|
82
75
|
|
83
76
|
describe "when running #{method}" do
|
84
77
|
it "should use any provided explicit command" do
|
85
|
-
|
86
|
-
expect(provider).to receive(:execute).with([
|
78
|
+
resource[method] = '/user/specified/command'
|
79
|
+
expect(provider).to receive(:execute).with(['/user/specified/command'], any_args)
|
87
80
|
provider.send(method)
|
88
81
|
end
|
89
82
|
|
90
83
|
it "should execute the init script with #{method} when no explicit command is provided" do
|
91
|
-
|
92
|
-
expect(provider).to receive(:execute).with(['/etc/init.d/myservice', method ], any_args)
|
84
|
+
expect(provider).to receive(:execute).with(['/etc/init.d/myservice', method], any_args)
|
93
85
|
provider.send(method)
|
94
86
|
end
|
95
87
|
end
|
@@ -41,8 +41,9 @@ describe 'Puppet::Type::Service::Provider::Redhat',
|
|
41
41
|
@services = ['one', 'two', 'three', 'four', 'kudzu', 'functions', 'halt', 'killall', 'single', 'linuxconf', 'boot', 'reboot']
|
42
42
|
@not_services = ['functions', 'halt', 'killall', 'single', 'linuxconf', 'reboot', 'boot']
|
43
43
|
allow(Dir).to receive(:entries).and_return(@services)
|
44
|
-
allow(
|
45
|
-
allow(
|
44
|
+
allow(Puppet::FileSystem).to receive(:directory?).and_call_original
|
45
|
+
allow(Puppet::FileSystem).to receive(:directory?).with('/etc/init.d').and_return(true)
|
46
|
+
allow(Puppet::FileSystem).to receive(:executable?).and_return(true)
|
46
47
|
end
|
47
48
|
|
48
49
|
it "should return instances for all services" do
|
@@ -138,6 +138,57 @@ describe Puppet::Transaction::Persistence do
|
|
138
138
|
persistence = Puppet::Transaction::Persistence.new
|
139
139
|
expect(persistence.load.dig("File[/tmp/audit]", "parameters", "mtime", "system_value")).to contain_exactly(be_a(Time))
|
140
140
|
end
|
141
|
+
|
142
|
+
it 'should load Regexp' do
|
143
|
+
write_state_file(<<~END)
|
144
|
+
system_value:
|
145
|
+
- !ruby/regexp /regexp/
|
146
|
+
END
|
147
|
+
|
148
|
+
persistence = Puppet::Transaction::Persistence.new
|
149
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Regexp))
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should load semantic puppet version' do
|
153
|
+
write_state_file(<<~END)
|
154
|
+
system_value:
|
155
|
+
- !ruby/object:SemanticPuppet::Version
|
156
|
+
major: 1
|
157
|
+
minor: 0
|
158
|
+
patch: 0
|
159
|
+
prerelease:
|
160
|
+
build:
|
161
|
+
END
|
162
|
+
|
163
|
+
persistence = Puppet::Transaction::Persistence.new
|
164
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(SemanticPuppet::Version))
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should load puppet time related objects' do
|
168
|
+
write_state_file(<<~END)
|
169
|
+
system_value:
|
170
|
+
- !ruby/object:Puppet::Pops::Time::Timestamp
|
171
|
+
nsecs: 1638316135955087259
|
172
|
+
- !ruby/object:Puppet::Pops::Time::TimeData
|
173
|
+
nsecs: 1495789430910161286
|
174
|
+
- !ruby/object:Puppet::Pops::Time::Timespan
|
175
|
+
nsecs: 1495789430910161286
|
176
|
+
END
|
177
|
+
|
178
|
+
persistence = Puppet::Transaction::Persistence.new
|
179
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Time::Timestamp), be_a(Puppet::Pops::Time::TimeData), be_a(Puppet::Pops::Time::Timespan))
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should load binary objects' do
|
183
|
+
write_state_file(<<~END)
|
184
|
+
system_value:
|
185
|
+
- !ruby/object:Puppet::Pops::Types::PBinaryType::Binary
|
186
|
+
binary_buffer: ''
|
187
|
+
END
|
188
|
+
|
189
|
+
persistence = Puppet::Transaction::Persistence.new
|
190
|
+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Types::PBinaryType::Binary))
|
191
|
+
end
|
141
192
|
end
|
142
193
|
end
|
143
194
|
|
@@ -27,6 +27,13 @@ describe Puppet::Type.type(:file).attrclass(:group) do
|
|
27
27
|
expect { group.insync?(5) }.to raise_error(/Could not find group foos/)
|
28
28
|
end
|
29
29
|
|
30
|
+
it "should return false if a group's id can't be found by name in noop" do
|
31
|
+
Puppet[:noop] = true
|
32
|
+
allow(resource.provider).to receive(:name2gid).and_return(nil)
|
33
|
+
|
34
|
+
expect(group.insync?('notcreatedyet')).to eq(false)
|
35
|
+
end
|
36
|
+
|
30
37
|
it "should use the id for comparisons, not the name" do
|
31
38
|
expect(group.insync?('foos')).to be_falsey
|
32
39
|
end
|
@@ -25,6 +25,13 @@ describe Puppet::Type.type(:file).attrclass(:owner) do
|
|
25
25
|
expect { owner.insync?(5) }.to raise_error(/Could not find user foo/)
|
26
26
|
end
|
27
27
|
|
28
|
+
it "should return false if an owner's id can't be found by name in noop" do
|
29
|
+
Puppet[:noop] = true
|
30
|
+
allow(resource.provider).to receive(:name2uid).and_return(nil)
|
31
|
+
|
32
|
+
expect(owner.insync?('notcreatedyet')).to eq(false)
|
33
|
+
end
|
34
|
+
|
28
35
|
it "should use the id for comparisons, not the name" do
|
29
36
|
expect(owner.insync?('foo')).to be_falsey
|
30
37
|
end
|
data/spec/unit/type/user_spec.rb
CHANGED
@@ -174,51 +174,6 @@ describe Puppet::Type.type(:user) do
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
-
describe "when managing the purge_ssh_keys property" do
|
178
|
-
context "with valid input" do
|
179
|
-
it "should support a :true value" do
|
180
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => :true) }.to_not raise_error
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should support a :false value" do
|
184
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => :false) }.to_not raise_error
|
185
|
-
end
|
186
|
-
|
187
|
-
it "should support a String value" do
|
188
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => File.expand_path('home/foo/.ssh/authorized_keys')) }.to_not raise_error
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should support an Array value" do
|
192
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => [File.expand_path('home/foo/.ssh/authorized_keys'),
|
193
|
-
File.expand_path('custom/authorized_keys')]) }.to_not raise_error
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context "with faulty input" do
|
198
|
-
it "should raise error for relative path" do
|
199
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => 'home/foo/.ssh/authorized_keys') }.to raise_error(Puppet::ResourceError,
|
200
|
-
/Paths to keyfiles must be absolute/ )
|
201
|
-
end
|
202
|
-
|
203
|
-
it "should raise error for invalid type" do
|
204
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => :invalid) }.to raise_error(Puppet::ResourceError,
|
205
|
-
/purge_ssh_keys must be true, false, or an array of file names/ )
|
206
|
-
end
|
207
|
-
|
208
|
-
it "should raise error for array with relative path" do
|
209
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => ['home/foo/.ssh/authorized_keys',
|
210
|
-
File.expand_path('custom/authorized_keys')]) }.to raise_error(Puppet::ResourceError,
|
211
|
-
/Paths to keyfiles must be absolute/ )
|
212
|
-
end
|
213
|
-
|
214
|
-
it "should raise error for array with invalid type" do
|
215
|
-
expect { described_class.new(:name => 'foo', :purge_ssh_keys => [:invalid,
|
216
|
-
File.expand_path('custom/authorized_keys')]) }.to raise_error(Puppet::ResourceError,
|
217
|
-
/Each entry for purge_ssh_keys must be a string/ )
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
177
|
describe "when managing the uid property" do
|
223
178
|
it "should convert number-looking strings into actual numbers" do
|
224
179
|
expect(described_class.new(:name => 'foo', :uid => '50')[:uid]).to eq(50)
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'puppet/util/json'
|
4
|
+
|
5
|
+
describe Puppet::Util::Json do
|
6
|
+
include PuppetSpec::Files
|
7
|
+
|
8
|
+
shared_examples_for 'json file loader' do |load_method|
|
9
|
+
it 'reads a JSON file from disk' do
|
10
|
+
file_path = file_containing('input', JSON.dump({ "my" => "data" }))
|
11
|
+
|
12
|
+
expect(load_method.call(file_path)).to eq({ "my" => "data" })
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'reads JSON as UTF-8' do
|
16
|
+
file_path = file_containing('input', JSON.dump({ "my" => "𠜎" }))
|
17
|
+
|
18
|
+
expect(load_method.call(file_path)).to eq({ "my" => "𠜎" })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#load" do
|
23
|
+
it 'raises an error if JSON is invalid' do
|
24
|
+
expect {
|
25
|
+
Puppet::Util::Json.load('{ invalid')
|
26
|
+
}.to raise_error(Puppet::Util::Json::ParseError, /unexpected token at '{ invalid'/)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'raises an error if the content is empty' do
|
30
|
+
expect {
|
31
|
+
Puppet::Util::Json.load('')
|
32
|
+
}.to raise_error(Puppet::Util::Json::ParseError)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'loads true' do
|
36
|
+
expect(Puppet::Util::Json.load('true')).to eq(true)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'loads false' do
|
40
|
+
expect(Puppet::Util::Json.load('false')).to eq(false)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'loads a numeric' do
|
44
|
+
expect(Puppet::Util::Json.load('42')).to eq(42)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'loads a string' do
|
48
|
+
expect(Puppet::Util::Json.load('"puppet"')).to eq('puppet')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'loads an array' do
|
52
|
+
expect(Puppet::Util::Json.load(<<~JSON)).to eq([1, 2])
|
53
|
+
[1, 2]
|
54
|
+
JSON
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'loads a hash' do
|
58
|
+
expect(Puppet::Util::Json.load(<<~JSON)).to eq('a' => 1, 'b' => 2)
|
59
|
+
{
|
60
|
+
"a": 1,
|
61
|
+
"b": 2
|
62
|
+
}
|
63
|
+
JSON
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "load_file_if_valid" do
|
68
|
+
before do
|
69
|
+
Puppet[:log_level] = 'debug'
|
70
|
+
end
|
71
|
+
|
72
|
+
it_should_behave_like 'json file loader', Puppet::Util::Json.method(:load_file_if_valid)
|
73
|
+
|
74
|
+
it 'returns nil when the file is invalid JSON and debug logs about it' do
|
75
|
+
file_path = file_containing('input', '{ invalid')
|
76
|
+
expect(Puppet).to receive(:debug)
|
77
|
+
.with(/Could not retrieve JSON content .+: unexpected token at '{ invalid'/).and_call_original
|
78
|
+
|
79
|
+
expect(Puppet::Util::Json.load_file_if_valid(file_path)).to eql(nil)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns nil when the filename is illegal and debug logs about it' do
|
83
|
+
expect(Puppet).to receive(:debug)
|
84
|
+
.with(/Could not retrieve JSON content .+: pathname contains null byte/).and_call_original
|
85
|
+
|
86
|
+
expect(Puppet::Util::Json.load_file_if_valid("not\0allowed")).to eql(nil)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns nil when the file does not exist and debug logs about it' do
|
90
|
+
expect(Puppet).to receive(:debug)
|
91
|
+
.with(/Could not retrieve JSON content .+: No such file or directory/).and_call_original
|
92
|
+
|
93
|
+
expect(Puppet::Util::Json.load_file_if_valid('does/not/exist.json')).to eql(nil)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context '#load_file' do
|
98
|
+
it_should_behave_like 'json file loader', Puppet::Util::Json.method(:load_file)
|
99
|
+
|
100
|
+
it 'raises an error when the file is invalid JSON' do
|
101
|
+
file_path = file_containing('input', '{ invalid')
|
102
|
+
|
103
|
+
expect {
|
104
|
+
Puppet::Util::Json.load_file(file_path)
|
105
|
+
}.to raise_error(Puppet::Util::Json::ParseError, /unexpected token at '{ invalid'/)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'raises an error when the filename is illegal' do
|
109
|
+
expect {
|
110
|
+
Puppet::Util::Json.load_file("not\0allowed")
|
111
|
+
}.to raise_error(ArgumentError, /null byte/)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'raises an error when the file does not exist' do
|
115
|
+
expect {
|
116
|
+
Puppet::Util::Json.load_file('does/not/exist.json')
|
117
|
+
}.to raise_error(Errno::ENOENT, /No such file or directory/)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'writes data formatted as JSON to disk' do
|
121
|
+
file_path = file_containing('input', Puppet::Util::Json.dump({ "my" => "data" }))
|
122
|
+
|
123
|
+
expect(Puppet::Util::Json.load_file(file_path)).to eq({ "my" => "data" })
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|