puppet 4.5.2-x86-mingw32 → 4.5.3-x86-mingw32
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.
- data/ext/project_data.yaml +12 -10
- data/lib/puppet/parser/scope.rb +17 -5
- data/lib/puppet/pops/evaluator/closure.rb +2 -2
- data/lib/puppet/pops/patterns.rb +4 -0
- data/lib/puppet/pops/types/string_converter.rb +79 -30
- data/lib/puppet/pops/types/type_formatter.rb +1 -2
- data/lib/puppet/pops/types/types.rb +20 -0
- data/lib/puppet/provider/group/windows_adsi.rb +5 -2
- data/lib/puppet/provider/package/dnf.rb +1 -1
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +7 -0
- data/lib/puppet/provider/user/windows_adsi.rb +7 -4
- data/lib/puppet/reference/configuration.rb +2 -0
- data/lib/puppet/resource/type.rb +1 -1
- data/lib/puppet/util/plist.rb +1 -1
- data/lib/puppet/util/windows/taskscheduler.rb +84 -28
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/parser/parameter_defaults_spec.rb +1 -1
- data/spec/integration/util/windows/security_spec.rb +1 -0
- data/spec/unit/functions/new_spec.rb +56 -5
- data/spec/unit/pops/types/string_converter_spec.rb +91 -55
- data/spec/unit/pops/types/types_spec.rb +1 -1
- data/spec/unit/provider/group/windows_adsi_spec.rb +4 -0
- data/spec/unit/provider/package/dnf_spec.rb +20 -0
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +197 -10
- data/spec/unit/provider/user/windows_adsi_spec.rb +4 -0
- data/spec/unit/resource/type_spec.rb +11 -2
- data/spec/unit/util/windows/sid_spec.rb +1 -0
- data/spec/unit/version_spec.rb +15 -0
- metadata +3629 -3629
@@ -115,18 +115,44 @@ describe 'The string converter' do
|
|
115
115
|
expect(converter.convert('3.1415', string_formats)).to eq('3.1415')
|
116
116
|
end
|
117
117
|
|
118
|
-
|
119
|
-
string_formats
|
120
|
-
|
118
|
+
context 'The %p format for string produces' do
|
119
|
+
let!(:string_formats) { { Puppet::Pops::Types::PStringType::DEFAULT => '%p'} }
|
120
|
+
it 'double quoted result for string that contains control characters' do
|
121
|
+
expect(converter.convert("hello\tworld.\r\nSun is brigth today.", string_formats)).to eq('"hello\\tworld.\\r\\nSun is brigth today."')
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'singe quoted result for string that is plain ascii without \\, $ or control characters' do
|
125
|
+
expect(converter.convert('hello world', string_formats)).to eq("'hello world'")
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'quoted 5-byte unicode chars' do
|
129
|
+
expect(converter.convert("smile \u{1f603}.", string_formats)).to eq('"smile \\u{1F603}."')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'quoted 2-byte unicode chars' do
|
133
|
+
expect(converter.convert("esc \u{1b}.", string_formats)).to eq('"esc \\u{1B}."')
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'escape for $' do
|
137
|
+
expect(converter.convert('escape the $ sign', string_formats)).to eq('"escape the \$ sign"')
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'escape for double qoute but not for single quote' do
|
141
|
+
expect(converter.convert('the \' single and " double quote', string_formats)).to eq('"the \' single and \\" double quote"')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'no escape for #' do
|
145
|
+
expect(converter.convert('do not escape #{x}', string_formats)).to eq('\'do not escape #{x}\'')
|
146
|
+
end
|
121
147
|
end
|
122
148
|
|
123
149
|
{
|
124
150
|
'%s' => 'hello::world',
|
125
|
-
'%p' => '
|
151
|
+
'%p' => "'hello::world'",
|
126
152
|
'%c' => 'Hello::world',
|
127
|
-
'%#c' => '
|
153
|
+
'%#c' => "'Hello::world'",
|
128
154
|
'%u' => 'HELLO::WORLD',
|
129
|
-
'%#u' => '
|
155
|
+
'%#u' => "'HELLO::WORLD'",
|
130
156
|
}.each do |fmt, result |
|
131
157
|
it "the format #{fmt} produces #{result}" do
|
132
158
|
string_formats = { Puppet::Pops::Types::PStringType::DEFAULT => fmt}
|
@@ -136,9 +162,9 @@ describe 'The string converter' do
|
|
136
162
|
|
137
163
|
{
|
138
164
|
'%c' => 'Hello::world',
|
139
|
-
'%#c' => '
|
165
|
+
'%#c' => "'Hello::world'",
|
140
166
|
'%d' => 'hello::world',
|
141
|
-
'%#d' => '
|
167
|
+
'%#d' => "'hello::world'",
|
142
168
|
}.each do |fmt, result |
|
143
169
|
it "the format #{fmt} produces #{result}" do
|
144
170
|
string_formats = { Puppet::Pops::Types::PStringType::DEFAULT => fmt}
|
@@ -146,6 +172,18 @@ describe 'The string converter' do
|
|
146
172
|
end
|
147
173
|
end
|
148
174
|
|
175
|
+
{
|
176
|
+
[nil, '%.1p'] => 'u',
|
177
|
+
[nil, '%#.2p'] => '"u',
|
178
|
+
[:default, '%.1p'] => 'd',
|
179
|
+
[true, '%.2s'] => 'tr',
|
180
|
+
[true, '%.2y'] => 'ye',
|
181
|
+
}.each do |args, result |
|
182
|
+
it "the format #{args[1]} produces #{result} for value #{args[0]}" do
|
183
|
+
expect(converter.convert(*args)).to eq(result)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
149
187
|
{
|
150
188
|
' a b ' => 'a b',
|
151
189
|
'a b ' => 'a b',
|
@@ -158,9 +196,9 @@ describe 'The string converter' do
|
|
158
196
|
end
|
159
197
|
|
160
198
|
{
|
161
|
-
' a b ' => '
|
162
|
-
'a b ' => '
|
163
|
-
' a b' => '
|
199
|
+
' a b ' => "'a b'",
|
200
|
+
'a b ' => "'a b'",
|
201
|
+
' a b' => "'a b'",
|
164
202
|
}.each do |input, result |
|
165
203
|
it "the input #{input} is trimmed to #{result} by using format '%#t'" do
|
166
204
|
string_formats = { Puppet::Pops::Types::PStringType::DEFAULT => '%#t'}
|
@@ -192,15 +230,13 @@ describe 'The string converter' do
|
|
192
230
|
|
193
231
|
{
|
194
232
|
'%4.2s' => ' he',
|
195
|
-
'%4.2p' => '
|
233
|
+
'%4.2p' => " 'h",
|
196
234
|
'%4.2c' => ' He',
|
197
|
-
'%#4.2c' => '
|
235
|
+
'%#4.2c' => " 'H",
|
198
236
|
'%4.2u' => ' HE',
|
199
|
-
'%#4.2u' => '
|
200
|
-
'%4.2c' => ' He',
|
201
|
-
'%#4.2c' => ' "H',
|
237
|
+
'%#4.2u' => " 'H",
|
202
238
|
'%4.2d' => ' he',
|
203
|
-
'%#4.2d' => '
|
239
|
+
'%#4.2d' => " 'h"
|
204
240
|
}.each do |fmt, result |
|
205
241
|
it "width and precision can be combined with #{fmt}" do
|
206
242
|
string_formats = { Puppet::Pops::Types::PStringType::DEFAULT => fmt}
|
@@ -580,30 +616,30 @@ describe 'The string converter' do
|
|
580
616
|
|
581
617
|
context 'when converting array' do
|
582
618
|
it 'the default string representation is using [] delimiters, joins with ',' and uses %p for values' do
|
583
|
-
expect(converter.convert(["hello", "world"], :default)).to eq('
|
619
|
+
expect(converter.convert(["hello", "world"], :default)).to eq("['hello', 'world']")
|
584
620
|
end
|
585
621
|
|
586
|
-
{ "%s" =>
|
587
|
-
"%p" =>
|
588
|
-
"%a" =>
|
589
|
-
"%<a" =>
|
590
|
-
"%[a" =>
|
591
|
-
"%(a" =>
|
592
|
-
"%{a" =>
|
593
|
-
"% a" =>
|
622
|
+
{ "%s" => "[1, 'hello']",
|
623
|
+
"%p" => "[1, 'hello']",
|
624
|
+
"%a" => "[1, 'hello']",
|
625
|
+
"%<a" => "<1, 'hello'>",
|
626
|
+
"%[a" => "[1, 'hello']",
|
627
|
+
"%(a" => "(1, 'hello')",
|
628
|
+
"%{a" => "{1, 'hello'}",
|
629
|
+
"% a" => "1, 'hello'",
|
594
630
|
|
595
631
|
{'format' => '%(a',
|
596
632
|
'separator' => ''
|
597
|
-
} =>
|
633
|
+
} => "(1 'hello')",
|
598
634
|
|
599
635
|
{'format' => '%|a',
|
600
636
|
'separator' => ''
|
601
|
-
} =>
|
637
|
+
} => "|1 'hello'|",
|
602
638
|
|
603
|
-
{'format' => '%(a',
|
604
|
-
'separator' => '',
|
639
|
+
{'format' => '%(a',
|
640
|
+
'separator' => '',
|
605
641
|
'string_formats' => {Puppet::Pops::Types::PIntegerType::DEFAULT => '%#x'}
|
606
|
-
} =>
|
642
|
+
} => "(0x1 'hello')",
|
607
643
|
}.each do |fmt, result |
|
608
644
|
it "the format #{fmt} produces #{result}" do
|
609
645
|
string_formats = { Puppet::Pops::Types::PArrayType::DEFAULT => fmt}
|
@@ -614,7 +650,7 @@ describe 'The string converter' do
|
|
614
650
|
it "multiple rules selects most specific" do
|
615
651
|
short_array_t = factory.array_of(factory.integer, factory.range(1,2))
|
616
652
|
long_array_t = factory.array_of(factory.integer, factory.range(3,100))
|
617
|
-
string_formats = {
|
653
|
+
string_formats = {
|
618
654
|
short_array_t => "%(a",
|
619
655
|
long_array_t => "%[a",
|
620
656
|
}
|
@@ -715,27 +751,27 @@ describe 'The string converter' do
|
|
715
751
|
|
716
752
|
context 'when converting hash' do
|
717
753
|
it 'the default string representation is using {} delimiters, joins with '=>' and uses %p for values' do
|
718
|
-
expect(converter.convert({"hello" => "world"}, :default)).to eq('
|
754
|
+
expect(converter.convert({"hello" => "world"}, :default)).to eq("{'hello' => 'world'}")
|
719
755
|
end
|
720
756
|
|
721
|
-
{ "%s" =>
|
722
|
-
"%p" =>
|
723
|
-
"%h" =>
|
724
|
-
"%a" =>
|
725
|
-
"%<h" =>
|
726
|
-
"%[h" =>
|
727
|
-
"%(h" =>
|
728
|
-
"%{h" =>
|
729
|
-
"% h" =>
|
757
|
+
{ "%s" => "{1 => 'world'}",
|
758
|
+
"%p" => "{1 => 'world'}",
|
759
|
+
"%h" => "{1 => 'world'}",
|
760
|
+
"%a" => "[[1, 'world']]",
|
761
|
+
"%<h" => "<1 => 'world'>",
|
762
|
+
"%[h" => "[1 => 'world']",
|
763
|
+
"%(h" => "(1 => 'world')",
|
764
|
+
"%{h" => "{1 => 'world'}",
|
765
|
+
"% h" => "1 => 'world'",
|
730
766
|
|
731
767
|
{'format' => '%(h',
|
732
768
|
'separator2' => ' '
|
733
|
-
} =>
|
769
|
+
} => "(1 'world')",
|
734
770
|
|
735
|
-
{'format' => '%(h',
|
736
|
-
'separator2' => ' ',
|
771
|
+
{'format' => '%(h',
|
772
|
+
'separator2' => ' ',
|
737
773
|
'string_formats' => {Puppet::Pops::Types::PIntegerType::DEFAULT => '%#x'}
|
738
|
-
} =>
|
774
|
+
} => "(0x1 'world')",
|
739
775
|
}.each do |fmt, result |
|
740
776
|
it "the format #{fmt} produces #{result}" do
|
741
777
|
string_formats = { Puppet::Pops::Types::PHashType::DEFAULT => fmt}
|
@@ -743,17 +779,17 @@ describe 'The string converter' do
|
|
743
779
|
end
|
744
780
|
end
|
745
781
|
|
746
|
-
{ "%s" =>
|
782
|
+
{ "%s" => "{1 => 'hello', 2 => 'world'}",
|
747
783
|
|
748
784
|
{'format' => '%(h',
|
749
785
|
'separator2' => ' '
|
750
|
-
} =>
|
786
|
+
} => "(1 'hello', 2 'world')",
|
751
787
|
|
752
|
-
{'format' => '%(h',
|
753
|
-
'separator' => ' >>',
|
754
|
-
'separator2' => ' <=> ',
|
788
|
+
{'format' => '%(h',
|
789
|
+
'separator' => ' >>',
|
790
|
+
'separator2' => ' <=> ',
|
755
791
|
'string_formats' => {Puppet::Pops::Types::PIntegerType::DEFAULT => '%#x'}
|
756
|
-
} =>
|
792
|
+
} => "(0x1 <=> 'hello' >> 0x2 <=> 'world')",
|
757
793
|
}.each do |fmt, result |
|
758
794
|
it "the format #{fmt} produces #{result}" do
|
759
795
|
string_formats = { Puppet::Pops::Types::PHashType::DEFAULT => fmt}
|
@@ -770,9 +806,9 @@ describe 'The string converter' do
|
|
770
806
|
# formatting matters here
|
771
807
|
result = [
|
772
808
|
"{",
|
773
|
-
" 1 =>
|
809
|
+
" 1 => 'hello',",
|
774
810
|
" 2 => {",
|
775
|
-
" 3 =>
|
811
|
+
" 3 => 'world'",
|
776
812
|
" }",
|
777
813
|
"}"
|
778
814
|
].join("\n")
|
@@ -782,7 +818,7 @@ describe 'The string converter' do
|
|
782
818
|
|
783
819
|
context "containing an array" do
|
784
820
|
it 'the hash and array renders without breaks and indentation by default' do
|
785
|
-
result =
|
821
|
+
result = "{1 => [1, 2, 3]}"
|
786
822
|
formatted = converter.convert({ 1 => [1, 2, 3] }, :default)
|
787
823
|
expect(formatted).to eq(result)
|
788
824
|
end
|
@@ -353,7 +353,7 @@ describe 'Puppet Type System' do
|
|
353
353
|
end
|
354
354
|
|
355
355
|
it 'can be created with a runtime and, puppet name pattern, and runtime replacement' do
|
356
|
-
expect(tf.runtime('ruby', [/^MyPackage::(.*)$/, 'MyModule::\1']).to_s).to eq("Runtime[ruby, [/^MyPackage::(.*)$/,
|
356
|
+
expect(tf.runtime('ruby', [/^MyPackage::(.*)$/, 'MyModule::\1']).to_s).to eq("Runtime[ruby, [/^MyPackage::(.*)$/, \"MyModule::\\\\1\"]]")
|
357
357
|
end
|
358
358
|
|
359
359
|
it 'will map a Puppet name to a runtime type' do
|
@@ -74,6 +74,10 @@ describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.featur
|
|
74
74
|
resource[:auth_membership] = true
|
75
75
|
end
|
76
76
|
|
77
|
+
it "should return true when current and should contain the same users in a different order" do
|
78
|
+
expect(provider.members_insync?(['user1', 'user2', 'user3'], ['user3', 'user1', 'user2'])).to be_truthy
|
79
|
+
end
|
80
|
+
|
77
81
|
it "should return false when current is nil" do
|
78
82
|
expect(provider.members_insync?(nil, ['user2'])).to be_falsey
|
79
83
|
end
|
@@ -5,6 +5,26 @@ require 'spec_helper'
|
|
5
5
|
|
6
6
|
provider_class = Puppet::Type.type(:package).provider(:dnf)
|
7
7
|
|
8
|
+
context 'default' do
|
9
|
+
[ 19, 20, 21 ].each do |ver|
|
10
|
+
it "should not be the default provider on fedora#{ver}" do
|
11
|
+
Facter.stubs(:value).with(:osfamily).returns(:redhat)
|
12
|
+
Facter.stubs(:value).with(:operatingsystem).returns(:fedora)
|
13
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns("#{ver}")
|
14
|
+
expect(provider_class).to_not be_default
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
[ 22, 23, 24 ].each do |ver|
|
19
|
+
it "should be the default provider on fedora#{ver}" do
|
20
|
+
Facter.stubs(:value).with(:osfamily).returns(:redhat)
|
21
|
+
Facter.stubs(:value).with(:operatingsystem).returns(:fedora)
|
22
|
+
Facter.stubs(:value).with(:operatingsystemmajrelease).returns("#{ver}")
|
23
|
+
expect(provider_class).to be_default
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
8
28
|
describe provider_class do
|
9
29
|
let(:name) { 'mypackage' }
|
10
30
|
let(:resource) do
|
@@ -600,16 +600,6 @@ describe Puppet::Type.type(:scheduled_task).provider(:win32_taskscheduler), :if
|
|
600
600
|
|
601
601
|
expect(resource.provider.exists?).to eq(true)
|
602
602
|
end
|
603
|
-
|
604
|
-
it "uses SystemRoot in the path of Task folder" do
|
605
|
-
Win32::TaskScheduler.unstub(:new)
|
606
|
-
exists_test_task = Win32::TaskScheduler.new
|
607
|
-
Dir.stubs(:foreach).with('D:/WinNT/Tasks').returns([])
|
608
|
-
|
609
|
-
Puppet::Util.withenv('SystemRoot' => 'D:/WinNT') do
|
610
|
-
exists_test_task.exists?('Test Task')
|
611
|
-
end
|
612
|
-
end
|
613
603
|
end
|
614
604
|
|
615
605
|
describe '#clear_task' do
|
@@ -1583,6 +1573,7 @@ describe Puppet::Type.type(:scheduled_task).provider(:win32_taskscheduler), :if
|
|
1583
1573
|
end
|
1584
1574
|
|
1585
1575
|
it 'should save the task' do
|
1576
|
+
@mock_task.expects(:set_account_information).with(nil, nil)
|
1586
1577
|
@mock_task.expects(:save)
|
1587
1578
|
|
1588
1579
|
resource.provider.flush
|
@@ -1856,4 +1847,200 @@ describe Puppet::Type.type(:scheduled_task).provider(:win32_taskscheduler), :if
|
|
1856
1847
|
resource.provider.create
|
1857
1848
|
end
|
1858
1849
|
end
|
1850
|
+
|
1851
|
+
describe "Win32::TaskScheduler", :if => Puppet.features.microsoft_windows? do
|
1852
|
+
|
1853
|
+
let(:name) { SecureRandom.uuid }
|
1854
|
+
|
1855
|
+
describe 'sets appropriate generic trigger defaults' do
|
1856
|
+
before(:each) do
|
1857
|
+
@now = Time.now
|
1858
|
+
Time.stubs(:now).returns(@now)
|
1859
|
+
end
|
1860
|
+
|
1861
|
+
it 'for a ONCE schedule' do
|
1862
|
+
task = Win32::TaskScheduler.new(name, { 'trigger_type' => Win32::TaskScheduler::ONCE })
|
1863
|
+
expect(task.trigger(0)['start_year']).to eq(@now.year)
|
1864
|
+
expect(task.trigger(0)['start_month']).to eq(@now.month)
|
1865
|
+
expect(task.trigger(0)['start_day']).to eq(@now.day)
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
it 'for a DAILY schedule' do
|
1869
|
+
trigger = {
|
1870
|
+
'trigger_type' => Win32::TaskScheduler::DAILY,
|
1871
|
+
'type' => { 'days_interval' => 1 }
|
1872
|
+
}
|
1873
|
+
task = Win32::TaskScheduler.new(name, trigger)
|
1874
|
+
|
1875
|
+
expect(task.trigger(0)['start_year']).to eq(@now.year)
|
1876
|
+
expect(task.trigger(0)['start_month']).to eq(@now.month)
|
1877
|
+
expect(task.trigger(0)['start_day']).to eq(@now.day)
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
it 'for a WEEKLY schedule' do
|
1881
|
+
trigger = {
|
1882
|
+
'trigger_type' => Win32::TaskScheduler::WEEKLY,
|
1883
|
+
'type' => { 'weeks_interval' => 1, 'days_of_week' => 1 }
|
1884
|
+
}
|
1885
|
+
task = Win32::TaskScheduler.new(name, trigger)
|
1886
|
+
|
1887
|
+
expect(task.trigger(0)['start_year']).to eq(@now.year)
|
1888
|
+
expect(task.trigger(0)['start_month']).to eq(@now.month)
|
1889
|
+
expect(task.trigger(0)['start_day']).to eq(@now.day)
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
it 'for a MONTHLYDATE schedule' do
|
1893
|
+
trigger = {
|
1894
|
+
'trigger_type' => Win32::TaskScheduler::MONTHLYDATE,
|
1895
|
+
'type' => { 'days' => 1, 'months' => 1 }
|
1896
|
+
}
|
1897
|
+
task = Win32::TaskScheduler.new(name, trigger)
|
1898
|
+
|
1899
|
+
expect(task.trigger(0)['start_year']).to eq(@now.year)
|
1900
|
+
expect(task.trigger(0)['start_month']).to eq(@now.month)
|
1901
|
+
expect(task.trigger(0)['start_day']).to eq(@now.day)
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
it 'for a MONTHLYDOW schedule' do
|
1905
|
+
trigger = {
|
1906
|
+
'trigger_type' => Win32::TaskScheduler::MONTHLYDOW,
|
1907
|
+
'type' => { 'weeks' => 1, 'days_of_week' => 1, 'months' => 1 }
|
1908
|
+
}
|
1909
|
+
task = Win32::TaskScheduler.new(name, trigger)
|
1910
|
+
|
1911
|
+
expect(task.trigger(0)['start_year']).to eq(@now.year)
|
1912
|
+
expect(task.trigger(0)['start_month']).to eq(@now.month)
|
1913
|
+
expect(task.trigger(0)['start_day']).to eq(@now.day)
|
1914
|
+
end
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
describe 'enforces maximum lengths' do
|
1918
|
+
let(:task) { Win32::TaskScheduler.new(name, { 'trigger_type' => Win32::TaskScheduler::ONCE }) }
|
1919
|
+
|
1920
|
+
it 'on account user name' do
|
1921
|
+
expect {
|
1922
|
+
task.set_account_information('a' * (Win32::TaskScheduler::MAX_ACCOUNT_LENGTH + 1), 'pass')
|
1923
|
+
}.to raise_error(Puppet::Error)
|
1924
|
+
end
|
1925
|
+
|
1926
|
+
it 'on application name' do
|
1927
|
+
expect {
|
1928
|
+
task.application_name = 'a' * (Win32::TaskScheduler::MAX_PATH + 1)
|
1929
|
+
}.to raise_error(Puppet::Error)
|
1930
|
+
end
|
1931
|
+
|
1932
|
+
it 'on parameters' do
|
1933
|
+
expect {
|
1934
|
+
task.parameters = 'a' * (Win32::TaskScheduler::MAX_PARAMETERS_LENGTH + 1)
|
1935
|
+
}.to raise_error(Puppet::Error)
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
it 'on working directory' do
|
1939
|
+
expect {
|
1940
|
+
task.working_directory = 'a' * (Win32::TaskScheduler::MAX_PATH + 1)
|
1941
|
+
}.to raise_error(Puppet::Error)
|
1942
|
+
end
|
1943
|
+
|
1944
|
+
it 'on comment' do
|
1945
|
+
expect {
|
1946
|
+
task.comment = 'a' * (Win32::TaskScheduler::MAX_COMMENT_LENGTH + 1)
|
1947
|
+
}.to raise_error(Puppet::Error)
|
1948
|
+
end
|
1949
|
+
|
1950
|
+
it 'on creator' do
|
1951
|
+
expect {
|
1952
|
+
task.creator = 'a' * (Win32::TaskScheduler::MAX_ACCOUNT_LENGTH + 1)
|
1953
|
+
}.to raise_error(Puppet::Error)
|
1954
|
+
end
|
1955
|
+
end
|
1956
|
+
|
1957
|
+
describe '#exists?' do
|
1958
|
+
it 'works with Unicode task names' do
|
1959
|
+
task_name = name + "\u16A0\u16C7\u16BB" # ᚠᛇᚻ
|
1960
|
+
|
1961
|
+
begin
|
1962
|
+
task = Win32::TaskScheduler.new(task_name, { 'trigger_type' => Win32::TaskScheduler::ONCE })
|
1963
|
+
task.save()
|
1964
|
+
|
1965
|
+
expect(Puppet::FileSystem.exist?("C:\\Windows\\Tasks\\#{task_name}.job")).to be_truthy
|
1966
|
+
expect(task.exists?(task_name)).to be_truthy
|
1967
|
+
ensure
|
1968
|
+
task.delete(task_name) if Win32::TaskScheduler.new.exists?(task_name)
|
1969
|
+
end
|
1970
|
+
end
|
1971
|
+
|
1972
|
+
it 'is case insensitive' do
|
1973
|
+
task_name = name + 'abc' # name is a guid, but might not have alpha chars
|
1974
|
+
|
1975
|
+
begin
|
1976
|
+
task = Win32::TaskScheduler.new(task_name.upcase, { 'trigger_type' => Win32::TaskScheduler::ONCE })
|
1977
|
+
task.save()
|
1978
|
+
|
1979
|
+
expect(task.exists?(task_name.downcase)).to be_truthy
|
1980
|
+
ensure
|
1981
|
+
task.delete(task_name) if Win32::TaskScheduler.new.exists?(task_name)
|
1982
|
+
end
|
1983
|
+
end
|
1984
|
+
end
|
1985
|
+
|
1986
|
+
describe 'does not corrupt tasks' do
|
1987
|
+
it 'when setting maximum length values for all settings' do
|
1988
|
+
begin
|
1989
|
+
task = Win32::TaskScheduler.new(name, { 'trigger_type' => Win32::TaskScheduler::ONCE })
|
1990
|
+
|
1991
|
+
application_name = 'a' * Win32::TaskScheduler::MAX_PATH
|
1992
|
+
parameters = 'b' * Win32::TaskScheduler::MAX_PARAMETERS_LENGTH
|
1993
|
+
working_directory = 'c' * Win32::TaskScheduler::MAX_PATH
|
1994
|
+
comment = 'd' * Win32::TaskScheduler::MAX_COMMENT_LENGTH
|
1995
|
+
creator = 'e' * Win32::TaskScheduler::MAX_ACCOUNT_LENGTH
|
1996
|
+
|
1997
|
+
task.application_name = application_name
|
1998
|
+
task.parameters = parameters
|
1999
|
+
task.working_directory = working_directory
|
2000
|
+
task.comment = comment
|
2001
|
+
task.creator = creator
|
2002
|
+
|
2003
|
+
# saving and reloading (activating) can induce COM load errors when
|
2004
|
+
# file is corrupted, which can happen when the upper bounds of these lengths are set too high
|
2005
|
+
task.save()
|
2006
|
+
task.activate(name)
|
2007
|
+
|
2008
|
+
# furthermore, corrupted values may not necessarily be read back properly
|
2009
|
+
# note that SYSTEM is always returned as an empty string in account_information
|
2010
|
+
expect(task.account_information).to eq('')
|
2011
|
+
expect(task.application_name).to eq(application_name)
|
2012
|
+
expect(task.parameters).to eq(parameters)
|
2013
|
+
expect(task.working_directory).to eq(working_directory)
|
2014
|
+
expect(task.comment).to eq(comment)
|
2015
|
+
expect(task.creator).to eq(creator)
|
2016
|
+
ensure
|
2017
|
+
task.delete(name) if Win32::TaskScheduler.new.exists?(name)
|
2018
|
+
end
|
2019
|
+
end
|
2020
|
+
|
2021
|
+
it 'by preventing a save() not preceded by a set_account_information()' do
|
2022
|
+
begin
|
2023
|
+
# creates a default new task with SYSTEM user
|
2024
|
+
task = Win32::TaskScheduler.new(name, { 'trigger_type' => Win32::TaskScheduler::ONCE })
|
2025
|
+
# save automatically resets the current task
|
2026
|
+
task.save()
|
2027
|
+
|
2028
|
+
# re-activate named task, try to modify, and save
|
2029
|
+
task.activate(name)
|
2030
|
+
task.application_name = 'c:/windows/system32/notepad.exe'
|
2031
|
+
|
2032
|
+
expect { task.save() }.to raise_error(Puppet::Error, /Account information must be set on the current task to save it properly/)
|
2033
|
+
|
2034
|
+
# on a failed save, the current task is still active - add SYSTEM
|
2035
|
+
task.set_account_information('', nil)
|
2036
|
+
expect(task.save()).to be_instance_of(Win32::TaskScheduler::COM::Task)
|
2037
|
+
|
2038
|
+
# the most appropriate additional validation here would be to confirm settings with schtasks.exe
|
2039
|
+
# but that test can live inside a system-level acceptance test
|
2040
|
+
ensure
|
2041
|
+
task.delete(name) if Win32::TaskScheduler.new.exists?(name)
|
2042
|
+
end
|
2043
|
+
end
|
2044
|
+
end
|
2045
|
+
end
|
1859
2046
|
end
|