puppet 2.6.7 → 2.6.8
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/CHANGELOG +49 -0
- data/install.rb +6 -2
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application.rb +16 -8
- data/lib/puppet/application/agent.rb +2 -0
- data/lib/puppet/application/apply.rb +3 -0
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/configurer.rb +10 -1
- data/lib/puppet/defaults.rb +9 -0
- data/lib/puppet/file_serving/fileset.rb +1 -0
- data/lib/puppet/indirector/exec.rb +1 -2
- data/lib/puppet/indirector/report/yaml.rb +11 -0
- data/lib/puppet/node/environment.rb +1 -1
- data/lib/puppet/parameter.rb +2 -0
- data/lib/puppet/parameter/path.rb +42 -0
- data/lib/puppet/parser/compiler.rb +1 -1
- data/lib/puppet/parser/lexer.rb +3 -2
- data/lib/puppet/parser/parser_support.rb +0 -1
- data/lib/puppet/provider/exec/posix.rb +112 -0
- data/lib/puppet/provider/exec/shell.rb +17 -0
- data/lib/puppet/provider/group/groupadd.rb +3 -0
- data/lib/puppet/provider/nameservice/#directoryservice.rb# +519 -0
- data/lib/puppet/provider/package/gem.rb +2 -2
- data/lib/puppet/provider/package/macports.rb +106 -0
- data/lib/puppet/provider/service/debian.rb +6 -2
- data/lib/puppet/rails/inventory_node.rb +5 -0
- data/lib/puppet/reference/#providers.rb# +123 -0
- data/lib/puppet/resource/type_collection.rb +6 -1
- data/lib/puppet/simple_graph.rb +1 -1
- data/lib/puppet/transaction.rb +1 -1
- data/lib/puppet/transaction/report.rb +28 -10
- data/lib/puppet/type/cron.rb +3 -1
- data/lib/puppet/type/exec.rb +30 -167
- data/lib/puppet/type/file.rb +12 -1
- data/lib/puppet/type/file/source.rb +1 -0
- data/lib/puppet/type/group.rb +11 -1
- data/lib/puppet/type/service.rb +19 -11
- data/lib/puppet/util/command_line.rb +15 -12
- data/lib/puppet/util/command_line/puppetrun +0 -1
- data/lib/puppet/util/loadedfile.rb +1 -5
- data/lib/puppet/util/metric.rb +3 -5
- data/lib/puppet/util/plugins.rb +82 -0
- data/spec/integration/configurer_spec.rb +38 -5
- data/spec/integration/transaction_spec.rb +43 -42
- data/spec/lib/puppet_spec/verbose.rb +9 -0
- data/spec/shared_behaviours/path_parameters.rb +185 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/unit/application/agent_spec.rb +7 -0
- data/spec/unit/application/apply_spec.rb +6 -0
- data/spec/unit/application/master_spec.rb +2 -2
- data/spec/unit/configurer_spec.rb +48 -0
- data/spec/unit/file_serving/fileset_spec.rb +8 -0
- data/spec/unit/indirector/certificate_status/#file_spec.rb# +188 -0
- data/spec/unit/indirector/exec_spec.rb +2 -3
- data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -1
- data/spec/unit/indirector/report/yaml_spec.rb +38 -0
- data/spec/unit/node/environment_spec.rb +15 -14
- data/spec/unit/parameter/path_spec.rb +24 -0
- data/spec/unit/parser/compiler_spec.rb +1 -2
- data/spec/unit/parser/lexer_spec.rb +12 -0
- data/spec/unit/provider/exec/posix_spec.rb +120 -0
- data/spec/unit/provider/exec/shell_spec.rb +50 -0
- data/spec/unit/provider/group/groupadd_spec.rb +11 -1
- data/spec/unit/provider/package/gem_spec.rb +11 -1
- data/spec/unit/provider/package/macports_spec.rb +122 -0
- data/spec/unit/provider/service/debian_spec.rb +14 -2
- data/spec/unit/resource/#type_collection_spec.rb# +463 -0
- data/spec/unit/resource/type_collection_spec.rb +21 -17
- data/spec/unit/transaction/report_spec.rb +13 -2
- data/spec/unit/type/cron_spec.rb +466 -18
- data/spec/unit/type/exec_spec.rb +633 -106
- data/spec/unit/type/file/source_spec.rb +1 -0
- data/spec/unit/type/group_spec.rb +8 -1
- data/spec/unit/type_spec.rb +1 -1
- data/spec/unit/util/loadedfile_spec.rb +7 -0
- data/spec/unit/util/rdoc/parser_spec.rb +2 -1
- data/tasks/rake/git_workflow.rake +3 -1
- data/test/ral/type/exec.rb +87 -176
- metadata +21 -5
- data/lib/puppet/provider/package/darwinport.rb +0 -86
data/spec/unit/type/exec_spec.rb
CHANGED
@@ -1,162 +1,689 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
2
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
4
3
|
|
5
4
|
describe Puppet::Type.type(:exec) do
|
6
|
-
|
7
|
-
|
8
|
-
@user_name = 'some_user_name'
|
5
|
+
def exec_tester(command, exitstatus = 0, rest = {})
|
6
|
+
@user_name = 'some_user_name'
|
9
7
|
@group_name = 'some_group_name'
|
10
8
|
Puppet.features.stubs(:root?).returns(true)
|
11
|
-
@execer = Puppet::Type.type(:exec).new(:name => command, :path => @example_path, :user => @user_name, :group => @group_name, :returns => returns)
|
12
9
|
|
13
|
-
|
14
|
-
|
10
|
+
output = rest.delete(:output) || ''
|
11
|
+
tries = rest[:tries] || 1
|
12
|
+
|
13
|
+
args = {
|
14
|
+
:name => command,
|
15
|
+
:path => @example_path,
|
16
|
+
:user => @user_name,
|
17
|
+
:group => @group_name,
|
18
|
+
:logoutput => false,
|
19
|
+
:loglevel => :err,
|
20
|
+
:returns => 0
|
21
|
+
}.merge(rest)
|
22
|
+
|
23
|
+
exec = Puppet::Type.type(:exec).new(args)
|
15
24
|
|
16
|
-
|
25
|
+
status = stub "process", :exitstatus => exitstatus
|
26
|
+
Puppet::Util::SUIDManager.expects(:run_and_capture).times(tries).
|
27
|
+
with([command], @user_name, @group_name).returns([output, status])
|
28
|
+
|
29
|
+
return exec
|
17
30
|
end
|
18
31
|
|
19
|
-
|
20
|
-
|
21
|
-
@execer[:logoutput] = logoutput
|
22
|
-
@execer[:loglevel] = loglevel
|
32
|
+
before do
|
33
|
+
@command = Puppet.features.posix? ? '/bin/true whatever' : '"C:/Program Files/something.exe" whatever'
|
23
34
|
end
|
24
35
|
|
25
|
-
|
26
|
-
|
27
|
-
@
|
36
|
+
describe "when not stubbing the provider" do
|
37
|
+
before do
|
38
|
+
@executable = Puppet.features.posix? ? '/bin/true' : 'C:/Program Files/something.exe'
|
39
|
+
File.stubs(:exists?).returns false
|
40
|
+
File.stubs(:exists?).with(@executable).returns true
|
41
|
+
File.stubs(:exists?).with('/bin/false').returns true
|
42
|
+
@example_path = Puppet.features.posix? ? %w{/usr/bin /bin} : [ "C:/Program Files/something/bin", "C:/Ruby/bin" ]
|
43
|
+
File.stubs(:exists?).with(File.join(@example_path[0],"true")).returns true
|
44
|
+
File.stubs(:exists?).with(File.join(@example_path[0],"false")).returns true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return :executed_command as its event" do
|
48
|
+
resource = Puppet::Type.type(:exec).new :command => @command
|
49
|
+
resource.parameter(:returns).event.name.should == :executed_command
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "when execing" do
|
53
|
+
it "should use the 'run_and_capture' method to exec" do
|
54
|
+
exec_tester("true").refresh.should == :executed_command
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should report a failure" do
|
58
|
+
proc { exec_tester('false', 1).refresh }.
|
59
|
+
should raise_error(Puppet::Error, /^false returned 1 instead of/)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should not report a failure if the exit status is specified in a returns array" do
|
63
|
+
proc { exec_tester("false", 1, :returns => [0, 1]).refresh }.should_not raise_error
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should report a failure if the exit status is not specified in a returns array" do
|
67
|
+
proc { exec_tester('false', 1, :returns => [0, 100]).refresh }.
|
68
|
+
should raise_error(Puppet::Error, /^false returned 1 instead of/)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should log the output on success" do
|
72
|
+
output = "output1\noutput2\n"
|
73
|
+
exec_tester('false', 0, :output => output, :logoutput => true).refresh
|
74
|
+
output.split("\n").each do |line|
|
75
|
+
log = @logs.shift
|
76
|
+
log.level.should == :err
|
77
|
+
log.message.should == line
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should log the output on failure" do
|
82
|
+
output = "output1\noutput2\n"
|
83
|
+
proc { exec_tester('false', 1, :output => output, :logoutput => true).refresh }.
|
84
|
+
should raise_error(Puppet::Error)
|
85
|
+
|
86
|
+
output.split("\n").each do |line|
|
87
|
+
log = @logs.shift
|
88
|
+
log.level.should == :err
|
89
|
+
log.message.should == line
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "when logoutput=>on_failure is set" do
|
95
|
+
it "should log the output on failure" do
|
96
|
+
output = "output1\noutput2\n"
|
97
|
+
proc { exec_tester('false', 1, :output => output, :logoutput => :on_failure).refresh }.
|
98
|
+
should raise_error(Puppet::Error, /^false returned 1 instead of/)
|
99
|
+
|
100
|
+
output.split("\n").each do |line|
|
101
|
+
log = @logs.shift
|
102
|
+
log.level.should == :err
|
103
|
+
log.message.should == line
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should log the output on failure when returns is specified as an array" do
|
108
|
+
output = "output1\noutput2\n"
|
109
|
+
|
110
|
+
proc {
|
111
|
+
exec_tester('false', 1, :output => output, :returns => [0, 100],
|
112
|
+
:logoutput => :on_failure).refresh
|
113
|
+
}.should raise_error(Puppet::Error, /^false returned 1 instead of/)
|
114
|
+
|
115
|
+
output.split("\n").each do |line|
|
116
|
+
log = @logs.shift
|
117
|
+
log.level.should == :err
|
118
|
+
log.message.should == line
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "shouldn't log the output on success" do
|
123
|
+
exec_tester('true', 0, :output => "a\nb\nc\n", :logoutput => :on_failure).refresh
|
124
|
+
@logs.should == []
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "shouldn't log the output on success when non-zero exit status is in a returns array" do
|
129
|
+
exec_tester("true", 100, :output => "a\n", :logoutput => :on_failure, :returns => [1, 100]).refresh
|
130
|
+
@logs.should == []
|
131
|
+
end
|
132
|
+
|
133
|
+
describe " when multiple tries are set," do
|
134
|
+
it "should repeat the command attempt 'tries' times on failure and produce an error" do
|
135
|
+
tries = 5
|
136
|
+
resource = exec_tester("false", 1, :tries => tries, :try_sleep => 0)
|
137
|
+
proc { resource.refresh }.should raise_error(Puppet::Error)
|
138
|
+
end
|
28
139
|
end
|
29
140
|
end
|
30
141
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
142
|
+
it "should be able to autorequire files mentioned in the command" do
|
143
|
+
catalog = Puppet::Resource::Catalog.new
|
144
|
+
tmp = Puppet::Type.type(:file).new(:name => "/bin/foo")
|
145
|
+
catalog.add_resource tmp
|
146
|
+
execer = Puppet::Type.type(:exec).new(:name => "/bin/foo")
|
147
|
+
catalog.add_resource execer
|
148
|
+
|
149
|
+
catalog.relationship_graph.dependencies(execer).should == [tmp]
|
39
150
|
end
|
40
151
|
|
41
|
-
|
42
|
-
|
43
|
-
|
152
|
+
describe "when handling the path parameter" do
|
153
|
+
expect = %w{one two three four}
|
154
|
+
{ "an array" => expect,
|
155
|
+
"a colon separated list" => "one:two:three:four",
|
156
|
+
"a semi-colon separated list" => "one;two;three;four",
|
157
|
+
"both array and colon lists" => ["one", "two:three", "four"],
|
158
|
+
"both array and semi-colon lists" => ["one", "two;three", "four"],
|
159
|
+
"colon and semi-colon lists" => ["one:two", "three;four"]
|
160
|
+
}.each do |test, input|
|
161
|
+
it "should accept #{test}" do
|
162
|
+
type = Puppet::Type.type(:exec).new(:name => @command, :path => input)
|
163
|
+
type[:path].should == expect
|
164
|
+
end
|
165
|
+
end
|
44
166
|
end
|
45
167
|
|
46
|
-
describe "when
|
168
|
+
describe "when setting user" do
|
169
|
+
it "should fail if we are not root" do
|
170
|
+
Puppet.features.stubs(:root?).returns(false)
|
171
|
+
expect { Puppet::Type.type(:exec).new(:name => @command, :user => 'input') }.
|
172
|
+
should raise_error Puppet::Error, /Parameter user failed/
|
173
|
+
end
|
47
174
|
|
48
|
-
|
49
|
-
|
50
|
-
|
175
|
+
['one', 2, 'root', 4294967295, 4294967296].each do |value|
|
176
|
+
it "should accept '#{value}' as user if we are root" do
|
177
|
+
Puppet.features.stubs(:root?).returns(true)
|
178
|
+
type = Puppet::Type.type(:exec).new(:name => @command, :user => value)
|
179
|
+
type[:user].should == value
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
51
183
|
|
52
|
-
|
184
|
+
describe "when setting group" do
|
185
|
+
shared_examples_for "exec[:group]" do
|
186
|
+
['one', 2, 'wheel', 4294967295, 4294967296].each do |value|
|
187
|
+
it "should accept '#{value}' without error or judgement" do
|
188
|
+
type = Puppet::Type.type(:exec).new(:name => @command, :group => value)
|
189
|
+
type[:group].should == value
|
190
|
+
end
|
191
|
+
end
|
53
192
|
end
|
54
193
|
|
55
|
-
|
56
|
-
|
57
|
-
|
194
|
+
describe "when running as root" do
|
195
|
+
before :each do Puppet.features.stubs(:root?).returns(true) end
|
196
|
+
it_behaves_like "exec[:group]"
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "when not running as root" do
|
200
|
+
before :each do Puppet.features.stubs(:root?).returns(false) end
|
201
|
+
it_behaves_like "exec[:group]"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "when setting cwd" do
|
206
|
+
it_should_behave_like "all path parameters", :cwd, :array => false do
|
207
|
+
def instance(path)
|
208
|
+
Puppet::Type.type(:exec).new(:name => '/bin/true', :cwd => path)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
shared_examples_for "all exec command parameters" do |param|
|
214
|
+
{ "relative" => "example", "absolute" => "/bin/example" }.sort.each do |name, command|
|
215
|
+
describe "if command is #{name}" do
|
216
|
+
before :each do
|
217
|
+
@param = param
|
218
|
+
end
|
58
219
|
|
59
|
-
|
220
|
+
def test(command, valid)
|
221
|
+
if @param == :name then
|
222
|
+
instance = Puppet::Type.type(:exec).new()
|
223
|
+
else
|
224
|
+
instance = Puppet::Type.type(:exec).new(:name => "/bin/true")
|
225
|
+
end
|
226
|
+
if valid then
|
227
|
+
instance.provider.expects(:validatecmd).returns(true)
|
228
|
+
else
|
229
|
+
instance.provider.expects(:validatecmd).raises(Puppet::Error, "from a stub")
|
230
|
+
end
|
231
|
+
instance[@param] = command
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should work if the provider calls the command valid" do
|
235
|
+
expect { test(command, true) }.should_not raise_error
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should fail if the provider calls the command invalid" do
|
239
|
+
expect { test(command, false) }.
|
240
|
+
should raise_error Puppet::Error, /Parameter #{@param} failed: from a stub/
|
241
|
+
end
|
242
|
+
end
|
60
243
|
end
|
244
|
+
end
|
245
|
+
|
246
|
+
shared_examples_for "all exec command parameters that take arrays" do |param|
|
247
|
+
describe "when given an array of inputs" do
|
248
|
+
before :each do
|
249
|
+
@test = Puppet::Type.type(:exec).new(:name => "/bin/true")
|
250
|
+
end
|
61
251
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
252
|
+
it "should accept the array when all commands return valid" do
|
253
|
+
input = %w{one two three}
|
254
|
+
@test.provider.expects(:validatecmd).times(input.length).returns(true)
|
255
|
+
@test[param] = input
|
256
|
+
@test[param].should == input
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should reject the array when any commands return invalid" do
|
260
|
+
input = %w{one two three}
|
261
|
+
@test.provider.expects(:validatecmd).with(input.first).returns(false)
|
262
|
+
input[1..-1].each do |cmd|
|
263
|
+
@test.provider.expects(:validatecmd).with(cmd).returns(true)
|
264
|
+
end
|
265
|
+
@test[param] = input
|
266
|
+
@test[param].should == input
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should reject the array when all commands return invalid" do
|
270
|
+
input = %w{one two three}
|
271
|
+
@test.provider.expects(:validatecmd).times(input.length).returns(false)
|
272
|
+
@test[param] = input
|
273
|
+
@test[param].should == input
|
274
|
+
end
|
66
275
|
end
|
276
|
+
end
|
67
277
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
278
|
+
describe "when setting refresh" do
|
279
|
+
it_should_behave_like "all exec command parameters", :refresh
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "for simple parameters" do
|
283
|
+
before :each do
|
284
|
+
@exec = Puppet::Type.type(:exec).new(:name => '/bin/true')
|
72
285
|
end
|
73
286
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
287
|
+
describe "when setting env" do
|
288
|
+
it "should issue a deprecation warning" do
|
289
|
+
expect { @exec[:env] = 'foo=bar' }.should_not raise_error
|
290
|
+
@logs.first.message.should =~ /deprecate.*environment/
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should update the value of env" do
|
294
|
+
data = ['foo=bar']
|
295
|
+
@exec[:env] = data
|
296
|
+
@exec[:env].should == data
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should forward to environment" do
|
300
|
+
data = ['foo=bar']
|
301
|
+
@exec[:env] = data
|
302
|
+
@exec[:environment].should == data
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should not override environment if both are set" do
|
306
|
+
pending "can't fix: too disruptive for 2.6, removed in 2.7"
|
307
|
+
# ...so this test is here to validate that we know about the problem.
|
308
|
+
# This ensures correct order of evaluation to trigger the bug; don't
|
309
|
+
# count on this happening in the constructor. --daniel 2011-03-01
|
310
|
+
@exec[:environment] = 'environment=true'
|
311
|
+
@exec[:env] = 'env=true'
|
312
|
+
|
313
|
+
@exec[:environment].should == "environment=true"
|
314
|
+
end
|
81
315
|
end
|
82
316
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
317
|
+
describe "when setting environment" do
|
318
|
+
{ "single values" => "foo=bar",
|
319
|
+
"multiple values" => ["foo=bar", "baz=quux"],
|
320
|
+
}.each do |name, data|
|
321
|
+
it "should accept #{name}" do
|
322
|
+
@exec[:environment] = data
|
323
|
+
@exec[:environment].should == data
|
324
|
+
end
|
325
|
+
end
|
89
326
|
|
90
|
-
|
327
|
+
{ "single values" => "foo",
|
328
|
+
"only values" => ["foo", "bar"],
|
329
|
+
"any values" => ["foo=bar", "baz"]
|
330
|
+
}.each do |name, data|
|
331
|
+
it "should reject #{name} without assignment" do
|
332
|
+
expect { @exec[:environment] = data }.
|
333
|
+
should raise_error Puppet::Error, /Invalid environment setting/
|
334
|
+
end
|
335
|
+
end
|
91
336
|
end
|
92
337
|
|
338
|
+
describe "when setting timeout" do
|
339
|
+
[0, 0.1, 1, 10, 4294967295].each do |valid|
|
340
|
+
it "should accept '#{valid}' as valid" do
|
341
|
+
@exec[:timeout] = valid
|
342
|
+
@exec[:timeout].should == valid
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should accept '#{valid}' in an array as valid" do
|
346
|
+
@exec[:timeout] = [valid]
|
347
|
+
@exec[:timeout].should == valid
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
['1/2', '', 'foo', '5foo'].each do |invalid|
|
352
|
+
it "should reject '#{invalid}' as invalid" do
|
353
|
+
expect { @exec[:timeout] = invalid }.
|
354
|
+
should raise_error Puppet::Error, /The timeout must be a number/
|
355
|
+
end
|
356
|
+
|
357
|
+
it "should reject '#{invalid}' in an array as invalid" do
|
358
|
+
expect { @exec[:timeout] = [invalid] }.
|
359
|
+
should raise_error Puppet::Error, /The timeout must be a number/
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
it "should fail if timeout is exceeded" do
|
364
|
+
File.stubs(:exists?).with('/bin/sleep').returns(true)
|
365
|
+
File.stubs(:exists?).with('sleep').returns(false)
|
366
|
+
sleep_exec = Puppet::Type.type(:exec).new(:name => 'sleep 1', :path => ['/bin'], :timeout => '0.2')
|
367
|
+
lambda { sleep_exec.refresh }.should raise_error Puppet::Error, "Command exceeded timeout"
|
368
|
+
end
|
369
|
+
|
370
|
+
it "should convert timeout to a float" do
|
371
|
+
resource = Puppet::Type.type(:exec).new :command => "/bin/false", :timeout => "12"
|
372
|
+
resource[:timeout].should be_a(Float)
|
373
|
+
resource[:timeout].should == 12.0
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should munge negative timeouts to 0.0" do
|
377
|
+
resource = Puppet::Type.type(:exec).new :command => "/bin/false", :timeout => "-12.0"
|
378
|
+
resource.parameter(:timeout).value.should be_a(Float)
|
379
|
+
resource.parameter(:timeout).value.should == 0.0
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe "when setting tries" do
|
384
|
+
[1, 10, 4294967295].each do |valid|
|
385
|
+
it "should accept '#{valid}' as valid" do
|
386
|
+
@exec[:tries] = valid
|
387
|
+
@exec[:tries].should == valid
|
388
|
+
end
|
389
|
+
|
390
|
+
if "REVISIT: too much test log spam" == "a good thing" then
|
391
|
+
it "should accept '#{valid}' in an array as valid" do
|
392
|
+
pending "inconsistent, but this is not supporting arrays, unlike timeout"
|
393
|
+
@exec[:tries] = [valid]
|
394
|
+
@exec[:tries].should == valid
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
[-3.5, -1, 0, 0.2, '1/2', '1_000_000', '+12', '', 'foo'].each do |invalid|
|
400
|
+
it "should reject '#{invalid}' as invalid" do
|
401
|
+
expect { @exec[:tries] = invalid }.
|
402
|
+
should raise_error Puppet::Error, /Tries must be an integer/
|
403
|
+
end
|
404
|
+
|
405
|
+
if "REVISIT: too much test log spam" == "a good thing" then
|
406
|
+
it "should reject '#{invalid}' in an array as invalid" do
|
407
|
+
pending "inconsistent, but this is not supporting arrays, unlike timeout"
|
408
|
+
expect { @exec[:tries] = [invalid] }.
|
409
|
+
should raise_error Puppet::Error, /Tries must be an integer/
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "when setting try_sleep" do
|
416
|
+
[0, 0.2, 1, 10, 4294967295].each do |valid|
|
417
|
+
it "should accept '#{valid}' as valid" do
|
418
|
+
@exec[:try_sleep] = valid
|
419
|
+
@exec[:try_sleep].should == valid
|
420
|
+
end
|
421
|
+
|
422
|
+
if "REVISIT: too much test log spam" == "a good thing" then
|
423
|
+
it "should accept '#{valid}' in an array as valid" do
|
424
|
+
pending "inconsistent, but this is not supporting arrays, unlike timeout"
|
425
|
+
@exec[:try_sleep] = [valid]
|
426
|
+
@exec[:try_sleep].should == valid
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
{ -3.5 => "cannot be a negative number",
|
432
|
+
-1 => "cannot be a negative number",
|
433
|
+
'1/2' => 'must be a number',
|
434
|
+
'1_000_000' => 'must be a number',
|
435
|
+
'+12' => 'must be a number',
|
436
|
+
'' => 'must be a number',
|
437
|
+
'foo' => 'must be a number',
|
438
|
+
}.each do |invalid, error|
|
439
|
+
it "should reject '#{invalid}' as invalid" do
|
440
|
+
expect { @exec[:try_sleep] = invalid }.
|
441
|
+
should raise_error Puppet::Error, /try_sleep #{error}/
|
442
|
+
end
|
443
|
+
|
444
|
+
if "REVISIT: too much test log spam" == "a good thing" then
|
445
|
+
it "should reject '#{invalid}' in an array as invalid" do
|
446
|
+
pending "inconsistent, but this is not supporting arrays, unlike timeout"
|
447
|
+
expect { @exec[:try_sleep] = [invalid] }.
|
448
|
+
should raise_error Puppet::Error, /try_sleep #{error}/
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
describe "when setting refreshonly" do
|
455
|
+
[:true, :false].each do |value|
|
456
|
+
it "should accept '#{value}'" do
|
457
|
+
@exec[:refreshonly] = value
|
458
|
+
@exec[:refreshonly].should == value
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
[1, 0, "1", "0", "yes", "y", "no", "n"].each do |value|
|
463
|
+
it "should reject '#{value}'" do
|
464
|
+
expect { @exec[:refreshonly] = value }.
|
465
|
+
should raise_error(Puppet::Error,
|
466
|
+
/Invalid value #{value.inspect}\. Valid values are true, false/
|
467
|
+
)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe "when setting creates" do
|
473
|
+
it_should_behave_like "all path parameters", :creates, :array => true do
|
474
|
+
def instance(path)
|
475
|
+
Puppet::Type.type(:exec).new(:name => '/bin/true', :creates => path)
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
93
479
|
end
|
94
480
|
|
95
|
-
describe "when
|
481
|
+
describe "when setting unless" do
|
482
|
+
it_should_behave_like "all exec command parameters", :unless
|
483
|
+
it_should_behave_like "all exec command parameters that take arrays", :unless
|
484
|
+
end
|
96
485
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
create_logging_resource(command, output, 1, :on_failure, :err)
|
102
|
-
expect_output(output, :err)
|
486
|
+
describe "when setting onlyif" do
|
487
|
+
it_should_behave_like "all exec command parameters", :onlyif
|
488
|
+
it_should_behave_like "all exec command parameters that take arrays", :onlyif
|
489
|
+
end
|
103
490
|
|
104
|
-
|
491
|
+
describe "#check" do
|
492
|
+
before :each do
|
493
|
+
@test = Puppet::Type.type(:exec).new(:name => "/bin/true")
|
105
494
|
end
|
106
495
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
496
|
+
describe ":refreshonly" do
|
497
|
+
{ :true => false, :false => true }.each do |input, result|
|
498
|
+
it "should return '#{result}' when given '#{input}'" do
|
499
|
+
@test[:refreshonly] = input
|
500
|
+
@test.check_all_attributes.should == result
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
describe ":creates" do
|
506
|
+
before :all do
|
507
|
+
@exist = "/"
|
508
|
+
@unexist = "/this/path/should/never/exist"
|
509
|
+
while FileTest.exist?(@unexist) do @unexist += "/foo" end
|
510
|
+
end
|
511
|
+
|
512
|
+
context "with a single item" do
|
513
|
+
it "should run when the item does not exist" do
|
514
|
+
@test[:creates] = @unexist
|
515
|
+
@test.check_all_attributes.should == true
|
516
|
+
end
|
517
|
+
|
518
|
+
it "should not run when the item exists" do
|
519
|
+
@test[:creates] = @exist
|
520
|
+
@test.check_all_attributes.should == false
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
context "with an array with one item" do
|
525
|
+
it "should run when the item does not exist" do
|
526
|
+
@test[:creates] = [@unexist]
|
527
|
+
@test.check_all_attributes.should == true
|
528
|
+
end
|
529
|
+
|
530
|
+
it "should not run when the item exists" do
|
531
|
+
@test[:creates] = [@exist]
|
532
|
+
@test.check_all_attributes.should == false
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context "with an array with multiple items" do
|
537
|
+
it "should run when all items do not exist" do
|
538
|
+
@test[:creates] = [@unexist] * 3
|
539
|
+
@test.check_all_attributes.should == true
|
540
|
+
end
|
541
|
+
|
542
|
+
it "should not run when one item exists" do
|
543
|
+
@test[:creates] = [@unexist, @exist, @unexist]
|
544
|
+
@test.check_all_attributes.should == false
|
545
|
+
end
|
113
546
|
|
114
|
-
|
547
|
+
it "should not run when all items exist" do
|
548
|
+
@test[:creates] = [@exist] * 3
|
549
|
+
end
|
550
|
+
end
|
115
551
|
end
|
116
552
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
553
|
+
{ :onlyif => { :pass => false, :fail => true },
|
554
|
+
:unless => { :pass => true, :fail => false },
|
555
|
+
}.each do |param, sense|
|
556
|
+
describe ":#{param}" do
|
557
|
+
before :each do
|
558
|
+
@pass = "/magic/pass"
|
559
|
+
@fail = "/magic/fail"
|
560
|
+
|
561
|
+
@pass_status = stub('status', :exitstatus => sense[:pass] ? 0 : 1)
|
562
|
+
@fail_status = stub('status', :exitstatus => sense[:fail] ? 0 : 1)
|
563
|
+
|
564
|
+
@test.provider.stubs(:checkexe).returns(true)
|
565
|
+
[true, false].each do |check|
|
566
|
+
@test.provider.stubs(:run).with(@pass, check).
|
567
|
+
returns(['test output', @pass_status])
|
568
|
+
@test.provider.stubs(:run).with(@fail, check).
|
569
|
+
returns(['test output', @fail_status])
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
context "with a single item" do
|
574
|
+
it "should run if the command exits non-zero" do
|
575
|
+
@test[param] = @fail
|
576
|
+
@test.check_all_attributes.should == true
|
577
|
+
end
|
578
|
+
|
579
|
+
it "should not run if the command exits zero" do
|
580
|
+
@test[param] = @pass
|
581
|
+
@test.check_all_attributes.should == false
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
context "with an array with a single item" do
|
586
|
+
it "should run if the command exits non-zero" do
|
587
|
+
@test[param] = [@fail]
|
588
|
+
@test.check_all_attributes.should == true
|
589
|
+
end
|
590
|
+
|
591
|
+
it "should not run if the command exits zero" do
|
592
|
+
@test[param] = [@pass]
|
593
|
+
@test.check_all_attributes.should == false
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
context "with an array with multiple items" do
|
598
|
+
it "should run if all the commands exits non-zero" do
|
599
|
+
@test[param] = [@fail] * 3
|
600
|
+
@test.check_all_attributes.should == true
|
601
|
+
end
|
602
|
+
|
603
|
+
it "should not run if one command exits zero" do
|
604
|
+
@test[param] = [@pass, @fail, @pass]
|
605
|
+
@test.check_all_attributes.should == false
|
606
|
+
end
|
607
|
+
|
608
|
+
it "should not run if all command exits zero" do
|
609
|
+
@test[param] = [@pass] * 3
|
610
|
+
@test.check_all_attributes.should == false
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
124
614
|
end
|
125
615
|
end
|
126
616
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
617
|
+
describe "#retrieve" do
|
618
|
+
before :each do
|
619
|
+
@exec_resource = Puppet::Type.type(:exec).new(:name => "/bogus/cmd")
|
620
|
+
end
|
621
|
+
|
622
|
+
it "should return :notrun when check_all_attributes returns true" do
|
623
|
+
@exec_resource.stubs(:check_all_attributes).returns true
|
624
|
+
@exec_resource.retrieve[:returns].should == :notrun
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should return default exit code 0 when check_all_attributes returns false" do
|
628
|
+
@exec_resource.stubs(:check_all_attributes).returns false
|
629
|
+
@exec_resource.retrieve[:returns].should == ['0']
|
630
|
+
end
|
631
|
+
|
632
|
+
it "should return the specified exit code when check_all_attributes returns false" do
|
633
|
+
@exec_resource.stubs(:check_all_attributes).returns false
|
634
|
+
@exec_resource[:returns] = 42
|
635
|
+
@exec_resource.retrieve[:returns].should == ["42"]
|
636
|
+
end
|
134
637
|
end
|
135
638
|
|
136
|
-
describe "
|
639
|
+
describe "#output" do
|
640
|
+
before :each do
|
641
|
+
@exec_resource = Puppet::Type.type(:exec).new(:name => "/bogus/cmd")
|
642
|
+
end
|
643
|
+
|
644
|
+
it "should return the provider's run output" do
|
645
|
+
provider = stub 'provider'
|
646
|
+
status = stubs "process_status"
|
647
|
+
status.stubs(:exitstatus).returns("0")
|
648
|
+
provider.expects(:run).returns(["silly output", status])
|
649
|
+
@exec_resource.stubs(:provider).returns(provider)
|
137
650
|
|
138
|
-
|
139
|
-
|
140
|
-
command = "false"
|
141
|
-
user = "user"
|
142
|
-
group = "group"
|
143
|
-
tries = 5
|
144
|
-
retry_exec = Puppet::Type.type(:exec).new(:name => command, :path => %w{/usr/bin /bin}, :user => user, :group => group, :returns => 0, :tries => tries, :try_sleep => 0)
|
145
|
-
status = stub "process"
|
146
|
-
status.stubs(:exitstatus).returns(1)
|
147
|
-
Puppet::Util::SUIDManager.expects(:run_and_capture).with([command], user, group).times(tries).returns(["", status])
|
148
|
-
proc { retry_exec.refresh }.should raise_error(Puppet::Error)
|
651
|
+
@exec_resource.refresh
|
652
|
+
@exec_resource.output.should == 'silly output'
|
149
653
|
end
|
150
654
|
end
|
151
655
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
656
|
+
describe "#refresh" do
|
657
|
+
before :each do
|
658
|
+
@exec_resource = Puppet::Type.type(:exec).new(:name => "/bogus/cmd")
|
659
|
+
end
|
660
|
+
|
661
|
+
it "should call provider run with the refresh parameter if it is set" do
|
662
|
+
provider = stub 'provider'
|
663
|
+
@exec_resource.stubs(:provider).returns(provider)
|
664
|
+
@exec_resource.stubs(:[]).with(:refresh).returns('/myother/bogus/cmd')
|
665
|
+
provider.expects(:run).with('/myother/bogus/cmd')
|
157
666
|
|
158
|
-
|
159
|
-
|
160
|
-
|
667
|
+
@exec_resource.refresh
|
668
|
+
end
|
669
|
+
|
670
|
+
it "should call provider run with the specified command if the refresh parameter is not set" do
|
671
|
+
provider = stub 'provider'
|
672
|
+
status = stubs "process_status"
|
673
|
+
status.stubs(:exitstatus).returns("0")
|
674
|
+
provider.expects(:run).with('/bogus/cmd').returns(["silly output", status])
|
675
|
+
@exec_resource.stubs(:provider).returns(provider)
|
676
|
+
|
677
|
+
@exec_resource.refresh
|
678
|
+
end
|
679
|
+
|
680
|
+
it "should not run the provider if check_all_attributes is false" do
|
681
|
+
@exec_resource.stubs(:check_all_attributes).returns false
|
682
|
+
provider = stub 'provider'
|
683
|
+
provider.expects(:run).never
|
684
|
+
@exec_resource.stubs(:provider).returns(provider)
|
685
|
+
|
686
|
+
@exec_resource.refresh
|
687
|
+
end
|
161
688
|
end
|
162
689
|
end
|