3
require File.dirname(__FILE__) + '/../../spec_helper'
5
require 'puppet/application/puppet'
9
@puppet = Puppet::Application[:puppet]
10
Puppet::Util::Log.stubs(:newdestination)
11
Puppet::Util::Log.stubs(:level=)
14
[:debug,:loadclasses,:verbose,:use_nodes,:detailed_exitcodes].each do |option|
15
it "should declare handle_#{option} method" do
16
@puppet.should respond_to("handle_#{option}".to_sym)
19
it "should store argument value when calling handle_#{option}" do
20
@puppet.options.expects(:[]=).with(option, 'arg')
21
@puppet.send("handle_#{option}".to_sym, 'arg')
25
it "should set the code to the provided code when :execute is used" do
26
@puppet.options.expects(:[]=).with(:code, 'arg')
27
@puppet.send("handle_execute".to_sym, 'arg')
30
it "should ask Puppet::Application to parse Puppet configuration file" do
31
@puppet.should_parse_config?.should be_true
34
describe "when applying options" do
36
it "should set the log destination with --logdest" do
37
Puppet::Log.expects(:newdestination).with("console")
39
@puppet.handle_logdest("console")
42
it "should put the logset options to true" do
43
@puppet.options.expects(:[]=).with(:logset,true)
45
@puppet.handle_logdest("console")
49
describe "during setup" do
52
Puppet::Log.stubs(:newdestination)
54
Puppet::Log.stubs(:level=)
55
Puppet.stubs(:parse_config)
56
Puppet::Network::Client.dipper.stubs(:new)
59
@puppet.options.stubs(:[]).with(any_parameters)
62
it "should set show_diff on --noop" do
64
Puppet.stubs(:[]).with(:config)
65
Puppet.stubs(:[]).with(:noop).returns(true)
67
Puppet.expects(:[]=).with(:show_diff, true)
72
it "should set console as the log destination if logdest option wasn't provided" do
73
Puppet::Log.expects(:newdestination).with(:console)
78
it "should set INT trap" do
79
@puppet.expects(:trap).with(:INT)
84
it "should set log level to debug if --debug was passed" do
85
@puppet.options.stubs(:[]).with(:debug).returns(true)
87
Puppet::Log.expects(:level=).with(:debug)
92
it "should set log level to info if --verbose was passed" do
93
@puppet.options.stubs(:[]).with(:verbose).returns(true)
95
Puppet::Log.expects(:level=).with(:info)
100
it "should print puppet config if asked to in Puppet config" do
102
Puppet.settings.stubs(:print_configs?).returns(true)
104
Puppet.settings.expects(:print_configs)
109
it "should exit after printing puppet config if asked to in Puppet config" do
110
Puppet.settings.stubs(:print_configs?).returns(true)
112
lambda { @puppet.run_setup }.should raise_error(SystemExit)
117
describe "when executing" do
119
it "should dispatch to parseonly if parseonly is set" do
120
@puppet.stubs(:options).returns({})
121
Puppet.stubs(:[]).with(:parseonly).returns(true)
123
@puppet.get_command.should == :parseonly
126
it "should dispatch to 'apply' if it was called with 'apply'" do
127
@puppet.options[:catalog] = "foo"
129
@puppet.get_command.should == :apply
132
it "should dispatch to main if parseonly is not set" do
133
@puppet.stubs(:options).returns({})
134
Puppet.stubs(:[]).with(:parseonly).returns(false)
136
@puppet.get_command.should == :main
139
describe "the parseonly command" do
141
Puppet.stubs(:[]).with(:environment)
142
Puppet.stubs(:[]).with(:manifest).returns("site.pp")
143
@interpreter = stub_everything
146
@puppet.options.stubs(:[]).with(:code).returns "some code"
147
Puppet::Parser::Interpreter.stubs(:new).returns(@interpreter)
150
it "should delegate to the Puppet Parser" do
152
@interpreter.expects(:parser)
157
it "should exit with exit code 0 if no error" do
158
@puppet.expects(:exit).with(0)
163
it "should exit with exit code 1 if error" do
164
@interpreter.stubs(:parser).raises(Puppet::ParseError)
166
@puppet.expects(:exit).with(1)
173
describe "the main command" do
176
Puppet.stubs(:[]).with(:trace).returns(true)
178
@puppet.options.stubs(:[])
180
@facts = stub_everything 'facts'
181
Puppet::Node::Facts.stubs(:find).returns(@facts)
183
@node = stub_everything 'node'
184
Puppet::Node.stubs(:find).returns(@node)
186
@catalog = stub_everything 'catalog'
187
@catalog.stubs(:to_ral).returns(@catalog)
188
Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
192
@transaction = stub_everything 'transaction'
193
@catalog.stubs(:apply).returns(@transaction)
198
it "should set the code to run from --code" do
199
@puppet.options.stubs(:[]).with(:code).returns("code to run")
200
Puppet.expects(:[]=).with(:code,"code to run")
205
it "should set the code to run from STDIN if no arguments" do
206
ARGV.stubs(:length).returns(0)
207
STDIN.stubs(:read).returns("code to run")
209
Puppet.expects(:[]=).with(:code,"code to run")
214
it "should set the manifest if some files are passed on command line" do
215
ARGV.stubs(:length).returns(1)
216
ARGV.stubs(:shift).returns("site.pp")
218
Puppet.expects(:[]=).with(:manifest,"site.pp")
223
it "should collect the node facts" do
224
Puppet::Node::Facts.expects(:find).returns(@facts)
229
it "should find the node" do
230
Puppet::Node.expects(:find).returns(@node)
235
it "should raise an error if we can't find the node" do
236
Puppet::Node.expects(:find).returns(nil)
238
lambda { @puppet.main }.should raise_error
241
it "should merge in our node the loaded facts" do
242
@facts.stubs(:values).returns("values")
244
@node.expects(:merge).with("values")
249
it "should load custom classes if loadclasses" do
250
@puppet.options.stubs(:[]).with(:loadclasses).returns(true)
251
Puppet.stubs(:[]).with(:classfile).returns("/etc/puppet/classes.txt")
252
FileTest.stubs(:exists?).with("/etc/puppet/classes.txt").returns(true)
253
FileTest.stubs(:readable?).with("/etc/puppet/classes.txt").returns(true)
254
File.stubs(:read).with("/etc/puppet/classes.txt").returns("class")
256
@node.expects(:classes=)
261
it "should compile the catalog" do
262
Puppet::Resource::Catalog.expects(:find).returns(@catalog)
267
it "should transform the catalog to ral" do
269
@catalog.expects(:to_ral).returns(@catalog)
274
it "should finalize the catalog" do
275
@catalog.expects(:finalize)
280
it "should apply the catalog" do
281
@catalog.expects(:apply)
286
it "should generate a report if not noop" do
287
Puppet.stubs(:[]).with(:noop).returns(false)
288
@puppet.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
289
metrics = stub 'metrics', :[] => { :total => 10, :failed => 0}
290
report = stub 'report', :metrics => metrics
291
@transaction.stubs(:report).returns(report)
293
@transaction.expects(:generate_report)
298
describe "with detailed_exitcodes" do
300
Puppet.stubs(:[]).with(:noop).returns(false)
301
@puppet.options.stubs(:[]).with(:detailed_exitcodes).returns(true)
304
it "should exit with exit code of 2 if changes" do
305
report = stub 'report', :metrics => { "changes" => {:total => 1}, "resources" => {:failed => 0} }
306
@transaction.stubs(:generate_report).returns(report)
307
@transaction.stubs(:report).returns(report)
308
@puppet.expects(:exit).with(2)
313
it "should exit with exit code of 4 if failures" do
314
report = stub 'report', :metrics => { "changes" => {:total => 0}, "resources" => {:failed => 1} }
315
@transaction.stubs(:generate_report).returns(report)
316
@transaction.stubs(:report).returns(report)
317
@puppet.expects(:exit).with(4)
322
it "should exit with exit code of 6 if changes and failures" do
323
report = stub 'report', :metrics => { "changes" => {:total => 1}, "resources" => {:failed => 1} }
324
@transaction.stubs(:generate_report).returns(report)
325
@transaction.stubs(:report).returns(report)
326
@puppet.expects(:exit).with(6)
334
describe "the 'apply' command" do
335
confine "PSON library is missing; cannot test applying catalogs" => Puppet.features.pson?
338
#Puppet::Resource::Catalog.stubs(:pson_create).returns Puppet::Resource::Catalog.new
339
PSON.stubs(:parse).returns Puppet::Resource::Catalog.new
342
it "should read the catalog in from disk if a file name is provided" do
343
@puppet.options[:catalog] = "/my/catalog.pson"
345
File.expects(:read).with("/my/catalog.pson").returns "something"
350
it "should read the catalog in from stdin if '-' is provided" do
351
@puppet.options[:catalog] = "-"
353
$stdin.expects(:read).returns "something"
358
it "should deserialize the catalog from pson" do
359
@puppet.options[:catalog] = "/my/catalog.pson"
361
File.expects(:read).returns "something"
362
PSON.expects(:parse).with("something").returns Puppet::Resource::Catalog.new
367
it "should fail helpfully if deserializing fails" do
368
@puppet.options[:catalog] = "/my/catalog.pson"
370
File.expects(:read).returns "something"
371
PSON.expects(:parse).raises ArgumentError
373
lambda { @puppet.apply }.should raise_error(Puppet::Error)
376
it "should convert plain data structures into a catalog if deserialization does not do so" do
377
@puppet.options[:catalog] = "/my/catalog.pson"
379
File.expects(:read).returns "something"
380
PSON.expects(:parse).with("something").returns({:foo => "bar"})
381
Puppet::Resource::Catalog.expects(:pson_create).with({:foo => "bar"}).returns(Puppet::Resource::Catalog.new)
386
it "should convert the catalog to a RAL catalog and use a Configurer instance to apply it" do
387
@puppet.options[:catalog] = "/my/catalog.pson"
389
File.expects(:read).returns "something"
391
catalog = Puppet::Resource::Catalog.new
392
PSON.expects(:parse).returns catalog
394
catalog.expects(:to_ral).returns "mycatalog"
396
configurer = stub 'configurer'
397
Puppet::Configurer.expects(:new).returns configurer
399
configurer.expects(:run).with(:catalog => "mycatalog")