diff options
| author | Luke Kanies <luke@madstop.com> | 2009-02-13 18:24:34 -0600 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2009-02-13 18:24:34 -0600 |
| commit | 3fbec120768d84d208b14f574dfe916e25cfdbef (patch) | |
| tree | 865d59f4ea9cf3782db46ce1ae7fd54b95945035 /spec/unit | |
| parent | a2270b4a4f093c6c4f171dcf0c0e05fe101dd979 (diff) | |
| parent | 2561c8e252dcf66890513458750bb1329a03beec (diff) | |
| download | puppet-3fbec120768d84d208b14f574dfe916e25cfdbef.tar.gz puppet-3fbec120768d84d208b14f574dfe916e25cfdbef.tar.xz puppet-3fbec120768d84d208b14f574dfe916e25cfdbef.zip | |
Merge branch '0.24.x'
Conflicts:
lib/puppet/indirector/facts/facter.rb
lib/puppet/provider/augeas/augeas.rb
lib/puppet/util/filetype.rb
spec/unit/indirector/facts/facter.rb
spec/unit/provider/augeas/augeas.rb
test/util/filetype.rb
Diffstat (limited to 'spec/unit')
| -rwxr-xr-x | spec/unit/indirector/facts/facter.rb | 38 | ||||
| -rwxr-xr-x | spec/unit/network/xmlrpc/client.rb | 172 | ||||
| -rw-r--r-- | spec/unit/parser/functions/regsubst.rb | 88 | ||||
| -rw-r--r-- | spec/unit/parser/functions/sprintf.rb | 42 | ||||
| -rw-r--r-- | spec/unit/provider/augeas/augeas.rb | 30 | ||||
| -rwxr-xr-x | spec/unit/provider/parsedfile.rb | 36 | ||||
| -rwxr-xr-x | spec/unit/util/autoload.rb | 39 | ||||
| -rw-r--r-- | spec/unit/util/filetype.rb | 110 |
8 files changed, 529 insertions, 26 deletions
diff --git a/spec/unit/indirector/facts/facter.rb b/spec/unit/indirector/facts/facter.rb index c0b9dce36..ea68f63d6 100755 --- a/spec/unit/indirector/facts/facter.rb +++ b/spec/unit/indirector/facts/facter.rb @@ -93,15 +93,6 @@ describe Puppet::Node::Facts::Facter do end end - it "should load each directory in the Fact path when loading fact plugins" do - Puppet.settings.expects(:value).with(:factpath).returns("one%stwo" % File::PATH_SEPARATOR) - - Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("one") - Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("two") - - Puppet::Node::Facts::Facter.load_fact_plugins - end - it "should skip files when asked to load a directory" do FileTest.expects(:directory?).with("myfile").returns false @@ -119,4 +110,33 @@ describe Puppet::Node::Facts::Facter do Puppet::Node::Facts::Facter.load_facts_in_dir("mydir") end + + describe Puppet::Node::Facts::Facter, "when loading fact plugins from disk" do + it "should load each directory in the Fact path" do + Puppet.settings.stubs(:value).returns "foo" + Puppet.settings.expects(:value).with(:factpath).returns("one%stwo" % File::PATH_SEPARATOR) + + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("one") + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("two") + + Puppet::Node::Facts::Facter.load_fact_plugins + end + + it "should load all facts from the modules" do + Puppet.settings.stubs(:value).returns "foo" + Puppet::Node::Facts::Facter.stubs(:load_facts_in_dir) + + Puppet.settings.expects(:value).with(:modulepath).returns("one%stwo" % File::PATH_SEPARATOR) + + Dir.expects(:glob).with("one/*/plugins/facter").returns %w{oneA oneB} + Dir.expects(:glob).with("two/*/plugins/facter").returns %w{twoA twoB} + + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneA") + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("oneB") + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoA") + Puppet::Node::Facts::Facter.expects(:load_facts_in_dir).with("twoB") + + Puppet::Node::Facts::Facter.load_fact_plugins + end + end end diff --git a/spec/unit/network/xmlrpc/client.rb b/spec/unit/network/xmlrpc/client.rb index a0a2e77fb..36e59429c 100755 --- a/spec/unit/network/xmlrpc/client.rb +++ b/spec/unit/network/xmlrpc/client.rb @@ -2,12 +2,170 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } -describe Puppet::Network do - it "should raise an XMLRPCClientError if a generated class raises a Timeout::Error" do - http = mock 'http' - Puppet::Network::HttpPool.stubs(:http_instance).returns http - file = Puppet::Network::Client.file.new({:Server => "foo.com"}) - http.stubs(:post2).raises Timeout::Error - lambda { file.retrieve }.should raise_error(Puppet::Network::XMLRPCClientError) +describe Puppet::Network::XMLRPCClient do + describe "when performing the rpc call" do + before do + @client = Puppet::Network::Client.report.xmlrpc_client.new + @client.stubs(:call).returns "foo" + + end + + it "should call the specified namespace and method, with the specified arguments" do + @client.expects(:call).with("puppetreports.report", "eh").returns "foo" + @client.report("eh") + end + + it "should return the results from the call" do + @client.expects(:call).returns "foo" + @client.report("eh").should == "foo" + end + + it "should always close the http connection if it is still open after the call" do + http = mock 'http' + @client.stubs(:http).returns http + + http.expects(:started?).returns true + http.expects(:finish) + + @client.report("eh").should == "foo" + end + + it "should always close the http connection if it is still open after a call that raises an exception" do + http = mock 'http' + @client.stubs(:http).returns http + + @client.expects(:call).raises RuntimeError + + http.expects(:started?).returns true + http.expects(:finish) + + lambda { @client.report("eh") }.should raise_error + end + + describe "when returning the http instance" do + it "should use the http pool to create the instance" do + @client.instance_variable_set("@http", nil) + @client.expects(:host).returns "myhost" + @client.expects(:port).returns "myport" + Puppet::Network::HttpPool.expects(:http_instance).with("myhost", "myport", true).returns "http" + + @client.http.should == "http" + end + + it "should reuse existing instances" do + @client.http.should equal(@client.http) + end + end + + describe "when recycling the connection" do + it "should close the existing instance if it's open" do + http = mock 'http' + @client.stubs(:http).returns http + + http.expects(:started?).returns true + http.expects(:finish) + + @client.recycle_connection + end + + it "should force creation of a new instance" do + Puppet::Network::HttpPool.expects(:http_instance).returns "second_http" + + @client.recycle_connection + + @client.http.should == "second_http" + end + end + + describe "and an exception is raised" do + it "should raise XMLRPCClientError if XMLRPC::FaultException is raised" do + error = XMLRPC::FaultException.new("foo", "bar") + + @client.expects(:call).raises(error) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should raise XMLRPCClientError if Errno::ECONNREFUSED is raised" do + @client.expects(:call).raises(Errno::ECONNREFUSED) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should log and raise XMLRPCClientError if Timeout::Error is raised" do + Puppet.expects(:err) + @client.expects(:call).raises(Timeout::Error) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should log and raise XMLRPCClientError if SocketError is raised" do + Puppet.expects(:err) + @client.expects(:call).raises(SocketError) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should log, recycle the connection, and retry if Errno::EPIPE is raised" do + @client.expects(:call).times(2).raises(Errno::EPIPE).then.returns "eh" + + Puppet.expects(:warning) + @client.expects(:recycle_connection) + + @client.report("eh") + end + + it "should log, recycle the connection, and retry if EOFError is raised" do + @client.expects(:call).times(2).raises(EOFError).then.returns "eh" + + Puppet.expects(:warning) + @client.expects(:recycle_connection) + + @client.report("eh") + end + + it "should log and retry if an exception containing 'Wrong size' is raised" do + error = RuntimeError.new("Wrong size. Was 15, should be 30") + @client.expects(:call).times(2).raises(error).then.returns "eh" + + Puppet.expects(:warning) + + @client.report("eh") + end + + it "should raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised" do + @client.expects(:call).raises(OpenSSL::SSL::SSLError) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should log and raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised with certificate issues" do + error = OpenSSL::SSL::SSLError.new("hostname was not match") + @client.expects(:call).raises(error) + + Puppet.expects(:warning) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + + it "should log, recycle the connection, and retry if OpenSSL::SSL::SSLError is raised containing 'bad write retry'" do + error = OpenSSL::SSL::SSLError.new("bad write retry") + @client.expects(:call).times(2).raises(error).then.returns "eh" + + @client.expects(:recycle_connection) + + Puppet.expects(:warning) + + @client.report("eh") + end + + it "should log and raise XMLRPCClientError if any other exception is raised" do + @client.expects(:call).raises(RuntimeError) + + Puppet.expects(:err) + + lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError) + end + end end end diff --git a/spec/unit/parser/functions/regsubst.rb b/spec/unit/parser/functions/regsubst.rb new file mode 100644 index 000000000..18f49f7d4 --- /dev/null +++ b/spec/unit/parser/functions/regsubst.rb @@ -0,0 +1,88 @@ +#! /usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the regsubst function" do + + before :each do + @scope = Puppet::Parser::Scope.new() + end + + it "should exist" do + Puppet::Parser::Functions.function("regsubst").should == "function_regsubst" + end + + it "should raise a ParseError if there is less than 3 arguments" do + lambda { @scope.function_regsubst(["foo", "bar"]) }.should( + raise_error(Puppet::ParseError)) + end + + it "should raise a ParseError if there is more than 5 arguments" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "del", "x", "y"]) }.should( + raise_error(Puppet::ParseError)) + end + + + it "should raise a ParseError when given a bad flag" do + lambda { @scope.function_regsubst(["foo", "bar", "gazonk", "X"]) }.should( + raise_error(Puppet::ParseError)) + end + + it "should handle groups" do + result = @scope.function_regsubst( + [ '130.236.254.10', + '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$', + '\4-\3-\2-\1' + ]) + result.should(eql("10-254-236-130")) + end + + it "should handle simple regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks banana trees", + "b[an]*a", + "coconut" + ]) + result.should(eql("the monkey breaks coconut trees")) + end + + it "should handle case-sensitive regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks baNAna trees", + "b[an]+a", + "coconut" + ]) + result.should(eql("the monkey breaks baNAna trees")) + end + + it "should handle case-insensitive regexps" do + result = @scope.function_regsubst( + [ "the monkey breaks baNAna trees", + "b[an]+a", + "coconut", + "I" + ]) + result.should(eql("the monkey breaks coconut trees")) + end + + it "should handle global substitutions" do + result = @scope.function_regsubst( + [ "the monkey breaks\tbanana trees", + "[ \t]", + "--", + "G" + ]) + result.should(eql("the--monkey--breaks--banana--trees")) + end + + it "should handle global substitutions with groups" do + result = @scope.function_regsubst( + [ '130.236.254.10', + '([0-9]+)', + '<\1>', + 'G' + ]) + result.should(eql('<130>.<236>.<254>.<10>')) + end + +end diff --git a/spec/unit/parser/functions/sprintf.rb b/spec/unit/parser/functions/sprintf.rb new file mode 100644 index 000000000..8654b18fc --- /dev/null +++ b/spec/unit/parser/functions/sprintf.rb @@ -0,0 +1,42 @@ +#! /usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe "the sprintf function" do + + before :each do + @scope = Puppet::Parser::Scope.new() + end + + it "should exist" do + Puppet::Parser::Functions.function("sprintf").should == "function_sprintf" + end + + it "should raise a ParseError if there is less than 1 argument" do + lambda { @scope.function_sprintf([]) }.should( + raise_error(Puppet::ParseError)) + end + + it "should format integers" do + result = @scope.function_sprintf(["%+05d", "23"]) + result.should(eql("+0023")) + end + + it "should format floats" do + result = @scope.function_sprintf(["%+.2f", "2.7182818284590451"]) + result.should(eql("+2.72")) + end + + it "should format large floats" do + result = @scope.function_sprintf(["%+.2e", "27182818284590451"]) + result.should(eql("+2.72e+16")) + end + + it "should perform more complex formatting" do + result = @scope.function_sprintf( + [ "<%.8s:%#5o %#8X (%-8s)>", + "overlongstring", "23", "48879", "foo" ]) + result.should(eql("<overlong: 027 0XBEEF (foo )>")) + end + +end diff --git a/spec/unit/provider/augeas/augeas.rb b/spec/unit/provider/augeas/augeas.rb index 083448b4a..affc66676 100644 --- a/spec/unit/provider/augeas/augeas.rb +++ b/spec/unit/provider/augeas/augeas.rb @@ -285,32 +285,42 @@ describe provider_class do @augeas.expects(:clear).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end + end + - it "should handle insert commands" do - command = [["insert", "/Jar/Jar"]] + it "should handle ins commands with before" do + command = [["ins", "Binks", "before /Jar/Jar"]] context = "/foo" @resource.expects(:[]).times(2).returns(command).then.returns(context) - @augeas.expects(:insert).with("/foo/Jar/Jar") + @augeas.expects(:insert).with("/foo/Jar/Jar", "Binks", true) @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed end - it "should handle ins commands" do - command = [["ins", "/Jar/Jar"]] + it "should handle ins commands with before" do + command = [["ins", "Binks", "after /Jar/Jar"]] context = "/foo" @resource.expects(:[]).times(2).returns(command).then.returns(context) - @augeas.expects(:insert).with("/foo/Jar/Jar") + @augeas.expects(:insert).with("/foo/Jar/Jar", "Binks", false) @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed end + it "should handle ins with no context" do + command = [["ins", "Binks", "after /Jar/Jar"]] + context = "" # this is the default + @resource.expects(:[]).times(2).returns(command).then.returns(context) + @augeas.expects(:insert).with("/Jar/Jar", "Binks", false) + @augeas.expects(:save).returns(true) + @provider.execute_changes.should == :executed + end + it "should handle multiple commands" do - command = [["ins", "/Jar/Jar"], ["clear", "/Jar/Jar"]] + command = [["ins", "Binks", "after /Jar/Jar"], ["clear", "/Jar/Jar"]] context = "/foo" @resource.expects(:[]).times(2).returns(command).then.returns(context) - @augeas.expects(:insert).with("/foo/Jar/Jar") - @augeas.expects(:clear).with("/foo/Jar/Jar") + @augeas.expects(:insert).with("/foo/Jar/Jar", "Binks", false) + @augeas.expects(:clear).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed end diff --git a/spec/unit/provider/parsedfile.rb b/spec/unit/provider/parsedfile.rb index 05e9de3ab..11a91c8d7 100755 --- a/spec/unit/provider/parsedfile.rb +++ b/spec/unit/provider/parsedfile.rb @@ -47,4 +47,40 @@ describe Puppet::Provider::ParsedFile do @class.instances end end + + describe "when flushing a file's records to disk" do + before do + # This way we start with some @records, like we would in real life. + @class.stubs(:retrieve).returns [] + @class.default_target = "/foo/bar" + @class.initvars + @class.prefetch + + @filetype = mock 'filetype' + Puppet::Util::FileType.filetype(:flat).expects(:new).with("/my/file").returns @filetype + + @filetype.stubs(:write) + end + + it "should back up the file being written" do + @filetype.expects(:backup) + + @class.flush_target("/my/file") + end + + it "should not back up the file more than once between calls to 'prefetch'" do + @filetype.expects(:backup).once + + @class.flush_target("/my/file") + @class.flush_target("/my/file") + end + + it "should back the file up again once the file has been reread" do + @filetype.expects(:backup).times(2) + + @class.flush_target("/my/file") + @class.prefetch + @class.flush_target("/my/file") + end + end end diff --git a/spec/unit/util/autoload.rb b/spec/unit/util/autoload.rb new file mode 100755 index 000000000..ff717d6c5 --- /dev/null +++ b/spec/unit/util/autoload.rb @@ -0,0 +1,39 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +require 'puppet/util/autoload' + +describe Puppet::Util::Autoload do + before do + @autoload = Puppet::Util::Autoload.new("foo", "tmp") + + @autoload.stubs(:eachdir).yields "/my/dir" + end + + describe "when loading a file" do + [RuntimeError, LoadError, SyntaxError].each do |error| + it "should not die an if a #{error.to_s} exception is thrown" do + FileTest.stubs(:exists?).returns true + + Kernel.expects(:load).raises error + + lambda { @autoload.load("foo") }.should_not raise_error + end + end + end + + describe "when loading all files" do + before do + Dir.stubs(:glob).returns "file.rb" + end + + [RuntimeError, LoadError, SyntaxError].each do |error| + it "should not die an if a #{error.to_s} exception is thrown" do + Kernel.expects(:require).raises error + + lambda { @autoload.loadall }.should_not raise_error + end + end + end +end diff --git a/spec/unit/util/filetype.rb b/spec/unit/util/filetype.rb new file mode 100644 index 000000000..0506b6b47 --- /dev/null +++ b/spec/unit/util/filetype.rb @@ -0,0 +1,110 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +require 'puppet/util/filetype' + +# XXX Import all of the tests into this file. +describe Puppet::Util::FileType do + describe "when backing up a file" do + before do + @file = Puppet::Util::FileType.filetype(:flat).new("/my/file") + end + + it "should do nothing if the file does not exist" do + File.expects(:exists?).with("/my/file").returns false + @file.expects(:bucket).never + @file.backup + end + + it "should use its filebucket to backup the file if it exists" do + File.expects(:exists?).with("/my/file").returns true + + bucket = mock 'bucket' + bucket.expects(:backup).with("/my/file") + + @file.expects(:bucket).returns bucket + @file.backup + end + + it "should use the filebucket named 'puppet' if it finds one" do + bucket = mock 'bucket' + bucket.expects(:bucket).returns "mybucket" + + Puppet::Type.type(:filebucket).expects(:[]).with("puppet").returns bucket + + @file.bucket.should == "mybucket" + end + + it "should use the default filebucket if none named 'puppet' is found" do + bucket = mock 'bucket' + bucket.expects(:bucket).returns "mybucket" + + Puppet::Type.type(:filebucket).expects(:[]).with("puppet").returns nil + Puppet::Type.type(:filebucket).expects(:mkdefaultbucket).returns bucket + + @file.bucket.should == "mybucket" + end + end + + describe "the flat filetype" do + before do + @type = Puppet::Util::FileType.filetype(:flat) + end + it "should exist" do + @type.should_not be_nil + end + + describe "when the file already exists" do + it "should return the file's contents when asked to read it" do + file = @type.new("/my/file") + File.expects(:exist?).with("/my/file").returns true + File.expects(:read).with("/my/file").returns "my text" + + file.read.should == "my text" + end + + it "should unlink the file when asked to remove it" do + file = @type.new("/my/file") + File.expects(:exist?).with("/my/file").returns true + File.expects(:unlink).with("/my/file") + + file.remove + end + end + + describe "when the file does not exist" do + it "should return an empty string when asked to read the file" do + file = @type.new("/my/file") + File.expects(:exist?).with("/my/file").returns false + + file.read.should == "" + end + end + + describe "when writing the file" do + before do + @file = @type.new("/my/file") + FileUtils.stubs(:cp) + + @tempfile = stub 'tempfile', :print => nil, :close => nil, :flush => nil, :path => "/other/file" + Tempfile.stubs(:new).returns @tempfile + end + + it "should first create a temp file and copy its contents over to the file location" do + Tempfile.expects(:new).with("puppet").returns @tempfile + @tempfile.expects(:print).with("my text") + @tempfile.expects(:flush) + @tempfile.expects(:close) + FileUtils.expects(:cp).with(@tempfile.path, "/my/file") + + @file.write "my text" + end + + it "should set the selinux default context on the file" do + @file.expects(:set_selinux_default_context).with("/my/file") + @file.write "eh" + end + end + end +end |
