diff --git a/test/Rakefile b/test/Rakefile index e1fc374b0..463c7a9a1 100644 --- a/test/Rakefile +++ b/test/Rakefile @@ -1,71 +1,68 @@ require 'rake/testtask' require 'find' include Find include FileTest $exclusions = %W(lib data) $test_dirs = [] # this is used to generate all the targets. $test_files = [] # this is ONLY used for the top-level test suite. -# this basically amounts to: -# find $(pwd) -type d -maxdepth 1 | xargs basename -# with an exclusion list. +# Collect all of our test directories, skipping specifically excluded dirs. +$test_dirs = Dir.glob("*").find_all { |f| directory?(f) }.reject { |d| + $exclusions.include?(File.basename(d)) +} -find(Dir.pwd) do |path| - if File.basename(path) =~ /^\.+/ - prune - elsif path != Dir.pwd and directory? path and !$exclusions.include? File.basename(path) - $test_dirs.push File.basename(path) - prune - end -end - -# another find for the test files themselves: this could probably be rolled into the original find loop. +# another find for the test files themselves: this could probably be rolled +# into the original find loop. $test_dirs.each do |dir| find(dir) do |path| if File.basename(path) =~ /^\.+/ prune - elsif path != dir and !directory? path + elsif path != dir and ! directory?(path) $test_files.push path end end end desc "Run the full test suite" Rake::TestTask.new 'test' do |t| t.libs << 'lib' - t.test_files = $test_files.dup + t.test_files = $test_files.sort t.verbose = true end #task :test => $test_dirs -$test_dirs.each do |path| +task :default => :test + +$test_dirs.sort.each do |path| files = [] find(path) do |file| if directory? file and path != file prune elsif file =~ /.rb$/ files.push file end end Rake::TestTask.new path.to_sym do |t| t.libs << 'lib' - t.test_files = files + t.test_files = files.sort t.verbose = true end # task path.to_sym => files.collect { |x| path + ':' + File.basename(x, '.rb') } namespace path.to_sym do files.each do |file| Rake::TestTask.new File.basename(file, '.rb').to_sym do |t| t.libs << '..' t.test_files = [ file ] t.verbose = true end end end end + +# $Id$ diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb index 2275e9953..cc95822ee 100755 --- a/test/certmgr/certmgr.rb +++ b/test/certmgr/certmgr.rb @@ -1,362 +1,355 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/sslcertificates.rb' -require 'test/unit' require 'puppettest' # so, what kind of things do we want to test? # we don't need to test function, since we're confident in the # library tests. We do, however, need to test how things are actually # working in the language. # so really, we want to do things like test that our ast is correct # and test whether we've got things in the right scopes class TestCertMgr < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super #@dir = File.join(Puppet[:certdir], "testing") @dir = File.join(@configpath, "certest") system("mkdir -p %s" % @dir) end def mkPassFile() keyfile = File.join(@dir, "tmpkeyfile") @@tmpfiles << keyfile unless FileTest.exists?(@dir) system("mkdir -p %s" % @dir) end File.open(keyfile, "w", 0600) { |f| f.print "as;dklj23rlkjzdflij23wr" } return keyfile end def mkCA ca = nil assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new() } return ca end def testCreateSelfSignedCertificate cert = nil name = "testing" newcert = proc { Puppet::SSLCertificates::Certificate.new( :name => name, :selfsign => true ) } assert_nothing_raised { cert = newcert.call() } assert_nothing_raised { cert.mkselfsigned } assert_raise(Puppet::Error) { cert.mkselfsigned } assert_nothing_raised { cert.write } assert(FileTest.exists?(cert.certfile)) assert_nothing_raised { cert.delete } assert_nothing_raised { cert = newcert.call() } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.delete } end def disabled_testCreateEncryptedSelfSignedCertificate cert = nil name = "testing" keyfile = mkPassFile assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => name, :selfsign => true, :capass => keyfile ) } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.mkhash } assert_raise(Puppet::Error) { cert.mkselfsigned } assert(FileTest.exists?(cert.certfile)) assert(FileTest.exists?(cert.hash)) assert_nothing_raised { cert.delete } assert_nothing_raised { cert.mkselfsigned } assert_nothing_raised { cert.delete } end def testCreateCA ca = nil assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new() } # make the CA again and verify it doesn't fail because everything # still exists assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new() } end def testSignCert ca = mkCA() cert = nil assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "signedcertest", :state => "TN", :city => "Nashville", :country => "US", :email => "luke@madstop.com", :org => "Reductive", :ou => "Development", :encrypt => mkPassFile() ) } assert_nothing_raised { cert.mkcsr } signedcert = nil cacert = nil assert_nothing_raised { signedcert, cacert = ca.sign(cert.csr) } assert_instance_of(OpenSSL::X509::Certificate, signedcert) assert_instance_of(OpenSSL::X509::Certificate, cacert) assert_nothing_raised { cert.cert = signedcert cert.cacert = cacert cert.write } #system("find %s" % Puppet[:ssldir]) #system("cp -R %s /tmp/ssltesting" % Puppet[:ssldir]) output = nil assert_nothing_raised { output = %x{openssl verify -CAfile #{Puppet[:cacert]} -purpose sslserver #{cert.certfile}} #output = %x{openssl verify -CApath #{Puppet[:certdir]} -purpose sslserver #{cert.certfile}} } assert_equal($?,0) assert_equal(File.join(Puppet[:certdir], "signedcertest.pem: OK\n"), output) end def mkcert(hostname) cert = nil assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new(:name => hostname) cert.mkcsr } return cert end def test_interactiveca ca = nil assert_nothing_raised { ca = Puppet::SSLCertificates::CA.new } # basic initialization hostname = "test.hostname.com" cert = mkcert(hostname) # create the csr csr = nil assert_nothing_raised { csr = cert.mkcsr } assert_nothing_raised { ca.storeclientcsr(csr) } # store it pulledcsr = nil assert_nothing_raised { pulledcsr = ca.getclientcsr(hostname) } assert_equal(csr.to_pem, pulledcsr.to_pem) signedcert = nil assert_nothing_raised { signedcert, cacert = ca.sign(csr) } assert_instance_of(OpenSSL::X509::Certificate, signedcert) newsignedcert = nil assert_nothing_raised { newsignedcert, cacert = ca.getclientcert(hostname) } assert(newsignedcert) assert_equal(signedcert.to_pem, newsignedcert.to_pem) end def test_cafailures ca = mkCA() cert = cacert = nil assert_nothing_raised { cert, cacert = ca.getclientcert("nohost") } assert_nil(cert) end def test_crl ca = mkCA() h1 = mkSignedCert(ca, "host1.example.com") h2 = mkSignedCert(ca, "host2.example.com") assert(ca.cert.verify(ca.cert.public_key)) assert(h1.verify(ca.cert.public_key)) assert(h2.verify(ca.cert.public_key)) crl = ca.crl assert_not_nil(crl) store = mkStore(ca) assert( store.verify(ca.cert)) assert( store.verify(h1, [ca.cert])) assert( store.verify(h2, [ca.cert])) ca.revoke(h1.serial) # Recreate the CA from disk ca = mkCA() store = mkStore(ca) assert( store.verify(ca.cert)) assert(!store.verify(h1, [ca.cert])) assert( store.verify(h2, [ca.cert])) ca.revoke(h2.serial) assert_equal(1, ca.crl.extensions.size) File::open("/tmp/crl.pem", "w") { |f| f.write(ca.crl.to_pem) } # Recreate the CA from disk ca = mkCA() store = mkStore(ca) assert( store.verify(ca.cert)) assert(!store.verify(h1, [ca.cert])) assert(!store.verify(h2, [ca.cert])) end def mkSignedCert(ca, host) cert = mkcert(host) assert_nothing_raised { signedcert, cacert = ca.sign(cert.mkcsr) return signedcert } end def mkStore(ca) store = OpenSSL::X509::Store.new store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK store.add_cert(ca.cert) store.add_crl(ca.crl) store end def test_ttl cert = mksignedcert assert_equal(5 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = 7 * 24 * 60 * 60 cert = mksignedcert assert_equal(7 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "2y" cert = mksignedcert assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "2y" cert = mksignedcert assert_equal(2 * 365 * 24 * 60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "1h" cert = mksignedcert assert_equal(60 * 60, cert.not_after - cert.not_before) Puppet[:ca_ttl] = "900s" cert = mksignedcert assert_equal(900, cert.not_after - cert.not_before) # This needs to be last, to make sure that setting ca_days # overrides setting ca_ttl Puppet[:ca_days] = 3 cert = mksignedcert assert_equal(3 * 24 * 60 * 60, cert.not_after - cert.not_before) end def mksignedcert ca = mkCA() hostname = "ttltest.example.com" cert = nil assert_nothing_raised { cert, cacert = ca.sign(mkcert(hostname).mkcsr) } return cert end end diff --git a/test/client/client.rb b/test/client/client.rb index fa382392e..7d02f7acf 100644 --- a/test/client/client.rb +++ b/test/client/client.rb @@ -1,197 +1,190 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/client' require 'puppet/server' -require 'test/unit' -require 'puppettest.rb' - -# $Id$ +require 'puppettest' class TestClient < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest # a single run through of connect, auth, etc. def test_sslInitWithAutosigningLocalServer # autosign everything, for simplicity Puppet[:autosign] = true # create a server to which to connect mkserver() # create our client client = nil assert_nothing_raised { client = Puppet::Client::MasterClient.new( :Server => "localhost", :Port => @@port ) } # get our certs assert_nothing_raised { client.initcerts } # make sure all of our cert files exist certfile = File.join(Puppet[:certdir], [client.fqdn, "pem"].join(".")) keyfile = File.join(Puppet[:privatekeydir], [client.fqdn, "pem"].join(".")) publickeyfile = File.join(Puppet[:publickeydir], [client.fqdn, "pem"].join(".")) assert(File.exists?(keyfile)) assert(File.exists?(certfile)) assert(File.exists?(publickeyfile)) # verify we can retrieve the configuration assert_nothing_raised("Client could not retrieve configuration") { client.getconfig } # and apply it assert_nothing_raised("Client could not apply configuration") { client.apply } # and verify that it did what it was supposed to assert(FileTest.exists?(@createdfile), "Applied file does not exist") end # here we create two servers; we def test_failureWithUntrustedCerts Puppet[:autosign] = true # create a pair of clients with no certs nonemaster = nil assert_nothing_raised { nonemaster = Puppet::Client::MasterClient.new( :Server => "localhost", :Port => @@port ) } nonebucket = nil assert_nothing_raised { nonebucket = Puppet::Client::Dipper.new( :Server => "localhost", :Port => @@port ) } # create a ca so we can create a set of certs # make a new ssldir for it ca = nil assert_nothing_raised { ca = Puppet::Client::CA.new( :CA => true, :Local => true ) ca.requestcert } # initialize our clients with this set of certs certmaster = nil assert_nothing_raised { certmaster = Puppet::Client::MasterClient.new( :Server => "localhost", :Port => @@port ) } certbucket = nil assert_nothing_raised { certbucket = Puppet::Client::Dipper.new( :Server => "localhost", :Port => @@port ) } # Create a new ssl root. confdir = tempfile() Puppet[:ssldir] = confdir Puppet.config.mkdir(:ssldir) Puppet.config.clearused Puppet.config.use(:certificates, :ca) mkserver # now verify that our client cannot do non-cert operations # because its certs are signed by a different CA assert_raise(Puppet::Error, "Client was allowed to call getconfig with no certs") { nonemaster.getconfig } assert_raise(Puppet::Error, "Client was allowed to call getconfig with untrusted certs") { certmaster.getconfig } assert_raise(Puppet::NetworkClientError, "Client was allowed to call backup with no certs") { nonebucket.backup("/etc/passwd") } assert_raise(Puppet::NetworkClientError, "Client was allowed to call backup with untrusted certs") { certbucket.backup("/etc/passwd") } end def test_classfile manifest = tempfile() File.open(manifest, "w") do |file| file.puts "class yaytest {}\n class bootest {}\n include yaytest, bootest" end master = client = nil assert_nothing_raised() { master = Puppet::Server::Master.new( :Manifest => manifest, :UseNodes => false, :Local => false ) } assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } # Fake that it's local, so it creates the class file client.local = false assert_nothing_raised { client.getconfig } assert(FileTest.exists?(Puppet[:classfile]), "Class file does not exist") classes = File.read(Puppet[:classfile]).split("\n") assert_equal(%w{bootest yaytest}, classes.sort) end def test_setpidfile $clientrun = false newclass = Class.new(Puppet::Client) do def run $clientrun = true end def initialize end end inst = newclass.new assert_nothing_raised { inst.start } assert(FileTest.exists?(inst.pidfile), "PID file was not created") end end + +# $Id$ diff --git a/test/client/master.rb b/test/client/master.rb index 2f88123b5..2b6688979 100644 --- a/test/client/master.rb +++ b/test/client/master.rb @@ -1,271 +1,264 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/client' require 'puppet/server' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestMasterClient < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def mkmaster(file = nil) master = nil file ||= mktestmanifest() # create our master assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => false, :Local => true ) } return master end def mkclient(master = nil) master ||= mkmaster() client = nil assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } return client end def test_disable manifest = mktestmanifest master = mkmaster(manifest) client = mkclient(master) assert(! FileTest.exists?(@createdfile)) assert_nothing_raised { client.disable } assert_nothing_raised { client.run } assert(! FileTest.exists?(@createdfile), "Disabled client ran") assert_nothing_raised { client.enable } assert_nothing_raised { client.run } assert(FileTest.exists?(@createdfile), "Enabled client did not run") end # Make sure we're getting the client version in our list of facts def test_clientversionfact facts = nil assert_nothing_raised { facts = Puppet::Client::MasterClient.facts } assert_equal(Puppet.version.to_s, facts["clientversion"]) end # Make sure the client correctly locks itself def test_locking manifest = mktestmanifest master = nil # First test with a networked master client = Puppet::Client::MasterClient.new( :Server => "localhost" ) assert_nothing_raised do client.lock do pid = nil assert(client.locked?, "Client is not locked") assert(client.lockpid.is_a?(Integer), "PID #{client.lockpid} is, um, not a pid") end end assert(! client.locked?) # Now test with a local client client = mkclient assert_nothing_raised do client.lock do pid = nil assert(! client.locked?, "Local client is locked") end end assert(! client.locked?) end # Make sure non-string facts don't make things go kablooie def test_nonstring_facts # Add a nonstring fact Facter.add("nonstring") do setcode { 1 } end assert_equal(1, Facter.nonstring, "Fact was a string from facter") client = mkclient() assert(! FileTest.exists?(@createdfile)) assert_nothing_raised { client.run } end def test_getplugins Puppet[:pluginsource] = tempfile() Dir.mkdir(Puppet[:pluginsource]) myplugin = File.join(Puppet[:pluginsource], "myplugin.rb") File.open(myplugin, "w") do |f| f.puts %{Puppet::Type.newtype(:myplugin) do newparam(:argument) do isnamevar end end } end assert_nothing_raised { Puppet::Client::MasterClient.getplugins } destfile = File.join(Puppet[:plugindest], "myplugin.rb") assert(File.exists?(destfile), "Did not get plugin") obj = Puppet::Type.type(:myplugin) assert(obj, "Did not define type") assert(obj.validattr?(:argument), "Did not get namevar") # Now modify the file and make sure the type is replaced File.open(myplugin, "w") do |f| f.puts %{Puppet::Type.newtype(:myplugin) do newparam(:yayness) do isnamevar end newparam(:rahness) do end end } end assert_nothing_raised { Puppet::Client::MasterClient.getplugins } destfile = File.join(Puppet[:pluginpath], "myplugin.rb") obj = Puppet::Type.type(:myplugin) assert(obj, "Did not define type") assert(obj.validattr?(:yayness), "Did not get namevar") assert(obj.validattr?(:rahness), "Did not get other var") assert(! obj.validattr?(:argument), "Old namevar is still valid") end def test_getfacts Puppet[:factsource] = tempfile() Dir.mkdir(Puppet[:factsource]) myfact = File.join(Puppet[:factsource], "myfact.rb") File.open(myfact, "w") do |f| f.puts %{Facter.add("myfact") do setcode { "yayness" } end } end assert_nothing_raised { Puppet::Client::MasterClient.getfacts } destfile = File.join(Puppet[:factdest], "myfact.rb") assert(File.exists?(destfile), "Did not get fact") assert_equal("yayness", Facter["myfact"].value, "Did not get correct fact value") # Now modify the file and make sure the type is replaced File.open(myfact, "w") do |f| f.puts %{Facter.add("myfact") do setcode { "funtest" } end } end assert_nothing_raised { Puppet::Client::MasterClient.getfacts } assert_equal("funtest", Facter["myfact"].value, "Did not reload fact") end # Make sure we load all facts on startup. def test_loadfacts dirs = [tempfile(), tempfile()] count = 0 names = [] dirs.each do |dir| Dir.mkdir(dir) name = "fact%s" % count names << name file = File.join(dir, "%s.rb" % name) # Write out a plugin file File.open(file, "w") do |f| f.puts %{Facter.add("#{name}") do setcode { "#{name}" } end } end count += 1 end Puppet[:factpath] = dirs.join(":") names.each do |name| assert_nil(Facter.value(name), "Somehow retrieved invalid fact") end assert_nothing_raised { Puppet::Client::MasterClient.loadfacts } names.each do |name| assert_equal(name, Facter.value(name), "Did not retrieve facts") end end end # $Id$ diff --git a/test/client/pelement.rb b/test/client/pelement.rb index 4d782cf03..d5f8e824a 100644 --- a/test/client/pelement.rb +++ b/test/client/pelement.rb @@ -1,99 +1,92 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/client/pelement' require 'puppet/server' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' # $Id$ class TestPElementClient < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def mkpelementserver handlers = { :CA => {}, # so that certs autogenerate :PElement => {}, } return mkserver(handlers) end def mkclient client = nil assert_nothing_raised { client = Puppet::Client::PElement.new(:Server => "localhost", :Port => @@port) } return client end def test_pelements file = tempfile() text = "yayness\n" File.open(file, "w") { |f| f.print text } mkpelementserver() client = mkclient() # Test describing tobj = nil assert_nothing_raised { tobj = client.describe("file", file) } assert(tobj, "Did not get response") assert_instance_of(Puppet::TransObject, tobj) obj = nil assert_nothing_raised { obj = tobj.to_type } assert_events([], obj) File.unlink(file) assert_events([:file_created], obj) File.unlink(file) # Now test applying result = nil assert_nothing_raised { result = client.apply(tobj) } assert(FileTest.exists?(file), "File was not created on apply") # Lastly, test "list" list = nil assert_nothing_raised { list = client.list("user") } assert_instance_of(Puppet::TransBucket, list) count = 0 list.each do |tobj| break if count > 3 assert_instance_of(Puppet::TransObject, tobj) tobj2 = nil assert_nothing_raised { tobj2 = client.describe(tobj.type, tobj.name) } obj = nil assert_nothing_raised { obj = tobj2.to_type } assert_events([], obj) count += 1 end end end diff --git a/test/executables/puppetbin.rb b/test/executables/puppetbin.rb index bde9eaa8b..d7e05a810 100755 --- a/test/executables/puppetbin.rb +++ b/test/executables/puppetbin.rb @@ -1,72 +1,65 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' require 'puppet/sslcertificates' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestPuppetBin < Test::Unit::TestCase - include ExeTest + include PuppetTest::ExeTest def test_version output = nil assert_nothing_raised { output = %x{puppet --version}.chomp } assert_equal(Puppet.version, output) end def test_execution file = mktestmanifest() output = nil cmd = "puppet" if Puppet[:debug] cmd += " --debug" end cmd += " --confdir %s" % Puppet[:confdir] cmd += " --vardir %s" % Puppet[:vardir] unless Puppet[:debug] cmd += " --logdest %s" % "/dev/null" end assert_nothing_raised { output = %x{#{cmd + " " + file} 2>&1} } assert($? == 0, "Puppet exited with code %s" % $?.to_i) assert(FileTest.exists?(@createdfile), "Failed to create config'ed file") end def test_inlineexecution path = tempfile() code = "file { '#{path}': ensure => file }" output = nil cmd = "puppet" if Puppet[:debug] cmd += " --debug" end #cmd += " --fqdn %s" % fqdn cmd += " --confdir %s" % Puppet[:confdir] cmd += " --vardir %s" % Puppet[:vardir] unless Puppet[:debug] cmd += " --logdest %s" % "/dev/null" end cmd += " -e \"#{code}\"" assert_nothing_raised { out = %x{#{cmd} 2>&1} } assert($? == 0, "Puppet exited with code %s" % $?.to_i) assert(FileTest.exists?(path), "Failed to create config'ed file") end end # $Id$ diff --git a/test/executables/puppetca.rb b/test/executables/puppetca.rb index d21e94e7a..a6ea9aae4 100755 --- a/test/executables/puppetca.rb +++ b/test/executables/puppetca.rb @@ -1,114 +1,107 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' require 'puppet/sslcertificates' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestPuppetCA < Test::Unit::TestCase - include ExeTest + include PuppetTest::ExeTest def mkcert(hostname) cert = nil assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => hostname ) cert.mkcsr } return cert end def runca(args) debug = "" if Puppet[:debug] debug = "-d " end return %x{puppetca --user=#{Puppet[:user]} #{debug} --group=#{Puppet[:group]} --confdir=#{Puppet[:confdir]} --vardir=#{Puppet[:vardir]} #{args} 2>&1} end def test_signing ca = nil Puppet[:autosign] = false assert_nothing_raised { ca = Puppet::Server::CA.new() } #Puppet.warning "SSLDir is %s" % Puppet[:confdir] #system("find %s" % Puppet[:confdir]) cert = mkcert("host.test.com") resp = nil assert_nothing_raised { # We need to use a fake name so it doesn't think the cert is from # itself. resp = ca.getcert(cert.csr.to_pem, "fakename", "127.0.0.1") } assert_equal(["",""], resp) #Puppet.warning "SSLDir is %s" % Puppet[:confdir] #system("find %s" % Puppet[:confdir]) output = nil assert_nothing_raised { output = runca("--list").chomp.split("\n").reject { |line| line =~ /warning:/ } # stupid ssl.rb } #Puppet.warning "SSLDir is %s" % Puppet[:confdir] #system("find %s" % Puppet[:confdir]) assert_equal($?,0) assert_equal(%w{host.test.com}, output) assert_nothing_raised { output = runca("--sign -a").chomp.split("\n") } assert_equal($?,0) assert_equal(["Signed host.test.com"], output) signedfile = File.join(Puppet[:signeddir], "host.test.com.pem") assert(FileTest.exists?(signedfile), "cert does not exist") assert(! FileTest.executable?(signedfile), "cert is executable") uid = Puppet::Util.uid(Puppet[:user]) if Process.uid == 0 assert(! FileTest.owned?(signedfile), "cert is owned by root") end assert_nothing_raised { output = runca("--list").chomp.split("\n") } assert_equal($?,0) assert_equal(["No certificates to sign"], output) end # This method takes a long time to run because of all of the external # executable calls. def test_revocation ca = Puppet::SSLCertificates::CA.new() host1 = gen_cert(ca, "host1.example.com") host2 = gen_cert(ca, "host2.example.com") host3 = gen_cert(ca, "host3.example.com") runca("-r host1.example.com") runca("-r #{host2.serial}") runca("-r 0x#{host3.serial.to_s(16)}") runca("-r 0xff") # Recreate CA to force reading of CRL ca = Puppet::SSLCertificates::CA.new() crl = ca.crl revoked = crl.revoked.collect { |r| r.serial } exp = [host1.serial, host2.serial, host3.serial, 255] assert_equal(exp, revoked) end def gen_cert(ca, host) runca("-g #{host}") ca.getclientcert(host)[0] end end # $Id$ diff --git a/test/executables/puppetd.rb b/test/executables/puppetd.rb index 700ea5bd3..a1a886a0e 100755 --- a/test/executables/puppetd.rb +++ b/test/executables/puppetd.rb @@ -1,62 +1,55 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' require 'socket' require 'facter' class TestPuppetDExe < Test::Unit::TestCase - include ExeTest + include PuppetTest::ExeTest def test_normalstart # start the master file = startmasterd # create the client client = Puppet::Client::MasterClient.new(:Server => "localhost", :Port => @@port) # make a new fqdn fqdn = client.fqdn.sub(/^\w+\./, "testing.") cmd = "puppetd" cmd += " --verbose" cmd += " --onetime" #cmd += " --fqdn %s" % fqdn cmd += " --masterport %s" % @@port cmd += " --confdir %s" % Puppet[:confdir] cmd += " --vardir %s" % Puppet[:vardir] cmd += " --server localhost" # and verify our daemon runs assert_nothing_raised { %x{#{cmd} 2>&1} } sleep 1 assert($? == 0, "Puppetd exited with code %s" % $?) assert(FileTest.exists?(@createdfile), "Failed to create config'ed file") # now verify that --noop works File.unlink(@createdfile) cmd += " --noop" assert_nothing_raised { output = %x{#{cmd}}.chomp } sleep 1 assert($? == 0, "Puppetd exited with code %s" % $?) assert(! FileTest.exists?(@createdfile), "Noop created config'ed file") stopmasterd end end # $Id$ diff --git a/test/executables/puppetmasterd.rb b/test/executables/puppetmasterd.rb index 92a8c6b84..8d6d30875 100755 --- a/test/executables/puppetmasterd.rb +++ b/test/executables/puppetmasterd.rb @@ -1,148 +1,141 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' require 'puppet/daemon' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' require 'socket' require 'facter' class TestPuppetMasterD < Test::Unit::TestCase - include ExeTest + include PuppetTest::ExeTest def getcerts include Puppet::Daemon if self.readcerts return [@cert, @key, @cacert, @cacertfile] else raise "Couldn't read certs" end end # start the daemon and verify it responds and such def test_normalstart startmasterd pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid") assert(FileTest.exists?(pidfile), "PID file does not exist") sleep(1) assert_nothing_raised { socket = TCPSocket.new("127.0.0.1", @@port) socket.close } client = nil assert_nothing_raised() { client = Puppet::Client::StatusClient.new( :Server => "localhost", :Port => @@port ) } # set our client up to auto-sign assert(Puppet[:autosign] =~ /^#{File::SEPARATOR}/, "Autosign is set to %s, not a file" % Puppet[:autosign]) FileUtils.mkdir_p(File.dirname(Puppet[:autosign])) File.open(Puppet[:autosign], "w") { |f| f.puts client.fqdn } retval = nil # init the client certs assert_nothing_raised() { client.initcerts } # call status assert_nothing_raised() { retval = client.status } assert_equal(1, retval, "Status.status return value was %s" % retval) # this client shoulduse the same certs assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Server => "localhost", :Port => @@port ) } assert_nothing_raised() { retval = client.getconfig } objects = nil end # verify that we can run puppetmasterd in parse-only mode def test_parseonly startmasterd("--parseonly > /dev/null") sleep(1) pid = nil ps = Facter["ps"].value || "ps -ef" %x{#{ps}}.chomp.split(/\n/).each { |line| next if line =~ /^puppet/ # skip normal master procs if line =~ /puppetmasterd.+--manifest/ ary = line.split(" ") pid = ary[1].to_i end } assert($? == 0, "Puppetmasterd ended with non-zero exit status") assert_nil(pid, "Puppetmasterd is still running after parseonly") end def disabled_test_sslconnection - #file = File.join($puppetbase, "examples", "code", "head") + #file = File.join(exampledir, "code", "head") #startmasterd("--manifest #{file}") #assert_nothing_raised { # socket = TCPSocket.new("127.0.0.1", Puppet[:masterport]) # socket.close #} client = nil cert, key, cacert, cacertfile = getcerts() assert_nothing_raised() { client = Net::HTTP.new("localhost", Puppet[:masterport]) client.cert = cert client.key = key client.ca_file = cacertfile client.use_ssl = true client.start_immediately = true } retval = nil assert_nothing_raised() { retval = client.nothing } assert_equal(1, retval, "return value was %s" % retval) facts = {} Facter.each { |p,v| facts[p] = v } textfacts = CGI.escape(YAML.dump(facts)) assert_nothing_raised() { #Puppet.notice "calling status" #retval = client.call("status.status", "") retval = client.call("puppetmaster.getconfig", textfacts, "yaml") } objects = nil assert_nothing_raised { YAML.load(CGI.unescape(retval)) } #stopmasterd end end # $Id$ diff --git a/test/executables/puppetmodule.rb b/test/executables/puppetmodule.rb index cff43a0e5..0752fed14 100755 --- a/test/executables/puppetmodule.rb +++ b/test/executables/puppetmodule.rb @@ -1,55 +1,52 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' require 'puppet/sslcertificates' -require 'test/unit' -require 'puppettest.rb' - -$module = File.join($puppetbase, "ext", "module_puppet") +require 'puppettest' class TestPuppetModule < Test::Unit::TestCase - include ExeTest + include PuppetTest::ExeTest + + + def setup + super + @module = File.join(basedir, "ext", "module_puppet") + end def test_existence - assert(FileTest.exists?($module), "Module does not exist") + assert(FileTest.exists?(@module), "Module does not exist") end def test_execution file = tempfile() createdfile = tempfile() File.open(file, "w") { |f| f.puts "class yaytest { file { \"#{createdfile}\": ensure => file } }" } output = nil - cmd = $module + cmd = @module cmd += " --verbose" #cmd += " --fqdn %s" % fqdn cmd += " --confdir %s" % Puppet[:confdir] cmd += " --vardir %s" % Puppet[:vardir] if Puppet[:debug] cmd += " --logdest %s" % "console" cmd += " --debug" else cmd += " --logdest %s" % "/dev/null" end ENV["CFALLCLASSES"] = "yaytest:all" assert_nothing_raised { %x{#{cmd + " " + file} 2>&1} } assert($? == 0, "Puppet module exited with code %s" % $?.to_i) assert(FileTest.exists?(createdfile), "Failed to create config'ed file") end end # $Id$ diff --git a/test/language/ast.rb b/test/language/ast.rb index 5bf0c1e4f..ab528a49d 100755 --- a/test/language/ast.rb +++ b/test/language/ast.rb @@ -1,945 +1,938 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' -require 'test/unit' require 'puppettest' class TestAST < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting # A fake class that we can use for testing evaluation. class FakeAST attr_writer :evaluate def evaluate(*args) return @evaluate end def initialize(val = nil) if val @evaluate = val end end def safeevaluate(*args) evaluate() end end # Test that classes behave like singletons def test_classsingleton parent = child1 = child2 = nil children = [] # create the parent class children << classobj("parent") # Create child class one children << classobj("child1", :parentclass => nameobj("parent")) # Create child class two children << classobj("child2", :parentclass => nameobj("parent")) classes = %w{parent child1 child2} # Now call the two classes assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("child1"), :name => nameobj("yayness"), :params => astarray() ) children << AST::ObjectDef.new( :type => nameobj("child2"), :name => nameobj("booness"), :params => astarray() ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil objects = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } assert_instance_of(Puppet::TransBucket, objects) assert_equal(1, scope.find_all { |child| if child.is_a? Puppet::Parser::Scope child.lookupobject(:name => "/parent", :type => "file") else nil end }.length, "Found incorrect number of '/parent' objects") assert_equal(classes.sort, scope.classlist.sort) end # Test that 'tagobject' collects all of an object's parameters and stores # them in one TransObject, rather than many. This is probably a bad idea. def test_tagobject top = nil children = [ fileobj("/etc", "owner" => "root"), fileobj("/etc", "group" => "root") ] assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = Puppet::Parser::Scope.new() assert_nothing_raised("Could not evaluate") { top.evaluate(:scope => scope) } obj = nil assert_nothing_raised("Could not retrieve file object") { obj = scope.lookupobject(:name => "/etc", :type => "file") } assert(obj, "could not retrieve file object") %w{owner group}.each { |param| assert(obj.include?(param), "Object did not include %s" % param) } end # Verify that objects can only have parents of the same type. def test_validparent parent = child1 = nil children = [] # create the parent class children << compobj("parent", :args => AST::ASTArray.new(:children => [])) # Create child class one children << classobj("child1", :parentclass => nameobj("parent")) # Now call the two classes assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("child1"), :name => nameobj("yayness"), :params => astarray() ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil assert_raise(Puppet::ParseError, "Invalid parent type was allowed") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } end # Verify that nodes don't evaluate code in other node scopes but that their # facts work outside their scopes. def test_nodescopes parent = child1 = nil topchildren = [] # create the parent class topchildren << classobj("everyone") topchildren << classobj("parent") classes = %w{everyone parent} # And a variable, so we verify the facts get set at the top assert_nothing_raised { children = [] children << varobj("yaytest", "$hostname") } nodes = [] 3.times do |i| children = [] # Create a child class topchildren << classobj("perchild#{i}", :parentclass => nameobj("parent")) classes << "perchild%s" # Create a child class children << classobj("child", :parentclass => nameobj("parent")) classes << "child" ["child", "everyone", "perchild#{i}"].each do |name| # Now call our child class assert_nothing_raised { children << AST::ObjectDef.new( :type => nameobj(name), :params => astarray() ) } end # and another variable assert_nothing_raised { children << varobj("rahtest", "$hostname") } # create the node nodename = "node#{i}" nodes << nodename assert_nothing_raised("Could not create parent object") { topchildren << AST::NodeDef.new( :names => nameobj(nodename), :code => AST::ASTArray.new( :children => children ) ) } end # Create the wrapper object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => topchildren ) } nodes.each_with_index do |node, i| # Evaluate the parse tree scope = Puppet::Parser::Scope.new() args = {:names => [node], :facts => {"hostname" => node}, :ast => top} # verify that we can evaluate it okay trans = nil assert_nothing_raised("Could not retrieve node definition") { trans = scope.evaluate(args) } assert_equal(node, scope.lookupvar("hostname")) assert(trans, "Could not retrieve trans objects") # and that we can convert them to type objects objects = nil assert_nothing_raised("Could not retrieve node definition") { objects = trans.to_type } assert(objects, "Could not retrieve trans objects") count = 0 # Make sure the node name gets into the path correctly. Puppet.type(:file).each { |obj| count += 1 assert(obj.path !~ /#{node}\[#{node}\]/, "Node name appears twice") } assert(count > 0, "Did not create any files") classes.each do |name| if name =~ /%s/ name = name % i end assert(Puppet::Type.type(:file)["/#{name}"], "Could not find '#{name}'") end Puppet::Type.allclear end end # Verify that classes are correctly defined in node scopes. def disabled_test_nodeclasslookup parent = child1 = nil children = [] # create the parent class children << classobj("parent") # Create child class one children << classobj("child1", :parentclass => nameobj("parent")) # Now call the two classes assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("child1"), :name => nameobj("yayness"), :params => astarray() ) } # create the node nodename = "mynodename" node = nil assert_nothing_raised("Could not create parent object") { node = AST::NodeDef.new( :names => nameobj(nodename), :code => AST::ASTArray.new( :children => children ) ) } # Create the wrapper object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => [node] ) } # Evaluate the parse tree scope = nil assert_nothing_raised("Could not evaluate node") { scope = Puppet::Parser::Scope.new() top.evaluate(:scope => scope) } # Verify that, well, nothing really happened, and especially verify # that the top scope is not a node scope assert(scope.topscope?, "Scope is not top scope") assert(! scope.nodescope?, "Scope is mistakenly node scope") assert(! scope.lookupclass("parent"), "Found parent class in top scope") # verify we can find our node assert(scope.node(nodename), "Could not find node") # And verify that we can evaluate it okay objects = nil assert_nothing_raised("Could not retrieve node definition") { objects = scope.evalnode(:name => [nodename], :facts => {}) } assert(objects, "Could not retrieve node definition") # Because node scopes are temporary (i.e., they get destroyed after the node's # config is returned) we should not be able to find the node scope. nodescope = nil assert_nothing_raised { nodescope = scope.find { |child| child.nodescope? } } assert_nil(nodescope, "Found nodescope") # And now verify again that the top scope cannot find the node's definition # of the parent class assert(! scope.lookupclass("parent"), "Found parent class in top scope") trans = nil # Verify that we can evaluate the node twice assert_nothing_raised("Could not retrieve node definition") { trans = scope.evalnode(:name => [nodename], :facts => {}) } objects = nil assert_nothing_raised("Could not convert to objects") { objects = trans.to_type } Puppet.type(:file).each { |obj| assert(obj.path !~ /#{nodename}\[#{nodename}\]/, "Node name appears twice") } assert(Puppet::Type.type(:file)["/child1"], "Could not find child") assert(Puppet::Type.type(:file)["/parent"], "Could not find parent") end # Test that you can look a host up using multiple names, e.g., an FQDN and # a short name def test_multiplenodenames children = [] # create a short-name node shortname = "mynodename" children << nodedef(shortname) # And a long-name node longname = "node.domain.com" children << nodedef(longname) # Create the wrapper object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } # Evaluate the parse tree scope = Puppet::Parser::Scope.new() # Verify we can find the node via a search list objects = nil assert_nothing_raised("Could not retrieve short node definition") { objects = scope.evaluate( :names => ["%s.domain.com" % shortname, shortname], :facts => {}, :ast => top ) } assert(objects, "Could not retrieve short node definition") scope = Puppet::Parser::Scope.new() # and then look for the long name assert_nothing_raised("Could not retrieve long node definition") { objects = scope.evaluate( :names => [longname.sub(/\..+/, ''), longname], :facts => {}, :ast => top ) } assert(objects, "Could not retrieve long node definition") end # Test that a node gets the entire configuration except for work meant for # another node def test_fullconfigwithnodes children = [] children << fileobj("/testing") # create a short-name node name = "mynodename" children << nodedef(name) # Create the wrapper object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = Puppet::Parser::Scope.new() # Verify we can find the node via a search list objects = nil assert_nothing_raised("Could not retrieve short node definition") { objects = scope.evaluate(:names => [name], :facts => {}, :ast => top) } assert(objects, "Could not retrieve short node definition") assert_instance_of(Puppet::TransBucket, objects) # And now verify that we got both the top and node objects assert_nothing_raised("Could not find top-declared object") { assert_equal("/testing", objects[0].name) } assert_nothing_raised("Could not find node-declared object %s" % "/%s" % name ) { assert_equal("/%s" % name, objects[1][0].name) } end # Test that we can 'include' variables, not just normal strings. def test_includevars children = [] classes = [] # Create our class for testin klassname = "include" children << classobj(klassname) classes << klassname # Then add our variable assignment children << varobj("klassvar", klassname) # And finally add our calling of the variable children << AST::ObjectDef.new( :type => AST::Variable.new(:value => "klassvar"), :params => astarray ) # And then create our top object top = AST::ASTArray.new( :children => children ) # Evaluate the parse tree scope = nil objects = nil assert_nothing_raised("Could not evaluate node") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } # Verify we get the right classlist back assert_equal(classes.sort, scope.classlist.sort) # Verify we can find the node via a search list #assert_nothing_raised("Could not retrieve objects") { # objects = scope.to_trans #} assert(objects, "Could not retrieve objects") assert_nothing_raised("Could not find top-declared object") { assert_equal("/%s" % klassname, objects[0][0].name) } end # Test that node inheritance works correctly def test_nodeinheritance children = [] # create the base node name = "basenode" children << nodedef(name) # and the sub node name = "subnode" children << AST::NodeDef.new( :names => nameobj(name), :parentclass => nameobj("basenode"), :code => AST::ASTArray.new( :children => [ varobj("%svar" % name, "%svalue" % name), fileobj("/%s" % name) ] ) ) #subnode = nodedef(name) #subnode.parentclass = "basenode" #children << subnode # and the top object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } # Evaluate the parse tree scope = Puppet::Parser::Scope.new() # Verify we can find the node via a search list objects = nil assert_nothing_raised("Could not evaluate node") { objects = scope.evaluate(:names => [name], :facts => {}, :ast => top) } assert(objects, "Could not retrieve node definition") assert_nothing_raised { inner = objects[0] # And now verify that we got the subnode file assert_nothing_raised("Could not find basenode file") { base = inner[0] assert_equal("/basenode", base.name) } # and the parent node file assert_nothing_raised("Could not find subnode file") { sub = inner[1] assert_equal("/subnode", sub.name) } inner.each { |obj| %w{basenode subnode}.each { |tag| assert(obj.tags.include?(tag), "%s did not include %s tag" % [obj.name, tag] ) } } } end def test_typechecking object = nil children = [] type = "deftype" assert_nothing_raised("Could not add AST nodes for calling") { object = AST::ObjectDef.new( :type => nameobj(type), :name => nameobj("yayness"), :params => astarray() ) } assert_nothing_raised("Typecheck failed") { object.typecheck(type) } # Add a scope, which makes it think it's evaluating assert_nothing_raised { scope = Puppet::Parser::Scope.new() object.scope = scope } # Verify an error is thrown when it can't find the type assert_raise(Puppet::ParseError) { object.typecheck(type) } # Create child class one children << classobj(type) children << object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = top.evaluate(:scope => scope) } end def disabled_test_paramcheck object = nil children = [] type = "deftype" params = %w{param1 param2} comp = compobj(type, { :args => astarray( argobj("param1", "yay"), argobj("param2", "rah") ), :code => AST::ASTArray.new( :children => [ varobj("%svar" % name, "%svalue" % name), fileobj("/%s" % name) ] ) }) assert_nothing_raised("Could not add AST nodes for calling") { object = AST::ObjectDef.new( :type => nameobj(type), :name => nameobj("yayness"), :params => astarray( astarray(stringobj("param1"), stringobj("value1")), astarray(stringobj("param2"), stringobj("value2")) ) ) } # Add a scope, which makes it think it's evaluating assert_nothing_raised { scope = Puppet::Parser::Scope.new() object.scope = scope } # Verify an error is thrown when it can't find the type assert_raise(Puppet::ParseError) { object.paramcheck(false, comp) } # Create child class one children << classobj(type) children << object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = top.evaluate(:scope => scope) } end def test_setclass type = "yay" classes = [type] children = [] # Create child class one children << varobj("variable", "aclass") children << tagobj(type, varref("variable")) children << tagobj(type) classes << "aclass" top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = top.evaluate(:scope => scope) } classes.each do |tag| assert(scope.classlist.include?(tag), "Did not set class %s" % tag) end end # Test that we strip the domain off of host names before they are set as classes def test_nodenamestrip children = [] longname = "node.domain.com" children << nodedef(longname) # Create the wrapper object top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = Puppet::Parser::Scope.new() assert_nothing_raised("Could not evaluate node") { objects = scope.evaluate(:names => [longname], :facts => {}, :ast => top) } assert(!scope.classlist.include?("node.domain.com"), "Node's long name got set") assert(scope.classlist.include?("node"), "Node's name did not get set") end # Make sure that deep class parentage works def test_classparentage children = [] files = [] base = classobj("base") files << "/base" children << base parent = "base" 5.times { |i| name = "child%s" % i files << "/%s" % name children << classobj(name, :parentclass => nameobj(parent)) parent = name } children << functionobj("include", parent) top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } objects = objects.flatten files.each do |file| assert(objects.find { |o| o.name == file }, "Could not find file %s" % file) end end # Make sure we catch names that are specified like parameters. def test_name_or_param obj = nil assert_nothing_raised { obj = AST::ObjectDef.new( :type => nameobj("file"), :params => astarray(AST::ObjectParam.new( :param => stringobj("name"), :value => stringobj("yayness") )) ) } scope = Puppet::Parser::Scope.new trans = nil assert_nothing_raised { trans = scope.evaluate(:ast => obj, :facts => {}) } transobj = trans.shift assert(transobj.name, "Name did not convert from param to name") end if defined? ActiveRecord # Verify that our collection stuff works. def test_collection collectable = [] non = [] # First put some objects into the database. bucket = mk_transtree do |object, depth, width| # and mark some of them collectable if width % 2 == 1 object.collectable = true collectable << object else non << object end end # Now collect our facts facts = {} Facter.each do |fact, value| facts[fact] = value end assert_nothing_raised { Puppet::Rails.init } # Now try storing our crap assert_nothing_raised { host = Puppet::Rails::Host.store( :objects => bucket, :facts => facts, :host => facts["hostname"] ) } # Now create an ast tree that collects that. They should all be files. coll = nil assert_nothing_raised { coll = AST::Collection.new( :type => nameobj("file") ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => [coll] ) } objects = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top).flatten } assert(objects.length > 0, "Did not receive any collected objects") end else $stderr.puts "No ActiveRecord -- skipping collection tests" end # To fix #140. Currently non-functional. def disabled_test_classreuse children = [] # Create the parent class, with a definition in it. children << classobj("parent", :code => AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => [ compobj("foo", :args => AST::ASTArray.new( :children => [nameobj("arg")] ), :code => AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => [fileobj("/$arg")] ) ), objectdef("foo", "ptest", {"arg" => "parentfoo"}) ] )) # Create child class, also trying to use that definition children << classobj("child1", :parentclass => nameobj("parent"), :code => AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => [ objectdef("foo", "ctest", {"arg" => "childfoo"}) ] ) ) # Call the parent first children << functionobj("include", "parent") # Then call the child, and make sure it can look up the definition children << functionobj("include", "child1") top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } end def test_if astif = nil astelse = nil fakeelse = FakeAST.new(:else) faketest = FakeAST.new(true) fakeif = FakeAST.new(:if) assert_nothing_raised { astelse = AST::Else.new(:statements => fakeelse) } assert_nothing_raised { astif = AST::IfStatement.new( :test => faketest, :statements => fakeif, :else => astelse ) } # We initialized it to true, so we should get that first ret = nil assert_nothing_raised { ret = astif.evaluate(:scope => "yay") } assert_equal(:if, ret) # Now set it to false and check that faketest.evaluate = false assert_nothing_raised { ret = astif.evaluate(:scope => "yay") } assert_equal(:else, ret) end end # $Id$ diff --git a/test/language/functions.rb b/test/language/functions.rb index 3ae381d83..2c3246e6a 100755 --- a/test/language/functions.rb +++ b/test/language/functions.rb @@ -1,311 +1,304 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' -require 'test/unit' require 'puppettest' class TestLangFunctions < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def test_functions assert_raise(Puppet::ParseError) do Puppet::Parser::AST::Function.new( :name => "fakefunction", :arguments => AST::ASTArray.new( :children => [nameobj("avalue")] ) ) end assert_nothing_raised do Puppet::Parser::Functions.newfunction(:fakefunction, :rvalue) do |input| return "output %s" % input[0] end end func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "fakefunction", :ftype => :rvalue, :arguments => AST::ASTArray.new( :children => [nameobj("avalue")] ) ) end scope = Puppet::Parser::Scope.new() val = nil assert_nothing_raised do val = func.evaluate(:scope => scope) end assert_equal("output avalue", val) end def test_taggedfunction scope = Puppet::Parser::Scope.new() tag = "yayness" scope.setclass(tag.object_id, tag) {"yayness" => true, "booness" => false}.each do |tag, retval| func = taggedobj(tag, :rvalue) val = nil assert_nothing_raised do val = func.evaluate(:scope => scope) end assert_equal(retval, val, "'tagged' returned %s for %s" % [val, tag]) end end def test_failfunction func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "fail", :ftype => :statement, :arguments => AST::ASTArray.new( :children => [stringobj("this is a failure"), stringobj("and another")] ) ) end scope = Puppet::Parser::Scope.new() val = nil assert_raise(Puppet::ParseError) do val = func.evaluate(:scope => scope) end end def test_multipletemplates Dir.mkdir(Puppet[:templatedir]) onep = File.join(Puppet[:templatedir], "one") twop = File.join(Puppet[:templatedir], "two") File.open(onep, "w") do |f| f.puts "template <%= one %>" end File.open(twop, "w") do |f| f.puts "template <%= two %>" end func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "template", :ftype => :rvalue, :arguments => AST::ASTArray.new( :children => [stringobj("one"), stringobj("two")] ) ) end ast = varobj("output", func) scope = Puppet::Parser::Scope.new() assert_raise(Puppet::ParseError) do ast.evaluate(:scope => scope) end scope.setvar("one", "One") assert_raise(Puppet::ParseError) do ast.evaluate(:scope => scope) end scope.setvar("two", "Two") assert_nothing_raised do ast.evaluate(:scope => scope) end assert_equal("template One\ntemplate Two\n", scope.lookupvar("output"), "Templates were not handled correctly") end # Now make sure we can fully qualify files, and specify just one def test_singletemplates template = tempfile() File.open(template, "w") do |f| f.puts "template <%= yayness %>" end func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "template", :ftype => :rvalue, :arguments => AST::ASTArray.new( :children => [stringobj(template)] ) ) end ast = varobj("output", func) scope = Puppet::Parser::Scope.new() assert_raise(Puppet::ParseError) do ast.evaluate(:scope => scope) end scope.setvar("yayness", "this is yayness") assert_nothing_raised do ast.evaluate(:scope => scope) end assert_equal("template this is yayness\n", scope.lookupvar("output"), "Templates were not handled correctly") end def test_tempatefunction_cannot_see_scopes template = tempfile() File.open(template, "w") do |f| f.puts "<%= lookupvar('myvar') %>" end func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "template", :ftype => :rvalue, :arguments => AST::ASTArray.new( :children => [stringobj(template)] ) ) end ast = varobj("output", func) scope = Puppet::Parser::Scope.new() scope.setvar("myvar", "this is yayness") assert_raise(Puppet::ParseError) do ast.evaluate(:scope => scope) end end def test_template_reparses template = tempfile() File.open(template, "w") do |f| f.puts "original text" end manifest = tempfile() file = tempfile() File.open(manifest, "w") do |f| f.puts %{file { "#{file}": content => template("#{template}") }} end interpreter = Puppet::Parser::Interpreter.new( :Manifest => manifest, :UseNodes => false ) parsedate = interpreter.parsedate() objects = nil assert_nothing_raised { objects = interpreter.run("myhost", {}) } fileobj = objects[0] assert_equal("original text\n", fileobj["content"], "Template did not work") Puppet[:filetimeout] = 0 # Have to sleep because one second is the fs's time granularity. sleep(1) # Now modify the template File.open(template, "w") do |f| f.puts "new text" end assert_nothing_raised { objects = interpreter.run("myhost", {}) } newdate = interpreter.parsedate() assert(parsedate != newdate, "Parse date did not change") end def test_template_defined_vars template = tempfile() File.open(template, "w") do |f| f.puts "template <%= yayness %>" end func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => "template", :ftype => :rvalue, :arguments => AST::ASTArray.new( :children => [stringobj(template)] ) ) end ast = varobj("output", func) { "" => "", false => "false", }.each do |string, value| scope = Puppet::Parser::Scope.new() assert_raise(Puppet::ParseError) do ast.evaluate(:scope => scope) end scope.setvar("yayness", string) assert_nothing_raised("An empty string was not a valid variable value") do ast.evaluate(:scope => scope) end assert_equal("template #{value}\n", scope.lookupvar("output"), "%s did not get evaluated correctly" % string.inspect) end end def test_autoloading_functions assert_equal(false, Puppet::Parser::Functions.function(:autofunc), "Got told autofunc already exists") dir = tempfile() $: << dir newpath = File.join(dir, "puppet", "parser", "functions") FileUtils.mkdir_p(newpath) File.open(File.join(newpath, "autofunc.rb"), "w") { |f| f.puts %{ Puppet::Parser::Functions.newfunction(:autofunc, :rvalue) do |vals| Puppet.wanring vals.inspect end } } obj = nil assert_nothing_raised { obj = Puppet::Parser::Functions.function(:autofunc) } assert(obj, "Did not autoload function") assert(Puppet::Parser::Scope.method_defined?(:function_autofunc), "Did not set function correctly") end end # $Id$ diff --git a/test/language/interpreter.rb b/test/language/interpreter.rb index 36fd5922b..37b4e9022 100755 --- a/test/language/interpreter.rb +++ b/test/language/interpreter.rb @@ -1,399 +1,392 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'facter' require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' require 'puppet/rails' -require 'test/unit' require 'puppettest' class TestInterpreter < Test::Unit::TestCase - include TestPuppet - include ServerTest + include PuppetTest + include PuppetTest::ServerTest AST = Puppet::Parser::AST # create a simple manifest that uses nodes to create a file def mknodemanifest(node, file) createdfile = tempfile() File.open(file, "w") { |f| f.puts "node %s { file { \"%s\": ensure => file, mode => 755 } }\n" % [node, createdfile] } return [file, createdfile] end def test_simple file = tempfile() File.open(file, "w") { |f| f.puts "file { \"/etc\": owner => root }" } assert_nothing_raised { Puppet::Parser::Interpreter.new(:Manifest => file) } end def test_reloadfiles hostname = Facter["hostname"].value file = tempfile() # Create a first version createdfile = mknodemanifest(hostname, file) interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new(:Manifest => file) } config = nil assert_nothing_raised { config = interp.run(hostname, {}) } sleep(1) # Now create a new file createdfile = mknodemanifest(hostname, file) newconfig = nil assert_nothing_raised { newconfig = interp.run(hostname, {}) } assert(config != newconfig, "Configs are somehow the same") end if defined? ActiveRecord def test_hoststorage assert_nothing_raised { Puppet[:storeconfigs] = true } file = tempfile() File.open(file, "w") { |f| f.puts "file { \"/etc\": owner => root }" } interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => file, :UseNodes => false, :ForkSave => false ) } facts = {} Facter.each { |fact, val| facts[fact] = val } objects = nil assert_nothing_raised { objects = interp.run(facts["hostname"], facts) } obj = Puppet::Rails::Host.find_by_name(facts["hostname"]) assert(obj, "Could not find host object") end else $stderr.puts "No ActiveRecord -- skipping collection tests" end if Facter["domain"].value == "madstop.com" begin require 'ldap' $haveldap = true rescue LoadError $stderr.puts "Missing ldap; skipping ldap source tests" $haveldap = false end # Only test ldap stuff on luke's network, since that's the only place we # have data for. if $haveldap def ldapconnect @ldap = LDAP::Conn.new("ldap", 389) @ldap.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 ) @ldap.simple_bind("", "") return @ldap end def ldaphost(node) parent = nil classes = nil @ldap.search( "ou=hosts, dc=madstop, dc=com", 2, "(&(objectclass=puppetclient)(cn=%s))" % node ) do |entry| parent = entry.vals("parentnode").shift classes = entry.vals("puppetclass") || [] end return parent, classes end def test_ldapnodes Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com" Puppet[:ldapnodes] = true ldapconnect() file = tempfile() files = [] parentfile = tempfile() + "-parent" files << parentfile hostname = Facter["hostname"].value lparent, lclasses = ldaphost(Facter["hostname"].value) assert(lclasses, "Did not retrieve info from ldap") File.open(file, "w") { |f| f.puts "node #{lparent} { file { \"#{parentfile}\": ensure => file } }" lclasses.each { |klass| kfile = tempfile() + "-klass" files << kfile f.puts "class #{klass} { file { \"#{kfile}\": ensure => file } }" } } interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => file ) } parent = nil classes = nil # First make sure we get the default node for unknown hosts dparent, dclasses = ldaphost("default") assert_nothing_raised { parent, classes = interp.nodesearch("nosuchhostokay") } assert_equal(dparent, parent, "Default parent node did not match") assert_equal(dclasses, classes, "Default parent class list did not match") # Look for a host we know doesn't have a parent npparent, npclasses = ldaphost("noparent") assert_nothing_raised { #parent, classes = interp.nodesearch_ldap("noparent") parent, classes = interp.nodesearch("noparent") } assert_equal(npparent, parent, "Parent node did not match") assert_equal(npclasses, classes, "Class list did not match") # Now look for our normal host assert_nothing_raised { parent, classes = interp.nodesearch_ldap(hostname) } assert_equal(lparent, parent, "Parent node did not match") assert_equal(lclasses, classes, "Class list did not match") objects = nil assert_nothing_raised { objects = interp.run(hostname, Puppet::Client::MasterClient.facts) } comp = nil assert_nothing_raised { comp = objects.to_type } assert_apply(comp) files.each { |cfile| @@tmpfiles << cfile assert(FileTest.exists?(cfile), "Did not make %s" % cfile) } end if Process.uid == 0 and Facter["hostname"].value == "culain" def test_ldapreconnect Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com" Puppet[:ldapnodes] = true interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => mktestmanifest() ) } hostname = "culain.madstop.com" # look for our host assert_nothing_raised { parent, classes = interp.nodesearch_ldap(hostname) } # Now restart ldap system("/etc/init.d/slapd restart 2>/dev/null >/dev/null") sleep(1) # and look again assert_nothing_raised { parent, classes = interp.nodesearch_ldap(hostname) } # Now stop ldap system("/etc/init.d/slapd stop 2>/dev/null >/dev/null") cleanup do system("/etc/init.d/slapd start 2>/dev/null >/dev/null") end # And make sure we actually fail here assert_raise(Puppet::Error) { parent, classes = interp.nodesearch_ldap(hostname) } end else $stderr.puts "Run as root for ldap reconnect tests" end end else $stderr.puts "Not in madstop.com; skipping ldap tests" end # Make sure searchnode behaves as we expect. def test_nodesearch # First create a fake nodesearch algorithm i = 0 bucket = [] Puppet::Parser::Interpreter.send(:define_method, "nodesearch_fake") do |node| return nil, nil if node == "default" return bucket[0], bucket[1] end text = %{ node nodeparent {} node othernodeparent {} class nodeclass {} class nothernode {} } manifest = tempfile() File.open(manifest, "w") do |f| f.puts text end interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => manifest, :NodeSources => [:fake] ) } # Make sure it behaves correctly for all forms [[nil, nil], ["nodeparent", nil], [nil, ["nodeclass"]], [nil, ["nodeclass", "nothernode"]], ["othernodeparent", ["nodeclass", "nothernode"]],].each do |ary| # Set the return values bucket = ary # Look them back up parent, classes = interp.nodesearch("mynode") # Basically, just make sure that if we have either or both, # we get a result back. assert_equal(ary[0], parent, "Parent is not %s" % parent) assert_equal(ary[1], classes, "Parent is not %s" % parent) next if ary == [nil, nil] # Now make sure we actually get the configuration. This will throw # an exception if we don't. assert_nothing_raised do interp.run("mynode", {}) end end end # Make sure nodesearch uses all names, not just one. def test_nodesearch_multiple_names bucket = {} Puppet::Parser::Interpreter.send(:define_method, "nodesearch_multifake") do |node| if bucket[node] return *bucket[node] else return nil, nil end end manifest = tempfile() File.open(manifest, "w") do |f| f.puts "" end interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => manifest, :NodeSources => [:multifake] ) } bucket["name.domain.com"] = [:parent, [:classes]] ret = nil assert_nothing_raised do assert_equal bucket["name.domain.com"], interp.nodesearch("name", "name.domain.com") end end def test_parsedate Puppet[:filetimeout] = 0 main = tempfile() sub = tempfile() mainfile = tempfile() subfile = tempfile() count = 0 updatemain = proc do count += 1 File.open(main, "w") { |f| f.puts "import '#{sub}' file { \"#{mainfile}\": content => #{count} } " } end updatesub = proc do count += 1 File.open(sub, "w") { |f| f.puts "file { \"#{subfile}\": content => #{count} } " } end updatemain.call updatesub.call interp = Puppet::Parser::Interpreter.new( :Manifest => main, :Local => true ) date = interp.parsedate # Now update the site file and make sure we catch it sleep 1 updatemain.call newdate = interp.parsedate assert(date != newdate, "Parsedate was not updated") date = newdate # And then the subfile sleep 1 updatesub.call newdate = interp.parsedate assert(date != newdate, "Parsedate was not updated") end end diff --git a/test/language/lexer.rb b/test/language/lexer.rb index 8b578a3fd..496087ba2 100644 --- a/test/language/lexer.rb +++ b/test/language/lexer.rb @@ -1,161 +1,154 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/lexer' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' #%q{service("telnet") = \{ # port => "23", # protocol => "tcp", # name => "telnet", #\} #} => [[:NAME, "service"], [:LPAREN, "("], [:DQUOTE, "\""], [:NAME, "telnet"], [:DQUOTE, "\""], [:RPAREN, ")"], [:EQUALS, "="], [:lbrace, "{"], [:NAME, "port"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "23"], [:DQUOTE, "\""], [:COMMA, ","], [:NAME, "protocol"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "tcp"], [:DQUOTE, "\""], [:COMMA, ","], [:NAME, "name"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "telnet"], [:DQUOTE, "\""], [:COMMA, ","], [:RBRACE, "}"]] class TestLexer < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @lexer = Puppet::Parser::Lexer.new() end def test_simple_lex strings = { %q{\\} => [[:BACKSLASH,"\\"],[false,false]], %q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"],[false,false]], %q{returned scanner test } => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"],[false,false]] } strings.each { |str,ary| @lexer.string = str assert_equal( ary, @lexer.fullscan() ) } end def test_quoted_strings strings = { %q{a simple "scanner" test } => [[:NAME,"a"],[:NAME,"simple"],[:DQTEXT,"scanner"],[:NAME,"test"],[false,false]], %q{a simple 'single quote scanner' test } => [[:NAME,"a"],[:NAME,"simple"],[:SQTEXT,"single quote scanner"],[:NAME,"test"],[false,false]], %q{a harder 'a $b \c"' } => [[:NAME,"a"],[:NAME,"harder"],[:SQTEXT,'a $b \c"'],[false,false]], %q{a harder "scanner test" } => [[:NAME,"a"],[:NAME,"harder"],[:DQTEXT,"scanner test"],[false,false]], %q{a hardest "scanner \"test\"" } => [[:NAME,"a"],[:NAME,"hardest"],[:DQTEXT,'scanner "test"'],[false,false]], %q{a hardestest "scanner \"test\" " } => [[:NAME,"a"],[:NAME,"hardestest"],[:DQTEXT,'scanner "test" '],[false,false]], %q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:DQTEXT,'call'],[:RPAREN,")"],[false,false]] } strings.each { |str,array| @lexer.string = str assert_equal( array, @lexer.fullscan() ) } end def test_errors strings = %w{ ^ } strings.each { |str| @lexer.string = str assert_raise(RuntimeError) { @lexer.fullscan() } } end def test_more_error assert_raise(TypeError) { @lexer.fullscan() } end def test_files textfiles() { |file| @lexer.file = file assert_nothing_raised() { @lexer.fullscan() } Puppet::Type.allclear } end def test_strings names = %w{this is a bunch of names} types = %w{Many Different Words A Word} words = %w{differently Cased words A a} names.each { |t| @lexer.string = t assert_equal( [[:NAME,t],[false,false]], @lexer.fullscan ) } types.each { |t| @lexer.string = t assert_equal( [[:TYPE,t],[false,false]], @lexer.fullscan ) } end def test_emptystring bit = '$var = ""' assert_nothing_raised { @lexer.string = bit } assert_nothing_raised { @lexer.fullscan } end def test_collectlexing {"@" => :AT, "<|" => :LCOLLECT, "|>" => :RCOLLECT}.each do |string, token| assert_nothing_raised { @lexer.string = string } ret = nil assert_nothing_raised { ret = @lexer.fullscan } assert_equal([[token, string],[false, false]], ret) end end def test_collectabletype string = "@type {" assert_nothing_raised { @lexer.string = string } ret = nil assert_nothing_raised { ret = @lexer.fullscan } assert_equal([[:AT, "@"], [:NAME, "type"], [:LBRACE, "{"], [false,false]],ret) end end # $Id$ diff --git a/test/language/node.rb b/test/language/node.rb index a1bb58a9f..791c44874 100644 --- a/test/language/node.rb +++ b/test/language/node.rb @@ -1,131 +1,124 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/parser' -require 'test/unit' require 'puppettest' class TestParser < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def setup super Puppet[:parseonly] = true @parser = Puppet::Parser::Parser.new() end def test_simple_hostname check_parseable "host1" check_parseable "'host2'" check_parseable [ "'host1'", "host2" ] check_parseable [ "'host1'", "'host2'" ] end def test_qualified_hostname check_parseable "'host.example.com'" check_parseable [ "'host.example.com'", "host1" ] check_parseable "'host-1.37examples.example.com'" check_parseable "'svn.23.nu'" check_parseable "'HOST'" end def test_reject_hostname check_nonparseable "host.example.com" check_nonparseable "host@example.com" check_nonparseable "\"host\"" check_nonparseable "'$foo.example.com'" check_nonparseable "'host1 host2'" check_nonparseable "HOST" end AST = Puppet::Parser::AST def check_parseable(hostnames) unless hostnames.is_a?(Array) hostnames = [ hostnames ] end assert_nothing_raised { @parser.string = "node #{hostnames.join(", ")} { }" } # Strip quotes hostnames.map! { |s| s.sub(/^'(.*)'$/, "\\1") } ast = nil assert_nothing_raised { ast = @parser.parse } # Verify that the AST has the expected structure # and that the leaves have the right hostnames in them assert_kind_of(AST::ASTArray, ast) assert_equal(1, ast.children.size) nodedef = ast.children[0] assert_kind_of(AST::NodeDef, nodedef) assert_kind_of(AST::ASTArray, nodedef.names) assert_equal(hostnames.size, nodedef.names.children.size) hostnames.size.times do |i| hostnode = nodedef.names.children[i] assert_kind_of(AST::HostName, hostnode) assert_equal(hostnames[i], hostnode.value) end end def check_nonparseable(hostname) assert_nothing_raised { @parser.string = "node #{hostname} { }" } assert_raise(Puppet::DevError, Puppet::ParseError) { @parser.parse } end # Make sure we can find default nodes if there's no other entry def test_default_node Puppet[:parseonly] = false @parser = Puppet::Parser::Parser.new() fileA = tempfile() fileB = tempfile() @parser.string = %{ node mynode { file { "#{fileA}": ensure => file } } node default { file { "#{fileB}": ensure => file } } } # First make sure it parses ast = nil assert_nothing_raised { ast = @parser.parse } args = { :ast => ast, :facts => {}, :names => ["mynode"] } # Make sure we get a config for "mynode" trans = nil assert_nothing_raised { trans = Puppet::Parser::Scope.new.evaluate(args) } assert(trans, "Did not get config for mynode") args[:names] = ["othernode"] # Now make sure the default node is used trans = nil assert_nothing_raised { trans = Puppet::Parser::Scope.new.evaluate(args) } assert(trans, "Did not get config for default node") end end diff --git a/test/language/parser.rb b/test/language/parser.rb index 6dd9b4bca..d6e176870 100644 --- a/test/language/parser.rb +++ b/test/language/parser.rb @@ -1,506 +1,499 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/parser' -require 'test/unit' require 'puppettest' class TestParser < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def setup super Puppet[:parseonly] = true #@lexer = Puppet::Parser::Lexer.new() @parser = Puppet::Parser::Parser.new() end def test_each_file textfiles { |file| Puppet.debug("parsing %s" % file) if __FILE__ == $0 assert_nothing_raised() { @parser.file = file @parser.parse } Puppet::Type.eachtype { |type| type.each { |obj| assert(obj.file) assert(obj.name) assert(obj.line) } } Puppet::Type.allclear } end def test_failers failers { |file| Puppet.debug("parsing failer %s" % file) if __FILE__ == $0 assert_raise(Puppet::ParseError) { @parser.file = file ast = @parser.parse Puppet::Parser::Scope.new.evaluate(:ast => ast) } Puppet::Type.allclear } end def test_arrayrvalues parser = Puppet::Parser::Parser.new() ret = nil file = tempfile() assert_nothing_raised { parser.string = "file { \"#{file}\": mode => [755, 640] }" } assert_nothing_raised { ret = parser.parse } end def mkmanifest(file) name = File.join(tmpdir, "file%s" % rand(100)) @@tmpfiles << name File.open(file, "w") { |f| f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % name } end def test_importglobbing basedir = File.join(tmpdir(), "importesting") @@tmpfiles << basedir Dir.mkdir(basedir) subdir = "subdir" Dir.mkdir(File.join(basedir, subdir)) manifest = File.join(basedir, "manifest") File.open(manifest, "w") { |f| f.puts "import \"%s/*\"" % subdir } 4.times { |i| path = File.join(basedir, subdir, "subfile%s" % i) mkmanifest(path) } assert_nothing_raised("Could not parse multiple files") { parser = Puppet::Parser::Parser.new() parser.file = manifest parser.parse } end def test_nonexistent_import basedir = File.join(tmpdir(), "importesting") @@tmpfiles << basedir Dir.mkdir(basedir) manifest = File.join(basedir, "manifest") File.open(manifest, "w") do |f| f.puts "import \" no such file \"" end assert_raise(Puppet::ParseError) { parser = Puppet::Parser::Parser.new() parser.file = manifest parser.parse } end def test_defaults basedir = File.join(tmpdir(), "defaulttesting") @@tmpfiles << basedir Dir.mkdir(basedir) defs1 = { "testing" => "value" } defs2 = { "one" => "two", "three" => "four", "five" => false, "seven" => "eight", "nine" => true, "eleven" => "twelve" } mkdef = proc { |hash| hash.collect { |arg, value| "$%s = %s" % [arg, value] }.join(", ") } manifest = File.join(basedir, "manifest") File.open(manifest, "w") { |f| f.puts " define method(#{mkdef.call(defs1)}, $other) { $variable = $testing } define othermethod(#{mkdef.call(defs2)}, $goodness) { $more = less } method { other => yayness } othermethod { goodness => rahness } " } ast = nil assert_nothing_raised("Could not parse multiple files") { parser = Puppet::Parser::Parser.new() parser.file = manifest ast = parser.parse } assert(ast, "Did not receive AST while parsing defaults") scope = nil assert_nothing_raised("Could not evaluate defaults parse tree") { scope = Puppet::Parser::Scope.new() scope.name = "parsetest" scope.type = "parsetest" objects = scope.evaluate(:ast => ast) } method = nil othermethod = nil assert_nothing_raised { method = scope.find { |child| child.is_a?(Puppet::Parser::Scope) and child.type == "method" } defs1.each { |var, value| curval = method.lookupvar(var) assert_equal(value, curval, "Did not get default") } } assert_nothing_raised { method = scope.find { |child| child.is_a?(Puppet::Parser::Scope) and child.type == "othermethod" } defs2.each { |var, value| curval = method.lookupvar(var) assert_equal(value, curval, "Did not get default") } } end def test_trailingcomma path = tempfile() str = %{file { "#{path}": ensure => file, } } parser = Puppet::Parser::Parser.new parser.string = str assert_nothing_raised("Could not parse trailing comma") { parser.parse } end def test_importedclasses imported = tempfile() importer = tempfile() made = tempfile() File.open(imported, "w") do |f| f.puts %{class foo { file { "#{made}": ensure => file }}} end File.open(importer, "w") do |f| f.puts %{import "#{imported}"\ninclude foo} end parser = Puppet::Parser::Parser.new parser.file = importer # Make sure it parses fine assert_nothing_raised { parser.parse } # Now make sure it actually does the work assert_creates(importer, made) end # Make sure fully qualified and unqualified files can be imported def test_fqfilesandlocalfiles dir = tempfile() Dir.mkdir(dir) importer = File.join(dir, "site.pp") fullfile = File.join(dir, "full.pp") localfile = File.join(dir, "local.pp") files = [] File.open(importer, "w") do |f| f.puts %{import "#{fullfile}"\ninclude full\nimport "local.pp"\ninclude local} end fullmaker = tempfile() files << fullmaker File.open(fullfile, "w") do |f| f.puts %{class full { file { "#{fullmaker}": ensure => file }}} end localmaker = tempfile() files << localmaker File.open(localfile, "w") do |f| f.puts %{class local { file { "#{localmaker}": ensure => file }}} end parser = Puppet::Parser::Parser.new parser.file = importer # Make sure it parses assert_nothing_raised { parser.parse } # Now make sure it actually does the work assert_creates(importer, *files) end # Make sure the parser adds '.pp' when necessary def test_addingpp dir = tempfile() Dir.mkdir(dir) importer = File.join(dir, "site.pp") localfile = File.join(dir, "local.pp") files = [] File.open(importer, "w") do |f| f.puts %{import "local"\ninclude local} end file = tempfile() files << file File.open(localfile, "w") do |f| f.puts %{class local { file { "#{file}": ensure => file }}} end parser = Puppet::Parser::Parser.new parser.file = importer assert_nothing_raised { parser.parse } end # Make sure that file importing changes file relative names. def test_changingrelativenames dir = tempfile() Dir.mkdir(dir) Dir.mkdir(File.join(dir, "subdir")) top = File.join(dir, "site.pp") subone = File.join(dir, "subdir/subone") subtwo = File.join(dir, "subdir/subtwo") files = [] file = tempfile() files << file File.open(subone + ".pp", "w") do |f| f.puts %{class one { file { "#{file}": ensure => file }}} end otherfile = tempfile() files << otherfile File.open(subtwo + ".pp", "w") do |f| f.puts %{import "subone"\n class two inherits one { file { "#{otherfile}": ensure => file } }} end File.open(top, "w") do |f| f.puts %{import "subdir/subtwo"} end parser = Puppet::Parser::Parser.new parser.file = top assert_nothing_raised { parser.parse } end # Verify that collectable objects are marked that way. def test_collectable Puppet[:storeconfigs] = true ["@port { ssh: protocols => tcp, number => 22 }", "@port { ssh: protocols => tcp, number => 22; smtp: protocols => tcp, number => 25 }"].each do |text| parser = Puppet::Parser::Parser.new parser.string = text ret = nil assert_nothing_raised { ret = parser.parse } assert_instance_of(AST::ASTArray, ret) ret.each do |obj| assert_instance_of(AST::ObjectDef, obj) assert(obj.collectable, "Object was not marked collectable") end end end # Defaults are purely syntactical, so it doesn't make sense to be able to # collect them. def test_uncollectabledefaults string = "@Port { protocols => tcp }" parser = Puppet::Parser::Parser.new parser.string = string assert_raise(Puppet::ParseError) { parser.parse } end # Verify that we can parse collections def test_collecting Puppet[:storeconfigs] = true text = "port <| |>" parser = Puppet::Parser::Parser.new parser.string = text ret = nil assert_nothing_raised { ret = parser.parse } assert_instance_of(AST::ASTArray, ret) ret.each do |obj| assert_instance_of(AST::Collection, obj) end end def test_emptyfile file = tempfile() File.open(file, "w") do |f| f.puts %{} end parser = Puppet::Parser::Parser.new parser.file = file assert_nothing_raised { parser.parse } end def test_multiple_nodes_named file = tempfile() other = tempfile() File.open(file, "w") do |f| f.puts %{ node nodeA, nodeB { file { "#{other}": ensure => file } } } end parser = Puppet::Parser::Parser.new parser.file = file ast = nil assert_nothing_raised { ast = parser.parse } end def test_emptyarrays str = %{$var = []\n} parser = Puppet::Parser::Parser.new parser.string = str # Make sure it parses fine assert_nothing_raised { parser.parse } end # Make sure function names aren't reserved words. def test_functionnamecollision str = %{tag yayness tag(rahness) file { "/tmp/yayness": tag => "rahness", ensure => exists } } parser = Puppet::Parser::Parser.new parser.string = str # Make sure it parses fine assert_nothing_raised { parser.parse } end def test_metaparams_in_definition_prototypes parser = Puppet::Parser::Parser.new str1 = %{define mydef($schedule) {}} parser.string = str1 assert_raise(Puppet::ParseError) { parser.parse } str2 = %{define mydef($schedule = false) {}} parser.string = str2 assert_raise(Puppet::ParseError) { parser.parse } str3 = %{define mydef($schedule = daily) {}} parser.string = str3 assert_nothing_raised { parser.parse } end def test_parsingif parser = Puppet::Parser::Parser.new() exec = proc do |val| %{exec { "/bin/echo #{val}": logoutput => true }} end str1 = %{if true { #{exec.call("true")} }} ret = nil assert_nothing_raised { ret = parser.parse(str1)[0] } assert_instance_of(Puppet::Parser::AST::IfStatement, ret) str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }} assert_nothing_raised { ret = parser.parse(str2)[0] } assert_instance_of(Puppet::Parser::AST::IfStatement, ret) assert_instance_of(Puppet::Parser::AST::Else, ret.else) end end # $Id$ diff --git a/test/language/rails.rb b/test/language/rails.rb index df76b4f20..ada4e0915 100755 --- a/test/language/rails.rb +++ b/test/language/rails.rb @@ -1,105 +1,98 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/rails' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' -require 'test/unit' require 'puppettest' class TestRails < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def test_includerails assert_nothing_raised { require 'puppet/rails' } end # Don't do any tests w/out this class if defined? ActiveRecord::Base def test_hostcache # First make some objects bucket = mk_transtree do |object, depth, width| # and mark some of them collectable if width % 2 == 1 object.collectable = true end end # Now collect our facts facts = {} Facter.each do |fact, value| facts[fact] = value end assert_nothing_raised { Puppet::Rails.init } # Now try storing our crap host = nil assert_nothing_raised { host = Puppet::Rails::Host.store( :objects => bucket, :facts => facts, :host => facts["hostname"] ) } assert(host, "Did not create host") host = nil assert_nothing_raised { host = Puppet::Rails::Host.find_by_name(facts["hostname"]) } assert(host, "Could not find host object") assert(host.rails_objects, "No objects on host") assert_equal(facts["hostname"], host.facts["hostname"], "Did not retrieve facts") inline_test_objectcollection(host) end # This is called from another test, it just makes sense to split it out some def inline_test_objectcollection(host) # XXX For some reason, find_all doesn't work here at all. collectable = [] host.rails_objects.each do |obj| if obj.collectable? collectable << obj end end assert(collectable.length > 0, "Found no collectable objects") collectable.each do |obj| trans = nil assert_nothing_raised { trans = obj.to_trans } # Make sure that the objects do not retain their collectable # nature. assert(!trans.collectable, "Object from db was collectable") end # Now find all collectable objects directly through database APIs list = Puppet::Rails::RailsObject.find_all_by_collectable(true) assert_equal(collectable.length, list.length, "Did not get the right number of objects") end else $stderr.puts "Install Rails for Rails and Caching tests" end end # $Id$ diff --git a/test/language/scope.rb b/test/language/scope.rb index 3e5b5d24b..85189627d 100755 --- a/test/language/scope.rb +++ b/test/language/scope.rb @@ -1,922 +1,915 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' -require 'test/unit' require 'puppettest' # so, what kind of things do we want to test? # we don't need to test function, since we're confident in the # library tests. We do, however, need to test how things are actually # working in the language. # so really, we want to do things like test that our ast is correct # and test whether we've got things in the right scopes class TestScope < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def to_ary(hash) hash.collect { |key,value| [key,value] } end def test_variables scope = nil over = "over" scopes = [] vars = [] values = {} ovalues = [] 10.times { |index| # slap some recursion in there scope = Puppet::Parser::Scope.new(:parent => scope) scopes.push scope var = "var%s" % index value = rand(1000) ovalue = rand(1000) ovalues.push ovalue vars.push var values[var] = value # set the variable in the current scope assert_nothing_raised { scope.setvar(var,value) } # this should override previous values assert_nothing_raised { scope.setvar(over,ovalue) } assert_equal(value,scope.lookupvar(var)) #puts "%s vars, %s scopes" % [vars.length,scopes.length] i = 0 vars.zip(scopes) { |v,s| # this recurses all the way up the tree as necessary val = nil oval = nil # look up the values using the bottom scope assert_nothing_raised { val = scope.lookupvar(v) oval = scope.lookupvar(over) } # verify they're correct assert_equal(values[v],val) assert_equal(ovalue,oval) # verify that we get the most recent value assert_equal(ovalue,scope.lookupvar(over)) # verify that they aren't available in upper scopes if parent = s.parent val = nil assert_nothing_raised { val = parent.lookupvar(v) } assert_equal("", val, "Did not get empty string on missing var") # and verify that the parent sees its correct value assert_equal(ovalues[i - 1],parent.lookupvar(over)) end i += 1 } } end def test_declarative # set to declarative top = Puppet::Parser::Scope.new(:declarative => true) sub = Puppet::Parser::Scope.new(:parent => top) assert_nothing_raised { top.setvar("test","value") } assert_raise(Puppet::ParseError) { top.setvar("test","other") } assert_nothing_raised { sub.setvar("test","later") } assert_raise(Puppet::ParseError) { top.setvar("test","yeehaw") } end def test_notdeclarative # set to not declarative top = Puppet::Parser::Scope.new(:declarative => false) sub = Puppet::Parser::Scope.new(:parent => top) assert_nothing_raised { top.setvar("test","value") } assert_nothing_raised { top.setvar("test","other") } assert_nothing_raised { sub.setvar("test","later") } assert_nothing_raised { sub.setvar("test","yayness") } end def test_defaults scope = nil over = "over" scopes = [] vars = [] values = {} ovalues = [] defs = Hash.new { |hash,key| hash[key] = Hash.new(nil) } prevdefs = Hash.new { |hash,key| hash[key] = Hash.new(nil) } params = %w{a list of parameters that could be used for defaults} types = %w{a set of types that could be used to set defaults} 10.times { |index| scope = Puppet::Parser::Scope.new(:parent => scope) scopes.push scope tmptypes = [] # randomly create defaults for a random set of types tnum = rand(5) tnum.times { |t| # pick a type #Puppet.debug "Type length is %s" % types.length #s = rand(types.length) #Puppet.debug "Type num is %s" % s #type = types[s] #Puppet.debug "Type is %s" % s type = types[rand(types.length)] if tmptypes.include?(type) Puppet.debug "Duplicate type %s" % type redo else tmptypes.push type end Puppet.debug "type is %s" % type d = {} # randomly assign some parameters num = rand(4) num.times { |n| param = params[rand(params.length)] if d.include?(param) Puppet.debug "Duplicate param %s" % param redo else d[param] = rand(1000) end } # and then add a consistent type d["always"] = rand(1000) d.each { |var,val| defs[type][var] = val } assert_nothing_raised { scope.setdefaults(type,to_ary(d)) } fdefs = nil assert_nothing_raised { fdefs = scope.lookupdefaults(type) } # now, make sure that reassignment fails if we're # in declarative mode assert_raise(Puppet::ParseError) { scope.setdefaults(type,[%w{always funtest}]) } # assert that we have collected the same values assert_equal(defs[type],fdefs) # now assert that our parent still finds the same defaults # it got last time if parent = scope.parent unless prevdefs[type].nil? assert_equal(prevdefs[type],parent.lookupdefaults(type)) end end d.each { |var,val| prevdefs[type][var] = val } } } end def test_strinterp scope = Puppet::Parser::Scope.new() assert_nothing_raised { scope.setvar("test","value") } val = nil assert_nothing_raised { val = scope.strinterp("string ${test}") } assert_equal("string value", val) assert_nothing_raised { val = scope.strinterp("string ${test} ${test} ${test}") } assert_equal("string value value value", val) assert_nothing_raised { val = scope.strinterp("string $test ${test} $test") } assert_equal("string value value value", val) assert_nothing_raised { val = scope.strinterp("string \\$test") } assert_equal("string $test", val) assert_nothing_raised { val = scope.strinterp("\\$test string") } assert_equal("$test string", val) end # Test some of the host manipulations def test_hostlookup top = Puppet::Parser::Scope.new() # Create a deep scope tree, so that we know we're doing a deeply recursive # search. mid1 = Puppet::Parser::Scope.new(:parent => top) mid2 = Puppet::Parser::Scope.new(:parent => mid1) mid3 = Puppet::Parser::Scope.new(:parent => mid2) child1 = Puppet::Parser::Scope.new(:parent => mid3) mida = Puppet::Parser::Scope.new(:parent => top) midb = Puppet::Parser::Scope.new(:parent => mida) midc = Puppet::Parser::Scope.new(:parent => midb) child2 = Puppet::Parser::Scope.new(:parent => midc) # verify we can set a host assert_nothing_raised("Could not create host") { child1.setnode("testing", AST::Node.new( :type => "testing", :code => :notused ) ) } # Verify we cannot redefine it assert_raise(Puppet::ParseError, "Duplicate host creation succeeded") { child2.setnode("testing", AST::Node.new( :type => "testing", :code => :notused ) ) } # Now verify we can find the host again host = nil assert_nothing_raised("Host lookup failed") { hash = top.node("testing") host = hash[:node] } assert(host, "Could not find host") assert(host.code == :notused, "Host is not what we stored") end # Verify that two statements about a file within the same scope tree # will cause a conflict. def test_noconflicts filename = tempfile() children = [] # create the parent class children << classobj("one", :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "root") ] )) # now create a child class with differ values children << classobj("two", :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "bin") ] )) # Now call the child class assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("two"), :name => nameobj("yayness"), :params => astarray() ) << AST::ObjectDef.new( :type => nameobj("one"), :name => nameobj("yayness"), :params => astarray() ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil scope = nil # Here's where we should encounter the failure. It should find that # it has already created an object with that name, and this should result # in some pukey-pukeyness. assert_raise(Puppet::ParseError) { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } end # Verify that statements about the same element within the same scope # cause a conflict. def test_failonconflictinsamescope filename = tempfile() children = [] # Now call the child class assert_nothing_raised("Could not add AST nodes for calling") { children << fileobj(filename, "owner" => "root") children << fileobj(filename, "owner" => "bin") } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil scope = nil # Here's where we should encounter the failure. It should find that # it has already created an object with that name, and this should result # in some pukey-pukeyness. assert_raise(Puppet::ParseError) { scope = Puppet::Parser::Scope.new() scope.top = true objects = scope.evaluate(:ast => top) } end # Verify that we override statements that we find within our scope def test_suboverrides filename = tempfile() children = [] # create the parent class children << classobj("parent", :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "root") ] )) # now create a child class with differ values children << classobj("child", :parentclass => nameobj("parent"), :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "bin") ] )) # Now call the child class assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("child"), :name => nameobj("yayness"), :params => astarray() ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil scope = nil assert_nothing_raised("Could not evaluate") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } assert_equal(1, objects.length, "Returned too many objects: %s" % objects.inspect) assert_equal(1, objects[0].length, "Returned too many objects: %s" % objects[0].inspect) assert_nothing_raised { file = objects[0][0] assert_equal("bin", file["owner"], "Value did not override correctly") } end def test_multipletypes scope = Puppet::Parser::Scope.new() children = [] # create the parent class children << classobj("aclass") children << classobj("aclass") top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } scope = nil assert_raise(Puppet::ParseError) { scope = Puppet::Parser::Scope.new() objects = top.evaluate(:scope => scope) } end # Verify that definitions have a different context than classes. def test_newsubcontext filename = tempfile() children = [] # Create a component children << compobj("comp", :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "root" ) ] )) # Now create a class that modifies the same file and also # calls the component children << classobj("klass", :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "bin" ), AST::ObjectDef.new( :type => nameobj("comp"), :params => astarray() ) ] )) # Now call the class children << AST::ObjectDef.new( :type => nameobj("klass"), :params => astarray() ) top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } trans = nil scope = nil #assert_nothing_raised { assert_raise(Puppet::ParseError, "A conflict was allowed") { scope = Puppet::Parser::Scope.new() trans = scope.evaluate(:ast => top) } # scope = Puppet::Parser::Scope.new() # trans = scope.evaluate(:ast => top) #} end def test_defaultswithmultiplestatements path = tempfile() stats = [] stats << defaultobj("file", "group" => "root") stats << fileobj(path, "owner" => "root") stats << fileobj(path, "mode" => "755") top = AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => stats ) scope = Puppet::Parser::Scope.new() trans = nil assert_nothing_raised { trans = scope.evaluate(:ast => top) } obj = trans.find do |obj| obj.is_a? Puppet::TransObject end assert(obj, "Could not retrieve file obj") assert_equal("root", obj["group"], "Default did not take") assert_equal("root", obj["owner"], "Owner did not take") assert_equal("755", obj["mode"], "Mode did not take") end def test_validclassnames scope = Puppet::Parser::Scope.new() ["a class", "Class", "a.class"].each do |bad| assert_raise(Puppet::ParseError, "Incorrectly allowed %s" % bad.inspect) do scope.setclass(object_id, bad) end end ["a-class", "a_class", "class", "yayNess"].each do |good| assert_nothing_raised("Incorrectly banned %s" % good.inspect) do scope.setclass(object_id, good) end end end def test_tagfunction scope = Puppet::Parser::Scope.new() assert_nothing_raised { scope.function_tag(["yayness", "booness"]) } assert(scope.classlist.include?("yayness"), "tag 'yayness' did not get set") assert(scope.classlist.include?("booness"), "tag 'booness' did not get set") # Now verify that the 'tagged' function works correctly assert(scope.function_tagged("yayness"), "tagged function incorrectly returned false") assert(scope.function_tagged("booness"), "tagged function incorrectly returned false") assert(! scope.function_tagged("funtest"), "tagged function incorrectly returned true") end def test_includefunction scope = Puppet::Parser::Scope.new() one = tempfile() two = tempfile() children = [] children << classobj("one", :code => AST::ASTArray.new( :children => [ fileobj(one, "owner" => "root") ] )) children << classobj("two", :code => AST::ASTArray.new( :children => [ fileobj(two, "owner" => "root") ] )) children << Puppet::Parser::AST::Function.new( :name => "include", :ftype => :statement, :arguments => AST::ASTArray.new( :children => [nameobj("one"), nameobj("two")] ) ) top = AST::ASTArray.new(:children => children) #assert_nothing_raised { # scope.function_include(["one", "two"]) #} assert_nothing_raised { scope.evaluate(:ast => top) } assert(scope.classlist.include?("one"), "tag 'one' did not get set") assert(scope.classlist.include?("two"), "tag 'two' did not get set") # Now verify that the 'tagged' function works correctly assert(scope.function_tagged("one"), "tagged function incorrectly returned false") assert(scope.function_tagged("two"), "tagged function incorrectly returned false") end def test_definedfunction scope = Puppet::Parser::Scope.new() one = tempfile() two = tempfile() children = [] children << classobj("one", :code => AST::ASTArray.new( :children => [ fileobj(one, "owner" => "root") ] )) children << classobj("two", :code => AST::ASTArray.new( :children => [ fileobj(two, "owner" => "root") ] )) top = AST::ASTArray.new(:children => children) top.evaluate(:scope => scope) assert_nothing_raised { %w{one two file user}.each do |type| assert(scope.function_defined([type]), "Class #{type} was not considered defined") end assert(!scope.function_defined(["nopeness"]), "Class 'nopeness' was incorrectly considered defined") } end # Make sure components acquire defaults. def test_defaultswithcomponents children = [] # Create a component filename = tempfile() args = AST::ASTArray.new( :file => tempfile(), :line => rand(100), :children => [nameobj("argument")] ) children << compobj("comp", :args => args, :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => varref("argument") ) ] )) # Create a default children << defaultobj("comp", "argument" => "yayness") # lastly, create an object that calls our third component children << objectdef("comp", "boo", {"argument" => "parentfoo"}) trans = assert_evaluate(children) flat = trans.flatten assert(!flat.empty?, "Got no objects back") assert_equal("parentfoo", flat[0]["owner"], "default did not take") end # Make sure we know what we consider to be truth. def test_truth assert_equal(true, Puppet::Parser::Scope.true?("a string"), "Strings not considered true") assert_equal(true, Puppet::Parser::Scope.true?(true), "True considered true") assert_equal(false, Puppet::Parser::Scope.true?(""), "Empty strings considered true") assert_equal(false, Puppet::Parser::Scope.true?(false), "false considered true") end # Verify scope context is handled correctly. def test_scopeinside scope = Puppet::Parser::Scope.new() one = :one two = :two # First just test the basic functionality. assert_nothing_raised { scope.inside :one do assert_equal(:one, scope.inside, "Context did not get set") end assert_nil(scope.inside, "Context did not revert") } # Now make sure error settings work. assert_raise(RuntimeError) { scope.inside :one do raise RuntimeError, "This is a failure, yo" end } assert_nil(scope.inside, "Context did not revert") # Now test it a bit deeper in. assert_nothing_raised { scope.inside :one do scope.inside :two do assert_equal(:two, scope.inside, "Context did not get set") end assert_equal(:one, scope.inside, "Context did not get set") end assert_nil(scope.inside, "Context did not revert") } # And lastly, check errors deeper in assert_nothing_raised { scope.inside :one do begin scope.inside :two do raise "a failure" end rescue end assert_equal(:one, scope.inside, "Context did not get set") end assert_nil(scope.inside, "Context did not revert") } end if defined? ActiveRecord # Verify that we recursively mark as collectable the results of collectable # components. def test_collectablecomponents children = [] args = AST::ASTArray.new( :file => tempfile(), :line => rand(100), :children => [nameobj("arg")] ) # Create a top-level component children << compobj("one", :args => args) # And a component that calls it children << compobj("two", :args => args, :code => AST::ASTArray.new( :children => [ objectdef("one", "ptest", {"arg" => "parentfoo"}) ] )) # And then a third component that calls the second children << compobj("three", :args => args, :code => AST::ASTArray.new( :children => [ objectdef("two", "yay", {"arg" => "parentfoo"}) ] )) # lastly, create an object that calls our third component obj = objectdef("three", "boo", {"arg" => "parentfoo"}) # And mark it as collectable obj.collectable = true children << obj top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } trans = nil scope = nil assert_nothing_raised { scope = Puppet::Parser::Scope.new() trans = scope.evaluate(:ast => top) } %w{file}.each do |type| objects = scope.exported(type) assert(!objects.empty?, "Did not get an exported %s" % type) end end # Verify that we can both store and collect an object in the same # run, whether it's in the same scope as a collection or a different # scope. def test_storeandcollect Puppet[:storeconfigs] = true Puppet::Rails.clear Puppet::Rails.init sleep 1 children = [] file = tempfile() File.open(file, "w") { |f| f.puts " class yay { @host { myhost: ip => \"192.168.0.2\" } } include yay @host { puppet: ip => \"192.168.0.3\" } host <||>" } interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => file, :UseNodes => false, :ForkSave => false ) } objects = nil # We run it twice because we want to make sure there's no conflict # if we pull it up from the database. 2.times { |i| assert_nothing_raised { objects = interp.run("localhost", {}) } flat = objects.flatten %w{puppet myhost}.each do |name| assert(flat.find{|o| o.name == name }, "Did not find #{name}") end } end # Verify that we cannot override differently exported objects def test_exportedoverrides filename = tempfile() children = [] obj = fileobj(filename, "owner" => "root") obj.collectable = true # create the parent class children << classobj("parent", :code => AST::ASTArray.new( :children => [ obj ] )) # now create a child class with differ values children << classobj("child", :parentclass => nameobj("parent"), :code => AST::ASTArray.new( :children => [ fileobj(filename, "owner" => "bin") ] )) # Now call the child class assert_nothing_raised("Could not add AST nodes for calling") { children << AST::ObjectDef.new( :type => nameobj("child"), :name => nameobj("yayness"), :params => astarray() ) } top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } objects = nil scope = nil assert_raise(Puppet::ParseError, "Incorrectly allowed override") { scope = Puppet::Parser::Scope.new() objects = scope.evaluate(:ast => top) } end else $stderr.puts "No ActiveRecord -- skipping collection tests" end end diff --git a/test/language/snippets.rb b/test/language/snippets.rb index 2823f89ad..05ac066eb 100755 --- a/test/language/snippets.rb +++ b/test/language/snippets.rb @@ -1,559 +1,552 @@ #!/usr/bin/ruby -w -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' require 'puppet/server' -require 'test/unit' require 'puppettest' -# so, what kind of things do we want to test? - -# we don't need to test function, since we're confident in the -# library tests. We do, however, need to test how things are actually -# working in the language. - -# so really, we want to do things like test that our ast is correct -# and test whether we've got things in the right scopes - class TestSnippets < Test::Unit::TestCase - include TestPuppet + include PuppetTest include ObjectSpace - $snippetbase = File.join($puppetbase, "examples", "code", "snippets") + + def self.snippetdir + PuppetTest.exampledir "code", "snippets" + end + + def snippet(name) + File.join(self.class.snippetdir, name) + end def file2ast(file) parser = Puppet::Parser::Parser.new() parser.file = file ast = parser.parse return ast end def snippet2ast(text) parser = Puppet::Parser::Parser.new() parser.string = text ast = parser.parse return ast end def client args = { :Listen => false } Puppet::Client.new(args) end def ast2scope(ast) interp = Puppet::Parser::Interpreter.new( :ast => ast, :client => client() ) scope = Puppet::Parser::Scope.new() ast.evaluate(scope) return scope end def scope2objs(scope) objs = scope.to_trans end def snippet2scope(snippet) ast = snippet2ast(snippet) scope = ast2scope(ast) end def snippet2objs(snippet) ast = snippet2ast(snippet) scope = ast2scope(ast) objs = scope2objs(scope) end def states(type) states = type.validstates end def metaparams(type) mparams = [] Puppet::Type.eachmetaparam { |param| mparams.push param } mparams end def params(type) params = [] type.parameters.each { |name,state| params.push name } params end def randthing(thing,type) list = self.send(thing,type) list[rand(list.length)] end def randeach(type) [:states, :metaparams, :params].collect { |thing| randthing(thing,type) } end @@snippets = { true => [ %{File { mode => 755 }} ], } def disabled_test_defaults Puppet::Type.eachtype { |type| next if type.name == :puppet or type.name == :component rands = randeach(type) name = type.name.to_s.capitalize [0..1, 0..2].each { |range| params = rands[range] paramstr = params.collect { |param| "%s => fake" % param }.join(", ") str = "%s { %s }" % [name, paramstr] scope = nil assert_nothing_raised { scope = snippet2scope(str) } defaults = nil assert_nothing_raised { defaults = scope.lookupdefaults(name) } p defaults params.each { |param| puts "%s => '%s'" % [name,param] assert(defaults.include?(param)) } } } end # this is here in case no tests get defined; otherwise we get a warning def test_nothing end def snippet_filecreate(trans) %w{a b c d}.each { |letter| file = "/tmp/create%stest" % letter Puppet.info "testing %s" % file assert(Puppet.type(:file)[file], "File %s does not exist" % file) assert(FileTest.exists?(file)) @@tmpfiles << file } %w{a b}.each { |letter| file = "/tmp/create%stest" % letter assert(File.stat(file).mode & 007777 == 0755) } assert_nothing_raised { trans.rollback } %w{a b c d}.each { |letter| file = "/tmp/create%stest" % letter assert(! FileTest.exists?(file), "File %s still exists" % file) } end def snippet_simpledefaults(trans) file = "/tmp/defaulttest" @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755) assert_nothing_raised { trans.rollback } assert(! FileTest.exists?(file), "%s still exists" % file) end def snippet_simpleselector(trans) files = %w{a b c d}.collect { |letter| "/tmp/snippetselect%stest" % letter } @@tmpfiles += files files.each { |file| assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is the incorrect mode" % file) @@tmpfiles << file } assert_nothing_raised { trans.rollback } files.each { |file| assert(! FileTest.exists?(file), "%s still exists" % file) } end def snippet_classpathtest(trans) file = "/tmp/classtest" @@tmpfiles << file assert(FileTest.exists?(file)) obj = nil assert_nothing_raised { obj = Puppet.type(:file)[file] } assert_nothing_raised { assert_equal( "//testing/component[componentname]/file=/tmp/classtest", obj.path) #Puppet.err obj.path } assert_nothing_raised { trans.rollback } assert(! FileTest.exists?(file), "%s still exists" % file) end def snippet_argumentdefaults(trans) file1 = "/tmp/argumenttest1" file2 = "/tmp/argumenttest2" @@tmpfiles << file1 @@tmpfiles << file2 assert(FileTest.exists?(file1)) assert(File.stat(file1).mode & 007777 == 0755) assert(FileTest.exists?(file2)) assert(File.stat(file2).mode & 007777 == 0644) end def snippet_casestatement(trans) files = %w{ /tmp/existsfile /tmp/existsfile2 /tmp/existsfile3 /tmp/existsfile4 /tmp/existsfile5 } files.each { |file| assert(FileTest.exists?(file), "File %s is missing" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } assert_nothing_raised { trans.rollback } end def snippet_implicititeration(trans) files = %w{a b c d e f g h}.collect { |l| "/tmp/iteration%stest" % l } files.each { |file| @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } assert_nothing_raised { trans.rollback } files.each { |file| assert(! FileTest.exists?(file), "file %s still exists" % file) } end def snippet_multipleinstances(trans) files = %w{a b c}.collect { |l| "/tmp/multipleinstances%s" % l } files.each { |file| @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } assert_nothing_raised { trans.rollback } files.each { |file| assert(! FileTest.exists?(file), "file %s still exists" % file) } end def snippet_namevartest(trans) file = "/tmp/testfiletest" dir = "/tmp/testdirtest" @@tmpfiles << file @@tmpfiles << dir assert(FileTest.file?(file), "File %s does not exist" % file) assert(FileTest.directory?(dir), "Directory %s does not exist" % dir) end def snippet_scopetest(trans) file = "/tmp/scopetest" @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) end def snippet_failmissingexecpath(trans) file = "/tmp/exectesting1" execfile = "/tmp/execdisttesting" @@tmpfiles << file @@tmpfiles << execfile assert(!FileTest.exists?(execfile), "File %s exists" % execfile) end def snippet_selectorvalues(trans) nums = %w{1 2 3 4 5} files = nums.collect { |n| "/tmp/selectorvalues%s" % n } files.each { |f| @@tmpfiles << f assert(FileTest.exists?(f), "File %s does not exist" % f) assert(File.stat(f).mode & 007777 == 0755, "File %s is not 755" % f) } end def snippet_singleselector(trans) nums = %w{1 2 3} files = nums.collect { |n| "/tmp/singleselector%s" % n } files.each { |f| @@tmpfiles << f assert(FileTest.exists?(f), "File %s does not exist" % f) assert(File.stat(f).mode & 007777 == 0755, "File %s is not 755" % f) } end def snippet_falsevalues(trans) file = "/tmp/falsevaluesfalse" @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) end def disabled_snippet_classargtest(trans) [1,2].each { |num| file = "/tmp/classargtest%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end def snippet_classheirarchy(trans) [1,2,3].each { |num| file = "/tmp/classheir%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end def snippet_singleary(trans) [1,2,3,4].each { |num| file = "/tmp/singleary%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) } end def snippet_classincludes(trans) [1,2,3].each { |num| file = "/tmp/classincludes%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end def snippet_componentmetaparams(trans) ["/tmp/component1", "/tmp/component2"].each { |file| assert(FileTest.file?(file), "File %s does not exist" % file) } end def snippet_aliastest(trans) %w{/tmp/aliastest /tmp/aliastest2 /tmp/aliastest3}.each { |file| assert(FileTest.file?(file), "File %s does not exist" % file) } end def snippet_singlequote(trans) { 1 => 'a $quote', 2 => 'some "\yayness\"' }.each { |count, str| path = "/tmp/singlequote%s" % count assert(FileTest.exists?(path), "File %s is missing" % path) text = File.read(path) assert_equal(str, text) } end # There's no way to actually retrieve the list of classes from the # transaction. def snippet_tag(trans) @@tmpfiles << "/tmp/settestingness" end # Make sure that set tags are correctly in place, yo. def snippet_tagged(trans) tags = {"testing" => true, "yayness" => false, "both" => false, "bothtrue" => true, "define" => true} tags.each do |tag, retval| @@tmpfiles << "/tmp/tagged#{tag}true" @@tmpfiles << "/tmp/tagged#{tag}false" assert(FileTest.exists?("/tmp/tagged#{tag}#{retval.to_s}"), "'tagged' did not return %s with %s" % [retval, tag]) end end def snippet_defineoverrides(trans) file = "/tmp/defineoverrides1" assert(FileTest.exists?(file), "File does not exist") assert_equal(0755, filemode(file)) end def snippet_deepclassheirarchy(trans) 5.times { |i| i += 1 file = "/tmp/deepclassheir%s" % i assert(FileTest.exists?(file), "File %s does not exist" % file) } end def snippet_emptyclass(trans) # There's nothing to check other than that it works end def snippet_emptyexec(trans) assert(FileTest.exists?("/tmp/emptyexectest"), "Empty exec was ignored") @@tmpfiles << "/tmp/emptyexextest" end def disabled_snippet_dirchmod(trans) dirs = %w{a b}.collect { |letter| "/tmp/dirchmodtest%s" % letter } @@tmpfiles << dirs dirs.each { |dir| assert(FileTest.directory?(dir)) } assert(File.stat("/tmp/dirchmodtesta").mode & 007777 == 0755) assert(File.stat("/tmp/dirchmodtestb").mode & 007777 == 0700) assert_nothing_raised { trans.rollback } end - # XXX this is the answer - Dir.entries($snippetbase).sort.each { |file| + # Iterate across each of the snippets and create a test. + Dir.entries(snippetdir).sort.each { |file| next if file =~ /^\./ mname = "snippet_" + file.sub(/\.pp$/, '') if self.method_defined?(mname) #eval("alias %s %s" % [testname, mname]) testname = ("test_" + mname).intern self.send(:define_method, testname) { # first parse the file server = Puppet::Server::Master.new( - :Manifest => File.join($snippetbase, file), + :Manifest => snippet(file), :Local => true ) client = Puppet::Client::MasterClient.new( :Master => server, :Cache => false ) assert(client.local) assert_nothing_raised { client.getconfig() } client = Puppet::Client::MasterClient.new( :Master => server, :Cache => false ) assert(client.local) # Now do it again Puppet::Type.allclear assert_nothing_raised { client.getconfig() } trans = nil assert_nothing_raised { trans = client.apply() } Puppet::Type.eachtype { |type| type.each { |obj| # don't worry about this for now #unless obj.name == "puppet[top]" or # obj.is_a?(Puppet.type(:schedule)) # assert(obj.parent, "%s has no parent" % obj.name) #end assert(obj.name) if obj.is_a?(Puppet.type(:file)) @@tmpfiles << obj[:path] end } } assert_nothing_raised { self.send(mname, trans) } client.clear } mname = mname.intern end } end + +# $Id$ diff --git a/test/language/transportable.rb b/test/language/transportable.rb index c973583cd..217bb3370 100755 --- a/test/language/transportable.rb +++ b/test/language/transportable.rb @@ -1,111 +1,104 @@ #!/usr/bin/ruby -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/transportable' -require 'test/unit' require 'puppettest' require 'yaml' class TestTransportable < Test::Unit::TestCase - include ParserTesting + include PuppetTest::ParserTesting def test_yamldumpobject obj = mk_transobject obj.to_yaml_properties str = nil assert_nothing_raised { str = YAML.dump(obj) } newobj = nil assert_nothing_raised { newobj = YAML.load(str) } assert(newobj.name, "Object has no name") assert(newobj.type, "Object has no type") end def test_yamldumpbucket objects = %w{/etc/passwd /etc /tmp /var /dev}.collect { |d| mk_transobject(d) } bucket = mk_transbucket(*objects) str = nil assert_nothing_raised { str = YAML.dump(bucket) } newobj = nil assert_nothing_raised { newobj = YAML.load(str) } assert(newobj.name, "Bucket has no name") assert(newobj.type, "Bucket has no type") end # Verify that we correctly strip out collectable objects, since they should # not be sent to the client. def test_collectstrip top = mk_transtree do |object, depth, width| if width % 2 == 1 object.collectable = true end end assert(top.flatten.find_all { |o| o.collectable }.length > 0, "Could not find any collectable objects") # Now strip out the collectable objects top.collectstrip! # And make sure they're actually gone assert_equal(0, top.flatten.find_all { |o| o.collectable }.length, "Still found collectable objects") end # Make sure our 'delve' command is working def test_delve top = mk_transtree do |object, depth, width| if width % 2 == 1 object.collectable = true end end objects = [] buckets = [] collectable = [] count = 0 assert_nothing_raised { top.delve do |object| count += 1 if object.is_a? Puppet::TransBucket buckets << object else objects << object if object.collectable collectable << object end end end } top.flatten.each do |obj| assert(objects.include?(obj), "Missing obj %s[%s]" % [obj.type, obj.name]) end assert_equal(collectable.length, top.flatten.find_all { |o| o.collectable }.length, "Found incorrect number of collectable objects") end end # $Id$ diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb index b08cfcfd9..bff410060 100644 --- a/test/lib/puppettest.rb +++ b/test/lib/puppettest.rb @@ -1,139 +1,199 @@ -require 'puppettest/support/helpers' +require 'puppet' +require 'test/unit' module PuppetTest - include PuppetTest::Support::Helpers + # Find the root of the Puppet tree; this is not the test directory, but + # the parent of that dir. + def basedir + unless defined? @@basedir + case $0 + when /rake_test_loader/ + @@basedir = File.dirname(Dir.getwd) + else + dir = nil + if /^#{File::SEPARATOR}.+\.rb/ + dir = $0 + else + dir = File.join(Dir.getwd, $0) + end + 3.times { dir = File.dirname(dir) } + @@basedir = dir + end + end + @@basedir + end def cleanup(&block) @@cleaners << block end + def datadir + File.join(basedir, "test", "data") + end + + def exampledir(*args) + unless defined? @@exampledir + @@exampledir = File.join(basedir, "examples") + end + + if args.empty? + return @@exampledir + else + return File.join(@@exampledir, *args) + end + end + + module_function :basedir, :datadir, :exampledir + + def rake? + $0 =~ /rake_test_loader/ + end + def setup @memoryatstart = Puppet::Util.memory if defined? @@testcount @@testcount += 1 else @@testcount = 0 end @configpath = File.join(tmpdir, self.class.to_s + "configdir" + @@testcount.to_s + "/" ) unless defined? $user and $group $user = nonrootuser().uid.to_s $group = nonrootgroup().gid.to_s end Puppet[:user] = $user Puppet[:group] = $group Puppet[:confdir] = @configpath Puppet[:vardir] = @configpath unless File.exists?(@configpath) Dir.mkdir(@configpath) end @@tmpfiles = [@configpath, tmpdir()] @@tmppids = [] @@cleaners = [] - if $0 =~ /.+\.rb/ or Puppet[:debug] + # If we're running under rake, then disable debugging and such. + if rake? and ! Puppet[:debug] + Puppet::Log.close + Puppet::Log.newdestination tempfile() + Puppet[:httplog] = tempfile() + else Puppet::Log.newdestination :console Puppet::Log.level = :debug #$VERBOSE = 1 Puppet.info @method_name - else - Puppet::Log.close - Puppet::Log.newdestination tempfile() - Puppet[:httplog] = tempfile() end + #if $0 =~ /.+\.rb/ or Puppet[:debug] + # Puppet::Log.newdestination :console + # Puppet::Log.level = :debug + # #$VERBOSE = 1 + # Puppet.info @method_name + #else + # Puppet::Log.close + # Puppet::Log.newdestination tempfile() + # Puppet[:httplog] = tempfile() + #end Puppet[:ignoreschedules] = true end def tempfile if defined? @@tmpfilenum @@tmpfilenum += 1 else @@tmpfilenum = 1 end f = File.join(self.tmpdir(), self.class.to_s + "_" + @method_name + @@tmpfilenum.to_s) @@tmpfiles << f return f end def tstdir dir = tempfile() Dir.mkdir(dir) return dir end def tmpdir unless defined? @tmpdir and @tmpdir @tmpdir = case Facter["operatingsystem"].value when "Darwin": "/private/tmp" when "SunOS": "/var/tmp" else "/tmp" end @tmpdir = File.join(@tmpdir, "puppettesting") unless File.exists?(@tmpdir) FileUtils.mkdir_p(@tmpdir) File.chmod(01777, @tmpdir) end end @tmpdir end def teardown stopservices @@cleaners.each { |cleaner| cleaner.call() } @@tmpfiles.each { |file| if FileTest.exists?(file) system("chmod -R 755 %s" % file) system("rm -rf %s" % file) end } @@tmpfiles.clear @@tmppids.each { |pid| %x{kill -INT #{pid} 2>/dev/null} } @@tmppids.clear Puppet::Type.allclear Puppet::Storage.clear Puppet::Rails.clear Puppet.clear @memoryatend = Puppet::Util.memory diff = @memoryatend - @memoryatstart if diff > 1000 Puppet.info "%s#%s memory growth (%s to %s): %s" % [self.class, @method_name, @memoryatstart, @memoryatend, diff] end # reset all of the logs Puppet::Log.close # Just in case there are processes waiting to die... Process.waitall if File.stat("/dev/null").mode & 007777 != 0666 File.open("/tmp/nullfailure", "w") { |f| f.puts self.class } exit(74) end end end +require 'puppettest/support' +require 'puppettest/filetesting' +require 'puppettest/fakes' +require 'puppettest/exetest' +require 'puppettest/parsertesting' +require 'puppettest/servertest' + # $Id$ diff --git a/test/lib/puppettest/exetest.rb b/test/lib/puppettest/exetest.rb index 2d2a68db1..5f155b47f 100644 --- a/test/lib/puppettest/exetest.rb +++ b/test/lib/puppettest/exetest.rb @@ -1,122 +1,122 @@ -require 'servertest' +require 'puppettest/servertest' module PuppetTest::ExeTest include PuppetTest::ServerTest def setup super setbindir setlibdir end def bindir - File.join($puppetbase, "bin") + File.join(basedir, "bin") end def setbindir unless ENV["PATH"].split(":").include?(bindir) ENV["PATH"] = [bindir, ENV["PATH"]].join(":") end end def setlibdir ENV["RUBYLIB"] = $:.find_all { |dir| dir =~ /puppet/ or dir =~ /\.\./ }.join(":") end # Run a ruby command. This explicitly uses ruby to run stuff, since we # don't necessarily know where our ruby binary is, dernit. # Currently unused, because I couldn't get it to work. def rundaemon(*cmd) @ruby ||= %x{which ruby}.chomp cmd = cmd.unshift(@ruby).join(" ") out = nil Dir.chdir(bindir()) { out = %x{#{@ruby} #{cmd}} } return out end def startmasterd(args = "") output = nil manifest = mktestmanifest() args += " --manifest %s" % manifest args += " --confdir %s" % Puppet[:confdir] args += " --vardir %s" % Puppet[:vardir] args += " --masterport %s" % @@port args += " --user %s" % Process.uid args += " --group %s" % Process.gid args += " --nonodes" args += " --autosign true" #if Puppet[:debug] # args += " --debug" #end cmd = "puppetmasterd %s" % args assert_nothing_raised { output = %x{#{cmd}}.chomp } assert_equal("", output, "Puppetmasterd produced output %s" % output) assert($? == 0, "Puppetmasterd exit status was %s" % $?) sleep(1) cleanup do stopmasterd sleep(1) end return manifest end def stopmasterd(running = true) ps = Facter["ps"].value || "ps -ef" pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid") pid = nil if FileTest.exists?(pidfile) pid = File.read(pidfile).chomp.to_i File.unlink(pidfile) end return unless running if running or pid runningpid = nil %x{#{ps}}.chomp.split(/\n/).each { |line| if line =~ /ruby.+puppetmasterd/ next if line =~ /\.rb/ # skip the test script itself next if line =~ /^puppet/ # skip masters running as 'puppet' ary = line.sub(/^\s+/, '').split(/\s+/) pid = ary[1].to_i end } end # we default to mandating that it's running, but teardown # doesn't require that if pid if pid == $$ raise Puppet::Error, "Tried to kill own pid" end begin Process.kill(:INT, pid) rescue # ignore it end end end def teardown stopmasterd(false) super end end # $Id$ diff --git a/test/lib/puppettest/fakes.rb b/test/lib/puppettest/fakes.rb index 42ba0c6af..0d27faf1f 100644 --- a/test/lib/puppettest/fakes.rb +++ b/test/lib/puppettest/fakes.rb @@ -1,146 +1,148 @@ -module PuppetTest::Fakes +require 'puppettest' + +module PuppetTest # A baseclass for the faketypes. class FakeModel class << self attr_accessor :name @name = :fakemodel end def self.validstates Puppet::Type.type(@name).validstates end def self.validstate?(name) Puppet::Type.type(@name).validstate?(name) end def self.to_s "Fake%s" % @name.to_s.capitalize end def [](param) if @realmodel.attrtype(param) == :state @is[param] else @params[param] end end def []=(param, value) unless @realmodel.attrtype(param) raise Puppet::DevError, "Invalid attribute %s for %s" % [param, @realmodel.name] end if @realmodel.attrtype(param) == :state @should[param] = value else @params[param] = value end end def initialize(name) @realmodel = Puppet::Type.type(self.class.name) raise "Could not find type #{self.class.name}" unless @realmodel @is = {} @should = {} @params = {} self[:name] = name end def inspect "%s(%s)" % [self.class.to_s.sub(/.+::/, ''), super()] end def is(param) @is[param] end def should(param) @should[param] end def name self[:name] end end class FakeProvider attr_accessor :model class << self attr_accessor :name, :model, :methods end # A very low number, so these never show up as defaults via the standard # algorithms. def self.defaultnum -50 end # Set up methods to fake things def self.apimethods(*ary) @model.validstates.each do |state| ary << state unless ary.include? state end attr_accessor(*ary) @methods = ary end def self.default? false end def self.initvars @calls = Hash.new do |hash, key| hash[key] = 0 end end def self.suitable? true end def clear @model = nil end def initialize(model) @model = model end end @@fakemodels = {} @@fakeproviders = {} def fakemodel(type, name, options = {}) type = type.intern if type.is_a? String unless @@fakemodels.include? type @@fakemodels[type] = Class.new(FakeModel) @@fakemodels[type].name = type end obj = @@fakemodels[type].new(name) obj[:name] = name options.each do |name, val| obj[name] = val end obj end module_function :fakemodel def fakeprovider(type, model) type = type.intern if type.is_a? String unless @@fakeproviders.include? type @@fakeproviders[type] = Class.new(FakeModel) do @name = type end end @@fakeproviders[type].new(model) end module_function :fakeprovider end # $Id$ diff --git a/test/lib/puppettest/support/file.rb b/test/lib/puppettest/filetesting.rb similarity index 98% rename from test/lib/puppettest/support/file.rb rename to test/lib/puppettest/filetesting.rb index d2810d4e0..43a2ae1a0 100644 --- a/test/lib/puppettest/support/file.rb +++ b/test/lib/puppettest/filetesting.rb @@ -1,228 +1,231 @@ -module PuppetTest::Support::File +require 'puppettest' + +module PuppetTest::FileTesting + include PuppetTest def cycle(comp) trans = nil assert_nothing_raised { trans = comp.evaluate } assert_nothing_raised { trans.evaluate } end def randlist(list) num = rand(4) if num == 0 num = 1 end set = [] ret = [] num.times { |index| item = list[rand(list.length)] if set.include?(item) redo end ret.push item } return ret end def mkranddirsandfiles(dirs = nil,files = nil,depth = 3) if depth < 0 return end unless dirs dirs = %w{This Is A Set Of Directories} end unless files files = %w{and this is a set of files} end tfiles = randlist(files) tdirs = randlist(dirs) tfiles.each { |file| File.open(file, "w") { |of| 4.times { of.puts rand(100) } } } tdirs.each { |dir| # it shouldn't already exist, but... unless FileTest.exists?(dir) Dir.mkdir(dir) FileUtils.cd(dir) { mkranddirsandfiles(dirs,files,depth - 1) } end } end def file_list(dir) list = nil FileUtils.cd(dir) { list = %x{find . 2>/dev/null}.chomp.split(/\n/) } return list end def assert_trees_equal(fromdir,todir) assert(FileTest.directory?(fromdir)) assert(FileTest.directory?(todir)) # verify the file list is the same fromlist = nil FileUtils.cd(fromdir) { fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file| ! FileTest.readable?(file) }.sort } tolist = file_list(todir).sort fromlist.sort.zip(tolist.sort).each { |a,b| assert_equal(a, b, "Fromfile %s with length %s does not match tofile %s with length %s" % [a, fromlist.length, b, tolist.length]) } #assert_equal(fromlist,tolist) # and then do some verification that the files are actually set up # the same checked = 0 fromlist.each_with_index { |file,i| fromfile = File.join(fromdir,file) tofile = File.join(todir,file) fromstat = File.stat(fromfile) tostat = File.stat(tofile) [:ftype,:gid,:mode,:uid].each { |method| assert_equal( fromstat.send(method), tostat.send(method) ) next if fromstat.ftype == "directory" if checked < 10 and i % 3 == 0 from = File.open(fromfile) { |f| f.read } to = File.open(tofile) { |f| f.read } assert_equal(from,to) checked += 1 end } } end def random_files(dir) checked = 0 list = file_list(dir) list.reverse.each_with_index { |file,i| path = File.join(dir,file) stat = File.stat(dir) if checked < 10 and (i % 3) == 2 unless yield path next end checked += 1 end } end def delete_random_files(dir) deleted = [] random_files(dir) { |file| stat = File.stat(file) begin if stat.ftype == "directory" false else deleted << file File.unlink(file) true end rescue => detail # we probably won't be able to open our own secured files puts detail false end } return deleted end def add_random_files(dir) added = [] random_files(dir) { |file| stat = File.stat(file) begin if stat.ftype == "directory" name = File.join(file,"file" + rand(100).to_s) File.open(name, "w") { |f| f.puts rand(10) } added << name else false end rescue => detail # we probably won't be able to open our own secured files puts detail false end } return added end def modify_random_files(dir) modded = [] random_files(dir) { |file| stat = File.stat(file) begin if stat.ftype == "directory" false else File.open(file, "w") { |f| f.puts rand(10) } modded << name true end rescue => detail # we probably won't be able to open our own secured files puts detail false end } return modded end def readonly_random_files(dir) modded = [] random_files(dir) { |file| stat = File.stat(file) begin if stat.ftype == "directory" File.new(file).chmod(0111) else File.new(file).chmod(0000) end modded << file rescue => detail # we probably won't be able to open our own secured files puts detail false end } return modded end def conffile - File.join($puppetbase,"examples/root/etc/configfile") + exampledir("root/etc/configfile") end end # $Id$ diff --git a/test/lib/puppettest/support/parser.rb b/test/lib/puppettest/parsertesting.rb similarity index 99% rename from test/lib/puppettest/support/parser.rb rename to test/lib/puppettest/parsertesting.rb index c4db871a5..e0606c501 100644 --- a/test/lib/puppettest/support/parser.rb +++ b/test/lib/puppettest/parsertesting.rb @@ -1,344 +1,347 @@ -module PuppetTest::Support::Parser +require 'puppettest' + +module PuppetTest::ParserTesting + include PuppetTest AST = Puppet::Parser::AST def astarray(*args) AST::ASTArray.new( :children => args ) end def classobj(name, args = {}) args[:type] ||= nameobj(name) args[:code] ||= AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => [ varobj("%svar" % name, "%svalue" % name), fileobj("/%s" % name) ] ) assert_nothing_raised("Could not create class %s" % name) { return AST::ClassDef.new(args) } end def tagobj(*names) args = {} newnames = names.collect do |name| if name.is_a? AST name else nameobj(name) end end args[:type] = astarray(*newnames) assert_nothing_raised("Could not create tag %s" % names.inspect) { return AST::Tag.new(args) } end def compobj(name, args = {}) args[:file] ||= tempfile() args[:line] ||= rand(100) args[:type] ||= nameobj(name) args[:args] ||= AST::ASTArray.new( :file => tempfile(), :line => rand(100), :children => [] ) args[:code] ||= AST::ASTArray.new( :file => tempfile(), :line => rand(100), :children => [ varobj("%svar" % name, "%svalue" % name), fileobj("/%s" % name) ] ) assert_nothing_raised("Could not create compdef %s" % name) { return AST::CompDef.new(args) } end def objectdef(type, name, params) assert_nothing_raised("Could not create %s %s" % [type, name]) { return AST::ObjectDef.new( :file => __FILE__, :line => __LINE__, :name => stringobj(name), :type => nameobj(type), :params => objectinst(params) ) } end def fileobj(path, hash = {"owner" => "root"}) assert_nothing_raised("Could not create file %s" % path) { return objectdef("file", path, hash) # return AST::ObjectDef.new( # :file => tempfile(), # :line => rand(100), # :name => stringobj(path), # :type => nameobj("file"), # :params => objectinst(hash) # ) } end def nameobj(name) assert_nothing_raised("Could not create name %s" % name) { return AST::Name.new( :file => tempfile(), :line => rand(100), :value => name ) } end def typeobj(name) assert_nothing_raised("Could not create type %s" % name) { return AST::Type.new( :file => tempfile(), :line => rand(100), :value => name ) } end def nodedef(name) assert_nothing_raised("Could not create node %s" % name) { return AST::NodeDef.new( :file => tempfile(), :line => rand(100), :names => nameobj(name), :code => AST::ASTArray.new( :children => [ varobj("%svar" % name, "%svalue" % name), fileobj("/%s" % name) ] ) ) } end def objectinst(hash) assert_nothing_raised("Could not create object instance") { params = hash.collect { |param, value| objectparam(param, value) } return AST::ObjectInst.new( :file => tempfile(), :line => rand(100), :children => params ) } end def objectparam(param, value) # Allow them to pass non-strings in if value.is_a?(String) value = stringobj(value) end assert_nothing_raised("Could not create param %s" % param) { return AST::ObjectParam.new( :file => tempfile(), :line => rand(100), :param => nameobj(param), :value => value ) } end def stringobj(value) AST::String.new( :file => tempfile(), :line => rand(100), :value => value ) end def varobj(name, value) unless value.is_a? AST value = stringobj(value) end assert_nothing_raised("Could not create %s code" % name) { return AST::VarDef.new( :file => tempfile(), :line => rand(100), :name => nameobj(name), :value => value ) } end def varref(name) assert_nothing_raised("Could not create %s variable" % name) { return AST::Variable.new( :file => __FILE__, :line => __LINE__, :value => name ) } end def argobj(name, value) assert_nothing_raised("Could not create %s compargument" % name) { return AST::CompArgument.new( :children => [nameobj(name), stringobj(value)] ) } end def defaultobj(type, params) pary = [] params.each { |p,v| pary << AST::ObjectParam.new( :file => __FILE__, :line => __LINE__, :param => nameobj(p), :value => stringobj(v) ) } past = AST::ASTArray.new( :file => __FILE__, :line => __LINE__, :children => pary ) assert_nothing_raised("Could not create defaults for %s" % type) { return AST::TypeDefaults.new( :file => __FILE__, :line => __LINE__, :type => typeobj(type), :params => past ) } end def taggedobj(name, ftype = :statement) functionobj("tagged", name, ftype) end def functionobj(function, name, ftype = :statement) func = nil assert_nothing_raised do func = Puppet::Parser::AST::Function.new( :name => function, :ftype => ftype, :arguments => AST::ASTArray.new( :children => [nameobj(name)] ) ) end return func end # This assumes no nodes def assert_creates(manifest, *files) interp = nil assert_nothing_raised { interp = Puppet::Parser::Interpreter.new( :Manifest => manifest, :UseNodes => false ) } config = nil assert_nothing_raised { config = interp.run(Facter["hostname"].value, {}) } comp = nil assert_nothing_raised { comp = config.to_type } assert_apply(comp) files.each do |file| assert(FileTest.exists?(file), "Did not create %s" % file) end end def mk_transobject(file = "/etc/passwd") obj = nil assert_nothing_raised { obj = Puppet::TransObject.new("file", file) obj["owner"] = "root" obj["mode"] = "644" } return obj end def mk_transbucket(*objects) bucket = nil assert_nothing_raised { bucket = Puppet::TransBucket.new bucket.name = "yayname" bucket.type = "yaytype" } objects.each { |o| bucket << o } return bucket end # Make a tree of objects, yielding if desired def mk_transtree(depth = 4, width = 2) top = nil assert_nothing_raised { top = Puppet::TransBucket.new top.name = "top" top.type = "bucket" } bucket = top file = tempfile() depth.times do |i| objects = [] width.times do |j| path = tempfile + i.to_s obj = Puppet::TransObject.new("file", path) obj["owner"] = "root" obj["mode"] = "644" # Yield, if they want if block_given? yield(obj, i, j) end objects << obj end newbucket = mk_transbucket(*objects) bucket.push newbucket bucket = newbucket end return top end # Take a list of AST objects, evaluate them, and return the results def assert_evaluate(children) top = nil assert_nothing_raised("Could not create top object") { top = AST::ASTArray.new( :children => children ) } trans = nil scope = nil assert_nothing_raised { scope = Puppet::Parser::Scope.new() trans = scope.evaluate(:ast => top) } return trans end end # $Id$ diff --git a/test/lib/puppettest/servertest.rb b/test/lib/puppettest/servertest.rb index 528b1a0d7..532256d74 100644 --- a/test/lib/puppettest/servertest.rb +++ b/test/lib/puppettest/servertest.rb @@ -1,70 +1,70 @@ -require 'scaffold' +require 'puppettest' module PuppetTest::ServerTest include PuppetTest def setup super if defined? @@port @@port += 1 else @@port = 20000 end end # create a simple manifest that just creates a file def mktestmanifest file = File.join(Puppet[:confdir], "%ssite.pp" % (self.class.to_s + "test")) #@createdfile = File.join(tmpdir(), self.class.to_s + "manifesttesting" + # "_" + @method_name) @createdfile = tempfile() File.open(file, "w") { |f| f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile } @@tmpfiles << @createdfile @@tmpfiles << file return file end # create a server, forked into the background def mkserver(handlers = nil) # our default handlers unless handlers handlers = { :CA => {}, # so that certs autogenerate :Master => { :Manifest => mktestmanifest(), :UseNodes => false }, } end # then create the actual server server = nil assert_nothing_raised { server = Puppet::Server.new( :Port => @@port, :Handlers => handlers ) } # fork it spid = fork { trap(:INT) { server.shutdown } server.start } # and store its pid for killing @@tmppids << spid # give the server a chance to do its thing sleep 1 return spid end end # $Id$ diff --git a/test/lib/puppettest/support.rb b/test/lib/puppettest/support.rb index 54b19ba7f..c81b5cd9d 100644 --- a/test/lib/puppettest/support.rb +++ b/test/lib/puppettest/support.rb @@ -1,8 +1,8 @@ +require 'puppettest' + module PuppetTest::Support end -require 'support/assertions' -require 'support/file' -require 'support/helpers' -require 'support/parser' -require 'support/utils' +require 'puppettest/support/assertions' +require 'puppettest/support/helpers' +require 'puppettest/support/utils' diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb index 63ce0cccb..0e272002e 100644 --- a/test/lib/puppettest/support/assertions.rb +++ b/test/lib/puppettest/support/assertions.rb @@ -1,65 +1,67 @@ -module PuppetTest::Support::Assertions +require 'puppettest' + +module PuppetTest def assert_rollback_events(events, trans, msg = nil) run_events(:rollback, events, trans, msg) end def assert_events(events, *items) trans = nil comp = nil msg = nil unless events.is_a? Array raise Puppet::DevError, "Incorrect call of assert_events" end if items[-1].is_a? String msg = items.pop end remove_comp = false # They either passed a comp or a list of items. if items[0].is_a? Puppet.type(:component) comp = items.shift else comp = newcomp(items[0].title, *items) remove_comp = true end msg ||= comp.title assert_nothing_raised("Component %s failed" % [msg]) { trans = comp.evaluate } run_events(:evaluate, trans, events, msg) if remove_comp Puppet.type(:component).delete(comp) end return trans end # A simpler method that just applies what we have. def assert_apply(*objects) if objects[0].is_a?(Puppet.type(:component)) comp = objects.shift unless objects.empty? objects.each { |o| comp.push o } end else comp = newcomp(*objects) end trans = nil assert_nothing_raised("Failed to create transaction") { trans = comp.evaluate } events = nil assert_nothing_raised("Failed to evaluate transaction") { events = trans.evaluate.collect { |e| e.event } } Puppet.type(:component).delete(comp) events end end # $Id$ diff --git a/test/lib/puppettest/support/helpers.rb b/test/lib/puppettest/support/helpers.rb index 41974d331..7fae994d9 100644 --- a/test/lib/puppettest/support/helpers.rb +++ b/test/lib/puppettest/support/helpers.rb @@ -1,19 +1,21 @@ -module PuppetTest::Support::Helpers +require 'puppettest' + +module PuppetTest def nonrootuser Etc.passwd { |user| if user.uid != Process.uid and user.uid > 0 return user end } end def nonrootgroup Etc.group { |group| if group.gid != Process.gid and group.gid > 0 return group end } end end # $Id$ diff --git a/test/lib/puppettest/support/utils.rb b/test/lib/puppettest/support/utils.rb index 1b22e8d6e..00ea1a1c9 100644 --- a/test/lib/puppettest/support/utils.rb +++ b/test/lib/puppettest/support/utils.rb @@ -1,145 +1,147 @@ -module PuppetTest::Support::Utils +require 'puppettest' + +module PuppetTest def gcdebug(type) Puppet.warning "%s: %s" % [type, ObjectSpace.each_object(type) { |o| }] end # # TODO: I think this method needs to be renamed to something a little more # explanatory. # def newobj(type, name, hash) transport = Puppet::TransObject.new(name, "file") transport[:path] = path transport[:ensure] = "file" assert_nothing_raised { file = transport.to_type } - end + end # stop any services that might be hanging around def stopservices if stype = Puppet::Type.type(:service) stype.each { |service| service[:ensure] = :stopped service.evaluate } - end + end end # TODO: rewrite this to use the 'etc' module. def setme # retrieve the user name id = %x{id}.chomp if id =~ /uid=\d+\(([^\)]+)\)/ @me = $1 else puts id end unless defined? @me raise "Could not retrieve user name; 'id' did not work" end end def run_events(type, trans, events, msg) case type when :evaluate, :rollback: # things are hunky-dory else raise Puppet::DevError, "Incorrect run_events type" end method = type newevents = nil assert_nothing_raised("Transaction %s %s failed" % [type, msg]) { newevents = trans.send(method).reject { |e| e.nil? }.collect { |e| e.event } } assert_equal(events, newevents, "Incorrect %s %s events" % [type, msg]) return trans end # If there are any fake data files, retrieve them def fakedata(dir) - ary = [$puppetbase, "test"] + ary = [basedir, "test"] ary += dir.split("/") dir = File.join(ary) unless FileTest.exists?(dir) raise Puppet::DevError, "No fakedata dir %s" % dir end files = Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) } return files end def fakefile(name) - ary = [$puppetbase, "test"] + ary = [basedir, "test"] ary += name.split("/") file = File.join(ary) unless FileTest.exists?(file) raise Puppet::DevError, "No fakedata file %s" % file end return file end # wrap how to retrieve the masked mode def filemode(file) File.stat(file).mode & 007777 end def memory Puppet::Util.memory end # a list of files that we can parse for testing def textfiles - textdir = File.join($puppetbase,"examples","code", "snippets") + textdir = File.join(exampledir,"code", "snippets") Dir.entries(textdir).reject { |f| f =~ /^\./ or f =~ /fail/ }.each { |f| yield File.join(textdir, f) } end def failers - textdir = File.join($puppetbase,"examples","code", "failers") + textdir = File.join(exampledir,"code", "failers") # only parse this one file now files = Dir.entries(textdir).reject { |file| file =~ %r{\.swp} }.reject { |file| file =~ %r{\.disabled} }.collect { |file| File.join(textdir,file) }.find_all { |file| FileTest.file?(file) }.sort.each { |file| Puppet.debug "Processing %s" % file yield file } end def newcomp(*ary) name = nil if ary[0].is_a?(String) name = ary.shift else name = ary[0].title end comp = Puppet.type(:component).create(:name => name) ary.each { |item| comp.push item } return comp end end # $Id$ diff --git a/test/other/autoload.rb b/test/other/autoload.rb index 95fafbda2..7cbb11c1a 100644 --- a/test/other/autoload.rb +++ b/test/other/autoload.rb @@ -1,111 +1,104 @@ #!/usr/bin/env ruby -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/autoload' require 'puppettest' -require 'test/unit' class TestAutoload < Test::Unit::TestCase - include TestPuppet + include PuppetTest @things = [] def self.newthing(name) @things << name end def self.thing?(name) @things.include? name end def self.clear @things.clear end def mkfile(name, path) # Now create a file to load File.open(path, "w") do |f| f.puts %{ TestAutoload.newthing(:#{name.to_s}) } end end def teardown super self.class.clear end def test_load dir = tempfile() $: << dir cleanup do $:.delete(dir) end Dir.mkdir(dir) rbdir = File.join(dir, "yayness") Dir.mkdir(rbdir) # An object for specifying autoload klass = self.class loader = nil assert_nothing_raised { loader = Puppet::Autoload.new(klass, :yayness) } assert_equal(loader.object_id, Puppet::Autoload[klass].object_id, "Did not retrieve loader object by class") # Make sure we don't fail on missing files assert_nothing_raised { assert_equal(false, loader.load(:mything), "got incorrect return on failed load") } # Now create a couple of files for testing path = File.join(rbdir, "mything.rb") mkfile(:mything, path) opath = File.join(rbdir, "othing.rb") mkfile(:othing, opath) # Now try to actually load it. assert_nothing_raised { assert_equal(true, loader.load(:mything), "got incorrect return on failed load") } assert(loader.loaded?(:mything), "Not considered loaded") assert(klass.thing?(:mything), "Did not get loaded thing") # Now clear everything, and test loadall assert_nothing_raised { loader.clear } self.class.clear assert_nothing_raised { loader.loadall } [:mything, :othing].each do |thing| assert(loader.loaded?(thing), "#{thing.to_s} not considered loaded") assert(klass.thing?(thing), "Did not get loaded #{thing.to_s}") end end def test_loadall end end diff --git a/test/other/config.rb b/test/other/config.rb index 33dad6892..3e2c125c7 100755 --- a/test/other/config.rb +++ b/test/other/config.rb @@ -1,812 +1,805 @@ #!/usr/bin/env ruby -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/config' require 'puppettest' -require 'test/unit' class TestConfig < Test::Unit::TestCase - include TestPuppet + include PuppetTest def check_for_users count = Puppet::Type.type(:user).inject(0) { |c,o| c + 1 } assert(count > 0, "Found no users") end def check_to_transportable(config) trans = nil assert_nothing_raised("Could not convert to a transportable") { trans = config.to_transportable } comp = nil assert_nothing_raised("Could not convert transportable to component") { comp = trans.to_type } check_for_users() assert_nothing_raised("Could not retrieve transported config") { comp.retrieve } end def check_to_manifest(config) manifest = nil assert_nothing_raised("Could not convert to a manifest") { manifest = config.to_manifest } Puppet[:parseonly] = true parser = Puppet::Parser::Parser.new() objects = nil assert_nothing_raised("Could not parse generated manifest") { parser.string = manifest objects = parser.parse } scope = Puppet::Parser::Scope.new assert_nothing_raised("Could not compile objects") { scope.evaluate(:ast => objects) } trans = nil assert_nothing_raised("Could not convert objects to transportable") { trans = scope.to_trans } assert_nothing_raised("Could not instantiate objects") { trans.to_type } check_for_users() end def check_to_comp(config) comp = nil assert_nothing_raised("Could not convert to a component") { comp = config.to_component } assert_nothing_raised("Could not retrieve component") { comp.retrieve } check_for_users() end def check_to_config(config) newc = config.dup newfile = tempfile() File.open(newfile, "w") { |f| f.print config.to_config } assert_nothing_raised("Could not parse generated configuration") { newc.parse(newfile) } assert_equal(config, newc, "Configurations are not equal") end def mkconfig c = nil assert_nothing_raised { c = Puppet::Config.new } return c end def test_addbools c = mkconfig assert_nothing_raised { c.setdefaults(:testing, :booltest => [true, "testing"]) } assert(c[:booltest]) c = mkconfig assert_nothing_raised { c.setdefaults(:testing, :booltest => ["true", "testing"]) } assert(c[:booltest]) assert_nothing_raised { c[:booltest] = false } assert(! c[:booltest], "Booltest is not false") assert_nothing_raised { c[:booltest] = "false" } assert(! c[:booltest], "Booltest is not false") assert_raise(Puppet::Error) { c[:booltest] = "yayness" } assert_raise(Puppet::Error) { c[:booltest] = "/some/file" } end def test_strings c = mkconfig val = "this is a string" assert_nothing_raised { c.setdefaults(:testing, :strtest => [val, "testing"]) } assert_equal(val, c[:strtest]) # Verify that variables are interpolated assert_nothing_raised { c.setdefaults(:testing, :another => ["another $strtest", "testing"]) } assert_equal("another #{val}", c[:another]) end def test_files c = mkconfig parent = "/puppet" assert_nothing_raised { c.setdefaults(:testing, :parentdir => [parent, "booh"]) } assert_nothing_raised { c.setdefaults(:testing, :child => ["$parent/child", "rah"]) } assert_equal(parent, c[:parentdir]) assert_equal("/puppet/child", File.join(c[:parentdir], "child")) end def test_getset c = mkconfig initial = "an initial value" assert_raise(Puppet::Error) { c[:yayness] = initial } default = "this is a default" assert_nothing_raised { c.setdefaults(:testing, :yayness => [default, "rah"]) } assert_equal(default, c[:yayness]) assert_nothing_raised { c[:yayness] = initial } assert_equal(initial, c[:yayness]) assert_nothing_raised { c.clear } assert_equal(default, c[:yayness]) assert_nothing_raised { c[:yayness] = "not default" } assert_equal("not default", c[:yayness]) end def test_parse text = %{ one = this is a test two = another test owner = root group = root yay = /a/path [section1] attr = value owner = puppet group = puppet attrdir = /some/dir attr3 = $attrdir/other } file = tempfile() File.open(file, "w") { |f| f.puts text } c = mkconfig assert_nothing_raised { c.setdefaults("puppet", :one => ["a", "one"], :two => ["a", "two"], :yay => ["/default/path", "boo"], :mkusers => [true, "uh, yeah"] ) } assert_nothing_raised { c.setdefaults("section1", :attr => ["a", "one"], :attrdir => ["/another/dir", "two"], :attr3 => ["$attrdir/maybe", "boo"] ) } assert_nothing_raised { c.parse(file) } assert_equal("value", c[:attr]) assert_equal("/some/dir", c[:attrdir]) assert_equal(:directory, c.element(:attrdir).type) assert_equal("/some/dir/other", c[:attr3]) elem = nil assert_nothing_raised { elem = c.element(:attr3) } assert(elem) assert_equal("puppet", elem.owner) config = nil assert_nothing_raised { config = c.to_config } assert_nothing_raised("Could not create transportable config") { c.to_transportable } check_to_comp(c) Puppet::Type.allclear check_to_manifest(c) Puppet::Type.allclear check_to_config(c) Puppet::Type.allclear check_to_transportable(c) end def test_arghandling c = mkconfig assert_nothing_raised { c.setdefaults("testing", :onboolean => [true, "An on bool"], :offboolean => [false, "An off bool"], :string => ["a string", "A string arg"], :file => ["/path/to/file", "A file arg"] ) } data = { :onboolean => [true, false], :offboolean => [true, false], :string => ["one string", "another string"], :file => %w{/a/file /another/file} } data.each { |param, values| values.each { |val| opt = nil arg = nil if c.boolean?(param) if val opt = "--%s" % param else opt = "--no-%s" % param end else opt = "--%s" % param arg = val end assert_nothing_raised("Could not handle arg %s with value %s" % [opt, val]) { c.handlearg(opt, arg) } } } end def test_argadding c = mkconfig assert_nothing_raised { c.setdefaults("testing", :onboolean => [true, "An on bool"], :offboolean => [false, "An off bool"], :string => ["a string", "A string arg"], :file => ["/path/to/file", "A file arg"] ) } options = [] c.addargs(options) c.each { |param, obj| opt = "--%s" % param assert(options.find { |ary| ary[0] == opt }, "Argument %s was not added" % opt) if c.boolean?(param) o = "--no-%s" % param assert(options.find { |ary| ary[0] == o }, "Boolean off %s was not added" % o) end } end def test_usesection c = mkconfig dir = tempfile() file = "$mydir/myfile" realfile = File.join(dir, "myfile") otherfile = File.join(dir, "otherfile") section = "testing" assert_nothing_raised { c.setdefaults(section, :mydir => [dir, "A dir arg"], :otherfile => { :default => "$mydir/otherfile", :create => true, :desc => "A file arg" }, :myfile => [file, "A file arg"] ) } assert_nothing_raised("Could not use a section") { c.use(section) } assert_nothing_raised("Could not reuse a section") { c.use(section) } assert(FileTest.directory?(dir), "Did not create directory") assert(FileTest.exists?(otherfile), "Did not create file") assert(!FileTest.exists?(realfile), "Created file") end def test_setdefaultsarray c = mkconfig assert_nothing_raised { c.setdefaults("yay", :a => [false, "some value"], :b => ["/my/file", "a file"] ) } assert_equal(false, c[:a], "Values are not equal") assert_equal("/my/file", c[:b], "Values are not equal") end def test_setdefaultshash c = mkconfig assert_nothing_raised { c.setdefaults("yay", :a => {:default => false, :desc => "some value"}, :b => {:default => "/my/file", :desc => "a file"} ) } assert_equal(false, c[:a], "Values are not equal") assert_equal("/my/file", c[:b], "Values are not equal") end def test_reuse c = mkconfig file = tempfile() section = "testing" assert_nothing_raised { c.setdefaults(section, :myfile => {:default => file, :create => true} ) } assert_nothing_raised("Could not use a section") { c.use(section) } assert(FileTest.exists?(file), "Did not create file") assert(! Puppet::Type.type(:file)[file], "File obj still exists") File.unlink(file) c.reuse assert(FileTest.exists?(file), "Did not create file") end def test_mkusers c = mkconfig file = tempfile() section = "testing" assert_nothing_raised { c.setdefaults(section, :mkusers => [false, "yay"], :myfile => { :default => file, :owner => "pptest", :group => "pptest", :create => true } ) } comp = nil assert_nothing_raised { comp = c.to_component } [:user, :group].each do |type| # The objects might get created internally by Puppet::Util; just # make sure they're not being managed if obj = Puppet.type(type)["pptest"] assert(! obj.managed?, "%s objectis managed" % type) end end comp.each { |o| o.remove } c[:mkusers] = true assert_nothing_raised { c.to_component } assert(Puppet.type(:user)["pptest"], "User object did not get created") assert(Puppet.type(:user)["pptest"].managed?, "User object is not managed." ) assert(Puppet.type(:group)["pptest"], "Group object did not get created") assert(Puppet.type(:group)["pptest"].managed?, "Group object is not managed." ) end def test_notmanagingdev c = mkconfig path = "/dev/testing" c.setdefaults(:test, :file => { :default => path, :mode => 0640, :desc => 'yay' } ) assert_nothing_raised { c.to_component } assert(! Puppet.type(:file)["/dev/testing"], "Created dev file") end def test_groupsetting cfile = tempfile() group = "yayness" File.open(cfile, "w") do |f| f.puts "[#{Puppet.name}] group = #{group} " end config = mkconfig config.setdefaults(Puppet.name, :group => ["puppet", "a group"]) assert_nothing_raised { config.parse(cfile) } assert_equal(group, config[:group], "Group did not take") end # provide a method to modify and create files w/out specifying the info # already stored in a config def test_writingfiles path = tempfile() mode = 0644 config = mkconfig args = { :default => path, :mode => mode } user = nonrootuser() group = nonrootgroup() if Process.uid == 0 args[:owner] = user.name args[:group] = group.name end config.setdefaults(:testing, :myfile => args) assert_nothing_raised { config.write(:myfile) do |file| file.puts "yay" end } assert_equal(mode, filemode(path), "Modes are not equal") # OS X is broken in how it chgrps files if Process.uid == 0 assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal") case Facter["operatingsystem"].value when /BSD/, "Darwin": # nothing else assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal") end end end def test_mkdir path = tempfile() mode = 0755 config = mkconfig args = { :default => path, :mode => mode } user = nonrootuser() group = nonrootgroup() if Process.uid == 0 args[:owner] = user.name args[:group] = group.name end config.setdefaults(:testing, :mydir => args) assert_nothing_raised { config.mkdir(:mydir) } assert_equal(mode, filemode(path), "Modes are not equal") # OS X and *BSD is broken in how it chgrps files if Process.uid == 0 assert_equal(user.uid, File.stat(path).uid, "UIDS are not equal") case Facter["operatingsystem"].value when /BSD/, "Darwin": # nothing else assert_equal(group.gid, File.stat(path).gid, "GIDS are not equal") end end end def test_booleans_and_integers config = mkconfig config.setdefaults(:mysection, :booltest => [false, "yay"], :inttest => [14, "yay"] ) file = tempfile() File.open(file, "w") do |f| f.puts %{ [mysection] booltest = true inttest = 27 } end assert_nothing_raised { config.parse(file) } assert_equal(true, config[:booltest], "Boolean was not converted") assert_equal(27, config[:inttest], "Integer was not converted") # Now make sure that they get converted through handlearg config.handlearg("--inttest", "true") assert_equal(true, config[:inttest], "Boolean was not converted") config.handlearg("--no-booltest", "false") assert_equal(false, config[:booltest], "Boolean was not converted") end # Make sure that tags are ignored when configuring def test_configs_ignore_tags config = mkconfig file = tempfile() config.setdefaults(:mysection, :mydir => [file, "a file"] ) Puppet[:tags] = "yayness" assert_nothing_raised { config.use(:mysection) } assert(FileTest.directory?(file), "Directory did not get created") assert_equal("yayness", Puppet[:tags], "Tags got changed during config") end def test_configs_replace_in_url config = mkconfig config.setdefaults(:mysection, :name => ["yayness", "yay"]) config.setdefaults(:mysection, :url => ["http://$name/rahness", "yay"]) val = nil assert_nothing_raised { val = config[:url] } assert_equal("http://yayness/rahness", val, "Config got messed up") end def test_correct_type_assumptions config = mkconfig file = Puppet::Config::CFile element = Puppet::Config::CElement bool = Puppet::Config::CBoolean # We have to keep these ordered, unfortunately. [ ["/this/is/a/file", file], ["true", bool], [true, bool], ["false", bool], ["server", element], ["http://$server/yay", element], ["$server/yayness", file], ["$server/yayness.conf", file] ].each do |ary| value, type = ary elem = nil assert_nothing_raised { elem = config.newelement( :name => value, :default => value, :section => :yayness ) } assert_instance_of(type, elem, "%s got created as wrong type" % value.inspect) end end # Make sure we correctly reparse our config files but don't lose CLI values. def test_reparse Puppet[:filetimeout] = 0 config = mkconfig() config.setdefaults(:mysection, :default => ["default", "yay"]) config.setdefaults(:mysection, :clichange => ["clichange", "yay"]) config.setdefaults(:mysection, :filechange => ["filechange", "yay"]) file = tempfile() # Set one parameter in the file File.open(file, "w") { |f| f.puts %{[mysection]\nfilechange = filevalue} } assert_nothing_raised { config.parse(file) } # Set another "from the cli" assert_nothing_raised { config.handlearg("clichange", "clivalue") } # And leave the other unset assert_equal("default", config[:default]) assert_equal("filevalue", config[:filechange]) assert_equal("clivalue", config[:clichange]) # Now rewrite the file File.open(file, "w") { |f| f.puts %{[mysection]\nfilechange = newvalue} } cfile = config.file cfile.send("tstamp=".intern, Time.now - 50) # And check all of the values assert_equal("default", config[:default]) assert_equal("clivalue", config[:clichange]) assert_equal("newvalue", config[:filechange]) end def test_parse_removes_quotes config = mkconfig() config.setdefaults(:mysection, :singleq => ["single", "yay"]) config.setdefaults(:mysection, :doubleq => ["double", "yay"]) config.setdefaults(:mysection, :none => ["noquote", "yay"]) config.setdefaults(:mysection, :middle => ["midquote", "yay"]) file = tempfile() # Set one parameter in the file File.open(file, "w") { |f| f.puts %{[mysection]\n singleq = 'one' doubleq = "one" none = one middle = mid"quote } } assert_nothing_raised { config.parse(file) } %w{singleq doubleq none}.each do |p| assert_equal("one", config[p], "%s did not match" % p) end assert_equal('mid"quote', config["middle"], "middle did not match") end def test_timer Puppet[:filetimeout] = 0.1 origpath = tempfile() config = mkconfig() config.setdefaults(:mysection, :paramdir => [tempfile(), "yay"]) file = tempfile() # Set one parameter in the file File.open(file, "w") { |f| f.puts %{[mysection]\n paramdir = #{origpath} } } assert_nothing_raised { config.parse(file) config.use(:mysection) } assert(FileTest.directory?(origpath), "dir did not get created") # Now start the timer assert_nothing_raised { EventLoop.current.monitor_timer config.timer } newpath = tempfile() File.open(file, "w") { |f| f.puts %{[mysection]\n paramdir = #{newpath} } } config.file.send("tstamp=".intern, Time.now - 50) sleep 1 assert_equal(newpath, config["paramdir"], "File did not get reparsed from timer") assert(FileTest.directory?(newpath), "new dir did not get created") end end # $Id$ diff --git a/test/other/events.rb b/test/other/events.rb index 967fb9395..ab6270b2b 100755 --- a/test/other/events.rb +++ b/test/other/events.rb @@ -1,159 +1,152 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestEvents < Test::Unit::TestCase - include TestPuppet + include PuppetTest def teardown super Puppet::Event::Subscription.clear end def test_simplesubscribe name = tempfile() file = Puppet.type(:file).create( :name => name, :ensure => "file" ) exec = Puppet.type(:exec).create( :name => "echo true", :path => "/usr/bin:/bin", :refreshonly => true, :subscribe => [[file.class.name, file.name]] ) comp = newcomp("eventtesting", file, exec) trans = assert_events([:file_created], comp) assert_equal(1, trans.triggered?(exec, :refresh)) end def test_simplerequire name = tempfile() file = Puppet.type(:file).create( :name => name, :ensure => "file" ) exec = Puppet.type(:exec).create( :name => "echo true", :path => "/usr/bin:/bin", :refreshonly => true, :require => [[file.class.name, file.name]] ) comp = Puppet.type(:component).create( :name => "eventtesting" ) comp.push exec trans = comp.evaluate events = nil assert_nothing_raised { events = trans.evaluate } assert_equal(1, events.length) assert_equal(0, trans.triggered?(exec, :refresh)) end # Verify that one component can subscribe to another component and the "right" # thing happens def test_ladderrequire comps = {} objects = {} fname = tempfile() file = Puppet.type(:file).create( :name => tempfile(), :ensure => "file" ) exec = Puppet.type(:exec).create( :name => "touch %s" % fname, :path => "/usr/bin:/bin", :refreshonly => true ) fcomp = newcomp(file) ecomp = newcomp(exec) comp = newcomp("laddercomp", fcomp, ecomp) ecomp[:subscribe] = [[fcomp.class.name, fcomp.name]] comp.finalize trans = comp.evaluate events = nil assert_nothing_raised { events = trans.evaluate } assert(FileTest.exists?(fname), "#{fname} does not exist") #assert_equal(events.length, trans.triggered?(objects[:b], :refresh)) end def test_multiplerefreshes files = [] 4.times { |i| files << Puppet.type(:file).create( :name => tempfile(), :ensure => "file" ) } fname = tempfile() exec = Puppet.type(:exec).create( :name => "touch %s" % fname, :path => "/usr/bin:/bin", :refreshonly => true ) exec[:subscribe] = files.collect { |f| ["file", f.name] } comp = newcomp(exec, *files) assert_apply(comp) assert(FileTest.exists?(fname), "Exec file did not get created") end def test_refreshordering file = tempfile() exec1 = Puppet.type(:exec).create( :name => "echo one >> %s" % file, :path => "/usr/bin:/bin" ) exec2 = Puppet.type(:exec).create( :name => "echo two >> %s" % file, :path => "/usr/bin:/bin", :refreshonly => true, :subscribe => ["exec", exec1.name] ) exec3 = Puppet.type(:exec).create( :name => "echo three >> %s" % file, :path => "/usr/bin:/bin" ) comp = newcomp(exec1,exec2,exec3) assert_apply(comp) assert(FileTest.exists?(file), "File does not exist") assert_equal("one\ntwo\nthree\n", File.read(file)) end end diff --git a/test/other/filetype.rb b/test/other/filetype.rb index e16ffd86e..6cd749816 100755 --- a/test/other/filetype.rb +++ b/test/other/filetype.rb @@ -1,95 +1,88 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/filetype' require 'puppettest' -require 'test/unit' class TestFileType < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_flat obj = nil path = tempfile() type = nil assert_nothing_raised { type = Puppet::FileType.filetype(:flat) } assert(type, "Could not retrieve flat filetype") assert_nothing_raised { obj = type.new(path) } text = "This is some text\n" newtext = nil assert_nothing_raised { newtext = obj.read } # The base class doesn't allow a return of nil assert_equal("", newtext, "Somehow got some text") assert_nothing_raised { obj.write(text) } assert_nothing_raised { newtext = obj.read } assert_equal(text, newtext, "Text was changed somehow") File.open(path, "w") { |f| f.puts "someyayness" } text = File.read(path) assert_nothing_raised { newtext = obj.read } assert_equal(text, newtext, "Text was changed somehow") end if Facter["operatingsystem"].value == "Darwin" def test_ninfotoarray obj = nil type = nil assert_nothing_raised { type = Puppet::FileType.filetype(:netinfo) } assert(type, "Could not retrieve netinfo filetype") %w{users groups aliases}.each do |map| assert_nothing_raised { obj = type.new(map) } assert_nothing_raised("could not read map %s" % map) { obj.read } array = nil assert_nothing_raised { array = obj.to_array } assert_instance_of(Array, array) array.each do |record| assert_instance_of(Hash, record) assert(record.length != 0) end end end end end # $Id$ diff --git a/test/other/inifile.rb b/test/other/inifile.rb index eb2fde83d..113036505 100644 --- a/test/other/inifile.rb +++ b/test/other/inifile.rb @@ -1,114 +1,107 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/inifile' require 'puppettest' -require 'test/unit' class TestFileType < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @file = Puppet::IniConfig::File.new end def teardown @file = nil super end def test_simple fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value2") assert_nothing_raised { @file.read(fname) } s = get_section('main') assert_entries(s, { 'key1' => 'value1', 'key2' => 'value2' }) @file['main']['key2'] = 'newvalue2' @file['main']['key3'] = 'newvalue3' text = s.format assert_equal("[main]\nkey1=value1\n# Comment\nkey2=newvalue2\nkey3=newvalue3\n", s.format) end def test_multi fmain = mkfile("[main]\nkey1=main.value1\n# Comment\nkey2=main.value2") fsub = mkfile("[sub1]\nkey1=sub1 value1\n\n" + "[sub2]\nkey1=sub2.value1") main_mtime = File::stat(fmain).mtime assert_nothing_raised { @file.read(fmain) @file.read(fsub) } main = get_section('main') assert_entries(main, { 'key1' => 'main.value1', 'key2' => 'main.value2' }) sub1 = get_section('sub1') assert_entries(sub1, { 'key1' => 'sub1 value1' }) sub2 = get_section('sub2') assert_entries(sub2, { 'key1' => 'sub2.value1' }) [main, sub1, sub2].each { |s| assert( !s.dirty? ) } sub1['key1'] = 'sub1 newvalue1' sub2['key2'] = 'sub2 newvalue2' assert(! main.dirty?) [sub1, sub2].each { |s| assert( s.dirty? ) } @file.store [main, sub1, sub2].each { |s| assert( !s.dirty? ) } assert( File.exists?(fmain) ) assert( File.exists?(fsub) ) assert_equal(main_mtime, File::stat(fmain).mtime) subtext = File.read(fsub) assert_equal("[sub1]\nkey1=sub1 newvalue1\n\n" + "[sub2]\nkey1=sub2.value1\nkey2=sub2 newvalue2\n", subtext) end def test_format_nil fname = mkfile("[main]\nkey1=value1\n# Comment\nkey2=value2\n" + "# Comment2\n") assert_nothing_raised { @file.read(fname) } s = get_section('main') s['key2'] = nil s['key3'] = nil text = s.format assert_equal("[main]\nkey1=value1\n# Comment\n# Comment2\n", s.format) end def test_whitespace fname = mkfile("[main]\n key1=v1\nkey2 =v2\n") assert_nothing_raised { @file.read(fname) } s = get_section('main') assert_equal('v1', s['key1']) assert_equal('v2', s['key2']) end def assert_entries(section, hash) hash.each do |k, v| assert_equal(v, section[k], "Expected <#{v}> for #{section.name}[#{k}] " + "but got <#{section[k]}>") end end def get_section(name) result = @file[name] assert_not_nil(result) return result end def mkfile(content) file = tempfile() File.open(file, "w") { |f| f.print(content) } return file end end diff --git a/test/other/loadedfile.rb b/test/other/loadedfile.rb index 1089402a1..8ba45bb81 100755 --- a/test/other/loadedfile.rb +++ b/test/other/loadedfile.rb @@ -1,87 +1,80 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/loadedfile' require 'puppettest' -require 'test/unit' class TestLoadedFile < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_file Puppet[:filetimeout] = 0 file = nil path = tempfile() File.open(path, "w") { |f| f.puts "yayness" } assert_nothing_raised { file = Puppet::LoadedFile.new(path) } assert(!file.changed?, "File incorrectly returned changed") File.open(path, "w") { |f| f.puts "booness" } #file.tstamp = File.stat(path).ctime - 5 new = File.stat(path).ctime - 5 file.tstamp = new assert(file.changed?, "File did not catch change") end def test_timeout Puppet[:filetimeout] = 50 path = tempfile() File.open(path, "w") { |f| f.puts "yay" } file = nil assert_nothing_raised { file = Puppet::LoadedFile.new(path) } assert_nothing_raised { assert(!file.changed?, "File thought it changed immediately") } sleep 1 File.open(path, "w") { |f| f.puts "yay" } #file.tstamp = File.stat(path).ctime - 5 assert(!file.changed?, "File was marked as changed too soon") Puppet[:filetimeout] = 0 assert(file.changed?, "File was not marked as changed soon enough") end def test_stamp file = tempfile() File.open(file, "w") { |f| f.puts "" } obj = nil assert_nothing_raised { obj = Puppet::LoadedFile.new(file) } # Make sure we don't refresh Puppet[:filetimeout] = 50 stamp = File.stat(file).ctime assert_equal(stamp, obj.stamp) sleep 1 # Now change the file, and make sure the stamp doesn't update yet File.open(file, "w") { |f| f.puts "" } assert_equal(stamp, obj.stamp, "File prematurely refreshed") Puppet[:filetimeout] = 0 assert_equal(File.stat(file).ctime, obj.stamp, "File did not refresh") end end # $Id$ diff --git a/test/other/log.rb b/test/other/log.rb index eec20b278..750014e05 100644 --- a/test/other/log.rb +++ b/test/other/log.rb @@ -1,229 +1,222 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/log' require 'puppettest' -require 'test/unit' # $Id$ class TestLog < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @oldloglevel = Puppet::Log.level Puppet::Log.close end def teardown super Puppet::Log.close Puppet::Log.level = @oldloglevel Puppet::Log.newdestination(:console) end def getlevels levels = nil assert_nothing_raised() { levels = [] Puppet::Log.eachlevel { |level| levels << level } } # Don't test the top levels; too annoying return levels.reject { |level| level == :emerg or level == :crit } end def mkmsgs(levels) levels.collect { |level| next if level == :alert assert_nothing_raised() { Puppet::Log.new( :level => level, :source => "Test", :message => "Unit test for %s" % level ) } } end def test_logfile fact = nil levels = nil Puppet::Log.level = :debug levels = getlevels logfile = tempfile() fact = nil assert_nothing_raised() { Puppet::Log.newdestination(logfile) } msgs = mkmsgs(levels) assert(msgs.length == levels.length) Puppet::Log.close count = 0 assert(FileTest.exists?(logfile), "Did not create logfile") assert_nothing_raised() { File.open(logfile) { |of| count = of.readlines.length } } assert(count == levels.length - 1) # skip alert end def test_syslog levels = nil assert_nothing_raised() { levels = getlevels.reject { |level| level == :emerg || level == :crit } } assert_nothing_raised() { Puppet::Log.newdestination("syslog") } # there's really no way to verify that we got syslog messages... msgs = mkmsgs(levels) assert(msgs.length == levels.length) end def test_consolelog fact = nil levels = getlevels assert_nothing_raised() { Puppet::Log.newdestination(:console) } msgs = mkmsgs(levels) assert(msgs.length == levels.length) Puppet::Log.close end def test_levelmethods assert_nothing_raised() { Puppet::Log.newdestination("/dev/null") } getlevels.each { |level| assert_nothing_raised() { Puppet.send(level,"Testing for %s" % level) } } end def test_output Puppet::Log.level = :notice assert(Puppet.err("This is an error").is_a?(Puppet::Log)) assert(Puppet.debug("This is debugging").nil?) Puppet::Log.level = :debug assert(Puppet.err("This is an error").is_a?(Puppet::Log)) assert(Puppet.debug("This is debugging").is_a?(Puppet::Log)) end def test_creatingdirs dir = tempfile() file = File.join(dir, "logfile") Puppet::Log.newdestination file Puppet.info "testing logs" assert(FileTest.directory?(dir)) assert(FileTest.file?(file)) end def test_logtags path = tempfile File.open(path, "w") { |f| f.puts "yayness" } file = Puppet.type(:file).create( :path => path, :check => [:owner, :group, :mode, :checksum] ) file.tags = %w{this is a test} log = nil assert_nothing_raised { log = Puppet::Log.new( :level => :info, :source => file, :message => "A test message" ) } assert(log.tags, "Got no tags") assert_equal(log.tags, file.tags, "Tags were not equal") assert_equal(log.source, file.path, "Source was not set correctly") end # Verify that we can pass strings that match printf args def test_percentlogs Puppet::Log.newdestination :syslog assert_nothing_raised { Puppet::Log.new( :level => :info, :message => "A message with %s in it" ) } end # Verify that the error and source are always strings def test_argsAreStrings msg = nil file = Puppet.type(:file).create( :path => tempfile(), :check => %w{owner group} ) assert_nothing_raised { msg = Puppet::Log.new(:level => :info, :message => "This is a message") } assert_nothing_raised { msg.source = file } assert_instance_of(String, msg.to_s) assert_instance_of(String, msg.source) end # Verify that loglevel behaves as one expects def test_loglevel path = tempfile() file = Puppet.type(:file).create( :path => path, :ensure => "file" ) assert_nothing_raised { assert_equal(:notice, file[:loglevel]) } assert_nothing_raised { file[:loglevel] = "warning" } assert_nothing_raised { assert_equal(:warning, file[:loglevel]) } end def test_destination_matching dest = nil assert_nothing_raised { dest = Puppet::Log.newdesttype("Destine") do def handle(msg) puts msg end end } [:destine, "Destine", "destine"].each do |name| assert(dest.match?(name), "Did not match %s" % name.inspect) end assert_nothing_raised { dest.match(:yayness) } assert(dest.match("Yayness"), "Did not match yayness") Puppet::Log.close(dest) end end diff --git a/test/other/metrics.rb b/test/other/metrics.rb index c6a563bb2..380ee30bd 100644 --- a/test/other/metrics.rb +++ b/test/other/metrics.rb @@ -1,91 +1,84 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet/metric' require 'puppet' require 'puppettest' require 'puppet/type' -require 'test/unit' $haverrd = true begin require 'RRD' rescue LoadError $haverrd = false end if $haverrd class TestMetric < Test::Unit::TestCase - include TestPuppet + include PuppetTest def gendata totalmax = 1000 changemax = 1000 eventmax = 10 maxdiff = 10 types = [Puppet.type(:file), Puppet.type(:package), Puppet.type(:package)] data = [:total, :managed, :outofsync, :changed, :totalchanges] events = [:file_changed, :package_installed, :service_started] # if this is the first set of data points... typedata = Hash.new { |typehash,type| typehash[type] = Hash.new(0) } eventdata = Hash.new(0) typedata = {} typedata[:total] = rand(totalmax) typedata[:managed] = rand(typedata[:total]) typedata[:outofsync] = rand(typedata[:managed]) typedata[:changed] = rand(typedata[:outofsync]) typedata[:totalchanges] = rand(changemax) events.each { |event| eventdata[event] = rand(eventmax) } return {:typedata => typedata, :eventdata => eventdata} end def rundata(report, time) assert_nothing_raised { gendata.each do |name, data| report.newmetric(name, data) end report.metrics.each { |n, m| m.store(time) } } end def setup super Puppet[:rrdgraph] = true end def test_fakedata report = Puppet::Transaction::Report.new time = Time.now.to_i start = time 10.times { rundata(report, time) time += 300 } rundata(report, time) report.metrics.each do |n, m| m.graph end File.open(File.join(Puppet[:rrddir],"index.html"),"w") { |of| of.puts "" report.metrics.each { |name, metric| of.puts "
" % metric.name } } end end else $stderr.puts "Missing RRD library -- skipping metric tests" end # $Id$ diff --git a/test/other/overrides.rb b/test/other/overrides.rb index d9220264e..92f4068ef 100755 --- a/test/other/overrides.rb +++ b/test/other/overrides.rb @@ -1,115 +1,108 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestOverrides < Test::Unit::TestCase - include TestPuppet + include PuppetTest def mksubdirs(basedir, level) @@tmpfiles << basedir dir = basedir.dup (level + 1).times { |index| Dir.mkdir(dir) path = File.join(dir, "file") File.open(path, "w") { |f| f.puts "yayness" } dir = File.join(dir, index.to_s) } end def test_simpleoverride basedir = File.join(tmpdir(), "overridetesting") mksubdirs(basedir, 1) baseobj = nil basefile = File.join(basedir, "file") assert_nothing_raised("Could not create base obj") { baseobj = Puppet.type(:file).create( :path => basedir, :recurse => true, :mode => "755" ) } subobj = nil subdir = File.join(basedir, "0") subfile = File.join(subdir, "file") assert_nothing_raised("Could not create sub obj") { subobj = Puppet.type(:file).create( :path => subdir, :recurse => true, :mode => "644" ) } comp = newcomp("overrides", baseobj, subobj) assert_nothing_raised("Could not eval component") { trans = comp.evaluate trans.evaluate } assert(File.stat(basefile).mode & 007777 == 0755) assert(File.stat(subfile).mode & 007777 == 0644) end def test_zdeepoverride basedir = File.join(tmpdir(), "deepoverridetesting") mksubdirs(basedir, 10) baseobj = nil assert_nothing_raised("Could not create base obj") { baseobj = Puppet.type(:file).create( :path => basedir, :recurse => true, :mode => "755" ) } children = [] files = {} subdir = basedir.dup mode = nil 10.times { |index| next unless index % 3 subdir = File.join(subdir, index.to_s) path = File.join(subdir, "file") if index % 2 mode = "644" files[path] = 0644 else mode = "750" files[path] = 0750 end assert_nothing_raised("Could not create sub obj") { children << Puppet.type(:file).create( :path => subdir, :recurse => true, :mode => mode ) } } comp = newcomp("overrides", baseobj) children.each { |child| comp.push child } assert_nothing_raised("Could not eval component") { trans = comp.evaluate trans.evaluate } files.each { |path, mode| assert(FileTest.exists?(path), "File %s does not exist" % path) curmode = File.stat(path).mode & 007777 assert(curmode == mode, "File %s was incorrect mode %o instead of %o" % [path, curmode, mode]) } end end # $Id$ diff --git a/test/other/provider.rb b/test/other/provider.rb index fc04b9926..771c54bf9 100644 --- a/test/other/provider.rb +++ b/test/other/provider.rb @@ -1,165 +1,158 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/provider' require 'puppettest' -require 'test/unit' class TestImpl < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @type = newtype(@method_name.to_s + "type") # But create a new provider for every method. @provider = newprovider(@method_name.to_s + "provider") end def newtype(name) # First create a fake type return Puppet::Type.newtype(name) { newparam(:name) { isnamevar } } end def newprovider(name, type = nil) type ||= @type provider = nil assert_nothing_raised("Could not create provider") do provider = type.provide(name) {} end return provider end # Just a quick run-through to see if the basics work def test_newprovider assert_nothing_raised do @provider.confine :operatingsystem => Facter["operatingsystem"].value @provider.defaultfor :operatingsystem => Facter["operatingsystem"].value end assert(@provider.suitable?, "Implementation was not considered suitable") assert(@provider.default?, "Implementation was not considered a default") assert_equal(@provider, @type.defaultprovider, "Did not correctly find default provider") end def test_provider_false_confine assert_nothing_raised do @provider.confine :false => false end assert(@provider.suitable?, "False did not check correctly") end def test_provider_true_confine assert_nothing_raised do @provider.confine :true => true end assert(@provider.suitable?, "True did not check correctly") # Now check whether we multiple true things work assert_nothing_raised do @provider.confine :true => false @provider.confine :true => true end assert(! @provider.suitable?, "One truth overrode another") end def test_provider_exists_confine file = tempfile() assert_nothing_raised do @provider.confine :exists => file end assert(! @provider.suitable?, "Exists did not check correctly") File.open(file, "w") { |f| f.puts "" } assert(@provider.suitable?, "Exists did not find file correctly") end def test_provider_facts_confine # Now check for multiple platforms assert_nothing_raised do @provider.confine :operatingsystem => [Facter["operatingsystem"].value, :yayos] @provider.confine :operatingsystem => [:fakeos, :otheros] end assert(@provider.suitable?, "Implementation not considered suitable") end def test_provider_default nondef = nil assert_nothing_raised { nondef = newprovider(:nondefault) } assert_nothing_raised do @provider.defaultfor :operatingsystem => Facter["operatingsystem"].value end assert_equal(@provider.name, @type.defaultprovider.name, "Did not get right provider") @type.suitableprovider end def test_subclassconfines parent = newprovider("parentprovider") # Now make a bad confine on the parent parent.confine :exists => "/this/file/definitely/does/not/exist" child = nil assert_nothing_raised { child = @type.provide("child", :parent => parent.name) {} } assert(child.suitable?, "Parent ruled out child") end def test_commands parent = newprovider("parentprovider") child = nil assert_nothing_raised { child = @type.provide("child", :parent => parent.name) {} } assert_nothing_raised { child.commands :which => "which" } assert(child.command(:which), "Did not find 'which' command") assert(child.command(:which) =~ /^\//, "Command did not become fully qualified") assert(FileTest.exists?(child.command(:which)), "Did not find actual 'which' binary") assert_raise(Puppet::DevError) do child.command(:nosuchcommand) end # Now create a parent command assert_nothing_raised { parent.commands :sh => Puppet::Util.binary('sh') } assert(parent.command(:sh), "Did not find 'sh' command") assert(child.command(:sh), "Did not find parent's 'sh' command") assert(FileTest.exists?(child.command(:sh)), "Somehow broke path to sh") end end # $Id$ diff --git a/test/other/puppet.rb b/test/other/puppet.rb index 18600f7a0..76d978c7c 100755 --- a/test/other/puppet.rb +++ b/test/other/puppet.rb @@ -1,78 +1,71 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' # Test the different features of the main puppet module class TestPuppetModule < Test::Unit::TestCase - include TestPuppet + include PuppetTest include SignalObserver def mkfakeclient Class.new(Puppet::Client) do def initialize end def runnow Puppet.info "fake client has run" end end end def mktestclass Class.new do def initialize(file) @file = file end def started? FileTest.exists?(@file) end def start File.open(@file, "w") do |f| f.puts "" end end def shutdown File.unlink(@file) end end end # Make sure that services get correctly started and stopped def test_servicehandling file = tempfile() testclass = mktestclass() obj = testclass.new(file) assert_nothing_raised { Puppet.newservice(obj) } assert_nothing_raised { Puppet.start(false) } # Give it a sec or so sleep 0.3 assert(obj.started?, "Object was not started") assert_nothing_raised { Puppet.shutdown(false) } # Give it a sec or so sleep 0.3 assert(!obj.started?, "Object is still running") end end # $Id$ diff --git a/test/other/relationships.rb b/test/other/relationships.rb index 83949d1ed..e2d65beb1 100755 --- a/test/other/relationships.rb +++ b/test/other/relationships.rb @@ -1,143 +1,136 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestRelationships < Test::Unit::TestCase - include TestPuppet + include PuppetTest def newfile assert_nothing_raised() { return Puppet.type(:file).create( :path => tempfile, :check => [:mode, :owner, :group] ) } end def test_simplerel file1 = newfile() file2 = newfile() assert_nothing_raised { file1[:require] = [file2.class.name, file2.name] } comp = newcomp(file1, file2) comp.finalize deps = [] assert_nothing_raised { file1.eachdependency { |obj| deps << obj } } assert_equal(1, deps.length, "Did not get dependency") assert_nothing_raised { file1.unsubscribe(file2) } deps = [] assert_nothing_raised { file1.eachdependency { |obj| deps << obj } } assert_equal(0, deps.length, "Still have dependency") end def test_newsub file1 = newfile() file2 = newfile() sub = nil assert_nothing_raised("Could not create subscription") { sub = Puppet::Event::Subscription.new( :source => file1, :target => file2, :event => :ALL_EVENTS, :callback => :refresh ) } subs = nil assert_nothing_raised { subs = Puppet::Event::Subscription.subscribers(file1) } assert_equal(1, subs.length, "Got incorrect number of subs") assert_equal(sub.target, subs[0], "Got incorrect sub") deps = nil assert_nothing_raised { deps = Puppet::Event::Subscription.dependencies(file2) } assert_equal(1, deps.length, "Got incorrect number of deps") assert_equal(sub, deps[0], "Got incorrect dep") end def test_eventmatch file1 = newfile() file2 = newfile() sub = nil assert_nothing_raised("Could not create subscription") { sub = Puppet::Event::Subscription.new( :source => file1, :target => file2, :event => :ALL_EVENTS, :callback => :refresh ) } assert(sub.match?(:anything), "ALL_EVENTS did not match") assert(! sub.match?(:NONE), "ALL_EVENTS matched :NONE") sub.event = :file_created assert(sub.match?(:file_created), "event did not match") assert(sub.match?(:ALL_EVENTS), "ALL_EVENTS did not match") assert(! sub.match?(:NONE), "ALL_EVENTS matched :NONE") sub.event = :NONE assert(! sub.match?(:file_created), "Invalid match") assert(! sub.match?(:ALL_EVENTS), "ALL_EVENTS matched") assert(! sub.match?(:NONE), "matched :NONE") end def test_deletingsubs file1 = newfile() file2 = newfile() file1[:subscribe] = [:file, file2.name] comp = newcomp(file1, file2) comp.finalize assert(file1.requires?(file2)) assert_nothing_raised { file1.unsubscribe(file2) } assert(!file1.requires?(file2)) # Now readd it, so we can use 'remove' file1[:subscribe] = [:file, file2.name] comp.finalize assert_nothing_raised { file1.remove } assert(!comp.include?(file1)) assert(!file2.subscribesto?(file1)) end end # $Id$ diff --git a/test/other/report.rb b/test/other/report.rb index 2aa78172c..b98813927 100755 --- a/test/other/report.rb +++ b/test/other/report.rb @@ -1,106 +1,99 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/transaction/report' require 'puppettest' -require 'test/unit' class TestReports < Test::Unit::TestCase - include TestPuppet + include PuppetTest # Make sure we can use reports as log destinations. def test_reports_as_log_destinations report = nil assert_nothing_raised { report = Puppet::Transaction::Report.new } assert_nothing_raised { Puppet::Log.newdestination(report) } # Now make a file for testing logging file = Puppet::Type.newfile(:path => tempfile(), :ensure => "file") log = nil assert_nothing_raised { log = file.log "This is a message, yo" } assert(report.logs.include?(log), "Report did not get log message") log = Puppet.info "This is a non-sourced message" assert(! report.logs.include?(log), "Report got log message") assert_nothing_raised { Puppet::Log.close(report) } log = file.log "This is another message, yo" assert(! report.logs.include?(log), "Report got log message after close") end def test_newmetric report = nil assert_nothing_raised { report = Puppet::Transaction::Report.new } assert_nothing_raised { report.newmetric(:mymetric, :total => 12, :done => 6 ) } end if Puppet::Metric.haverrd? def test_rrdgraph_report Puppet.config.use(:metrics) # First do some work objects = [] 25.times do |i| file = tempfile() # Make every third file File.open(file, "w") { |f| f.puts "" } if i % 3 == 0 objects << Puppet::Type.newfile( :path => file, :ensure => "file" ) end comp = newcomp(*objects) trans = nil assert_nothing_raised("Failed to create transaction") { trans = comp.evaluate } assert_nothing_raised("Failed to evaluate transaction") { trans.evaluate } method = Puppet::Server::Report.report("rrdgraph") server = nil assert_nothing_raised { server = Puppet::Server::Report.new() } assert_nothing_raised { server.report_rrdgraph(trans.report) } end else $stderr.puts "Install RRD for metric reporting tests" end end # $Id$ diff --git a/test/other/storage.rb b/test/other/storage.rb index 64fddf332..789495fee 100755 --- a/test/other/storage.rb +++ b/test/other/storage.rb @@ -1,100 +1,93 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestStorage < Test::Unit::TestCase - include TestPuppet + include PuppetTest def mkfile path = tempfile() File.open(path, "w") { |f| f.puts :yayness } f = Puppet.type(:file).create( :name => path, :check => %w{checksum type} ) return f end def test_storeandretrieve path = tempfile() f = mkfile() hash = {:a => :b, :c => :d} state = nil assert_nothing_raised { state = Puppet::Storage.cache(f) } assert(!state.include?("name")) assert_nothing_raised { state["name"] = hash } assert_nothing_raised { Puppet::Storage.store } assert_nothing_raised { Puppet::Storage.clear } assert_nothing_raised { Puppet::Storage.load } # Reset it state = nil assert_nothing_raised { state = Puppet::Storage.cache(f) } assert_equal(state["name"], hash) end # we're getting corrupt files, probably because multiple processes # are reading or writing the file at once # so we need to test that def test_multiwrite f = mkfile() value = {:a => :b} threads = [] 9.times { |a| threads << Thread.new { 9.times { |b| assert_nothing_raised { Puppet::Storage.load state = Puppet::Storage.cache(f) value.each { |k,v| state[k] = v } state[:e] = rand(100) Puppet::Storage.store } } } } threads.each { |th| th.join } end def test_emptyrestore Puppet::Storage.load Puppet::Storage.store Puppet::Storage.clear Puppet::Storage.load f = mkfile() state = Puppet::Storage.cache(f) assert_same Hash, state.class assert_equal 0, state.size end end # $Id$ diff --git a/test/other/transactions.rb b/test/other/transactions.rb index aea593c1f..e66151979 100644 --- a/test/other/transactions.rb +++ b/test/other/transactions.rb @@ -1,402 +1,395 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestTransactions < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def test_reports path1 = tempfile() path2 = tempfile() objects = [] objects << Puppet::Type.newfile( :path => path1, :content => "yayness" ) objects << Puppet::Type.newfile( :path => path2, :content => "booness" ) trans = assert_events([:file_created, :file_created], *objects) report = nil assert_nothing_raised { report = trans.report } # First test the report logs assert(report.logs.length > 0, "Did not get any report logs") report.logs.each do |obj| assert_instance_of(Puppet::Log, obj) end # Then test the metrics metrics = report.metrics assert(metrics, "Did not get any metrics") assert(metrics.length > 0, "Did not get any metrics") assert(metrics.has_key?("objects"), "Did not get object metrics") assert(metrics.has_key?("changes"), "Did not get change metrics") metrics.each do |name, metric| assert_instance_of(Puppet::Metric, metric) end end unless %x{groups}.chomp.split(/ /).length > 1 $stderr.puts "You must be a member of more than one group to test transactions" else def ingroup(gid) require 'etc' begin group = Etc.getgrgid(gid) rescue => detail puts "Could not retrieve info for group %s: %s" % [gid, detail] return nil end return @groups.include?(group.name) end def setup super @groups = %x{groups}.chomp.split(/ /) unless @groups.length > 1 p @groups raise "You must be a member of more than one group to test this" end end def newfile(hash = {}) tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } # XXX now, because os x apparently somehow allows me to make a file # owned by a group i'm not a member of, i have to verify that # the file i just created is owned by one of my groups # grrr unless ingroup(File.stat(tmpfile).gid) Puppet.info "Somehow created file in non-member group %s; fixing" % File.stat(tmpfile).gid require 'etc' firstgr = @groups[0] unless firstgr.is_a?(Integer) str = Etc.getgrnam(firstgr) firstgr = str.gid end File.chown(nil, firstgr, tmpfile) end hash[:name] = tmpfile assert_nothing_raised() { return Puppet.type(:file).create(hash) } end def newservice assert_nothing_raised() { return Puppet.type(:service).create( :name => "sleeper", :type => "init", - :path => File.join($puppetbase,"examples/root/etc/init.d"), + :path => exampledir("root/etc/init.d"), :hasstatus => true, :check => [:ensure] ) } end def newexec(file) assert_nothing_raised() { return Puppet.type(:exec).create( :name => "touch %s" % file, :path => "/bin:/usr/bin:/sbin:/usr/sbin", :returns => 0 ) } end # modify a file and then roll the modifications back def test_filerollback transaction = nil file = newfile() states = {} check = [:group,:mode] file[:check] = check assert_nothing_raised() { file.retrieve } assert_nothing_raised() { check.each { |state| assert(file[state]) states[state] = file[state] } } component = newcomp("file",file) require 'etc' groupname = Etc.getgrgid(File.stat(file.name).gid).name assert_nothing_raised() { # Find a group that it's not set to group = @groups.find { |group| group != groupname } unless group raise "Could not find suitable group" end file[:group] = group file[:mode] = "755" } trans = assert_events([:file_changed, :file_changed], component) file.retrieve assert_rollback_events(trans, [:file_changed, :file_changed], "file") assert_nothing_raised() { file.retrieve } states.each { |state,value| assert_equal( value,file.is(state), "File %s remained %s" % [state, file.is(state)] ) } end # start a service, and then roll the modification back # Disabled, because it wasn't really worth the effort. def disabled_test_servicetrans transaction = nil service = newservice() component = newcomp("service",service) assert_nothing_raised() { service[:ensure] = 1 } service.retrieve assert(service.insync?, "Service did not start") system("ps -ef | grep ruby") trans = assert_events([:service_started], component) service.retrieve assert_rollback_events(trans, [:service_stopped], "service") end # test that services are correctly restarted and that work is done # in the right order def test_refreshing transaction = nil file = newfile() execfile = File.join(tmpdir(), "exectestingness") exec = newexec(execfile) states = {} check = [:group,:mode] file[:check] = check @@tmpfiles << execfile component = newcomp("both",file,exec) # 'subscribe' expects an array of arrays exec[:subscribe] = [[file.class.name,file.name]] exec[:refreshonly] = true assert_nothing_raised() { file.retrieve exec.retrieve } check.each { |state| states[state] = file[state] } assert_nothing_raised() { file[:mode] = "755" } trans = assert_events([:file_changed], component) assert(FileTest.exists?(execfile), "Execfile does not exist") File.unlink(execfile) assert_nothing_raised() { file[:group] = @groups[1] } trans = assert_events([:file_changed], component) assert(FileTest.exists?(execfile), "Execfile does not exist") end def test_refreshAcrossTwoComponents transaction = nil file = newfile() execfile = File.join(tmpdir(), "exectestingness2") @@tmpfiles << execfile exec = newexec(execfile) states = {} check = [:group,:mode] file[:check] = check fcomp = newcomp("file",file) ecomp = newcomp("exec",exec) component = newcomp("both",fcomp,ecomp) # 'subscribe' expects an array of arrays #component[:require] = [[file.class.name,file.name]] ecomp[:subscribe] = [[fcomp.class.name,fcomp.name]] exec[:refreshonly] = true trans = assert_events([], component) assert_nothing_raised() { file[:group] = @groups[1] file[:mode] = "755" } trans = assert_events([:file_changed, :file_changed], component) end # Make sure that multiple subscriptions get triggered. def test_multisubs path = tempfile() file1 = tempfile() file2 = tempfile() file = Puppet.type(:file).create( :path => path, :ensure => "file" ) exec1 = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "touch %s" % file1, :refreshonly => true, :subscribe => [:file, path] ) exec2 = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "touch %s" % file2, :refreshonly => true, :subscribe => [:file, path] ) assert_apply(file, exec1, exec2) assert(FileTest.exists?(file1), "File 1 did not get created") assert(FileTest.exists?(file2), "File 2 did not get created") end # Make sure that a failed trigger doesn't result in other events not # getting triggered. def test_failedrefreshes path = tempfile() newfile = tempfile() file = Puppet.type(:file).create( :path => path, :ensure => "file" ) svc = Puppet.type(:service).create( :name => "thisservicedoesnotexist", :subscribe => [:file, path] ) exec = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "touch %s" % newfile, :logoutput => true, :refreshonly => true, :subscribe => [:file, path] ) assert_apply(file, svc, exec) assert(FileTest.exists?(path), "File did not get created") assert(FileTest.exists?(newfile), "Refresh file did not get created") end # Make sure that unscheduled and untagged objects still respond to events def test_unscheduledanduntaggedresponse Puppet::Type.type(:schedule).mkdefaultschedules Puppet[:ignoreschedules] = false file = Puppet.type(:file).create( :name => tempfile(), :ensure => "file" ) fname = tempfile() exec = Puppet.type(:exec).create( :name => "touch %s" % fname, :path => "/usr/bin:/bin", :schedule => "monthly", :subscribe => ["file", file.name] ) comp = newcomp(file,exec) comp.finalize # Run it once assert_apply(comp) assert(FileTest.exists?(fname), "File did not get created") assert(!exec.scheduled?, "Exec is somehow scheduled") # Now remove it, so it can get created again File.unlink(fname) file[:content] = "some content" assert_events([:file_changed], comp) assert(FileTest.exists?(fname), "File did not get recreated") # Now remove it, so it can get created again File.unlink(fname) # And tag our exec exec.tag("testrun") # And our file, so it runs file.tag("norun") Puppet[:tags] = "norun" file[:content] = "totally different content" assert(! file.insync?, "Uh, file is in sync?") assert_events([:file_changed], comp) assert(FileTest.exists?(fname), "File did not get recreated") end def test_failed_reqs_mean_no_run exec = Puppet::Type.type(:exec).create( :command => "/bin/mkdir /this/path/cannot/possibly/exit", :title => "mkdir" ) file = Puppet::Type.type(:file).create( :path => tempfile(), :require => ["exec", "mkdir"], :ensure => :file ) comp = newcomp(exec, file) comp.finalize assert_apply(comp) assert(! FileTest.exists?(file[:path]), "File got created even tho its dependency failed") end end end diff --git a/test/providers/group.rb b/test/providers/group.rb index a23dbb50c..63aafc1f7 100755 --- a/test/providers/group.rb +++ b/test/providers/group.rb @@ -1,246 +1,239 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'etc' require 'puppet/type' require 'puppettest' -require 'test/unit' class TestGroupProvider < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @@tmpgroups = [] @provider = nil assert_nothing_raised { @provider = Puppet::Type.type(:group).defaultprovider } assert(@provider, "Could not find default group provider") assert(@provider.name != :fake, "Got a fake provider") end def teardown super Puppet.type(:group).clear @@tmpgroups.each { |group| unless missing?(group) remove(group) end } end def mkgroup(name, hash = {}) fakemodel = fakemodel(:group, name) group = nil assert_nothing_raised { group = @provider.new(fakemodel) } hash.each do |name, val| fakemodel[name] = val end assert(group, "Could not create provider group") return group end case Facter["operatingsystem"].value when "Darwin": def missing?(group) output = %x{nidump -r /groups/#{group} / 2>/dev/null}.chomp if output == "" return true else return false end assert_equal("", output, "Group %s is present:\n%s" % [group, output]) end def gid(name) %x{nireport / /groups name gid}.split("\n").each { |line| group, id = line.chomp.split(/\s+/) assert(id =~ /^-?\d+$/, "Group id %s for %s is not a number" % [id.inspect, group]) if group == name return Integer(id) end } return nil end def remove(group) system("niutil -destroy / /groups/%s" % group) end else def missing?(group) begin obj = Etc.getgrnam(group) return false rescue ArgumentError return true end end def gid(name) assert_nothing_raised { obj = Etc.getgrnam(name) return obj.gid } return nil end def remove(group) system("groupdel %s" % group) end end def groupnames %x{groups}.chomp.split(/ /) end def groupids Process.groups end def attrtest_ensure(group) old = group.ensure assert_nothing_raised { group.ensure = :absent } assert(!group.exists?, "Group was not deleted") assert_nothing_raised { group.ensure = :present } assert(group.exists?, "Group was not created") unless old == :present assert_nothing_raised { group.ensure = old } end end def attrtest_gid(group) old = gid(group.name) newgid = old while true newgid += 1 if newgid - old > 1000 $stderr.puts "Could not find extra test UID" return end begin Etc.getgrgid(newgid) rescue ArgumentError => detail break end end assert_nothing_raised("Failed to change group id") { group.gid = newgid } curgid = nil assert_nothing_raised { curgid = gid(group.name) } assert_equal(newgid, curgid, "GID was not changed") # Refresh group.getinfo(true) assert_equal(newgid, group.gid, "Object got wrong gid") assert_nothing_raised("Failed to change group id") { group.gid = old } end # Iterate over each of our groups and try to grab the gid. def test_ownprovidergroups groupnames().each { |group| gobj = nil comp = nil fakemodel = fakemodel(:group, group) assert_nothing_raised { gobj = @provider.new(fakemodel) } assert(gobj.gid, "Failed to retrieve gid") } end if Process.uid == 0 def test_mkgroup gobj = nil comp = nil name = "pptestgr" assert(missing?(name), "Group %s is still present" % name) group = mkgroup(name) @@tmpgroups << name assert(group.respond_to?(:addcmd), "no respondo?") assert_nothing_raised { group.create } assert(!missing?(name), "Group %s is missing" % name) tests = Puppet.type(:group).validstates tests.each { |test| if self.respond_to?("attrtest_%s" % test) self.send("attrtest_%s" % test, group) else $stderr.puts "Not testing attr %s of group" % test end } assert_nothing_raised { group.delete } end # groupadd -o is broken in FreeBSD. unless Facter["operatingsystem"].value == "FreeBSD" def test_duplicateIDs group1 = mkgroup("group1", :gid => 125) group2 = mkgroup("group2", :gid => 125) @@tmpgroups << "group1" @@tmpgroups << "group2" # Create the first group assert_nothing_raised { group1.create } # Not all OSes fail here, so we can't test that it doesn't work with # it off, only that it does work with it on. assert_nothing_raised { group2.model[:allowdupe] = :true } # Now create the second group assert_nothing_raised { group2.create } assert_equal(:present, group2.ensure, "Group did not get created") end end else $stderr.puts "Not running as root; skipping group creation tests." end end # $Id$ diff --git a/test/providers/nameservice.rb b/test/providers/nameservice.rb index 0e0f8050f..dafc8dcf0 100644 --- a/test/providers/nameservice.rb +++ b/test/providers/nameservice.rb @@ -1,36 +1,29 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' class TestNameServiceProvider < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def test_option klass = Class.new(Puppet::Type::Provider::NameService) klass.model = Puppet::Type.type(:user) val = nil assert_nothing_raised { val = klass.option(:home, :flag) } assert_nil(val, "Got an option") assert_nothing_raised { klass.options :home, :flag => "-d" } assert_nothing_raised { val = klass.option(:home, :flag) } assert_equal("-d", val, "Got incorrect option") end end # $Id$ diff --git a/test/providers/package.rb b/test/providers/package.rb index 210fae5c1..1c3621909 100644 --- a/test/providers/package.rb +++ b/test/providers/package.rb @@ -1,86 +1,79 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'etc' require 'puppet/type' require 'puppettest' -require 'test/unit' class TestPackageProvider < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @provider = nil assert_nothing_raised { @provider = Puppet::Type.type(:package).defaultprovider } assert(@provider, "Could not find default package provider") assert(@provider.name != :fake, "Got a fake provider") end def test_nothing end if Facter["operatingsystem"].value == "Solaris" and Process.uid == 0 if Puppet.type(:package).provider(:blastwave).suitable? # FIXME The packaging crap needs to be rewritten to support testing # multiple package types on the same platform. def test_list_blastwave pkgs = nil assert_nothing_raised { pkgs = Puppet::Type.type(:package).provider(:blastwave).list } pkgs.each do |pkg| if pkg[:name] =~ /^CSW/ assert_equal(:blastwave, pkg[:provider], "Type was not set correctly") end end end def test_install_blastwave pkg = nil name = "cabextract" model = fakemodel(:package, name) assert_nothing_raised { pkg = Puppet::Type.type(:package).provider(:blastwave).new(model) } if hash = pkg.query and hash[:ensure] != :absent p hash $stderr.puts "Cannot test pkg installation; %s is already installed" % name return end assert_nothing_raised { pkg.install } hash = nil assert(hash = pkg.query, "package did not install") assert(hash[:ensure] != :absent, "package did not install") latest = nil assert_nothing_raised { latest = pkg.latest } assert(latest, "Could not find latest package version") assert_nothing_raised { pkg.uninstall } end else $stderr.puts "No pkg-get scripting; skipping blastwave tests" end end end # $Id$ diff --git a/test/providers/provider.rb b/test/providers/provider.rb index cd9b32da2..e540f29fe 100644 --- a/test/providers/provider.rb +++ b/test/providers/provider.rb @@ -1,154 +1,147 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' class TestProvider < Test::Unit::TestCase - include TestPuppet + include PuppetTest def echo echo = Puppet::Util.binary("echo") unless echo raise "Could not find 'echo' binary; cannot complete test" end return echo end def newprovider # Create our provider provider = Class.new(Puppet::Provider) do @name = :fakeprovider end provider.initvars return provider end def test_confine provider = newprovider assert(provider.suitable?, "Marked unsuitable with no confines") { {:true => true} => true, {:true => false} => false, {:false => false} => true, {:false => true} => false, {:operatingsystem => Facter.value(:operatingsystem)} => true, {:operatingsystem => :yayness} => false, {:nothing => :yayness} => false, {:exists => echo} => true, {:exists => "/this/file/does/not/exist"} => false, }.each do |hash, result| # First test :true hash.each do |test, val| assert_nothing_raised do provider.confine test => val end end assert_equal(result, provider.suitable?, "Failed for %s" % [hash.inspect]) provider.initvars end # Make sure multiple confines don't overwrite each other provider.confine :true => false assert(! provider.suitable?) provider.confine :true => true assert(! provider.suitable?) provider.initvars # Make sure we test multiple of them, and that a single false wins provider.confine :true => true, :false => false assert(provider.suitable?) provider.confine :true => false assert(! provider.suitable?) end def test_command provider = newprovider assert_nothing_raised do provider.commands :echo => "echo" end assert_equal(echo, provider.command(:echo)) assert(provider.method_defined?(:echo), "Instance method not defined") assert(provider.respond_to?(:echo), "Class method not defined") # Now make sure they both work inst = provider.new(nil) assert_nothing_raised do [provider, inst].each do |thing| out = thing.echo "some text" assert_equal("some text\n", out) end end assert(provider.suitable?, "Provider considered unsuitable") # Now add an invalid command assert_nothing_raised do provider.commands :fake => "nosuchcommanddefinitely" end assert(! provider.suitable?, "Provider considered suitable") assert_raise(Puppet::Error) do provider.command(:fake) end assert_raise(Puppet::DevError) do provider.command(:nosuchcmd) end # Lastly, verify that we can find our superclass commands newprov = Class.new(provider) newprov.initvars assert_equal(echo, newprov.command(:echo)) end def test_default? provider = newprovider assert(! provider.default?, "Was considered default with no settings") assert_nothing_raised do provider.defaultfor :operatingsystem => Facter.value(:operatingsystem) end assert(provider.default?, "Was not considered default") # Make sure any true value is sufficient. assert_nothing_raised do provider.defaultfor :operatingsystem => [ :yayness, :rahness, Facter.value(:operatingsystem) ] end assert(provider.default?, "Was not considered default") # Now make sure that a random setting returns false. assert_nothing_raised do provider.defaultfor :operatingsystem => :yayness end assert(! provider.default?, "Was considered default") end end # $Id$ diff --git a/test/providers/user.rb b/test/providers/user.rb index 0778a257f..15fc202f5 100644 --- a/test/providers/user.rb +++ b/test/providers/user.rb @@ -1,528 +1,521 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' class TestUserProvider < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def setup super setme() @@tmpusers = [] @provider = nil assert_nothing_raised { @provider = Puppet::Type.type(:user).defaultprovider } assert(@provider, "Could not find default user provider") end def teardown @@tmpusers.each { |user| unless missing?(user) remove(user) end } super #Puppet.type(:user).clear end case Facter["operatingsystem"].value when "Darwin": def missing?(user) output = %x{nidump -r /users/#{user} / 2>/dev/null}.chomp if output == "" return true else return false end assert_equal("", output, "User %s is present:\n%s" % [user, output]) end def current?(param, user) state = Puppet.type(:user).states.find { |st| st.name == param } output = %x{nireport / /users name #{state.netinfokey}} output.split("\n").each { |line| if line =~ /^(\w+)\s+(.+)$/ username = $1 id = $2.sub(/\s+$/, '') if username == user.name if id =~ /^[-0-9]+$/ return Integer(id) else return id end end else raise "Could not match %s" % line end } return nil end def remove(user) system("niutil -destroy / /users/%s" % user) end else def missing?(user) begin obj = Etc.getpwnam(user) return false rescue ArgumentError return true end end def current?(param, user) state = Puppet.type(:user).states.find { |st| st.name == param } assert_nothing_raised { obj = Etc.getpwnam(user.name) return obj.send(user.posixmethod(param)) } return nil end def remove(user) system("userdel %s" % user) end end def eachstate Puppet::Type.type(:user).validstates.each do |state| yield state end end def findshell(old = nil) %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh /usr/bin/tcsh}.find { |shell| if old FileTest.exists?(shell) and shell != old else FileTest.exists?(shell) end } end def fakedata(name, param) case param when :name: name when :ensure: :present when :comment: "Puppet Testing User %s" % name when :gid: nonrootgroup.name when :shell: findshell() when :home: "/home/%s" % name else return nil end end def mkuser(name) fakemodel = fakemodel(:user, name) user = nil assert_nothing_raised { user = @provider.new(fakemodel) } assert(user, "Could not create provider user") return user end def test_list names = nil assert_nothing_raised { names = @provider.listbyname } assert(names.length > 0, "Listed no users") # Now try it by object assert_nothing_raised { names = @provider.list } assert(names.length > 0, "Listed no users as objects") names.each do |obj| assert_instance_of(Puppet::Type.type(:user), obj) assert(obj[:provider], "Provider was not set") end end def test_infocollection fakemodel = fakemodel(:user, @me) user = nil assert_nothing_raised { user = @provider.new(fakemodel) } assert(user, "Could not create user provider") Puppet::Type.type(:user).validstates.each do |state| next if state == :ensure val = nil assert_nothing_raised { val = user.send(state) } assert(val != :absent, "State %s is missing" % state) assert(val, "Did not get value for %s" % state) end end def test_exists user = mkuser("nosuchuserok") assert(! user.exists?, "Fake user exists?") user = mkuser(@me) assert(user.exists?, "I don't exist?") end def attrtest_ensure(user) old = user.ensure assert_nothing_raised { user.ensure = :absent } assert(missing?(user.name), "User is still present") assert_nothing_raised { user.ensure = :present } assert(!missing?(user.name), "User is absent") assert_nothing_raised { user.ensure = :absent } unless old == :absent user.ensure = old end end def attrtest_comment(user) old = user.comment assert_nothing_raised { user.comment = "A different comment" } assert_equal("A different comment", current?(:comment, user), "Comment was not changed") assert_nothing_raised { user.comment = old } assert_equal(old, current?(:comment, user), "Comment was not reverted") end def attrtest_home(user) old = current?(:home, user) assert_nothing_raised { user.home = "/tmp" } assert_equal("/tmp", current?(:home, user), "Home was not changed") assert_nothing_raised { user.home = old } assert_equal(old, current?(:home, user), "Home was not reverted") end def attrtest_shell(user) old = current?(:shell, user) newshell = findshell(old) unless newshell $stderr.puts "Cannot find alternate shell; skipping shell test" return end assert_nothing_raised { user.shell = newshell } assert_equal(newshell, current?(:shell, user), "Shell was not changed") assert_nothing_raised { user.shell = old } assert_equal(old, current?(:shell, user), "Shell was not reverted") end def attrtest_gid(user) old = current?(:gid, user) newgroup = %w{nogroup nobody staff users daemon}.find { |gid| begin group = Etc.getgrnam(gid) rescue ArgumentError => detail next end old != group.gid } group = Etc.getgrnam(newgroup) unless newgroup $stderr.puts "Cannot find alternate group; skipping gid test" return end assert_raise(ArgumentError, "gid allowed a non-integer value") do user.gid = group.name end assert_nothing_raised("Failed to specify group by id") { user.gid = group.gid } assert_equal(group.gid, current?(:gid,user), "GID was not changed") assert_nothing_raised("Failed to change back to old gid") { user.gid = old } end def attrtest_uid(user) old = current?(:uid, user) newuid = old while true newuid += 1 if newuid - old > 1000 $stderr.puts "Could not find extra test UID" return end begin newuser = Etc.getpwuid(newuid) rescue ArgumentError => detail break end end assert_nothing_raised("Failed to change user id") { user.uid = newuid } assert_equal(newuid, current?(:uid, user), "UID was not changed") assert_nothing_raised("Failed to change user id") { user.uid = old } assert_equal(old, current?(:uid, user), "UID was not changed back") end def attrtest_groups(user) Etc.setgrent max = 0 while group = Etc.getgrent if group.gid > max and group.gid < 5000 max = group.gid end end groups = [] main = [] extra = [] 5.times do |i| i += 1 name = "pptstgr%s" % i tmpgroup = Puppet.type(:group).create( :name => name, :gid => max + i ) groups << tmpgroup cleanup do tmpgroup.provider.delete if tmpgroup.provider.exists? end if i < 3 main << name else extra << name end end # Create our test groups assert_apply(*groups) # Now add some of them to our user assert_nothing_raised { user.model[:groups] = extra.join(",") } # Some tests to verify that groups work correctly startig from nothing # Remove our user user.ensure = :absent # And add it again user.ensure = :present # Make sure that the group list is added at creation time. # This is necessary because we don't have default fakedata for groups. assert(user.groups, "Did not retrieve group list") list = user.groups.split(",") assert_equal(extra.sort, list.sort, "Group list was not set at creation time") # Now set to our main list of groups assert_nothing_raised { user.groups = main.join(",") } list = user.groups.split(",") assert_equal(main.sort, list.sort, "Group list is not equal") end if Process.uid == 0 def test_simpleuser name = "pptest" assert(missing?(name), "User %s is present" % name) user = mkuser(name) eachstate do |state| if val = fakedata(user.name, state) user.model[state] = val end end @@tmpusers << name assert_nothing_raised { user.create } assert_equal("Puppet Testing User pptest", user.comment, "Comment was not set") assert_nothing_raised { user.delete } assert(missing?(user.name), "User was not deleted") end def test_alluserstates user = nil name = "pptest" assert(missing?(name), "User %s is present" % name) user = mkuser(name) eachstate do |state| if val = fakedata(user.name, state) user.model[state] = val end end @@tmpusers << name assert_nothing_raised { user.create } assert_equal("Puppet Testing User pptest", user.comment, "Comment was not set") tests = Puppet::Type.type(:user).validstates just = nil tests.each { |test| next unless test == :groups if self.respond_to?("attrtest_%s" % test) self.send("attrtest_%s" % test, user) else Puppet.err "Not testing attr %s of user" % test end } assert_nothing_raised { user.delete } end # This is a weird method that shows how annoying the interface between # types and providers is. Grr. def test_duplicateIDs user1 = mkuser("user1") user1.create user1.uid = 125 user2 = mkuser("user2") user2.model[:uid] = 125 cleanup do user1.ensure = :absent user2.ensure = :absent end # Not all OSes fail here, so we can't test that it doesn't work with # it off, only that it does work with it on. assert_nothing_raised { user2.model[:allowdupe] = :true } assert_nothing_raised { user2.create } assert_equal(:present, user2.ensure, "User did not get created") end else $stderr.puts "Not root; skipping user creation/modification tests" end # Here is where we test individual providers def test_useradd_flags useradd = nil assert_nothing_raised { useradd = Puppet::Type.type(:user).provider(:useradd) } assert(useradd, "Did not retrieve useradd provider") user = nil assert_nothing_raised { fakemodel = fakemodel(:user, @me) user = useradd.new(fakemodel) } assert_equal("-d", user.send(:flag, :home), "Incorrect home flag") assert_equal("-s", user.send(:flag, :shell), "Incorrect shell flag") end end # $Id$ diff --git a/test/puppet/conffiles.rb b/test/puppet/conffiles.rb index 095ac9c99..9234e2dfd 100755 --- a/test/puppet/conffiles.rb +++ b/test/puppet/conffiles.rb @@ -1,104 +1,97 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppet/config' require 'puppettest' -require 'test/unit' class TestConfFiles < Test::Unit::TestCase - include TestPuppet + include PuppetTest @@gooddata = [ { "fun" => { "a" => "b", "c" => "d", "e" => "f" }, "yay" => { "aa" => "bk", "ca" => "dk", "ea" => "fk" }, "boo" => { "eb" => "fb" }, }, { "puppet" => { "yay" => "rah" }, "booh" => { "okay" => "rah" }, "back" => { "yayness" => "rah" }, } ] def data2config(data) str = "" if data.include?("puppet") # because we're modifying it data = data.dup str += "[puppet]\n" data["puppet"].each { |var, value| str += "%s = %s\n" % [var, value] } data.delete("puppet") end data.each { |type, settings| str += "[%s]\n" % type settings.each { |var, value| str += "%s = %s\n" % [var, value] } } return str end def sampledata if block_given? @@gooddata.each { |hash| yield hash } else return @@gooddata[0] end end def test_readconfig path = tempfile() sampledata { |data| config = Puppet::Config.new data.each { |section, hash| hash.each { |param, value| config.setdefaults(section, param => [value, value]) } } # Write it out as a config file File.open(path, "w") { |f| f.print data2config(data) } assert_nothing_raised { config.parse(path) } data.each { |section, hash| hash.each { |var, value| assert_equal( data[section][var], config[var], "Got different values at %s/%s" % [section, var] ) } } } end end # $Id$ diff --git a/test/puppet/defaults.rb b/test/puppet/defaults.rb index 2557140e6..46accc9c6 100755 --- a/test/puppet/defaults.rb +++ b/test/puppet/defaults.rb @@ -1,102 +1,95 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestPuppetDefaults < Test::Unit::TestCase - include TestPuppet + include PuppetTest @@dirs = %w{rrddir confdir vardir logdir statedir} @@files = %w{statefile manifest masterlog} @@normals = %w{puppetport masterport server} @@booleans = %w{rrdgraph noop} def testVersion assert( Puppet.version =~ /^[0-9]+(\.[0-9]+)*$/ ) end def testStringOrParam [@@dirs,@@files,@@booleans].flatten.each { |param| assert_nothing_raised { Puppet[param] } assert_nothing_raised { Puppet[param.intern] } } end def test_valuesForEach [@@dirs,@@files,@@booleans].flatten.each { |param| param = param.intern assert_nothing_raised { Puppet[param] } } end def testValuesForEach [@@dirs,@@files,@@booleans].flatten.each { |param| assert_nothing_raised { Puppet[param] } } end if __FILE__ == $0 def disabled_testContained confdir = Regexp.new(Puppet[:confdir]) vardir = Regexp.new(Puppet[:vardir]) [@@dirs,@@files].flatten.each { |param| value = Puppet[param] unless value =~ confdir or value =~ vardir assert_nothing_raised { raise "%s is in wrong dir: %s" % [param,value] } end } end end def testArgumentTypes assert_raise(ArgumentError) { Puppet[["string"]] } assert_raise(ArgumentError) { Puppet[[:symbol]] } end def testFailOnBogusArgs [0, "ashoweklj", ";"].each { |param| assert_raise(ArgumentError, "No error on %s" % param) { Puppet[param] } } end # we don't want user defaults in /, or root defaults in ~ def testDefaultsInCorrectRoots notval = nil if Process.uid == 0 notval = Regexp.new(File.expand_path("~")) else notval = /^\/var|^\/etc/ end [@@dirs,@@files].flatten.each { |param| value = Puppet[param] unless value !~ notval assert_nothing_raised { raise "%s is incorrectly set to %s" % [param,value] } end } end def test_settingdefaults testvals = { :fakeparam => "$confdir/yaytest", :anotherparam => "$vardir/goodtest", :string => "a yay string", :boolean => true } testvals.each { |param, default| assert_nothing_raised { Puppet.setdefaults("testing", param => [default, "a value"]) } } end end diff --git a/test/puppet/errortest.rb b/test/puppet/errortest.rb index f27d79822..264cde857 100755 --- a/test/puppet/errortest.rb +++ b/test/puppet/errortest.rb @@ -1,23 +1,16 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestError < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_errorisstring error = nil assert_nothing_raised { error = Puppet::ParseError.new("This is an error") } assert_instance_of(String, error.to_s) end end # $Id$ diff --git a/test/puppettest.rb b/test/puppettest.rb deleted file mode 100644 index 70775e0e3..000000000 --- a/test/puppettest.rb +++ /dev/null @@ -1,1320 +0,0 @@ -#libdir = File.join(File.dirname(__FILE__), '../lib') -#unless $:.include?(libdir) -# $:.unshift libdir -#end - -require 'puppet' -require 'test/unit' - -module TestPuppet - include ObjectSpace - - # A baseclass for the faketypes. - class FakeModel - class << self - attr_accessor :name - @name = :fakemodel - end - - def self.validstates - Puppet::Type.type(@name).validstates - end - - def self.validstate?(name) - Puppet::Type.type(@name).validstate?(name) - end - - def self.to_s - "Fake%s" % @name.to_s.capitalize - end - - def [](param) - if @realmodel.attrtype(param) == :state - @is[param] - else - @params[param] - end - end - - def []=(param, value) - unless @realmodel.attrtype(param) - raise Puppet::DevError, "Invalid attribute %s for %s" % - [param, @realmodel.name] - end - if @realmodel.attrtype(param) == :state - @should[param] = value - else - @params[param] = value - end - end - - def initialize(name) - @realmodel = Puppet::Type.type(self.class.name) - raise "Could not find type #{self.class.name}" unless @realmodel - @is = {} - @should = {} - @params = {} - self[:name] = name - end - - def inspect - "%s(%s)" % [self.class.to_s.sub(/.+::/, ''), super()] - end - - def is(param) - @is[param] - end - - def should(param) - @should[param] - end - - def name - self[:name] - end - end - - class FakeProvider - attr_accessor :model - class << self - attr_accessor :name, :model, :methods - end - - # A very low number, so these never show up as defaults via the standard - # algorithms. - def self.defaultnum - -50 - end - - # Set up methods to fake things - def self.apimethods(*ary) - @model.validstates.each do |state| - ary << state unless ary.include? state - end - attr_accessor(*ary) - - @methods = ary - end - - def self.default? - false - end - - def self.initvars - @calls = Hash.new do |hash, key| - hash[key] = 0 - end - end - - def self.suitable? - true - end - - def clear - @model = nil - end - - def initialize(model) - @model = model - end - end - - @@fakemodels = {} - @@fakeproviders = {} - - def fakemodel(type, name, options = {}) - type = type.intern if type.is_a? String - unless @@fakemodels.include? type - @@fakemodels[type] = Class.new(FakeModel) - @@fakemodels[type].name = type - end - - obj = @@fakemodels[type].new(name) - obj[:name] = name - options.each do |name, val| - obj[name] = val - end - obj - end - - def fakeprovider(type, model) - type = type.intern if type.is_a? String - unless @@fakeproviders.include? type - @@fakeproviders[type] = Class.new(FakeModel) do - @name = type - end - end - - @@fakeproviders[type].new(model) - end - - def gcdebug(type) - Puppet.warning "%s: %s" % [type, ObjectSpace.each_object(type) { |o| }] - end - - def newcomp(*ary) - name = nil - if ary[0].is_a?(String) - name = ary.shift - else - name = ary[0].title - end - - comp = Puppet.type(:component).create( - :name => name - ) - ary.each { |item| - comp.push item - } - - return comp - end - - def setup - @memoryatstart = Puppet::Util.memory - if defined? @@testcount - @@testcount += 1 - else - @@testcount = 0 - end - - @configpath = File.join(tmpdir, - self.class.to_s + "configdir" + @@testcount.to_s + "/" - ) - - unless defined? $user and $group - $user = nonrootuser().uid.to_s - $group = nonrootgroup().gid.to_s - end - Puppet[:user] = $user - Puppet[:group] = $group - - Puppet[:confdir] = @configpath - Puppet[:vardir] = @configpath - - unless File.exists?(@configpath) - Dir.mkdir(@configpath) - end - - @@tmpfiles = [@configpath, tmpdir()] - @@tmppids = [] - - @@cleaners = [] - - if $0 =~ /.+\.rb/ or Puppet[:debug] - Puppet::Log.newdestination :console - Puppet::Log.level = :debug - #$VERBOSE = 1 - Puppet.info @method_name - else - Puppet::Log.close - Puppet::Log.newdestination tempfile() - Puppet[:httplog] = tempfile() - end - - Puppet[:ignoreschedules] = true - end - - def newobj(type, name, hash) - transport = Puppet::TransObject.new(name, "file") - transport[:path] = path - transport[:ensure] = "file" - assert_nothing_raised { - file = transport.to_type - } - end - - def spin - # Just disable spin, unless we really need it - return -# if Puppet[:debug] -# return -# end -# @modes = %w{| / - \\} -# unless defined? @mode -# @mode = 0 -# end -# -# $stderr.print "%s" % @modes[@mode] -# if @mode == @modes.length - 1 -# @mode = 0 -# else -# @mode += 1 -# end -# $stderr.flush - end - - # stop any services that might be hanging around - def stopservices - if stype = Puppet::Type.type(:service) - stype.each { |service| - service[:ensure] = :stopped - service.evaluate - } - end - end - - def cleanup(&block) - @@cleaners << block - end - - def setme - # retrieve the user name - id = %x{id}.chomp - if id =~ /uid=\d+\(([^\)]+)\)/ - @me = $1 - else - puts id - end - unless defined? @me - raise "Could not retrieve user name; 'id' did not work" - end - end - - def teardown - stopservices - - @@cleaners.each { |cleaner| cleaner.call() } - - @@tmpfiles.each { |file| - if FileTest.exists?(file) - system("chmod -R 755 %s" % file) - system("rm -rf %s" % file) - end - } - @@tmpfiles.clear - - @@tmppids.each { |pid| - %x{kill -INT #{pid} 2>/dev/null} - } - - @@tmppids.clear - Puppet::Type.allclear - Puppet::Storage.clear - Puppet::Rails.clear - Puppet.clear - - @memoryatend = Puppet::Util.memory - diff = @memoryatend - @memoryatstart - - if diff > 1000 - Puppet.info "%s#%s memory growth (%s to %s): %s" % - [self.class, @method_name, @memoryatstart, @memoryatend, diff] - end - - # reset all of the logs - Puppet::Log.close - - # Just in case there are processes waiting to die... - Process.waitall - if File.stat("/dev/null").mode & 007777 != 0666 - File.open("/tmp/nullfailure", "w") { |f| - f.puts self.class - } - exit(74) - end - end - - def tempfile - if defined? @@tmpfilenum - @@tmpfilenum += 1 - else - @@tmpfilenum = 1 - end - - f = File.join(self.tmpdir(), self.class.to_s + "_" + @method_name + - @@tmpfilenum.to_s) - @@tmpfiles << f - return f - end - - def tstdir - tempfile() - end - - def tmpdir - unless defined? @tmpdir and @tmpdir - @tmpdir = case Facter["operatingsystem"].value - when "Darwin": "/private/tmp" - when "SunOS": "/var/tmp" - else - "/tmp" - end - - - @tmpdir = File.join(@tmpdir, "puppettesting") - - unless File.exists?(@tmpdir) - FileUtils.mkdir_p(@tmpdir) - File.chmod(01777, @tmpdir) - end - end - @tmpdir - end - - def assert_rollback_events(events, trans, msg = nil) - run_events(:rollback, events, trans, msg) - end - - def assert_events(events, *items) - trans = nil - comp = nil - msg = nil - - unless events.is_a? Array - raise Puppet::DevError, "Incorrect call of assert_events" - end - if items[-1].is_a? String - msg = items.pop - end - - remove_comp = false - # They either passed a comp or a list of items. - if items[0].is_a? Puppet.type(:component) - comp = items.shift - else - comp = newcomp(items[0].title, *items) - remove_comp = true - end - msg ||= comp.title - assert_nothing_raised("Component %s failed" % [msg]) { - trans = comp.evaluate - } - - run_events(:evaluate, trans, events, msg) - - if remove_comp - Puppet.type(:component).delete(comp) - end - - return trans - end - - # A simpler method that just applies what we have. - def assert_apply(*objects) - if objects[0].is_a?(Puppet.type(:component)) - comp = objects.shift - unless objects.empty? - objects.each { |o| comp.push o } - end - else - comp = newcomp(*objects) - end - trans = nil - - assert_nothing_raised("Failed to create transaction") { - trans = comp.evaluate - } - - events = nil - assert_nothing_raised("Failed to evaluate transaction") { - events = trans.evaluate.collect { |e| e.event } - } - Puppet.type(:component).delete(comp) - events - end - - def run_events(type, trans, events, msg) - case type - when :evaluate, :rollback: # things are hunky-dory - else - raise Puppet::DevError, "Incorrect run_events type" - end - - method = type - - newevents = nil - assert_nothing_raised("Transaction %s %s failed" % [type, msg]) { - newevents = trans.send(method).reject { |e| e.nil? }.collect { |e| - e.event - } - } - - assert_equal(events, newevents, "Incorrect %s %s events" % [type, msg]) - - return trans - end - - def nonrootuser - Etc.passwd { |user| - if user.uid != Process.uid and user.uid > 0 - return user - end - } - end - - def nonrootgroup - Etc.group { |group| - if group.gid != Process.gid and group.gid > 0 - return group - end - } - end - - # If there are any fake data files, retrieve them - def fakedata(dir) - ary = [$puppetbase, "test"] - ary += dir.split("/") - dir = File.join(ary) - - unless FileTest.exists?(dir) - raise Puppet::DevError, "No fakedata dir %s" % dir - end - files = Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| - File.join(dir, f) - } - - return files - end - - def fakefile(name) - ary = [$puppetbase, "test"] - ary += name.split("/") - file = File.join(ary) - unless FileTest.exists?(file) - raise Puppet::DevError, "No fakedata file %s" % file - end - return file - end - - # wrap how to retrieve the masked mode - def filemode(file) - File.stat(file).mode & 007777 - end - - def memory - Puppet::Util.memory - end -end - - -module ServerTest - include TestPuppet - def setup - super - - if defined? @@port - @@port += 1 - else - @@port = 20000 - end - end - - # create a simple manifest that just creates a file - def mktestmanifest - file = File.join(Puppet[:confdir], "%ssite.pp" % (self.class.to_s + "test")) - #@createdfile = File.join(tmpdir(), self.class.to_s + "manifesttesting" + - # "_" + @method_name) - @createdfile = tempfile() - - File.open(file, "w") { |f| - f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile - } - - @@tmpfiles << @createdfile - @@tmpfiles << file - - return file - end - - # create a server, forked into the background - def mkserver(handlers = nil) - # our default handlers - unless handlers - handlers = { - :CA => {}, # so that certs autogenerate - :Master => { - :Manifest => mktestmanifest(), - :UseNodes => false - }, - } - end - - # then create the actual server - server = nil - assert_nothing_raised { - server = Puppet::Server.new( - :Port => @@port, - :Handlers => handlers - ) - } - - # fork it - spid = fork { - trap(:INT) { server.shutdown } - server.start - } - - # and store its pid for killing - @@tmppids << spid - - # give the server a chance to do its thing - sleep 1 - return spid - end - -end - -module ExeTest - include ServerTest - - def setup - super - setbindir - setlibdir - end - - def bindir - File.join($puppetbase, "bin") - end - - def setbindir - unless ENV["PATH"].split(":").include?(bindir) - ENV["PATH"] = [bindir, ENV["PATH"]].join(":") - end - end - - def setlibdir - ENV["RUBYLIB"] = $:.find_all { |dir| - dir =~ /puppet/ or dir =~ /\.\./ - }.join(":") - end - - # Run a ruby command. This explicitly uses ruby to run stuff, since we - # don't necessarily know where our ruby binary is, dernit. - # Currently unused, because I couldn't get it to work. - def rundaemon(*cmd) - @ruby ||= %x{which ruby}.chomp - cmd = cmd.unshift(@ruby).join(" ") - - out = nil - Dir.chdir(bindir()) { - out = %x{#{@ruby} #{cmd}} - } - return out - end - - def startmasterd(args = "") - output = nil - - manifest = mktestmanifest() - args += " --manifest %s" % manifest - args += " --confdir %s" % Puppet[:confdir] - args += " --vardir %s" % Puppet[:vardir] - args += " --masterport %s" % @@port - args += " --user %s" % Process.uid - args += " --group %s" % Process.gid - args += " --nonodes" - args += " --autosign true" - - #if Puppet[:debug] - # args += " --debug" - #end - - cmd = "puppetmasterd %s" % args - - - assert_nothing_raised { - output = %x{#{cmd}}.chomp - } - assert_equal("", output, "Puppetmasterd produced output %s" % output) - assert($? == 0, "Puppetmasterd exit status was %s" % $?) - sleep(1) - - cleanup do - stopmasterd - sleep(1) - end - - return manifest - end - - def stopmasterd(running = true) - ps = Facter["ps"].value || "ps -ef" - - pidfile = File.join(Puppet[:vardir], "run", "puppetmasterd.pid") - - pid = nil - if FileTest.exists?(pidfile) - pid = File.read(pidfile).chomp.to_i - File.unlink(pidfile) - end - - return unless running - if running or pid - runningpid = nil - %x{#{ps}}.chomp.split(/\n/).each { |line| - if line =~ /ruby.+puppetmasterd/ - next if line =~ /\.rb/ # skip the test script itself - next if line =~ /^puppet/ # skip masters running as 'puppet' - ary = line.sub(/^\s+/, '').split(/\s+/) - pid = ary[1].to_i - end - } - - end - - # we default to mandating that it's running, but teardown - # doesn't require that - if pid - if pid == $$ - raise Puppet::Error, "Tried to kill own pid" - end - begin - Process.kill(:INT, pid) - rescue - # ignore it - end - end - end - - def teardown - stopmasterd(false) - super - end -end - -module FileTesting - include TestPuppet - def cycle(comp) - trans = nil - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } - end - - def randlist(list) - num = rand(4) - if num == 0 - num = 1 - end - set = [] - - ret = [] - num.times { |index| - item = list[rand(list.length)] - if set.include?(item) - redo - end - - ret.push item - } - return ret - end - - def mkranddirsandfiles(dirs = nil,files = nil,depth = 3) - if depth < 0 - return - end - - unless dirs - dirs = %w{This Is A Set Of Directories} - end - - unless files - files = %w{and this is a set of files} - end - - tfiles = randlist(files) - tdirs = randlist(dirs) - - tfiles.each { |file| - File.open(file, "w") { |of| - 4.times { - of.puts rand(100) - } - } - } - - tdirs.each { |dir| - # it shouldn't already exist, but... - unless FileTest.exists?(dir) - Dir.mkdir(dir) - FileUtils.cd(dir) { - mkranddirsandfiles(dirs,files,depth - 1) - } - end - } - end - - def file_list(dir) - list = nil - FileUtils.cd(dir) { - list = %x{find . 2>/dev/null}.chomp.split(/\n/) - } - return list - end - - def assert_trees_equal(fromdir,todir) - assert(FileTest.directory?(fromdir)) - assert(FileTest.directory?(todir)) - - # verify the file list is the same - fromlist = nil - FileUtils.cd(fromdir) { - fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file| - ! FileTest.readable?(file) - }.sort - } - tolist = file_list(todir).sort - - fromlist.sort.zip(tolist.sort).each { |a,b| - assert_equal(a, b, - "Fromfile %s with length %s does not match tofile %s with length %s" % - [a, fromlist.length, b, tolist.length]) - } - #assert_equal(fromlist,tolist) - - # and then do some verification that the files are actually set up - # the same - checked = 0 - fromlist.each_with_index { |file,i| - fromfile = File.join(fromdir,file) - tofile = File.join(todir,file) - fromstat = File.stat(fromfile) - tostat = File.stat(tofile) - [:ftype,:gid,:mode,:uid].each { |method| - assert_equal( - fromstat.send(method), - tostat.send(method) - ) - - next if fromstat.ftype == "directory" - if checked < 10 and i % 3 == 0 - from = File.open(fromfile) { |f| f.read } - to = File.open(tofile) { |f| f.read } - - assert_equal(from,to) - checked += 1 - end - } - } - end - - def random_files(dir) - checked = 0 - list = file_list(dir) - list.reverse.each_with_index { |file,i| - path = File.join(dir,file) - stat = File.stat(dir) - if checked < 10 and (i % 3) == 2 - unless yield path - next - end - checked += 1 - end - } - end - - def delete_random_files(dir) - deleted = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - deleted << file - File.unlink(file) - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - - return deleted - end - - def add_random_files(dir) - added = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - name = File.join(file,"file" + rand(100).to_s) - File.open(name, "w") { |f| - f.puts rand(10) - } - added << name - else - false - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return added - end - - def modify_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - File.open(file, "w") { |f| - f.puts rand(10) - } - modded << name - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return modded - end - - def readonly_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - File.new(file).chmod(0111) - else - File.new(file).chmod(0000) - end - modded << file - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return modded - end - - def conffile - File.join($puppetbase,"examples/root/etc/configfile") - end -end - -module ParserTesting - include TestPuppet - AST = Puppet::Parser::AST - - def astarray(*args) - AST::ASTArray.new( - :children => args - ) - end - - def classobj(name, args = {}) - args[:type] ||= nameobj(name) - args[:code] ||= AST::ASTArray.new( - :file => __FILE__, - :line => __LINE__, - :children => [ - varobj("%svar" % name, "%svalue" % name), - fileobj("/%s" % name) - ] - ) - assert_nothing_raised("Could not create class %s" % name) { - return AST::ClassDef.new(args) - } - end - - def tagobj(*names) - args = {} - newnames = names.collect do |name| - if name.is_a? AST - name - else - nameobj(name) - end - end - args[:type] = astarray(*newnames) - assert_nothing_raised("Could not create tag %s" % names.inspect) { - return AST::Tag.new(args) - } - end - - def compobj(name, args = {}) - args[:file] ||= tempfile() - args[:line] ||= rand(100) - args[:type] ||= nameobj(name) - args[:args] ||= AST::ASTArray.new( - :file => tempfile(), - :line => rand(100), - :children => [] - ) - args[:code] ||= AST::ASTArray.new( - :file => tempfile(), - :line => rand(100), - :children => [ - varobj("%svar" % name, "%svalue" % name), - fileobj("/%s" % name) - ] - ) - assert_nothing_raised("Could not create compdef %s" % name) { - return AST::CompDef.new(args) - } - end - - def objectdef(type, name, params) - assert_nothing_raised("Could not create %s %s" % [type, name]) { - return AST::ObjectDef.new( - :file => __FILE__, - :line => __LINE__, - :name => stringobj(name), - :type => nameobj(type), - :params => objectinst(params) - ) - } - end - - def fileobj(path, hash = {"owner" => "root"}) - assert_nothing_raised("Could not create file %s" % path) { - return objectdef("file", path, hash) -# return AST::ObjectDef.new( -# :file => tempfile(), -# :line => rand(100), -# :name => stringobj(path), -# :type => nameobj("file"), -# :params => objectinst(hash) -# ) - } - end - - def nameobj(name) - assert_nothing_raised("Could not create name %s" % name) { - return AST::Name.new( - :file => tempfile(), - :line => rand(100), - :value => name - ) - } - end - - def typeobj(name) - assert_nothing_raised("Could not create type %s" % name) { - return AST::Type.new( - :file => tempfile(), - :line => rand(100), - :value => name - ) - } - end - - def nodedef(name) - assert_nothing_raised("Could not create node %s" % name) { - return AST::NodeDef.new( - :file => tempfile(), - :line => rand(100), - :names => nameobj(name), - :code => AST::ASTArray.new( - :children => [ - varobj("%svar" % name, "%svalue" % name), - fileobj("/%s" % name) - ] - ) - ) - } - end - - def objectinst(hash) - assert_nothing_raised("Could not create object instance") { - params = hash.collect { |param, value| - objectparam(param, value) - } - return AST::ObjectInst.new( - :file => tempfile(), - :line => rand(100), - :children => params - ) - } - end - - def objectparam(param, value) - # Allow them to pass non-strings in - if value.is_a?(String) - value = stringobj(value) - end - assert_nothing_raised("Could not create param %s" % param) { - return AST::ObjectParam.new( - :file => tempfile(), - :line => rand(100), - :param => nameobj(param), - :value => value - ) - } - end - - def stringobj(value) - AST::String.new( - :file => tempfile(), - :line => rand(100), - :value => value - ) - end - - def varobj(name, value) - unless value.is_a? AST - value = stringobj(value) - end - assert_nothing_raised("Could not create %s code" % name) { - return AST::VarDef.new( - :file => tempfile(), - :line => rand(100), - :name => nameobj(name), - :value => value - ) - } - end - - def varref(name) - assert_nothing_raised("Could not create %s variable" % name) { - return AST::Variable.new( - :file => __FILE__, - :line => __LINE__, - :value => name - ) - } - end - - def argobj(name, value) - assert_nothing_raised("Could not create %s compargument" % name) { - return AST::CompArgument.new( - :children => [nameobj(name), stringobj(value)] - ) - } - end - - def defaultobj(type, params) - pary = [] - params.each { |p,v| - pary << AST::ObjectParam.new( - :file => __FILE__, - :line => __LINE__, - :param => nameobj(p), - :value => stringobj(v) - ) - } - past = AST::ASTArray.new( - :file => __FILE__, - :line => __LINE__, - :children => pary - ) - - assert_nothing_raised("Could not create defaults for %s" % type) { - return AST::TypeDefaults.new( - :file => __FILE__, - :line => __LINE__, - :type => typeobj(type), - :params => past - ) - } - end - - def taggedobj(name, ftype = :statement) - functionobj("tagged", name, ftype) - end - - def functionobj(function, name, ftype = :statement) - func = nil - assert_nothing_raised do - func = Puppet::Parser::AST::Function.new( - :name => function, - :ftype => ftype, - :arguments => AST::ASTArray.new( - :children => [nameobj(name)] - ) - ) - end - - return func - end - - # This assumes no nodes - def assert_creates(manifest, *files) - interp = nil - assert_nothing_raised { - interp = Puppet::Parser::Interpreter.new( - :Manifest => manifest, - :UseNodes => false - ) - } - - config = nil - assert_nothing_raised { - config = interp.run(Facter["hostname"].value, {}) - } - - comp = nil - assert_nothing_raised { - comp = config.to_type - } - - assert_apply(comp) - - files.each do |file| - assert(FileTest.exists?(file), "Did not create %s" % file) - end - end - - def mk_transobject(file = "/etc/passwd") - obj = nil - assert_nothing_raised { - obj = Puppet::TransObject.new("file", file) - obj["owner"] = "root" - obj["mode"] = "644" - } - - return obj - end - - def mk_transbucket(*objects) - bucket = nil - assert_nothing_raised { - bucket = Puppet::TransBucket.new - bucket.name = "yayname" - bucket.type = "yaytype" - } - - objects.each { |o| bucket << o } - - return bucket - end - - # Make a tree of objects, yielding if desired - def mk_transtree(depth = 4, width = 2) - top = nil - assert_nothing_raised { - top = Puppet::TransBucket.new - top.name = "top" - top.type = "bucket" - } - - bucket = top - - file = tempfile() - depth.times do |i| - objects = [] - width.times do |j| - path = tempfile + i.to_s - obj = Puppet::TransObject.new("file", path) - obj["owner"] = "root" - obj["mode"] = "644" - - # Yield, if they want - if block_given? - yield(obj, i, j) - end - - objects << obj - end - - newbucket = mk_transbucket(*objects) - - bucket.push newbucket - bucket = newbucket - end - - return top - end - - # Take a list of AST objects, evaluate them, and return the results - def assert_evaluate(children) - top = nil - assert_nothing_raised("Could not create top object") { - top = AST::ASTArray.new( - :children => children - ) - } - - trans = nil - scope = nil - assert_nothing_raised { - scope = Puppet::Parser::Scope.new() - trans = scope.evaluate(:ast => top) - } - - return trans - end -end - -class PuppetTestSuite - attr_accessor :subdir - - def self.basedir - unless defined? @basedir - @basedir = File.join($puppetbase, "test") - end - @basedir - end - - def self.list - Dir.entries(self.basedir).find_all { |file| - path = File.join(@basedir, file) - # Data is for storing test data - FileTest.directory?(path) and file !~ /^\./ and file != "data" and - file != "lib" - } - end - - def initialize(name) - path = File.join(self.class.basedir, name) - if FileTest.directory?(path) - # load each of the files - Dir.entries(path).collect { |file| - File.join(path,file) - }.find_all { |file| - FileTest.file?(file) and file =~ /\.rb$/ - }.sort { |a,b| - # in the order they were modified, so the last modified files - # are loaded and thus displayed last - File.stat(b) <=> File.stat(a) - }.each { |file| - require file - } - elsif FileTest.file?(path) && path =~ /\.rb$/ - require path - else - puts "TestSuites are directories or files containing test cases" - puts "no such directory: %s" % path - exit(65) - end - end -end - -# a list of files that we can parse for testing -def textfiles - textdir = File.join($puppetbase,"examples","code", "snippets") - Dir.entries(textdir).reject { |f| - f =~ /^\./ or f =~ /fail/ - }.each { |f| - yield File.join(textdir, f) - } -end - -def failers - textdir = File.join($puppetbase,"examples","code", "failers") - # only parse this one file now - files = Dir.entries(textdir).reject { |file| - file =~ %r{\.swp} - }.reject { |file| - file =~ %r{\.disabled} - }.collect { |file| - File.join(textdir,file) - }.find_all { |file| - FileTest.file?(file) - }.sort.each { |file| - Puppet.debug "Processing %s" % file - yield file - } -end - -# $Id$ diff --git a/test/server/authconfig.rb b/test/server/authconfig.rb index 32ae46dff..a5a0a1c00 100755 --- a/test/server/authconfig.rb +++ b/test/server/authconfig.rb @@ -1,56 +1,49 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/authconfig' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestAuthConfig < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_parsingconfigfile file = tempfile() assert(Puppet[:authconfig], "No config path") Puppet[:authconfig] = file File.open(file, "w") { |f| f.puts "[pelementserver.describe] allow *.madstop.com deny 10.10.1.1 [fileserver] allow *.madstop.com deny 10.10.1.1 [fileserver.list] allow 10.10.1.1 " } config = nil assert_nothing_raised { config = Puppet::Server::AuthConfig.new(file) } assert_nothing_raised { assert(config.allowed?("pelementserver.describe", "culain.madstop.com", "1.1.1.1"), "Did not allow host") assert(! config.allowed?("pelementserver.describe", "culain.madstop.com", "10.10.1.1"), "Allowed host") assert(config.allowed?("fileserver.yay", "culain.madstop.com", "10.1.1.1"), "Did not allow host to fs") assert(! config.allowed?("fileserver.yay", "culain.madstop.com", "10.10.1.1"), "Allowed host to fs") assert(config.allowed?("fileserver.list", "culain.madstop.com", "10.10.1.1"), "Did not allow host to fs.list") } end end # $Id$ diff --git a/test/server/authstore.rb b/test/server/authstore.rb index db580d68e..30eb5ea04 100755 --- a/test/server/authstore.rb +++ b/test/server/authstore.rb @@ -1,218 +1,207 @@ -if __FILE__ == $0 - if Dir.getwd =~ /test\/server$/ - Dir.chdir("..") - end - - $:.unshift '../lib' - $puppetbase = ".." - -end - require 'puppet' require 'puppet/server/authstore' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestAuthStore < Test::Unit::TestCase - include TestPuppet + include PuppetTest def mkstore store = nil assert_nothing_raised { store = Puppet::Server::AuthStore.new } return store end def test_localallow store = mkstore assert_nothing_raised { assert(store.allowed?(nil, nil), "Store disallowed local access") } assert_raise(Puppet::DevError) { store.allowed?("kirby.madstop.com", nil) } assert_raise(Puppet::DevError) { store.allowed?(nil, "192.168.0.1") } end def test_hostnames store = mkstore %w{ kirby.madstop.com luke.madstop.net name-other.madstop.net }.each { |name| assert_nothing_raised("Failed to store simple name %s" % name) { store.allow(name) } assert(store.allowed?(name, "192.168.0.1"), "Name %s not allowed" % name) } %w{ invalid ^invalid! inval$id }.each { |pat| assert_raise(Puppet::Server::AuthStoreError, "name '%s' was allowed" % pat) { store.allow(pat) } } end def test_domains store = mkstore assert_nothing_raised("Failed to store domains") { store.allow("*.a.very.long.domain.name.com") store.allow("*.madstop.com") store.allow("*.some-other.net") store.allow("*.much.longer.more-other.net") } %w{ madstop.com culain.madstop.com kirby.madstop.com funtest.some-other.net ya-test.madstop.com some.much.much.longer.more-other.net }.each { |name| assert(store.allowed?(name, "192.168.0.1"), "Host %s not allowed" % name) } assert_raise(Puppet::Server::AuthStoreError) { store.allow("domain.*.com") } assert(!store.allowed?("very.long.domain.name.com", "1.2.3.4"), "Long hostname allowed") assert_raise(Puppet::Server::AuthStoreError) { store.allow("domain.*.other.com") } end def test_simpleips store = mkstore %w{ 192.168.0.5 7.0.48.7 }.each { |ip| assert_nothing_raised("Failed to store IP address %s" % ip) { store.allow(ip) } assert(store.allowed?("hosttest.com", ip), "IP %s not allowed" % ip) } #assert_raise(Puppet::Server::AuthStoreError) { # store.allow("192.168.674.0") #} assert_raise(Puppet::Server::AuthStoreError) { store.allow("192.168.0") } end def test_ipranges store = mkstore %w{ 192.168.0.* 192.168.1.0/24 192.178.* 193.179.0.0/8 }.each { |range| assert_nothing_raised("Failed to store IP range %s" % range) { store.allow(range) } } %w{ 192.168.0.1 192.168.1.5 192.178.0.5 193.0.0.1 }.each { |ip| assert(store.allowed?("fakename.com", ip), "IP %s is not allowed" % ip) } end def test_iprangedenials store = mkstore assert_nothing_raised("Failed to store overlapping IP ranges") { store.allow("192.168.0.0/16") store.deny("192.168.0.0/24") } assert(store.allowed?("fake.name", "192.168.1.50"), "/16 ip not allowed") assert(! store.allowed?("fake.name", "192.168.0.50"), "/24 ip allowed") end def test_subdomaindenails store = mkstore assert_nothing_raised("Failed to store overlapping IP ranges") { store.allow("*.madstop.com") store.deny("*.sub.madstop.com") } assert(store.allowed?("hostname.madstop.com", "192.168.1.50"), "hostname not allowed") assert(! store.allowed?("name.sub.madstop.com", "192.168.0.50"), "subname name allowed") end def test_orderingstuff store = mkstore assert_nothing_raised("Failed to store overlapping IP ranges") { store.allow("*.madstop.com") store.deny("192.168.0.0/24") } assert(store.allowed?("hostname.madstop.com", "192.168.1.50"), "hostname not allowed") assert(! store.allowed?("hostname.madstop.com", "192.168.0.50"), "Host allowed over IP") end def test_globalallow store = mkstore assert_nothing_raised("Failed to add global allow") { store.allow("*") } [ %w{hostname.com 192.168.0.4}, %w{localhost 192.168.0.1}, %w{localhost 127.0.0.1} ].each { |ary| assert(store.allowed?(*ary), "Failed to allow %s" % [ary.join(",")]) } end # Make sure people can specify TLDs def test_match_tlds store = mkstore assert_nothing_raised { store.allow("*.tld") } end end # $Id$ diff --git a/test/server/bucket.rb b/test/server/bucket.rb index af2fd0865..dcb50d27e 100644 --- a/test/server/bucket.rb +++ b/test/server/bucket.rb @@ -1,266 +1,256 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." - $debug = true -else - $debug = false -end - require 'puppet' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' require 'base64' class TestBucket < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def out if defined? @num @num += 1 else @num = 1 end #Puppet.err "#{Process.pid}: %s: %s" % [@num, memory()] #gcdebug(String) end # run through all of the files and exercise the filebucket methods def checkfiles(client) files = filelist() #files = %w{/usr/local/bin/vim /etc/motd /etc/motd /etc/motd /etc/motd} #files = %w{/usr/local/bin/vim} # iterate across all of the files files.each { |file| Puppet.warning file out tempdir = tempfile() Dir.mkdir(tempdir) name = File.basename(file) tmppath = File.join(tempdir,name) @@tmpfiles << tmppath out # copy the files to our tmp directory so we can modify them... FileUtils.cp(file, tmppath) # make sure the copy worked assert(FileTest.exists?(tmppath)) # backup both the orig file and the tmp file osum = nil tsum = nil nsum = nil out assert_nothing_raised { osum = client.backup(file) } out assert_nothing_raised { tsum = client.backup(tmppath) } out # verify you got the same sum back for both assert(tsum == osum) # modify our tmp file unless FileTest.writable?(tmppath) File.chmod(0644, tmppath) end File.open(tmppath,File::WRONLY|File::TRUNC) { |wf| wf.print "This is some test text\n" } out # back it up assert_nothing_raised { #STDERR.puts("backing up %s" % tmppath) if $debug nsum = client.backup(tmppath) } out # and verify the sum changed assert(tsum != nsum) # restore the orig assert_nothing_raised { nsum = client.restore(tmppath,tsum) } out # and verify it actually got restored contents = File.open(tmppath) { |rf| #STDERR.puts("reading %s" % tmppath) if $debug rf.read } out csum = Digest::MD5.hexdigest(contents) out assert(tsum == csum) } end # a list of files that should be on the system # just something to test moving files around def filelist if defined? @files return @files else @files = [] end %w{ who bash sh uname /etc/passwd /etc/syslog.conf /etc/hosts }.each { |file| # if it's fully qualified, just add it if file =~ /^\// if FileTest.exists?(file) @files.push file end else # else if it's unqualified, look for it in our path begin path = %x{which #{file}} rescue => detail #STDERR.puts "Could not search for binaries: %s" % detail next end if path != "" @files.push path.chomp end end } return @files end def setup super @bucket = tempfile() end #def teardown # system("lsof -p %s" % Process.pid) # super #end # test operating against the local filebucket object # this calls the direct server methods, which are different than the # Dipper methods def test_localserver files = filelist() server = nil assert_nothing_raised { server = Puppet::Server::FileBucket.new( :Bucket => @bucket ) } # iterate across them... files.each { |file| contents = File.open(file) { |of| of.read } md5 = nil # add a file to the repository assert_nothing_raised { #STDERR.puts("adding %s" % file) if $debug md5 = server.addfile(Base64.encode64(contents),file) } # and get it back again newcontents = nil assert_nothing_raised { #STDERR.puts("getting %s" % file) if $debug newcontents = Base64.decode64(server.getfile(md5)) } # and then make sure they're still the same assert( contents == newcontents ) } end # test with a server and a Dipper def test_localboth files = filelist() bucket = nil client = nil threads = [] assert_nothing_raised { bucket = Puppet::Server::FileBucket.new( :Bucket => @bucket ) } #sleep(30) assert_nothing_raised { client = Puppet::Client::Dipper.new( :Bucket => bucket ) } #4.times { checkfiles(client) } checkfiles(client) end # test that things work over the wire def test_webxmlmix files = filelist() tmpdir = File.join(tmpdir(),"tmpfiledir") @@tmpfiles << tmpdir FileUtils.mkdir_p(tmpdir) Puppet[:autosign] = true client = nil port = Puppet[:masterport] pid = mkserver(:CA => {}, :FileBucket => { :Bucket => @bucket}) assert_nothing_raised { client = Puppet::Client::Dipper.new( :Server => "localhost", :Port => @@port ) } checkfiles(client) unless pid raise "Uh, we don't have a child pid" end Process.kill("TERM", pid) end def test_no_path_duplicates bucket = nil assert_nothing_raised { bucket = Puppet::Server::FileBucket.new( :Bucket => @bucket ) } sum = nil assert_nothing_raised { sum = bucket.addfile("yayness", "/my/file") } assert_nothing_raised { bucket.addfile("yayness", "/my/file") } pathfile = File.join(bucket.path, sum, "paths") assert(FileTest.exists?(pathfile), "No path file at %s" % pathfile) assert_equal("/my/file\n", File.read(pathfile)) end end # $Id$ diff --git a/test/server/ca.rb b/test/server/ca.rb index b7bad5cd6..8be0df334 100644 --- a/test/server/ca.rb +++ b/test/server/ca.rb @@ -1,239 +1,232 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/ca' require 'puppet/sslcertificates' require 'openssl' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' # $Id$ if ARGV.length > 0 and ARGV[0] == "short" $short = true else $short = false end class TestCA < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest # Verify that we're autosigning. We have to autosign a "different" machine, # since we always autosign the CA server's certificate. def test_autocertgeneration ca = nil # create our ca assert_nothing_raised { ca = Puppet::Server::CA.new(:autosign => true) } # create a cert with a fake name key = nil csr = nil cert = nil hostname = "test.domain.com" assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "test.domain.com" ) } # make the request assert_nothing_raised { cert.mkcsr } # and get it signed certtext = nil cacerttext = nil assert_nothing_raised { certtext, cacerttext = ca.getcert(cert.csr.to_s) } # they should both be strings assert_instance_of(String, certtext) assert_instance_of(String, cacerttext) # and they should both be valid certs assert_nothing_raised { OpenSSL::X509::Certificate.new(certtext) } assert_nothing_raised { OpenSSL::X509::Certificate.new(cacerttext) } # and pull it again, just to make sure we're getting the same thing newtext = nil assert_nothing_raised { newtext, cacerttext = ca.getcert( cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1" ) } assert_equal(certtext,newtext) end # this time don't use autosign def test_storeAndSign ca = nil caserv = nil # make our CA server assert_nothing_raised { caserv = Puppet::Server::CA.new(:autosign => false) } # retrieve the actual ca object assert_nothing_raised { ca = caserv.ca } # make our test cert again key = nil csr = nil cert = nil hostname = "test.domain.com" assert_nothing_raised { cert = Puppet::SSLCertificates::Certificate.new( :name => "anothertest.domain.com" ) } # and the CSR assert_nothing_raised { cert.mkcsr } # retrieve them certtext = nil assert_nothing_raised { certtext, cacerttext = caserv.getcert( cert.csr.to_s, "test.reductivelabs.com", "127.0.0.1" ) } # verify we got nothing back, since autosign is off assert_equal("", certtext) # now sign it manually, with the CA object x509 = nil assert_nothing_raised { x509, cacert = ca.sign(cert.csr) } # and write it out cert.cert = x509 assert_nothing_raised { cert.write } assert(File.exists?(cert.certfile)) # now get them again, and verify that we actually get them newtext = nil assert_nothing_raised { newtext, cacerttext = caserv.getcert(cert.csr.to_s) } assert(newtext) assert_nothing_raised { OpenSSL::X509::Certificate.new(newtext) } # Now verify that we can clean a given host's certs assert_nothing_raised { ca.clean("anothertest.domain.com") } assert(!File.exists?(cert.certfile), "Cert still exists after clean") end # and now test the autosign file def test_autosign autosign = File.join(tmpdir, "autosigntesting") @@tmpfiles << autosign File.open(autosign, "w") { |f| f.puts "hostmatch.domain.com" f.puts "*.other.com" } caserv = nil assert_nothing_raised { caserv = Puppet::Server::CA.new(:autosign => autosign) } # make sure we know what's going on assert(caserv.autosign?("hostmatch.domain.com")) assert(caserv.autosign?("fakehost.other.com")) assert(!caserv.autosign?("kirby.reductivelabs.com")) assert(!caserv.autosign?("culain.domain.com")) end # verify that things aren't autosigned by default def test_nodefaultautosign caserv = nil assert_nothing_raised { caserv = Puppet::Server::CA.new() } # make sure we know what's going on assert(!caserv.autosign?("hostmatch.domain.com")) assert(!caserv.autosign?("fakehost.other.com")) assert(!caserv.autosign?("kirby.reductivelabs.com")) assert(!caserv.autosign?("culain.domain.com")) end # We want the CA to autosign its own certificate, because otherwise # the puppetmasterd CA does not autostart. def test_caautosign server = nil assert_nothing_raised { server = Puppet::Server.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Status => nil } ) } end # Make sure true/false causes the file to be ignored. def test_autosign_true_beats_file caserv = nil assert_nothing_raised { caserv = Puppet::Server::CA.new() } host = "hostname.domain.com" # Create an autosign file file = tempfile() Puppet[:autosign] = file File.open(file, "w") { |f| f.puts host } # Start with "false" Puppet[:autosign] = false assert(! caserv.autosign?(host), "Host was incorrectly autosigned") # Then set it to true Puppet[:autosign] = true assert(caserv.autosign?(host), "Host was not autosigned") # And try a different host assert(caserv.autosign?("other.yay.com"), "Host was not autosigned") # And lastly the file Puppet[:autosign] = file assert(caserv.autosign?(host), "Host was not autosigned") # And try a different host assert(! caserv.autosign?("other.yay.com"), "Host was autosigned") end end diff --git a/test/server/fileserver.rb b/test/server/fileserver.rb index b42b1712f..e7aaa6017 100755 --- a/test/server/fileserver.rb +++ b/test/server/fileserver.rb @@ -1,1031 +1,1019 @@ -if __FILE__ == $0 - if Dir.getwd =~ /test\/server$/ - Dir.chdir("..") - end - - $:.unshift '../lib' - $puppetbase = ".." - -end - require 'puppet' require 'puppet/server/fileserver' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestFileServer < Test::Unit::TestCase - include TestPuppet + include PuppetTest def mkmount(path = nil) mount = nil name = "yaytest" base = path || tempfile() unless FileTest.exists?(base) Dir.mkdir(base) end # Create a test file File.open(File.join(base, "file"), "w") { |f| f.puts "bazoo" } assert_nothing_raised { mount = Puppet::Server::FileServer::Mount.new(name, base) } return mount end # make a simple file source def mktestdir testdir = File.join(tmpdir(), "remotefilecopytesting") @@tmpfiles << testdir # create a tmpfile pattern = "tmpfile" tmpfile = File.join(testdir, pattern) assert_nothing_raised { Dir.mkdir(testdir) File.open(tmpfile, "w") { |f| 3.times { f.puts rand(100) } } } return [testdir, %r{#{pattern}}, tmpfile] end # make a bunch of random test files def mktestfiles(testdir) @@tmpfiles << testdir assert_nothing_raised { - Dir.mkdir(testdir) files = %w{a b c d e}.collect { |l| name = File.join(testdir, "file%s" % l) File.open(name, "w") { |f| f.puts rand(100) } name } return files } end def assert_describe(base, file, server) file = File.basename(file) assert_nothing_raised { desc = server.describe(base + file) assert(desc, "Got no description for %s" % file) assert(desc != "", "Got no description for %s" % file) assert_match(/^\d+/, desc, "Got invalid description %s" % desc) } end # test for invalid names def test_namefailures server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_raise(Puppet::FileServerError) { server.mount("/tmp", "invalid+name") } assert_raise(Puppet::FileServerError) { server.mount("/tmp", "invalid-name") } assert_raise(Puppet::FileServerError) { server.mount("/tmp", "invalid name") } assert_raise(Puppet::FileServerError) { server.mount("/tmp", "") } end # verify that listing the root behaves as expected def test_listroot server = nil testdir, pattern, tmpfile = mktestdir() file = nil checks = Puppet::Server::FileServer::CHECKPARAMS # and make our fileserver assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } # mount the testdir assert_nothing_raised { server.mount(testdir, "test") } # and verify different iterations of 'root' return the same value list = nil assert_nothing_raised { list = server.list("/test/", :ignore, true, false) } assert(list =~ pattern) assert_nothing_raised { list = server.list("/test", :ignore, true, false) } assert(list =~ pattern) end # test listing individual files def test_getfilelist server = nil testdir, pattern, tmpfile = mktestdir() file = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_nothing_raised { server.mount(testdir, "test") } # get our listing list = nil sfile = "/test/tmpfile" assert_nothing_raised { list = server.list(sfile, :ignore, true, false) } assert_nothing_raised { file = Puppet.type(:file)[tmpfile] } output = "/\tfile" # verify it got listed as a file assert_equal(output, list) # verify we got all fields assert(list !~ /\t\t/) # verify that we didn't get the directory itself list.split("\n").each { |line| assert(line !~ %r{remotefile}) } # and then verify that the contents match contents = File.read(tmpfile) ret = nil assert_nothing_raised { ret = server.retrieve(sfile) } assert_equal(contents, ret) end # check that the fileserver is seeing newly created files def test_seenewfiles server = nil testdir, pattern, tmpfile = mktestdir() newfile = File.join(testdir, "newfile") # go through the whole schtick again... file = nil checks = Puppet::Server::FileServer::CHECKPARAMS assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_nothing_raised { server.mount(testdir, "test") } list = nil sfile = "/test/" assert_nothing_raised { list = server.list(sfile, :ignore, true, false) } # create the new file File.open(newfile, "w") { |f| 3.times { f.puts rand(100) } } newlist = nil assert_nothing_raised { newlist = server.list(sfile, :ignore, true, false) } # verify the list has changed assert(list != newlist) # and verify that we are specifically seeing the new file assert(newlist =~ /newfile/) end # verify we can mount /, which is what local file servers will # normally do def test_zmountroot server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_nothing_raised { server.mount("/", "root") } testdir, pattern, tmpfile = mktestdir() list = nil assert_nothing_raised { list = server.list("/root/" + testdir, :ignore, true, false) } assert(list =~ pattern) assert_nothing_raised { list = server.list("/root" + testdir, :ignore, true, false) } assert(list =~ pattern) end # verify that we're correctly recursing the right number of levels def test_recursionlevels server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } # make our deep recursion basedir = File.join(tmpdir(), "recurseremotetesting") testdir = "%s/with/some/sub/directories/for/the/purposes/of/testing" % basedir oldfile = File.join(testdir, "oldfile") assert_nothing_raised { system("mkdir -p %s" % testdir) File.open(oldfile, "w") { |f| 3.times { f.puts rand(100) } } @@tmpfiles << basedir } assert_nothing_raised { server.mount(basedir, "test") } # get our list list = nil assert_nothing_raised { list = server.list("/test/with", :ignore, false, false) } # make sure we only got one line, since we're not recursing assert(list !~ /\n/) # for each level of recursion, make sure we get the right list [0, 1, 2].each { |num| assert_nothing_raised { list = server.list("/test/with", :ignore, num, false) } count = 0 while list =~ /\n/ list.sub!(/\n/, '') count += 1 end assert_equal(num, count) } end # verify that we're not seeing the dir we ask for; i.e., that our # list is relative to that dir, not it's parent dir def test_listedpath server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } # create a deep dir basedir = tempfile() testdir = "%s/with/some/sub/directories/for/testing" % basedir oldfile = File.join(testdir, "oldfile") assert_nothing_raised { system("mkdir -p %s" % testdir) File.open(oldfile, "w") { |f| 3.times { f.puts rand(100) } } @@tmpfiles << basedir } # mounty mounty assert_nothing_raised { server.mount(basedir, "localhost") } list = nil # and then check a few dirs assert_nothing_raised { list = server.list("/localhost/with", :ignore, false, false) } assert(list !~ /with/) assert_nothing_raised { list = server.list("/localhost/with/some/sub", :ignore, true, false) } assert(list !~ /sub/) end # test many dirs, not necessarily very deep def test_widelists server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } basedir = tempfile() dirs = %w{a set of directories} assert_nothing_raised { Dir.mkdir(basedir) dirs.each { |dir| Dir.mkdir(File.join(basedir, dir)) } @@tmpfiles << basedir } assert_nothing_raised { server.mount(basedir, "localhost") } list = nil assert_nothing_raised { list = server.list("/localhost/", :ignore, 1, false) } assert_instance_of(String, list, "Server returned %s instead of string") list = list.split("\n") assert_equal(dirs.length + 1, list.length) end # verify that 'describe' works as advertised def test_describe server = nil testdir = tempfile() files = mktestfiles(testdir) file = nil checks = Puppet::Server::FileServer::CHECKPARAMS assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_nothing_raised { server.mount(testdir, "test") } # get our list list = nil sfile = "/test/" assert_nothing_raised { list = server.list(sfile, :ignore, true, false) } # and describe each file in the list assert_nothing_raised { list.split("\n").each { |line| file, type = line.split("\t") desc = server.describe(sfile + file) } } # and then make sure we can describe everything that we know is there files.each { |file| assert_describe(sfile, file, server) } # And then describe some files that we know aren't there retval = nil assert_nothing_raised("Describing non-existent files raised an error") { retval = server.describe(sfile + "noexisties") } assert_equal("", retval, "Description of non-existent files returned a value") # Now try to describe some sources that don't even exist retval = nil assert_raise(Puppet::FileServerError, "Describing non-existent mount did not raise an error") { retval = server.describe("/notmounted/" + "noexisties") } assert_nil(retval, "Description of non-existent mounts returned a value") end # test that our config file is parsing and working as planned def test_configfile server = nil basedir = File.join(tmpdir, "fileserverconfigfiletesting") @@tmpfiles << basedir # make some dirs for mounting Dir.mkdir(basedir) mounts = {} %w{thing thus these those}.each { |dir| path = File.join(basedir, dir) mounts[dir] = mktestfiles(path) } # create an example file with each of them conffile = tempfile @@tmpfiles << conffile File.open(conffile, "w") { |f| f.print "# a test config file [thing] path #{basedir}/thing allow 192.168.0.* [thus] path #{basedir}/thus allow *.madstop.com, *.kanies.com deny *.sub.madstop.com [these] path #{basedir}/these [those] path #{basedir}/those " } # create a server with the file assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => conffile ) } list = nil # run through once with no host/ip info, to verify everything is working mounts.each { |mount, files| mount = "/#{mount}/" assert_nothing_raised { list = server.list(mount, :ignore, true, false) } assert_nothing_raised { list.split("\n").each { |line| file, type = line.split("\t") desc = server.describe(mount + file) } } files.each { |f| assert_describe(mount, f, server) } } # now let's check that things are being correctly forbidden # this is just a map of names and expected results { "thing" => { :deny => [ ["hostname.com", "192.168.1.0"], ["hostname.com", "192.158.0.0"] ], :allow => [ ["hostname.com", "192.168.0.0"], ["hostname.com", "192.168.0.245"], ] }, "thus" => { :deny => [ ["hostname.com", "192.168.1.0"], ["name.sub.madstop.com", "192.158.0.0"] ], :allow => [ ["luke.kanies.com", "192.168.0.0"], ["luke.madstop.com", "192.168.0.245"], ] } }.each { |mount, hash| mount = "/#{mount}/" # run through the map hash.each { |type, ary| ary.each { |sub| host, ip = sub case type when :deny: assert_raise(Puppet::Server::AuthorizationError, "Host %s, ip %s, allowed %s" % [host, ip, mount]) { list = server.list(mount, :ignore, true, false, host, ip) } when :allow: assert_nothing_raised("Host %s, ip %s, denied %s" % [host, ip, mount]) { list = server.list(mount, :ignore, true, false, host, ip) } end } } } end # Test that we smoothly handle invalid config files def test_configfailures # create an example file with each of them conffile = tempfile() invalidmounts = { "noexist" => "[noexist] path /this/path/does/not/exist allow 192.168.0.* " } invalidconfigs = [ "[not valid] path /this/path/does/not/exist allow 192.168.0.* ", "[valid] invalidstatement path /etc allow 192.168.0.* ", "[valid] allow 192.168.0.* " ] invalidmounts.each { |mount, text| File.open(conffile, "w") { |f| f.print text } # create a server with the file server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => conffile ) } assert_raise(Puppet::FileServerError, "Invalid mount was mounted") { server.list(mount, :ignore) } } invalidconfigs.each_with_index { |text, i| File.open(conffile, "w") { |f| f.print text } # create a server with the file server = nil assert_raise(Puppet::FileServerError, "Invalid config %s did not raise error" % i) { server = Puppet::Server::FileServer.new( :Local => true, :Config => conffile ) } } end # verify we reread the config file when it changes def test_filereread server = nil conffile = tempfile() dir = tstdir() files = mktestfiles(dir) File.open(conffile, "w") { |f| f.print "# a test config file [thing] path #{dir} allow test1.domain.com " } # Reset the timeout, so we reload faster Puppet[:filetimeout] = 0.5 # start our server with a fast timeout assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => conffile ) } list = nil assert_nothing_raised { list = server.list("/thing/", :ignore, false, false, "test1.domain.com", "127.0.0.1") } assert(list != "", "List returned nothing in rereard test") assert_raise(Puppet::Server::AuthorizationError, "List allowed invalid host") { list = server.list("/thing/", :ignore, false, false, "test2.domain.com", "127.0.0.1") } sleep 1 File.open(conffile, "w") { |f| f.print "# a test config file [thing] path #{dir} allow test2.domain.com " } assert_raise(Puppet::Server::AuthorizationError, "List allowed invalid host") { list = server.list("/thing/", :ignore, false, false, "test1.domain.com", "127.0.0.1") } assert_nothing_raised { list = server.list("/thing/", :ignore, false, false, "test2.domain.com", "127.0.0.1") } assert(list != "", "List returned nothing in rereard test") list = nil end # Verify that we get converted to the right kind of string def test_mountstring mount = nil name = "yaytest" path = tmpdir() assert_nothing_raised { mount = Puppet::Server::FileServer::Mount.new(name, path) } assert_equal("mount[#{name}]", mount.to_s) end def test_servinglinks server = nil source = tempfile() file = File.join(source, "file") link = File.join(source, "link") Dir.mkdir(source) File.open(file, "w") { |f| f.puts "yay" } File.symlink(file, link) assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } assert_nothing_raised { server.mount(source, "mount") } # First describe the link when following results = {} assert_nothing_raised { server.describe("/mount/link", :follow).split("\t").zip( Puppet::Server::FileServer::CHECKPARAMS ).each { |v,p| results[p] = v } } assert_equal("file", results[:type]) # Then not results = {} assert_nothing_raised { server.describe("/mount/link", :ignore).split("\t").zip( Puppet::Server::FileServer::CHECKPARAMS ).each { |v,p| results[p] = v } } assert_equal("link", results[:type]) results.each { |p,v| assert(v, "%s has no value" % p) assert(v != "", "%s has no value" % p) } end # Test that substitution patterns in the path are exapanded # properly. Disabled, because it was testing too much of the process # and in a non-portable way. This is a thorough enough test that it should # be kept, but it should be done in a way that is clearly portable (e.g., # no md5 sums of file paths). def test_host_specific client1 = "client1.example.com" client2 = "client2.example.com" ip = "127.0.0.1" # Setup a directory hierarchy for the tests fsdir = File.join(tmpdir(), "host-specific") @@tmpfiles << fsdir hostdir = File.join(fsdir, "host") fqdndir = File.join(fsdir, "fqdn") client1_hostdir = File.join(hostdir, "client1") client2_fqdndir = File.join(fqdndir, client2) contents = { client1_hostdir => "client1\n", client2_fqdndir => client2 + "\n" } [fsdir, hostdir, fqdndir, client1_hostdir, client2_fqdndir].each { |d| Dir.mkdir(d) } [client1_hostdir, client2_fqdndir].each do |d| File.open(File.join(d, "file.txt"), "w") do |f| f.print contents[d] end end conffile = tempfile() File.open(conffile, "w") do |f| f.print(" [host] path #{hostdir}/%h allow * [fqdn] path #{fqdndir}/%H allow * ") end server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => conffile ) } # check that list returns the correct thing for the two clients list = nil sfile = "/host/file.txt" assert_nothing_raised { list = server.list(sfile, :ignore, true, false, client1, ip) } assert_equal("/\tfile", list) assert_nothing_raised { list = server.list(sfile, :ignore, true, false, client2, ip) } assert_equal("", list) sfile = "/fqdn/file.txt" assert_nothing_raised { list = server.list(sfile, :ignore, true, false, client1, ip) } assert_equal("", list) assert_nothing_raised { list = server.list(sfile, :ignore, true, false, client2, ip) } assert_equal("/\tfile", list) # check describe sfile = "/host/file.txt" assert_nothing_raised { list = server.describe(sfile, :ignore, client1, ip).split("\t") } assert_equal(5, list.size) assert_equal("file", list[1]) md5 = Digest::MD5.hexdigest(contents[client1_hostdir]) assert_equal("{md5}#{md5}", list[4]) assert_nothing_raised { list = server.describe(sfile, :ignore, client2, ip).split("\t") } assert_equal([], list) sfile = "/fqdn/file.txt" assert_nothing_raised { list = server.describe(sfile, :ignore, client1, ip).split("\t") } assert_equal([], list) assert_nothing_raised { list = server.describe(sfile, :ignore, client2, ip).split("\t") } assert_equal(5, list.size) assert_equal("file", list[1]) md5 = Digest::MD5.hexdigest(contents[client2_fqdndir]) assert_equal("{md5}#{md5}", list[4]) # Check retrieve sfile = "/host/file.txt" assert_nothing_raised { list = server.retrieve(sfile, :ignore, client1, ip).chomp } assert_equal(contents[client1_hostdir].chomp, list) assert_nothing_raised { list = server.retrieve(sfile, :ignore, client2, ip).chomp } assert_equal("", list) sfile = "/fqdn/file.txt" assert_nothing_raised { list = server.retrieve(sfile, :ignore, client1, ip).chomp } assert_equal("", list) assert_nothing_raised { list = server.retrieve(sfile, :ignore, client2, ip).chomp } assert_equal(contents[client2_fqdndir].chomp, list) end # Make sure the 'subdir' method in Mount works. def test_mount_subdir mount = nil base = tempfile() Dir.mkdir(base) subdir = File.join(base, "subdir") Dir.mkdir(subdir) [base, subdir].each do |d| File.open(File.join(d, "file"), "w") { |f| f.puts "bazoo" } end mount = mkmount(base) assert_equal(base, mount.subdir(), "Did not default to base path") assert_equal(subdir, mount.subdir("subdir"), "Did not default to base path") end # Make sure mounts get correctly marked expandable or not, depending on # the path. def test_expandable name = "yaytest" dir = tempfile() Dir.mkdir(dir) mount = mkmount() assert_nothing_raised { mount.path = dir } assert(! mount.expandable?, "Mount incorrectly called expandable") assert_nothing_raised { mount.path = "/dir/a%a" } assert(mount.expandable?, "Mount not called expandable") # This isn't a valid replacement pattern, so it should throw an error # because the dir doesn't exist assert_raise(Puppet::FileServerError) { mount.path = "/dir/a%" } # Now send it back to a normal path assert_nothing_raised { mount.path = dir } # Make sure it got reverted assert(! mount.expandable?, "Mount incorrectly called expandable") end def test_mount_expand mount = mkmount() check = proc do |client, pattern, repl| path = "/my/#{pattern}/file" assert_equal("/my/#{repl}/file", mount.expand(path, client)) end # Do a round of checks with a fake client client = "host.domain.com" {"%h" => "host", # Short name "%H" => client, # Full name "%d" => "domain.com", # domain "%%" => "%", # escape "%o" => "%o" # other }.each do |pat, repl| result = check.call(client, pat, repl) end # Now, check that they use Facter info Puppet.notice "The following messages are normal" client = nil local = Facter["hostname"].value domain = Facter["domain"].value fqdn = [local, domain].join(".") {"%h" => local, # Short name "%H" => fqdn, # Full name "%d" => domain, # domain "%%" => "%", # escape "%o" => "%o" # other }.each do |pat, repl| check.call(client, pat, repl) end end def test_fileserver_expansion server = nil assert_nothing_raised { server = Puppet::Server::FileServer.new( :Local => true, :Config => false ) } dir = tempfile() ip = Facter.value(:ipaddress) Dir.mkdir(dir) host = "host.domain.com" { "%H" => "host.domain.com", "%h" => "host", "%d" => "domain.com" }.each do |pattern, string| file = File.join(dir, string) mount = File.join(dir, pattern) File.open(file, "w") do |f| f.puts "yayness: %s" % string end name = "name" obj = nil assert_nothing_raised { obj = server.mount(mount, name) } obj.allow "*" ret = nil assert_nothing_raised do ret = server.list("/name", :ignore, false, false, host, ip) end assert_equal("/\tfile", ret) assert_nothing_raised do ret = server.describe("/name", :ignore, host, ip) end assert(ret =~ /\tfile\t/, "Did not get valid a description") assert_nothing_raised do ret = server.retrieve("/name", :ignore, host, ip) end assert_equal(ret, File.read(file)) server.umount(name) File.unlink(file) end end end # $Id$ diff --git a/test/server/logger.rb b/test/server/logger.rb index e0a03417e..8ba0d0067 100644 --- a/test/server/logger.rb +++ b/test/server/logger.rb @@ -1,183 +1,176 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' require 'base64' require 'cgi' class TestLogger < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def setup super #Puppet[:debug] = true Puppet::Log.newdestination :console end # Test the log driver manually def test_localaddlog logger = nil assert_nothing_raised { logger = Puppet::Server::Logger.new } msg = nil assert_nothing_raised { msg = Puppet::Log.create( :level => :warning, :message => "This is a message" ) } assert_nothing_raised { logger.addlog(msg) } end # Test it while replicating a remote client def test_remoteaddlog logger = nil assert_nothing_raised { logger = Puppet::Server::Logger.new } msg = nil assert_nothing_raised { msg = Puppet::Log.create( :level => :warning, :message => "This is a remote message" ) } assert_nothing_raised { msg = CGI.escape(YAML.dump(msg)) } assert_nothing_raised { logger.addlog(msg, "localhost", "127.0.0.1") } end # Now test it with a real client and server, but not remote def test_localclient client = nil assert_nothing_raised { client = Puppet::Client::LogClient.new(:Logger => true) } msg = nil assert_nothing_raised { msg = Puppet::Log.create( :level => :warning, :message => "This is a logclient message" ) } msg = CGI.escape(YAML.dump(msg)) assert_nothing_raised { client.addlog(msg, "localhost", "127.0.0.1") } end # And now test over the network # This test is disabled, since it doesn't work well and it's not the right # solution anyway. def disabled_test_logclient pid = nil clientlog = tempfile() serverlog = tempfile() Puppet.warning "serverlog is %s" % serverlog Puppet::Log.newdestination clientlog Puppet::Log.close(:syslog) # For testing Puppet[:autosign] = true logger = nil # Create our server assert_nothing_raised { logger = Puppet::Server.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Logger => {} } ) } # Start our server serverpid = fork { Puppet::Log.close(clientlog) Puppet::Log.newdestination serverlog assert_nothing_raised() { trap(:INT) { logger.shutdown } logger.start } } @@tmppids << serverpid sleep(0.5) # Start a raw xmlrpc client client = nil assert_nothing_raised() { client = Puppet::Client::LogClient.new( :Server => "localhost", :Port => @@port ) unless client.readcert raise "Could not get certs" end } retval = nil { :notice => "XMLRPC1", :warning => "XMLRPC2", :err => "XMLRPC3" }.each { |level, str| msg = CGI.escape(YAML.dump(Puppet::Log.create( :level => level, :message => str ))) assert_nothing_raised { retval = client.addlog(msg) } } # and now use the normal client action # Set the log destination to be the server Puppet::Log.newdestination "localhost:%s" % @@port # And now do some logging assert_nothing_raised { Puppet.notice "TEST1" Puppet.warning "TEST2" Puppet.err "TEST3" } assert_nothing_raised { Process.kill("INT", serverpid) } assert(FileTest.exists?(serverlog), "Server log does not exist") # Give it a bit to flush to disk sleep(0.5) content = nil assert_nothing_raised { content = File.read(serverlog) } %w{TEST1 TEST2 TEST3}.each { |str| assert(content =~ %r{#{str}}, "Content does not match %s" % str) } end end # $Id$ diff --git a/test/server/master.rb b/test/server/master.rb index 2f6804e56..2d1b9ec2c 100644 --- a/test/server/master.rb +++ b/test/server/master.rb @@ -1,259 +1,248 @@ -if __FILE__ == $0 - if Dir.getwd =~ /test\/server$/ - Dir.chdir("..") - end - - $:.unshift '../lib' - $puppetbase = ".." - -end - require 'puppet' require 'puppet/server' require 'puppet/client' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestMaster < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def teardown super #print "\n\n\n\n" if Puppet[:debug] end # run through all of the existing test files and make sure everything # works def test_files count = 0 textfiles { |file| Puppet.debug("parsing %s" % file) client = nil master = nil # create our master assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => false, :Local => true ) } # and our client assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } # pull our configuration a few times assert_nothing_raised() { client.getconfig stopservices Puppet::Type.allclear } assert_nothing_raised() { client.getconfig stopservices Puppet::Type.allclear } assert_nothing_raised() { client.getconfig stopservices Puppet::Type.allclear } # only test three files; that's plenty if count > 3 break end count += 1 } end def test_defaultmanifest textfiles { |file| Puppet[:manifest] = file client = nil master = nil assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => false, :Local => true ) } assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } # pull our configuration assert_nothing_raised() { client.getconfig stopservices Puppet::Type.allclear } break } end def test_filereread # Start with a normal setting Puppet[:filetimeout] = 15 manifest = mktestmanifest() file2 = @createdfile + "2" @@tmpfiles << file2 client = master = nil assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => manifest, :UseNodes => false, :Local => true ) } assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } # The client doesn't have a config, so it can't be up to date assert(! client.fresh?, "Client is incorrectly up to date") assert_nothing_raised { client.getconfig client.apply } # Now it should be up to date assert(client.fresh?, "Client is not up to date") # Cache this value for later parse1 = master.freshness # Verify the config got applied assert(FileTest.exists?(@createdfile), "Created file %s does not exist" % @createdfile) Puppet::Type.allclear sleep 1.5 # Create a new manifest File.open(manifest, "w") { |f| f.puts "file { \"%s\": ensure => file }\n" % file2 } # Verify that the master doesn't immediately reparse the file; we # want to wait through the timeout assert_equal(parse1, master.freshness, "Master did not wait through timeout") assert(client.fresh?, "Client is not up to date") # Then eliminate it Puppet[:filetimeout] = 0 # Now make sure the master does reparse #Puppet.notice "%s vs %s" % [parse1, master.freshness] assert(parse1 != master.freshness, "Master did not reparse file") assert(! client.fresh?, "Client is incorrectly up to date") # Retrieve and apply the new config assert_nothing_raised { client.getconfig client.apply } assert(client.fresh?, "Client is not up to date") assert(FileTest.exists?(file2), "Second file %s does not exist" % file2) end def test_addfacts master = nil file = mktestmanifest() # create our master assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => false, :Local => true ) } facts = {} assert_nothing_raised { master.addfacts(facts) } %w{serverversion servername serverip}.each do |fact| assert(facts.include?(fact), "Fact %s was not set" % fact) end end # Make sure we're using the hostname as configured with :node_name def test_hostname_in_getconfig master = nil file = tempfile() #@createdfile = File.join(tmpdir(), self.class.to_s + "manifesttesting" + # "_" + @method_name) file_cert = tempfile() file_fact = tempfile() certname = "y4yn3ss" factname = Facter["hostname"].value File.open(file, "w") { |f| f.puts %{ node #{certname} { file { "#{file_cert}": ensure => file, mode => 755 } } node #{factname} { file { "#{file_fact}": ensure => file, mode => 755 } } } } # create our master assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => true, :Local => true ) } result = nil # Use the hostname from facter Puppet[:node_name] = 'facter' assert_nothing_raised { result = master.getconfig({"hostname" => factname}, "yaml", certname, "127.0.0.1") } result = result.flatten assert(result.find { |obj| obj.name == file_fact }, "Could not find correct file") assert(!result.find { |obj| obj.name == file_cert }, "Found incorrect file") # Use the hostname from the cert Puppet[:node_name] = 'cert' assert_nothing_raised { result = master.getconfig({"hostname" => factname}, "yaml", certname, "127.0.0.1") } result = result.flatten assert(!result.find { |obj| obj.name == file_fact }, "Could not find correct file") assert(result.find { |obj| obj.name == file_cert }, "Found incorrect file") end end # $Id$ diff --git a/test/server/pelement.rb b/test/server/pelement.rb index 5d5b5ceb4..edfe89744 100644 --- a/test/server/pelement.rb +++ b/test/server/pelement.rb @@ -1,305 +1,298 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/pelement' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' require 'base64' require 'cgi' class TestPElementServer < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest def verify_described(type, described) described.each do |name, trans| type.clear obj = nil assert_nothing_raised do obj = trans.to_type end assert(obj, "Could not create object") assert_nothing_raised do obj.retrieve end if trans.type == :package assert_equal(Puppet::Type.type(:package).defaultprovider.name, obj[:provider]) end end type.clear end def test_describe_file # Make a file to describe file = tempfile() str = "yayness\n" server = nil assert_nothing_raised do server = Puppet::Server::PElement.new() end # The first run we create the file on the copy, the second run # the file is already there so the object should be in sync 2.times do |i| [ [nil], [[:content, :mode], []], [[], [:content]], [[:content], [:mode]] ].each do |ary| retrieve = ary[0] || [] ignore = ary[1] || [] File.open(file, "w") { |f| f.print str } result = nil assert_nothing_raised do result = server.describe("file", file, *ary) end assert(result, "Could not retrieve file information") assert_instance_of(Puppet::TransObject, result) # Now we have to clear, so that the server's object gets removed Puppet::Type.type(:file).clear # And remove the file, so we can verify it gets recreated if i == 0 File.unlink(file) end object = nil assert_nothing_raised do object = result.to_type end assert(object, "Could not create type") retrieve.each do |state| assert(object.should(state), "Did not retrieve %s" % state) end ignore.each do |state| assert(! object.should(state), "Incorrectly retrieved %s" % state) end if i == 0 assert_events([:file_created], object) else assert_nothing_raised { object.retrieve } assert(object.insync?, "Object was not in sync") end assert(FileTest.exists?(file), "File did not get recreated") if i == 0 if object.should(:content) assert_equal(str, File.read(file), "File contents are not the same") else assert_equal("", File.read(file), "File content was incorrectly made") end end if FileTest.exists? file File.unlink(file) end end end end def test_describe_directory # Make a file to describe file = tempfile() server = nil assert_nothing_raised do server = Puppet::Server::PElement.new() end [ [nil], [[:ensure, :checksum, :mode], []], [[], [:checksum]], [[:ensure, :checksum], [:mode]] ].each do |ary| retrieve = ary[0] || [] ignore = ary[1] || [] Dir.mkdir(file) result = nil assert_nothing_raised do result = server.describe("file", file, *ary) end assert(result, "Could not retrieve file information") assert_instance_of(Puppet::TransObject, result) # Now we have to clear, so that the server's object gets removed Puppet::Type.type(:file).clear # And remove the file, so we can verify it gets recreated Dir.rmdir(file) object = nil assert_nothing_raised do object = result.to_type end assert(object, "Could not create type") retrieve.each do |state| assert(object.should(state), "Did not retrieve %s" % state) end ignore.each do |state| assert(! object.should(state), "Incorrectly retrieved %s" % state) end assert_events([:directory_created], object) assert(FileTest.directory?(file), "Directory did not get recreated") Dir.rmdir(file) end end def test_describe_alltypes # Systems get pretty retarded, so I'm going to set the path to some fake # data for ports - #Puppet::Type::ParsedType::Port.path = File.join($puppetbase, + #Puppet::Type::ParsedType::Port.path = File.join(basedir, # "test/data/types/ports/1") #Puppet.err Puppet::Type::ParsedType::Port.path server = nil assert_nothing_raised do server = Puppet::Server::PElement.new() end require 'etc' # Make the example schedules, for testing Puppet::Type.type(:schedule).mkdefaultschedules Puppet::Type.eachtype do |type| unless type.respond_to? :list Puppet.warning "%s does not respond to :list" % type.name next end next unless type.name == :package Puppet.info "Describing each %s" % type.name # First do a listing from the server bucket = nil assert_nothing_raised { bucket = server.list(type.name) } #type.clear count = 0 described = {} bucket.each do |obj| assert_instance_of(Puppet::TransObject, obj) break if count > 5 described[obj.name] = server.describe(obj.type, obj.name) count += 1 end verify_described(type, described) count = 0 described = {} Puppet.info "listing again" type.list.each do |obj| assert_instance_of(type, obj) break if count > 5 trans = nil assert_nothing_raised do described[obj.name] = server.describe(type.name, obj.name) end count += 1 end if described.empty? Puppet.notice "Got no example objects for %s" % type.name end # We separate these, in case the list operation creates objects verify_described(type, described) end end def test_apply server = nil assert_nothing_raised do server = Puppet::Server::PElement.new() end file = tempfile() str = "yayness\n" File.open(file, "w") { |f| f.print str } filetrans = nil assert_nothing_raised { filetrans = server.describe("file", file) } Puppet::Type.type(:file).clear Puppet.err filetrans[:parent].inspect #p filetrans bucket = Puppet::TransBucket.new bucket.type = "file" bucket.push filetrans #p bucket oldbucket = bucket.dup File.unlink(file) assert_nothing_raised { server.apply(bucket) } assert(FileTest.exists?(file), "File did not get recreated") # Now try it as a "nonlocal" server server.local = false yaml = nil assert_nothing_raised { yaml = Base64.encode64(YAML::dump(bucket)) } Puppet::Type.type(:file).clear File.unlink(file) if Base64.decode64(yaml) =~ /(.{20}Loglevel.{20})/ Puppet.warning "YAML is broken on this machine" return end #puts Base64.decode64(yaml) assert_nothing_raised("Could not reload yaml") { YAML::load(Base64.decode64(yaml)) } assert_nothing_raised { server.apply(yaml) } assert(FileTest.exists?(file), "File did not get recreated from YAML") end end # $Id$ diff --git a/test/server/report.rb b/test/server/report.rb index 5e74dc1da..423b8ce90 100755 --- a/test/server/report.rb +++ b/test/server/report.rb @@ -1,135 +1,128 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/report' require 'puppet/client/reporter' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestReportServer < Test::Unit::TestCase - include TestPuppet + include PuppetTest Puppet::Util.logmethods(self) def mkserver server = nil assert_nothing_raised { server = Puppet::Server::Report.new() } server end def mkclient(server = nil) server ||= mkserver() client = nil assert_nothing_raised { client = Puppet::Client::Reporter.new(:Report => server) } client end def test_report # Create a bunch of log messages in an array. report = Puppet::Transaction::Report.new 10.times { |i| log = warning("Report test message %s" % i) log.tags = %w{a list of tags} log.tags << "tag%s" % i report.newlog(log) } # Now make our reporting client client = mkclient() # Now send the report file = nil assert_nothing_raised("Reporting failed") { file = client.report(report) } # And make sure our YAML file exists. assert(FileTest.exists?(file), "Report file did not get created") # And then try to reconstitute the report. newreport = nil assert_nothing_raised("Failed to load report file") { newreport = YAML.load(File.read(file)) } # Make sure our report is valid and stuff. report.logs.zip(newreport.logs).each do |ol,nl| %w{level message time tags source}.each do |method| assert_equal(ol.send(method), nl.send(method), "%s got changed" % method) end end end # Make sure we don't have problems with calling mkclientdir multiple # times. def test_multiple_clients server ||= mkserver() %w{hostA hostB hostC}.each do |host| dir = tempfile() assert_nothing_raised("Could not create multiple host report dirs") { server.send(:mkclientdir, host, dir) } assert(FileTest.directory?(dir), "Directory was not created") end end def test_report_autoloading # Create a fake report fakedir = tempfile() $: << fakedir cleanup do $:.delete(fakedir) end libdir = File.join(fakedir, "puppet", "reports") FileUtils.mkdir_p(libdir) $myreportrun = false file = File.join(libdir, "myreport.rb") File.open(file, "w") { |f| f.puts %{ Puppet::Server::Report.newreport(:myreport) do |report| $myreportrun = true return report end } } Puppet[:reports] = "myreport" # Create a server server = Puppet::Server::Report.new method = nil assert_nothing_raised { method = Puppet::Server::Report.reportmethod(:myreport) } assert(method, "Did not get report method") assert(! server.respond_to?(method), "Server already responds to report method") retval = nil assert_nothing_raised { retval = server.send(:process, YAML.dump("a string")) } assert($myreportrun, "Did not run report") assert(server.respond_to?(method), "Server does not respond to report method") end end # $Id$ diff --git a/test/server/rights.rb b/test/server/rights.rb index 09cb21e56..ac0944bd0 100755 --- a/test/server/rights.rb +++ b/test/server/rights.rb @@ -1,41 +1,34 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/rights' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestRights < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_rights store = nil assert_nothing_raised { store = Puppet::Server::Rights.new } assert(store, "Did not create store") assert_raise(ArgumentError, "Did not fail on unknown right") { store.allowed?(:write, "host.madstop.com", "0.0.0.0") } assert_nothing_raised { store.newright(:write) } assert(! store.allowed?(:write, "host.madstop.com", "0.0.0.0"), "Defaulted to allowing access") assert_nothing_raised { store[:write].info "This is a log message" } end end # $Id$ diff --git a/test/server/runner.rb b/test/server/runner.rb index 59487776f..1c2fa9cea 100755 --- a/test/server/runner.rb +++ b/test/server/runner.rb @@ -1,107 +1,100 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server/runner' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' class TestServerRunner < Test::Unit::TestCase - include TestPuppet + include PuppetTest def mkclient(file) master = nil client = nil # create our master assert_nothing_raised() { # this is the default server setup master = Puppet::Server::Master.new( :Manifest => file, :UseNodes => false, :Local => true ) } # and our client assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Master => master ) } client end def test_runner Puppet[:ignoreschedules] = false # Okay, make our manifest file = tempfile() created = tempfile() File.open(file, "w") do |f| f.puts %{ class yayness { file { "#{created}": ensure => file, schedule => weekly } } include yayness } end client = mkclient(file) runner = nil assert_nothing_raised { runner = Puppet::Server::Runner.new } # First: tags # Second: ignore schedules true/false # Third: background true/false # Fourth: whether file should exist true/false [ ["with no backgrounding", nil, true, true, true], ["in the background", nil, true, false, true], ["with a bad tag", ["coolness"], true, false, false], ["with another bad tag", "coolness", true, false, false], ["with a good tag", ["coolness", "yayness"], true, false, true], ["with another good tag", ["yayness"], true, false, true], ["with a third good tag", "yayness", true, false, true], ["not ignoring schedules", nil, false, false, false], ["ignoring schedules", nil, true, false, true], ].each do |msg, tags, ignore, fg, shouldexist| if FileTest.exists?(created) File.unlink(created) end assert_nothing_raised { # Try it without backgrounding runner.run(tags, ignore, fg) } unless fg Puppet.join end if shouldexist assert(FileTest.exists?(created), "File did not get created " + msg) else assert(!FileTest.exists?(created), "File got created incorrectly " + msg) end end end end # $Id$ diff --git a/test/server/server.rb b/test/server/server.rb index e279d8440..681fa1f42 100644 --- a/test/server/server.rb +++ b/test/server/server.rb @@ -1,201 +1,194 @@ -if __FILE__ == $0 - $:.unshift '../../lib' - $:.unshift '..' - $puppetbase = "../.." -end - require 'puppet' require 'puppet/server' -require 'test/unit' -require 'puppettest.rb' +require 'puppettest' # $Id$ if ARGV.length > 0 and ARGV[0] == "short" $short = true else $short = false end class TestServer < Test::Unit::TestCase - include ServerTest + include PuppetTest::ServerTest # test that we can connect to the server # we have to use fork here, because we apparently can't use threads # to talk to other threads def test_connect_with_fork Puppet[:autosign] = true serverpid, server = mk_status_server # create a status client, and verify it can talk client = mk_status_client retval = nil assert_nothing_raised() { retval = client.status } assert_equal(1, retval) end # similar to the last test, but this time actually run getconfig def test_getconfig_with_fork Puppet[:autosign] = true serverpid = nil file = mktestmanifest() server = nil # make our server again assert_nothing_raised() { server = Puppet::Server.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Master => { :UseNodes => false, :Manifest => file }, :Status => nil } ) } serverpid = fork { assert_nothing_raised() { #trap(:INT) { server.shutdown; Kernel.exit! } trap(:INT) { server.shutdown } server.start } } @@tmppids << serverpid client = nil # and then start a masterclient assert_nothing_raised() { client = Puppet::Client::MasterClient.new( :Server => "localhost", :Port => @@port ) } retval = nil # and run getconfig a couple of times assert_nothing_raised() { retval = client.getconfig } # Try it again, just for kicks assert_nothing_raised() { retval = client.getconfig } end def test_setpidfile_setting Puppet[:setpidfile] = false server = nil assert_nothing_raised() { server = Puppet::Server.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Status => nil } ) } assert_nothing_raised { server.setpidfile } assert(! FileTest.exists?(server.pidfile), "PID file was created") Puppet[:setpidfile] = true assert_nothing_raised { server.setpidfile } assert(FileTest.exists?(server.pidfile), "PID file was not created") end # Test that a client whose cert has been revoked really can't connect def test_certificate_revocation Puppet[:autosign] = true serverpid, server = mk_status_server client = mk_status_client status = nil assert_nothing_raised() { status = client.status } assert_equal(1, status) client.shutdown # Revoke the client's cert ca = Puppet::SSLCertificates::CA.new() fqdn = client.fqdn ca.revoke(ca.getclientcert(fqdn)[0].serial) # Restart the server @@port += 1 Puppet[:autosign] = false kill_and_wait(serverpid, server.pidfile) serverpid, server = mk_status_server client = mk_status_client # This time the client should be denied assert_raise(Puppet::NetworkClientError) { client.status } end def mk_status_client client = nil # Otherwise, the client initalization will trip over itself # since elements created in the last run are still around Puppet::Type::allclear assert_nothing_raised() { client = Puppet::Client::StatusClient.new( :Server => "localhost", :Port => @@port ) } client end def mk_status_server server = nil assert_nothing_raised() { server = Puppet::Server.new( :Port => @@port, :Handlers => { :CA => {}, # so that certs autogenerate :Status => nil } ) } pid = fork { assert_nothing_raised() { trap(:INT) { server.shutdown } server.start } } @@tmppids << pid [pid, server] end def kill_and_wait(pid, file) %x{kill -INT #{pid} 2>/dev/null} count = 0 while count < 30 && File::exist?(file) count += 1 sleep(1) end assert(count < 30, "Killing server #{pid} failed") end end diff --git a/test/tagging/tagging.rb b/test/tagging/tagging.rb index 434ef6e69..42f04ff4f 100644 --- a/test/tagging/tagging.rb +++ b/test/tagging/tagging.rb @@ -1,179 +1,177 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestTagging < Test::Unit::TestCase - include TestPuppet + include PuppetTest # Make sure the scopes are getting the right tags def test_scopetags scope = nil assert_nothing_raised { scope = Puppet::Parser::Scope.new() scope.name = "yayness" scope.type = "solaris" } assert_nothing_raised { assert_equal(%w{solaris}, scope.tags, "Incorrect scope tags") } end # Test deeper tags, where a scope gets all of its parent scopes' tags def test_deepscopetags scope = nil assert_nothing_raised { scope = Puppet::Parser::Scope.new() scope.name = "yayness" scope.type = "solaris" scope = scope.newscope scope.name = "booness" scope.type = "apache" } assert_nothing_raised { # Scopes put their own tags first assert_equal(%w{apache solaris}, scope.tags, "Incorrect scope tags") } end # Verify that the tags make their way to the objects def test_objecttags scope = nil assert_nothing_raised { scope = Puppet::Parser::Scope.new() scope.name = "yayness" scope.type = "solaris" } assert_nothing_raised { scope.setobject( :type => "file", :name => "/etc/passwd", :arguments => {"owner" => "root"}, :file => "/yay", :line => 1 ) } + ast = Puppet::Parser::AST::ASTArray.new({}) + + # We have to use 'evaluate', rather than just calling to_trans directly, + # because scopes do some internal checking to make sure the same object + # is not translated multiple times. objects = nil assert_nothing_raised { - objects = scope.to_trans + objects = scope.evaluate(:ast => ast) } # There's only one object, so shift it out object = objects.shift assert_nothing_raised { assert_equal(%w{solaris}, object.tags, "Incorrect tags") } end # Make sure that specifying tags results in only those objects getting # run. def test_tagspecs a = tempfile() b = tempfile() afile = Puppet.type(:file).create( :path => a, :ensure => :file ) afile.tag("a") bfile = Puppet.type(:file).create( :path => b, :ensure => :file ) bfile.tag(:b) # First, make sure they get created when no spec'ed tags assert_events([:file_created,:file_created], afile, bfile) assert(FileTest.exists?(a), "A did not get created") assert(FileTest.exists?(b), "B did not get created") File.unlink(a) File.unlink(b) # Set the tags to a assert_nothing_raised { Puppet[:tags] = "a" } assert_events([:file_created], afile, bfile) assert(FileTest.exists?(a), "A did not get created") assert(!FileTest.exists?(b), "B got created") File.unlink(a) # Set the tags to b assert_nothing_raised { Puppet[:tags] = "b" } assert_events([:file_created], afile, bfile) assert(!FileTest.exists?(a), "A got created") assert(FileTest.exists?(b), "B did not get created") File.unlink(b) # Set the tags to something else assert_nothing_raised { Puppet[:tags] = "c" } assert_events([], afile, bfile) assert(!FileTest.exists?(a), "A got created") assert(!FileTest.exists?(b), "B got created") # Now set both tags assert_nothing_raised { Puppet[:tags] = "b, a" } assert_events([:file_created, :file_created], afile, bfile) assert(FileTest.exists?(a), "A did not get created") assert(FileTest.exists?(b), "B did not get created") File.unlink(a) end def test_metaparamtag path = tempfile() start = %w{some tags} tags = %w{a list of tags} obj = nil assert_nothing_raised do obj = Puppet.type(:file).create( :path => path, :ensure => "file", :tag => start ) end assert(obj, "Did not make object") start.each do |tag| assert(obj.tagged?(tag), "Object was not tagged with %s" % tag) end tags.each do |tag| assert_nothing_raised { obj[:tag] = tag } end tags.each do |tag| assert(obj.tagged?(tag), "Object was not tagged with %s" % tag) end end end # $Id$ diff --git a/test/test b/test/test deleted file mode 100755 index 9b3613599..000000000 --- a/test/test +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env ruby - -#------------------------------------------------------------ -# run any or all test suites - -basedir = File.dirname(__FILE__) -if basedir == "." - basedir = Dir.getwd -end -$puppetbase = File.expand_path(File.join(basedir, "..")) - -$:.unshift basedir -$:.unshift "#{$puppetbase}/lib" - - -require 'puppettest.rb' -require 'getoptlong' - - #[ "--size", "-s", GetoptLong::REQUIRED_ARGUMENT ], -result = GetoptLong.new( - [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], - [ "-n", GetoptLong::REQUIRED_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ] -) - -usage = "USAGE: %s [--help] .." % $0 - -opts = [] - -result.each { |opt,arg| - case opt - when "--debug" - Puppet::Log.level = :debug - when "--help" - puts usage - exit - else - opts << opt << arg - #raise "Invalid option '#{opt}'" - end -} -suites = nil - -if ARGV.length != 0 - suites = ARGV.dup -else - suites = PuppetTestSuite.list -end - -ARGV.clear - -opts.each { |o| ARGV << o } - -suites.each { |suite| - PuppetTestSuite.new(suite) -} - -# This damn problem just doesn't seem to want to go away -system("%s/etc/init.d/sleeper stop 2>/dev/null 1>/dev/null" % $puppetbase) - -# $Id$ diff --git a/test/types/basic.rb b/test/types/basic.rb index f734cb5a0..e8dd38c77 100644 --- a/test/types/basic.rb +++ b/test/types/basic.rb @@ -1,117 +1,110 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestBasic < Test::Unit::TestCase - include TestPuppet + include PuppetTest # hmmm # this is complicated, because we store references to the created # objects in a central store def setup super @component = nil @configfile = nil @sleeper = nil assert_nothing_raised() { @component = Puppet.type(:component).create( :name => "yaytest", :type => "testing" ) } assert_nothing_raised() { @filepath = tempfile() @@tmpfiles << @filepath @configfile = Puppet.type(:file).create( :path => @filepath, :ensure => "file", :checksum => "md5" ) } assert_nothing_raised() { @sleeper = Puppet.type(:service).create( :name => "sleeper", :provider => "init", - :path => File.join($puppetbase,"examples/root/etc/init.d"), + :path => exampledir("root/etc/init.d"), :hasstatus => true, :ensure => :running ) } assert_nothing_raised() { @component.push( @configfile, @sleeper ) } #puts "Component is %s, id %s" % [@component, @component.object_id] #puts "ConfigFile is %s, id %s" % [@configfile, @configfile.object_id] end def test_name_calls [@sleeper,@configfile].each { |obj| Puppet.debug "obj is %s" % obj assert_nothing_raised(){ obj.name } } end def test_name_equality #puts "Component is %s, id %s" % [@component, @component.object_id] assert_equal( @filepath, @configfile.name ) assert_equal( "sleeper", @sleeper.name ) end def test_object_retrieval [@sleeper,@configfile].each { |obj| assert_equal( obj.class[obj.name].object_id, obj.object_id ) } end def test_transaction transaction = nil assert_nothing_raised() { transaction = @component.evaluate } assert_nothing_raised() { transaction.evaluate } assert_nothing_raised() { @sleeper[:ensure] = :running } assert_nothing_raised() { transaction = @component.evaluate } assert_nothing_raised() { transaction.evaluate } end def test_paths [@configfile,@sleeper,@component].each { |obj| assert_nothing_raised { assert_instance_of(String, obj.path) } } end end # $Id$ diff --git a/test/types/component.rb b/test/types/component.rb index 0754e7cdc..2ab0661d6 100755 --- a/test/types/component.rb +++ b/test/types/component.rb @@ -1,298 +1,291 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestComponent < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @@used = {} end def randnum(limit) num = nil looped = 0 loop do looped += 1 if looped > 2000 raise "Reached limit of looping" break end num = rand(limit) unless @@used.include?(num) @@used[num] = true break end end num end def mkfile(num = nil) unless num num = randnum(1000) end name = tempfile() + num.to_s file = Puppet.type(:file).create( :path => name, :checksum => "md5" ) @@tmpfiles << name file end def mkcomp Puppet.type(:component).create(:name => "component_" + randnum(1000).to_s) end def mkrandcomp(numfiles, numdivs) comp = mkcomp hash = {} found = 0 divs = {} numdivs.times { |i| num = i + 2 divs[num] = nil } while found < numfiles num = randnum(numfiles) found += 1 f = mkfile(num) hash[f.name] = f reqd = [] divs.each { |n,obj| if rand(50) % n == 0 if obj unless reqd.include?(obj.object_id) f[:require] = [[obj.class.name, obj.name]] reqd << obj.object_id end end end divs[n] = f } end hash.each { |name, obj| comp.push obj } comp.finalize comp end def test_ordering list = nil comp = mkrandcomp(30,5) assert_nothing_raised { list = comp.flatten } list.each_with_index { |obj, index| obj.eachdependency { |dep| assert(list.index(dep) < index) } } end def test_correctsorting tmpfile = tempfile() @@tmpfiles.push tmpfile trans = nil cmd = nil File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) } file = Puppet.type(:file).create( :path => tmpfile, :checksum => "md5" ) assert_nothing_raised { cmd = Puppet.type(:exec).create( :command => "pwd", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :subscribe => [[file.class.name,file.name]], :refreshonly => true ) } order = nil assert_nothing_raised { order = Puppet.type(:component).sort([file, cmd]) } [cmd, file].each { |obj| assert_equal(1, order.find_all { |o| o.name == obj.name }.length) } end def test_correctflattening tmpfile = tempfile() @@tmpfiles.push tmpfile trans = nil cmd = nil File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) } file = Puppet.type(:file).create( :path => tmpfile, :checksum => "md5" ) assert_nothing_raised { cmd = Puppet.type(:exec).create( :command => "pwd", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :subscribe => [[file.class.name,file.name]], :refreshonly => true ) } comp = newcomp(cmd, file) comp.finalize objects = nil assert_nothing_raised { objects = comp.flatten } [cmd, file].each { |obj| assert_equal(1, objects.find_all { |o| o.name == obj.name }.length) } assert(objects[0] == file, "File was not first object") assert(objects[1] == cmd, "Exec was not second object") end def test_deepflatten tmpfile = tempfile() @@tmpfiles.push tmpfile trans = nil cmd = nil File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) } file = Puppet.type(:file).create( :path => tmpfile, :checksum => "md5" ) assert_nothing_raised { cmd = Puppet.type(:exec).create( :command => "pwd", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :refreshonly => true ) } fcomp = newcomp("fflatten", file) ecomp = newcomp("eflatten", cmd) # this subscription can screw up the sorting ecomp[:subscribe] = [[fcomp.class.name,fcomp.name]] comp = newcomp("bflatten", ecomp, fcomp) comp.finalize objects = nil assert_nothing_raised { objects = comp.flatten } assert_equal(objects.length, 2, "Did not get two sorted objects") objects.each { |o| assert(o.is_a?(Puppet::Type), "Object %s is not a Type" % o.class) } assert(objects[0] == file, "File was not first object") assert(objects[1] == cmd, "Exec was not second object") end def test_deepflatten2 tmpfile = tempfile() @@tmpfiles.push tmpfile trans = nil cmd = nil File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) } file = Puppet.type(:file).create( :path => tmpfile, :checksum => "md5" ) assert_nothing_raised { cmd = Puppet.type(:exec).create( :command => "pwd", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :refreshonly => true ) } ocmd = nil assert_nothing_raised { ocmd = Puppet.type(:exec).create( :command => "echo true", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :refreshonly => true ) } fcomp = newcomp("fflatten", file) ecomp = newcomp("eflatten", cmd) ocomp = newcomp("oflatten", ocmd) # this subscription can screw up the sorting cmd[:subscribe] = [[fcomp.class.name,fcomp.name]] ocmd[:subscribe] = [[cmd.class.name,cmd.name]] comp = newcomp("bflatten", ocomp, ecomp, fcomp) comp.finalize objects = nil assert_nothing_raised { objects = comp.flatten } assert_equal(objects.length, 3, "Did not get three sorted objects") objects.each { |o| assert(o.is_a?(Puppet::Type), "Object %s is not a Type" % o.class) } assert(objects[0] == file, "File was not first object") assert(objects[1] == cmd, "Exec was not second object") assert(objects[2] == ocmd, "Other exec was not second object") end def test_moreordering dir = tempfile() comp = Puppet.type(:component).create( :name => "ordertesting" ) 10.times { |i| fileobj = Puppet.type(:file).create( :path => File.join(dir, "file%s" % i), :ensure => "file" ) comp.push(fileobj) } dirobj = Puppet.type(:file).create( :path => dir, :ensure => "directory" ) comp.push(dirobj) assert_apply(comp) end end diff --git a/test/types/cron.rb b/test/types/cron.rb index 65d37cfa0..b802a1c77 100755 --- a/test/types/cron.rb +++ b/test/types/cron.rb @@ -1,742 +1,735 @@ # Test cron job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' class TestCron < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super setme() # god i'm lazy @crontype = Puppet.type(:cron) @oldfiletype = @crontype.filetype @fakefiletype = Puppet::FileType.filetype(:ram) @crontype.filetype = @fakefiletype end def teardown @crontype.filetype = @oldfiletype Puppet::FileType.filetype(:ram).clear super end # Back up the user's existing cron tab if they have one. def cronback tab = nil assert_nothing_raised { tab = Puppet.type(:cron).filetype.read(@me) } if $? == 0 @currenttab = tab else @currenttab = nil end end # Restore the cron tab to its original form. def cronrestore assert_nothing_raised { if @currenttab @crontype.filetype.new(@me).write(@currenttab) else @crontype.filetype.new(@me).remove end } end # Create a cron job with all fields filled in. def mkcron(name, addargs = true) cron = nil command = "date > %s/crontest%s" % [tmpdir(), name] args = nil if addargs args = { :command => command, :name => name, :user => @me, :minute => rand(59), :month => "1", :monthday => "1", :hour => "1" } else args = {:command => command, :name => name} end assert_nothing_raised { cron = @crontype.create(args) } return cron end # Run the cron through its paces -- install it then remove it. def cyclecron(cron) obj = Puppet::Type::Cron.cronobj(@me) text = obj.read name = cron.name comp = newcomp(name, cron) assert_events([:cron_created], comp) cron.retrieve assert(cron.insync?, "Cron is not in sync") assert_events([], comp) curtext = obj.read text.split("\n").each do |line| assert(curtext.include?(line), "Missing '%s'" % line) end obj = Puppet::Type::Cron.cronobj(@me) cron[:ensure] = :absent assert_events([:cron_removed], comp) cron.retrieve assert(cron.insync?, "Cron is not in sync") assert_events([], comp) end # A simple test to see if we can load the cron from disk. def test_load assert_nothing_raised { @crontype.retrieve(@me) } end # Test that a cron job turns out as expected, by creating one and generating # it directly def test_simple_to_cron cron = nil # make the cron name = "yaytest" assert_nothing_raised { cron = @crontype.create( :name => name, :command => "date > /dev/null", :user => @me ) } str = nil # generate the text assert_nothing_raised { str = cron.to_record } assert_equal(str, "# Puppet Name: #{name}\n* * * * * date > /dev/null", "Cron did not generate correctly") end def test_simpleparsing @fakefiletype = Puppet::FileType.filetype(:ram) @crontype.filetype = @fakefiletype @crontype.retrieve(@me) obj = Puppet::Type::Cron.cronobj(@me) text = "5 1,2 * 1 0 /bin/echo funtest" assert_nothing_raised { @crontype.parse(@me, text) } @crontype.each do |obj| assert_equal(["5"], obj.is(:minute), "Minute was not parsed correctly") assert_equal(["1", "2"], obj.is(:hour), "Hour was not parsed correctly") assert_equal([:absent], obj.is(:monthday), "Monthday was not parsed correctly") assert_equal(["1"], obj.is(:month), "Month was not parsed correctly") assert_equal(["0"], obj.is(:weekday), "Weekday was not parsed correctly") assert_equal(["/bin/echo funtest"], obj.is(:command), "Command was not parsed correctly") end end # Test that changing any field results in the cron tab being rewritten. # it directly def test_any_field_changes cron = nil # make the cron name = "yaytest" assert_nothing_raised { cron = @crontype.create( :name => name, :command => "date > /dev/null", :month => "May", :user => @me ) } assert(cron, "Cron did not get created") comp = newcomp(cron) assert_events([:cron_created], comp) assert_nothing_raised { cron[:month] = "June" } cron.retrieve assert_events([:cron_changed], comp) end # Test that a cron job with spaces at the end doesn't get rewritten def test_trailingspaces cron = nil # make the cron name = "yaytest" assert_nothing_raised { cron = @crontype.create( :name => name, :command => "date > /dev/null ", :month => "May", :user => @me ) } comp = newcomp(cron) assert_events([:cron_created], comp, "did not create cron job") cron.retrieve assert_events([], comp, "cron job got rewritten") end # Test that comments are correctly retained def test_retain_comments str = "# this is a comment\n#and another comment\n" user = "fakeuser" @crontype.retrieve(@me) assert_nothing_raised { @crontype.parse(@me, str) } assert_nothing_raised { newstr = @crontype.tab(@me) assert(newstr.include?(str), "Comments were lost") } end # Test that a specified cron job will be matched against an existing job # with no name, as long as all fields match def test_matchcron str = "0,30 * * * * date\n" assert_nothing_raised { cron = @crontype.create( :name => "yaycron", :minute => [0, 30], :command => "date", :user => @me ) } assert_nothing_raised { @crontype.parse(@me, str) } count = @crontype.inject(0) do |c, obj| c + 1 end assert_equal(1, count, "Did not match cron job") modstr = "# Puppet Name: yaycron\n%s" % str assert_nothing_raised { newstr = @crontype.tab(@me) assert(newstr.include?(modstr), "Cron was not correctly matched") } end # Test adding a cron when there is currently no file. def test_mkcronwithnotab tab = @fakefiletype.new(@me) tab.remove @crontype.retrieve(@me) cron = mkcron("testwithnotab") cyclecron(cron) end def test_mkcronwithtab @crontype.retrieve(@me) obj = Puppet::Type::Cron.cronobj(@me) obj.write( "1 1 1 1 * date > %s/crontesting\n" % tstdir() ) cron = mkcron("testwithtab") cyclecron(cron) end def test_makeandretrievecron tab = @fakefiletype.new(@me) tab.remove %w{storeandretrieve a-name another-name more_naming SomeName}.each do |name| cron = mkcron(name) comp = newcomp(name, cron) trans = assert_events([:cron_created], comp, name) cron = nil Puppet.type(:cron).retrieve(@me) assert(cron = Puppet.type(:cron)[name], "Could not retrieve named cron") assert_instance_of(Puppet.type(:cron), cron) end end # Do input validation testing on all of the parameters. def test_arguments values = { :monthday => { :valid => [ 1, 13, "1" ], :invalid => [ -1, 0, 32 ] }, :weekday => { :valid => [ 0, 3, 6, "1", "tue", "wed", "Wed", "MOnday", "SaTurday" ], :invalid => [ -1, 7, "13", "tues", "teusday", "thurs" ] }, :hour => { :valid => [ 0, 21, 23 ], :invalid => [ -1, 24 ] }, :minute => { :valid => [ 0, 34, 59 ], :invalid => [ -1, 60 ] }, :month => { :valid => [ 1, 11, 12, "mar", "March", "apr", "October", "DeCeMbEr" ], :invalid => [ -1, 0, 13, "marc", "sept" ] } } cron = mkcron("valtesting") values.each { |param, hash| # We have to test the valid ones first, because otherwise the # state will fail to create at all. [:valid, :invalid].each { |type| hash[type].each { |value| case type when :valid: assert_nothing_raised { cron[param] = value } if value.is_a?(Integer) assert_equal(value.to_s, cron.should(param), "Cron value was not set correctly") end when :invalid: assert_raise(Puppet::Error, "%s is incorrectly a valid %s" % [value, param]) { cron[param] = value } end if value.is_a?(Integer) value = value.to_s redo end } } } end # Test that we can read and write cron tabs def test_crontab Puppet.type(:cron).filetype = Puppet.type(:cron).defaulttype type = nil unless type = Puppet.type(:cron).filetype $stderr.puts "No crontab type; skipping test" end obj = nil assert_nothing_raised { obj = type.new(Process.uid) } txt = nil assert_nothing_raised { txt = obj.read } assert_nothing_raised { obj.write(txt) } end # Verify that comma-separated numbers are not resulting in rewrites def test_norewrite cron = nil assert_nothing_raised { cron = Puppet.type(:cron).create( :command => "/bin/date > /dev/null", :minute => [0, 30], :name => "crontest" ) } assert_events([:cron_created], cron) cron.retrieve assert_events([], cron) end def test_fieldremoval cron = nil assert_nothing_raised { cron = Puppet.type(:cron).create( :command => "/bin/date > /dev/null", :minute => [0, 30], :name => "crontest" ) } assert_events([:cron_created], cron) cron[:minute] = :absent assert_events([:cron_changed], cron) assert_nothing_raised { cron.retrieve } assert_equal(:absent, cron.is(:minute)) end def test_listing @crontype.filetype = @oldfiletype crons = [] assert_nothing_raised { Puppet::Type.type(:cron).list.each do |cron| crons << cron end } crons.each do |cron| assert(cron, "Did not receive a real cron object") assert_instance_of(String, cron[:user], "Cron user is not a string") end end def verify_failonnouser assert_raise(Puppet::Error) do @crontype.retrieve("nosuchuser") end end def test_names cron = mkcron("nametest") ["bad name", "bad.name"].each do |name| assert_raise(ArgumentError) do cron[:name] = name end end ["good-name", "good-name", "AGoodName"].each do |name| assert_nothing_raised do cron[:name] = name end end end # Make sure we don't puke on env settings def test_envsettings cron = mkcron("envtst") assert_apply(cron) obj = Puppet::Type::Cron.cronobj(@me) assert(obj) text = obj.read text = "SHELL = /path/to/some/thing\n" + text obj.write(text) assert_nothing_raised { cron.retrieve } cron[:command] = "/some/other/command" assert_apply(cron) assert(obj.read =~ /SHELL/, "lost env setting") env1 = "TEST = /bin/true" env2 = "YAY = fooness" assert_nothing_raised { cron[:environment] = [env1, env2] } assert_apply(cron) cron.retrieve vals = cron.is(:environment) assert(vals, "Did not get environment settings") assert(vals != :absent, "Env is incorrectly absent") assert_instance_of(Array, vals) assert(vals.include?(env1), "Missing first env setting") assert(vals.include?(env2), "Missing second env setting") end def test_divisionnumbers cron = mkcron("divtest") cron[:minute] = "*/5" assert_apply(cron) cron.retrieve assert_equal(["*/5"], cron.is(:minute)) end def test_ranges cron = mkcron("rangetest") cron[:minute] = "2-4" assert_apply(cron) cron.retrieve assert_equal(["2-4"], cron.is(:minute)) end def test_data @fakefiletype = Puppet::FileType.filetype(:ram) @crontype.filetype = @fakefiletype @crontype.retrieve(@me) obj = Puppet::Type::Cron.cronobj(@me) fakedata("data/types/cron").each do |file| names = [] text = File.read(file) obj.write(File.read(file)) @crontype.retrieve(@me) @crontype.each do |cron| names << cron.name end name = File.basename(file) cron = mkcron("filetest-#{name}") assert_apply(cron) @crontype.retrieve(@me) names.each do |name| assert(@crontype[name], "Could not retrieve %s" % name) end tablines = @crontype.tab(@me).split("\n") text.split("\n").each do |line| assert(tablines.include?(line), "Did not get %s back out" % line.inspect) end end end def test_value cron = mkcron("valuetesting", false) # First, test the normal states [:minute, :hour, :month].each do |param| cron.newstate(param) state = cron.state(param) assert(state, "Did not get %s state" % param) assert_nothing_raised { state.is = :absent } # Make sure our minute default is 0, not * val = if param == :minute "*" # the "0" thing is disabled for now else "*" end assert_equal(val, cron.value(param)) # Make sure we correctly get the "is" value if that's all there is cron.is = [param, "1"] assert_equal("1", cron.value(param)) # Make sure arrays work, too cron.is = [param, ["1"]] assert_equal("1", cron.value(param)) # Make sure values get comma-joined cron.is = [param, ["2", "3"]] assert_equal("2,3", cron.value(param)) # Make sure "should" values work, too cron[param] = "4" assert_equal("4", cron.value(param)) cron[param] = ["4"] assert_equal("4", cron.value(param)) cron[param] = ["4", "5"] assert_equal("4,5", cron.value(param)) cron.is = [param, :absent] assert_equal("4,5", cron.value(param)) end # Now make sure that :command works correctly cron.delete(:command) cron.newstate(:command) state = cron.state(:command) assert_nothing_raised { state.is = :absent } assert(state, "Did not get command state") assert_raise(Puppet::DevError) do cron.value(:command) end param = :command # Make sure we correctly get the "is" value if that's all there is cron.is = [param, "1"] assert_equal("1", cron.value(param)) # Make sure arrays work, too cron.is = [param, ["1"]] assert_equal("1", cron.value(param)) # Make sure values are not comma-joined cron.is = [param, ["2", "3"]] assert_equal("2", cron.value(param)) # Make sure "should" values work, too cron[param] = "4" assert_equal("4", cron.value(param)) cron[param] = ["4"] assert_equal("4", cron.value(param)) cron[param] = ["4", "5"] assert_equal("4", cron.value(param)) cron.is = [param, :absent] assert_equal("4", cron.value(param)) end # Make sure we can successfully list all cron jobs on all users def test_cron_listing crons = [] %w{fake1 fake2 fake3 fake4 fake5}.each do |user| crons << @crontype.create( :name => "#{user}-1", :command => "/usr/bin/#{user}", :minute => "0", :user => user, :hour => user.sub("fake",'') ) crons << @crontype.create( :name => "#{user}-2", :command => "/usr/sbin/#{user}", :minute => "0", :user => user, :weekday => user.sub("fake",'') ) assert_apply(*crons) end list = @crontype.list.collect { |c| c.name } crons.each do |cron| assert(list.include?(cron.name), "Did not match cron %s" % name) end end # Make sure we can create a cron in an empty tab def test_mkcron_if_empty @crontype.filetype = @oldfiletype @crontype.retrieve(@me) # Backup our tab text = @crontype.tabobj(@me).read cleanup do if text == "" @crontype.tabobj(@me).remove else @crontype.tabobj(@me).write(text) end end # Now get rid of it @crontype.tabobj(@me).remove @crontype.clear cron = mkcron("emptycron") assert_apply(cron) # Clear the type, but don't clear the filetype @crontype.clear # Get the stuff again @crontype.retrieve(@me) assert(@crontype["emptycron"], "Did not retrieve cron") end def test_multiple_users crons = [] users = ["root", nonrootuser.name] users.each do |user| crons << Puppet::Type.type(:cron).create( :name => "testcron-#{user}", :user => user, :command => "/bin/echo", :minute => [0,30] ) end assert_apply(*crons) users.each do |user| users.each do |other| next if user == other assert(Puppet::Type.type(:cron).tabobj(other).read !~ /testcron-#{user}/, "%s's cron job is in %s's tab" % [user, other]) end end end end # $Id$ diff --git a/test/types/exec.rb b/test/types/exec.rb index 8f09420d1..4719e0baa 100755 --- a/test/types/exec.rb +++ b/test/types/exec.rb @@ -1,586 +1,579 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' require 'facter' class TestExec < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_execution command = nil output = nil assert_nothing_raised { command = Puppet.type(:exec).create( :command => "/bin/echo" ) } assert_nothing_raised { command.evaluate } assert_events([:executed_command], command) end def test_numvsstring [0, "0"].each { |val| Puppet.type(:exec).clear Puppet.type(:component).clear command = nil output = nil assert_nothing_raised { command = Puppet.type(:exec).create( :command => "/bin/echo", :returns => val ) } assert_events([:executed_command], command) } end def test_path_or_qualified command = nil output = nil assert_raise(Puppet::Error) { command = Puppet.type(:exec).create( :command => "echo" ) } assert_nothing_raised { command = Puppet.type(:exec).create( :command => "echo", :path => "/usr/bin:/bin:/usr/sbin:/sbin" ) } Puppet.type(:exec).clear assert_nothing_raised { command = Puppet.type(:exec).create( :command => "/bin/echo" ) } Puppet.type(:exec).clear assert_nothing_raised { command = Puppet.type(:exec).create( :command => "/bin/echo", :path => "/usr/bin:/bin:/usr/sbin:/sbin" ) } end def test_nonzero_returns assert_nothing_raised { command = Puppet.type(:exec).create( :command => "mkdir /this/directory/does/not/exist", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :returns => 1 ) } assert_nothing_raised { command = Puppet.type(:exec).create( :command => "touch /etc", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :returns => 1 ) } assert_nothing_raised { command = Puppet.type(:exec).create( :command => "thiscommanddoesnotexist", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :returns => 127 ) } end def test_cwdsettings command = nil dir = "/tmp" wd = Dir.chdir(dir) { Dir.getwd } assert_nothing_raised { command = Puppet.type(:exec).create( :command => "pwd", :cwd => dir, :path => "/usr/bin:/bin:/usr/sbin:/sbin", :returns => 0 ) } assert_events([:executed_command], command) assert_equal(wd,command.output.chomp) end def test_refreshonly file = nil cmd = nil tmpfile = tempfile() @@tmpfiles.push tmpfile trans = nil File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) } file = Puppet.type(:file).create( :path => tmpfile, :checksum => "md5" ) assert_instance_of(Puppet.type(:file), file) assert_nothing_raised { cmd = Puppet.type(:exec).create( :command => "pwd", :path => "/usr/bin:/bin:/usr/sbin:/sbin", :subscribe => [[file.class.name,file.name]], :refreshonly => true ) } assert_instance_of(Puppet.type(:exec), cmd) comp = Puppet.type(:component).create(:name => "RefreshTest") [file,cmd].each { |obj| comp.push obj } events = nil assert_nothing_raised { trans = comp.evaluate file.retrieve sum = file.state(:checksum) assert_equal(sum.is, sum.should) events = trans.evaluate.collect { |event| event.event } } # the first checksum shouldn't result in a changed file assert_equal([],events) File.open(tmpfile, File::WRONLY|File::CREAT|File::TRUNC) { |of| of.puts rand(100) of.puts rand(100) of.puts rand(100) } assert_nothing_raised { trans = comp.evaluate sum = file.state(:checksum) events = trans.evaluate.collect { |event| event.event } } # verify that only the file_changed event was kicked off, not the # command_executed assert_equal( [:file_changed], events ) end def test_creates file = tempfile() exec = nil assert(! FileTest.exists?(file), "File already exists") assert_nothing_raised { exec = Puppet.type(:exec).create( :command => "touch %s" % file, :path => "/usr/bin:/bin:/usr/sbin:/sbin", :creates => file ) } comp = newcomp("createstest", exec) assert_events([:executed_command], comp, "creates") assert_events([], comp, "creates") end # Verify that we can download the file that we're going to execute. def test_retrievethenmkexe exe = tempfile() oexe = tempfile() sh = %x{which sh} File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" } file = Puppet.type(:file).create( :path => oexe, :source => exe, :mode => 0755 ) exec = Puppet.type(:exec).create( :command => oexe, :require => [:file, oexe] ) comp = newcomp("Testing", file, exec) assert_events([:file_created, :executed_command], comp) end # Verify that we auto-require any managed scripts. def test_autorequire exe = tempfile() oexe = tempfile() sh = %x{which sh} File.open(exe, "w") { |f| f.puts "#!#{sh}\necho yup" } file = Puppet.type(:file).create( :path => oexe, :source => exe, :mode => 755 ) basedir = File.dirname(oexe) baseobj = Puppet.type(:file).create( :path => basedir, :source => exe, :mode => 755 ) ofile = Puppet.type(:file).create( :path => exe, :mode => 755 ) exec = Puppet.type(:exec).create( :command => oexe, :path => ENV["PATH"], :cwd => basedir ) cat = Puppet.type(:exec).create( :command => "cat %s %s" % [exe, oexe], :path => ENV["PATH"] ) comp = newcomp(ofile, exec, cat, file, baseobj) comp.finalize # Verify we get the script itself assert(exec.requires?(file), "Exec did not autorequire %s" % file) # Verify we catch the cwd assert(exec.requires?(baseobj), "Exec did not autorequire cwd") # Verify we don't require ourselves assert(!exec.requires?(ofile), "Exec incorrectly required file") # Verify that we catch inline files # We not longer autorequire inline files assert(! cat.requires?(ofile), "Exec required second inline file") assert(! cat.requires?(file), "Exec required inline file") end def test_ifonly afile = tempfile() bfile = tempfile() exec = nil assert_nothing_raised { exec = Puppet.type(:exec).create( :command => "touch %s" % bfile, :onlyif => "test -f %s" % afile, :path => ENV['PATH'] ) } assert_events([], exec) system("touch %s" % afile) assert_events([:executed_command], exec) assert_events([:executed_command], exec) system("rm %s" % afile) assert_events([], exec) end def test_unless afile = tempfile() bfile = tempfile() exec = nil assert_nothing_raised { exec = Puppet.type(:exec).create( :command => "touch %s" % bfile, :unless => "test -f %s" % afile, :path => ENV['PATH'] ) } comp = newcomp(exec) assert_events([:executed_command], comp) assert_events([:executed_command], comp) system("touch %s" % afile) assert_events([], comp) assert_events([], comp) system("rm %s" % afile) assert_events([:executed_command], comp) assert_events([:executed_command], comp) end if Process.uid == 0 # Verify that we can execute commands as a special user def mknverify(file, user, group = nil, id = true) args = { :command => "touch %s" % file, :path => "/usr/bin:/bin:/usr/sbin:/sbin", } if user #Puppet.warning "Using user %s" % user.name if id # convert to a string, because that's what the object expects args[:user] = user.uid.to_s else args[:user] = user.name end end if group #Puppet.warning "Using group %s" % group.name if id args[:group] = group.gid.to_s else args[:group] = group.name end end exec = nil assert_nothing_raised { exec = Puppet.type(:exec).create(args) } comp = newcomp("usertest", exec) assert_events([:executed_command], comp, "usertest") assert(FileTest.exists?(file), "File does not exist") if user assert_equal(user.uid, File.stat(file).uid, "File UIDs do not match") end # We can't actually test group ownership, unfortunately, because # behaviour changes wildlly based on platform. Puppet::Type.allclear end def test_userngroup file = tempfile() [ [nonrootuser()], # just user, by name [nonrootuser(), nil, true], # user, by uid [nil, nonrootgroup()], # just group [nil, nonrootgroup(), true], # just group, by id [nonrootuser(), nonrootgroup()], # user and group, by name [nonrootuser(), nonrootgroup(), true], # user and group, by id ].each { |ary| mknverify(file, *ary) { } } end end def test_logoutput exec = nil assert_nothing_raised { exec = Puppet.type(:exec).create( :title => "logoutputesting", :path => "/usr/bin:/bin", :command => "echo logoutput is false", :logoutput => false ) } assert_apply(exec) assert_nothing_raised { exec[:command] = "echo logoutput is true" exec[:logoutput] = true } assert_apply(exec) assert_nothing_raised { exec[:command] = "echo logoutput is warning" exec[:logoutput] = "warning" } assert_apply(exec) end def test_execthenfile exec = nil file = nil basedir = tempfile() path = File.join(basedir, "subfile") assert_nothing_raised { exec = Puppet.type(:exec).create( :title => "mkdir", :path => "/usr/bin:/bin", :creates => basedir, :command => "mkdir %s; touch %s" % [basedir, path] ) } assert_nothing_raised { file = Puppet.type(:file).create( :path => basedir, :recurse => true, :mode => "755", :require => ["exec", "mkdir"] ) } comp = newcomp(file, exec) comp.finalize assert_events([:executed_command, :file_changed], comp) assert(FileTest.exists?(path), "Exec ran first") assert(File.stat(path).mode & 007777 == 0755) end def test_falsevals exec = nil assert_nothing_raised do exec = Puppet.type(:exec).create( :command => "/bin/touch yayness" ) end Puppet.type(:exec).checks.each do |check| klass = Puppet.type(:exec).paramclass(check) next if klass.values.include? :false assert_raise(Puppet::Error, "Check %s did not fail on false" % check) do exec[check] = false end end end def test_createcwdandexe exec1 = exec2 = nil dir = tempfile() file = tempfile() assert_nothing_raised { exec1 = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "mkdir #{dir}" ) } assert_nothing_raised("Could not create exec w/out existing cwd") { exec2 = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "touch #{file}", :cwd => dir ) } # Throw a check in there with our cwd and make sure it works assert_nothing_raised("Could not check with a missing cwd") do exec2[:unless] = "test -f /this/file/does/not/exist" exec2.retrieve end assert_raise(Puppet::Error) do exec2.state(:returns).sync end assert_nothing_raised do exec2[:require] = ["exec", exec1.name] exec2.finish end assert_apply(exec1, exec2) assert(FileTest.exists?(file)) end def test_checkarrays exec = nil file = tempfile() test = "test -f #{file}" assert_nothing_raised { exec = Puppet.type(:exec).create( :path => ENV["PATH"], :command => "touch #{file}" ) } assert_nothing_raised { exec[:unless] = test } assert_nothing_raised { assert(exec.check, "Check did not pass") } assert_nothing_raised { exec[:unless] = [test, test] } assert_nothing_raised { exec.finish } assert_nothing_raised { assert(exec.check, "Check did not pass") } assert_apply(exec) assert_nothing_raised { assert(! exec.check, "Check passed") } end def test_missing_checks_cause_failures exec = Puppet::Type.newexec( :command => "echo true", :path => ENV["PATH"], :onlyif => "/bin/nosuchthingexists" ) assert_raise(ArgumentError, "Missing command did not raise error") { exec.run("/bin/nosuchthingexists") } end def test_envparam exec = Puppet::Type.newexec( :command => "echo $envtest", :path => ENV["PATH"], :env => "envtest=yayness" ) assert(exec, "Could not make exec") output = status = nil assert_nothing_raised { output, status = exec.run("echo $envtest") } assert_equal("yayness\n", output) # Now check whether we can do multiline settings assert_nothing_raised do exec[:env] = "envtest=a list of things and stuff" end output = status = nil assert_nothing_raised { output, status = exec.run('echo "$envtest"') } assert_equal("a list of things\nand stuff\n", output) # Now test arrays assert_nothing_raised do exec[:env] = ["funtest=A", "yaytest=B"] end output = status = nil assert_nothing_raised { output, status = exec.run('echo "$funtest" "$yaytest"') } assert_equal("A B\n", output) end end # $Id$ diff --git a/test/types/file.rb b/test/types/file.rb index e814b6c37..b87f1b928 100644 --- a/test/types/file.rb +++ b/test/types/file.rb @@ -1,1418 +1,1411 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' -require 'test/unit' require 'fileutils' require 'puppettest' class TestFile < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting # hmmm # this is complicated, because we store references to the created # objects in a central store def mkfile(hash) file = nil assert_nothing_raised { file = Puppet.type(:file).create(hash) } return file end def mktestfile # because luke's home directory is on nfs, it can't be used for testing # as root tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } @@tmpfiles.push tmpfile mkfile(:name => tmpfile) end def setup super begin initstorage rescue system("rm -rf %s" % Puppet[:statefile]) end end def teardown Puppet::Storage.clear system("rm -rf %s" % Puppet[:statefile]) super end def initstorage Puppet::Storage.init Puppet::Storage.load end def clearstorage Puppet::Storage.store Puppet::Storage.clear end def test_owner file = mktestfile() users = {} count = 0 # collect five users Etc.passwd { |passwd| if count > 5 break else count += 1 end users[passwd.uid] = passwd.name } fake = {} # find a fake user while true a = rand(1000) begin Etc.getpwuid(a) rescue fake[a] = "fakeuser" break end end uid, name = users.shift us = {} us[uid] = name users.each { |uid, name| assert_apply(file) assert_nothing_raised() { file[:owner] = name } assert_nothing_raised() { file.retrieve } assert_apply(file) } end def test_group file = mktestfile() [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group| assert_nothing_raised() { file[:group] = group } assert(file.state(:group)) assert(file.state(:group).should) } end if Process.uid == 0 def test_createasuser dir = tmpdir() user = nonrootuser() path = File.join(tmpdir, "createusertesting") @@tmpfiles << path file = nil assert_nothing_raised { file = Puppet.type(:file).create( :path => path, :owner => user.name, :ensure => "file", :mode => "755" ) } comp = newcomp("createusertest", file) assert_events([:file_created], comp) end def test_nofollowlinks basedir = tempfile() Dir.mkdir(basedir) file = File.join(basedir, "file") link = File.join(basedir, "link") File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush } File.symlink(file, link) # First test 'user' user = nonrootuser() inituser = File.lstat(link).uid File.lchown(inituser, nil, link) obj = nil assert_nothing_raised { obj = Puppet.type(:file).create( :title => link, :owner => user.name ) } obj.retrieve # Make sure it defaults to managing the link assert_events([:file_changed], obj) assert_equal(user.uid, File.lstat(link).uid) assert_equal(inituser, File.stat(file).uid) File.chown(inituser, nil, file) File.lchown(inituser, nil, link) # Try following obj[:links] = :follow assert_events([:file_changed], obj) assert_equal(user.uid, File.stat(file).uid) assert_equal(inituser, File.lstat(link).uid) # And then explicitly managing File.chown(inituser, nil, file) File.lchown(inituser, nil, link) obj[:links] = :manage assert_events([:file_changed], obj) assert_equal(user.uid, File.lstat(link).uid) assert_equal(inituser, File.stat(file).uid) obj.delete(:owner) obj[:links] = :ignore # And then test 'group' group = nonrootgroup initgroup = File.stat(file).gid obj[:group] = group.name assert_events([:file_changed], obj) assert_equal(initgroup, File.stat(file).gid) assert_equal(group.gid, File.lstat(link).gid) File.chown(nil, initgroup, file) File.lchown(nil, initgroup, link) obj[:links] = :follow assert_events([:file_changed], obj) assert_equal(group.gid, File.stat(file).gid) File.chown(nil, initgroup, file) File.lchown(nil, initgroup, link) obj[:links] = :manage assert_events([:file_changed], obj) assert_equal(group.gid, File.lstat(link).gid) assert_equal(initgroup, File.stat(file).gid) end def test_ownerasroot file = mktestfile() users = {} count = 0 # collect five users Etc.passwd { |passwd| if count > 5 break else count += 1 end next if passwd.uid < 0 users[passwd.uid] = passwd.name } fake = {} # find a fake user while true a = rand(1000) begin Etc.getpwuid(a) rescue fake[a] = "fakeuser" break end end users.each { |uid, name| assert_nothing_raised() { file[:owner] = name } changes = [] assert_nothing_raised() { changes << file.evaluate } assert(changes.length > 0) assert_apply(file) file.retrieve assert(file.insync?()) assert_nothing_raised() { file[:owner] = uid } assert_apply(file) file.retrieve # make sure changing to number doesn't cause a sync assert(file.insync?()) } # We no longer raise an error here, because we check at run time #fake.each { |uid, name| # assert_raise(Puppet::Error) { # file[:owner] = name # } # assert_raise(Puppet::Error) { # file[:owner] = uid # } #} end def test_groupasroot file = mktestfile() [%x{groups}.chomp.split(/ /), Process.groups].flatten.each { |group| assert_nothing_raised() { file[:group] = group } assert(file.state(:group)) assert(file.state(:group).should) assert_apply(file) file.retrieve assert(file.insync?()) assert_nothing_raised() { file.delete(:group) } } end if Facter.value(:operatingsystem) == "Darwin" def test_sillyowner file = tempfile() File.open(file, "w") { |f| f.puts "" } File.chown(-2, nil, file) assert(File.stat(file).uid > 120000, "eh?") user = nonrootuser obj = Puppet::Type.newfile( :path => file, :owner => user.name ) assert_apply(obj) assert_equal(user.uid, File.stat(file).uid) end end else $stderr.puts "Run as root for complete owner and group testing" end def test_create %w{a b c d}.collect { |name| tempfile() + name.to_s }.each { |path| file =nil assert_nothing_raised() { file = Puppet.type(:file).create( :name => path, :ensure => "file" ) } assert_events([:file_created], file) assert_events([], file) assert(FileTest.file?(path), "File does not exist") assert(file.insync?()) @@tmpfiles.push path } end def test_create_dir basedir = tempfile() Dir.mkdir(basedir) %w{a b c d}.collect { |name| "#{basedir}/%s" % name }.each { |path| file = nil assert_nothing_raised() { file = Puppet.type(:file).create( :name => path, :ensure => "directory" ) } assert(! FileTest.directory?(path), "Directory %s already exists" % [path]) assert_events([:directory_created], file) assert_events([], file) assert(file.insync?()) assert(FileTest.directory?(path)) @@tmpfiles.push path } end def test_modes file = mktestfile # Set it to something else initially File.chmod(0775, file.title) [0644,0755,0777,0641].each { |mode| assert_nothing_raised() { file[:mode] = mode } assert_events([:file_changed], file) assert_events([], file) assert(file.insync?()) assert_nothing_raised() { file.delete(:mode) } } end def test_checksums types = %w{md5 md5lite timestamp time} exists = "/tmp/sumtest-exists" nonexists = "/tmp/sumtest-nonexists" @@tmpfiles << exists @@tmpfiles << nonexists # try it both with files that exist and ones that don't files = [exists, nonexists] initstorage File.open(exists,File::CREAT|File::TRUNC|File::WRONLY) { |of| of.puts "initial text" } types.each { |type| files.each { |path| if Puppet[:debug] Puppet.warning "Testing %s on %s" % [type,path] end file = nil events = nil # okay, we now know that we have a file... assert_nothing_raised() { file = Puppet.type(:file).create( :name => path, :ensure => "file", :checksum => type ) } comp = Puppet.type(:component).create( :name => "checksum %s" % type ) comp.push file trans = nil file.retrieve if file.title !~ /nonexists/ sum = file.state(:checksum) assert_equal(sum.is, sum.should) assert(sum.insync?) end events = assert_apply(comp) assert(! events.include?(:file_changed), "File incorrectly changed") assert_events([], comp) # We have to sleep because the time resolution of the time-based # mechanisms is greater than one second sleep 1 assert_nothing_raised() { File.open(path,File::CREAT|File::TRUNC|File::WRONLY) { |of| of.puts "some more text, yo" } } Puppet.type(:file).clear Puppet.type(:component).clear # now recreate the file assert_nothing_raised() { file = Puppet.type(:file).create( :name => path, :checksum => type ) } comp = Puppet.type(:component).create( :name => "checksum, take 2, %s" % type ) comp.push file trans = nil # If the file was missing, it should not generate an event # when it gets created. #if path =~ /nonexists/ # assert_events([], comp) #else assert_events([:file_changed], comp) #end assert_nothing_raised() { File.unlink(path) File.open(path,File::CREAT|File::TRUNC|File::WRONLY) { |of| # We have to put a certain amount of text in here or # the md5-lite test fails 2.times { of.puts rand(100) } of.flush } } #assert_apply(comp) assert_events([:file_changed], comp) # verify that we're actually getting notified when a file changes assert_nothing_raised() { Puppet.type(:file).clear Puppet.type(:component).clear } if path =~ /nonexists/ File.unlink(path) end } } end def cyclefile(path) # i had problems with using :name instead of :path [:name,:path].each { |param| file = nil changes = nil comp = nil trans = nil initstorage assert_nothing_raised { file = Puppet.type(:file).create( param => path, :recurse => true, :checksum => "md5" ) } comp = Puppet.type(:component).create( :name => "component" ) comp.push file assert_nothing_raised { trans = comp.evaluate } assert_nothing_raised { trans.evaluate } clearstorage Puppet::Type.allclear } end def test_recursion basedir = tempfile() subdir = File.join(basedir, "this", "is", "sub", "dir") tmpfile = File.join(subdir,"testing") FileUtils.mkdir_p(subdir) dir = nil [true, "true", "inf", 50].each do |value| assert_nothing_raised { dir = Puppet.type(:file).create( :path => basedir, :recurse => value, :check => %w{owner mode group} ) } assert_nothing_raised { dir.evaluate } subobj = nil assert_nothing_raised { subobj = Puppet.type(:file)[subdir] } assert(subobj, "Could not retrieve %s object" % subdir) File.open(tmpfile, "w") { |f| f.puts "yayness" } dir.evaluate file = nil assert_nothing_raised { file = Puppet.type(:file)[tmpfile] } assert(file, "Could not retrieve %s object" % tmpfile) #system("rm -rf %s" % basedir) Puppet.type(:file).clear end end =begin def test_ignore end =end # XXX disabled until i change how dependencies work def disabled_test_recursionwithcreation path = "/tmp/this/directory/structure/does/not/exist" @@tmpfiles.push "/tmp/this" file = nil assert_nothing_raised { file = mkfile( :name => path, :recurse => true, :ensure => "file" ) } trans = nil comp = newcomp("recursewithfiles", file) assert_nothing_raised { trans = comp.evaluate } events = nil assert_nothing_raised { events = trans.evaluate.collect { |e| e.event.to_s } } puts "events are %s" % events.join(", ") end def test_filetype_retrieval file = nil # Verify it retrieves files of type directory assert_nothing_raised { file = Puppet.type(:file).create( :name => tmpdir(), :check => :type ) } assert_nothing_raised { file.evaluate } assert_equal("directory", file.state(:type).is) # And then check files assert_nothing_raised { file = Puppet.type(:file).create( :name => tempfile(), :ensure => "file" ) } assert_apply(file) file[:check] = "type" assert_apply(file) assert_equal("file", file.state(:type).is) file[:type] = "directory" assert_nothing_raised { file.retrieve } # The 'retrieve' method sets @should to @is, so they're never # out of sync. It's a read-only class. assert(file.insync?) end def test_remove basedir = tempfile() subdir = File.join(basedir, "this") FileUtils.mkdir_p(subdir) dir = nil assert_nothing_raised { dir = Puppet.type(:file).create( :path => basedir, :recurse => true, :check => %w{owner mode group} ) } assert_nothing_raised { dir.retrieve } obj = nil assert_nothing_raised { obj = Puppet.type(:file)[subdir] } assert(obj, "Could not retrieve subdir object") assert_nothing_raised { obj.remove(true) } assert_nothing_raised { obj = Puppet.type(:file)[subdir] } assert_nil(obj, "Retrieved removed object") end def test_path dir = tempfile() path = File.join(dir, "and", "a", "sub", "dir") assert_nothing_raised("Could not make file") { FileUtils.mkdir_p(File.dirname(path)) File.open(path, "w") { |f| f.puts "yayness" } } file = nil dirobj = nil assert_nothing_raised("Could not make file object") { dirobj = Puppet.type(:file).create( :path => dir, :recurse => true, :check => %w{mode owner group} ) } assert_nothing_raised { dirobj.evaluate } assert_nothing_raised { file = dirobj.class[path] } assert(file, "Could not retrieve file object") assert_equal("file=%s" % file.title, file.path) end def test_autorequire basedir = tempfile() subfile = File.join(basedir, "subfile") baseobj = Puppet.type(:file).create( :name => basedir, :ensure => "directory" ) subobj = Puppet.type(:file).create( :name => subfile, :ensure => "file" ) comp = newcomp(baseobj, subobj) comp.finalize assert(subobj.requires?(baseobj), "File did not require basedir") assert(!subobj.requires?(subobj), "File required itself") assert_events([:directory_created, :file_created], comp) end def test_content file = tempfile() str = "This is some content" obj = nil assert_nothing_raised { obj = Puppet.type(:file).create( :name => file, :content => str ) } assert(!obj.insync?, "Object is incorrectly in sync") assert_events([:file_created], obj) obj.retrieve assert(obj.insync?, "Object is not in sync") text = File.read(file) assert_equal(str, text, "Content did not copy correctly") newstr = "Another string, yo" obj[:content] = newstr assert(!obj.insync?, "Object is incorrectly in sync") assert_events([:file_changed], obj) text = File.read(file) assert_equal(newstr, text, "Content did not copy correctly") obj.retrieve assert(obj.insync?, "Object is not in sync") end # Unfortunately, I know this fails def disabled_test_recursivemkdir path = tempfile() subpath = File.join(path, "this", "is", "a", "dir") file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => subpath, :ensure => "directory", :recurse => true ) } comp = newcomp("yay", file) comp.finalize assert_apply(comp) #assert_events([:directory_created], comp) assert(FileTest.directory?(subpath), "Did not create directory") end # Make sure that content updates the checksum on the same run def test_checksumchange_for_content dest = tempfile() File.open(dest, "w") { |f| f.puts "yayness" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :checksum => "md5", :content => "This is some content" ) } file.retrieve assert_events([:file_changed], file) file.retrieve assert_events([], file) end # Make sure that content updates the checksum on the same run def test_checksumchange_for_ensure dest = tempfile() file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :checksum => "md5", :ensure => "file" ) } file.retrieve assert_events([:file_created], file) file.retrieve assert_events([], file) end # Make sure that content gets used before ensure def test_contentbeatsensure dest = tempfile() file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :ensure => "file", :content => "this is some content, yo" ) } file.retrieve assert_events([:file_created], file) file.retrieve assert_events([], file) assert_events([], file) end def test_nameandpath path = tempfile() file = nil assert_nothing_raised { file = Puppet.type(:file).create( :title => "fileness", :path => path, :content => "this is some content" ) } assert_apply(file) assert(FileTest.exists?(path)) end # Make sure that a missing group isn't fatal at object instantiation time. def test_missinggroup file = nil assert_nothing_raised { file = Puppet.type(:file).create( :path => tempfile(), :group => "fakegroup" ) } assert(file.state(:group), "Group state failed") end def test_modecreation path = tempfile() file = Puppet.type(:file).create( :path => path, :ensure => "file", :mode => "0777" ) assert_apply(file) assert_equal(0777, File.stat(path).mode & 007777) File.unlink(path) file[:ensure] = "directory" assert_apply(file) assert_equal(0777, File.stat(path).mode & 007777) end def test_followlinks basedir = tempfile() Dir.mkdir(basedir) file = File.join(basedir, "file") link = File.join(basedir, "link") File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush } File.symlink(file, link) obj = nil assert_nothing_raised { obj = Puppet.type(:file).create( :path => link, :mode => "755" ) } obj.retrieve assert_events([], obj) # Assert that we default to not following links assert_equal("%o" % 0644, "%o" % (File.stat(file).mode & 007777)) # Assert that we can manage the link directly, but modes still don't change obj[:links] = :manage assert_events([], obj) assert_equal("%o" % 0644, "%o" % (File.stat(file).mode & 007777)) obj[:links] = :follow assert_events([:file_changed], obj) assert_equal("%o" % 0755, "%o" % (File.stat(file).mode & 007777)) # Now verify that content and checksum don't update, either obj.delete(:mode) obj[:checksum] = "md5" obj[:links] = :ignore assert_events([], obj) File.open(file, "w") { |f| f.puts "more text" } assert_events([], obj) obj[:links] = :follow assert_events([], obj) File.open(file, "w") { |f| f.puts "even more text" } assert_events([:file_changed], obj) obj.delete(:checksum) obj[:content] = "this is some content" obj[:links] = :ignore assert_events([], obj) File.open(file, "w") { |f| f.puts "more text" } assert_events([], obj) obj[:links] = :follow assert_events([:file_changed], obj) end # If both 'ensure' and 'content' are used, make sure that all of the other # states are handled correctly. def test_contentwithmode path = tempfile() file = nil assert_nothing_raised { file = Puppet.type(:file).create( :path => path, :ensure => "file", :content => "some text\n", :mode => 0755 ) } assert_apply(file) assert_equal("%o" % 0755, "%o" % (File.stat(path).mode & 007777)) end # Make sure we can create symlinks def test_symlinks path = tempfile() link = tempfile() File.open(path, "w") { |f| f.puts "yay" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :ensure => path, :path => link ) } assert_events([:link_created], file) assert(FileTest.symlink?(link), "Link was not created") assert_equal(path, File.readlink(link), "Link was created incorrectly") # Make sure running it again works assert_events([], file) end def test_simplerecursivelinking source = tempfile() dest = tempfile() subdir = File.join(source, "subdir") file = File.join(subdir, "file") system("mkdir -p %s" % subdir) system("touch %s" % file) link = nil assert_nothing_raised { link = Puppet.type(:file).create( :ensure => source, :path => dest, :recurse => true ) } assert_apply(link) subdest = File.join(dest, "subdir") linkpath = File.join(subdest, "file") assert(File.directory?(dest), "dest is not a dir") assert(File.directory?(subdest), "subdest is not a dir") assert(File.symlink?(linkpath), "path is not a link") assert_equal(file, File.readlink(linkpath)) assert_events([], link) end def test_recursivelinking source = tempfile() dest = tempfile() files = [] dirs = [] # Make a bunch of files and dirs Dir.mkdir(source) Dir.chdir(source) do system("mkdir -p %s" % "some/path/of/dirs") system("mkdir -p %s" % "other/path/of/dirs") system("touch %s" % "file") system("touch %s" % "other/file") system("touch %s" % "some/path/of/file") system("touch %s" % "some/path/of/dirs/file") system("touch %s" % "other/path/of/file") files = %x{find . -type f}.chomp.split(/\n/) dirs = %x{find . -type d}.chomp.split(/\n/).reject{|d| d =~ /^\.+$/ } end link = nil assert_nothing_raised { link = Puppet.type(:file).create( :ensure => source, :path => dest, :recurse => true ) } assert_apply(link) files.each do |f| f.sub!(/^\.#{File::SEPARATOR}/, '') path = File.join(dest, f) assert(FileTest.exists?(path), "Link %s was not created" % path) assert(FileTest.symlink?(path), "%s is not a link" % f) target = File.readlink(path) assert_equal(File.join(source, f), target) end dirs.each do |d| d.sub!(/^\.#{File::SEPARATOR}/, '') path = File.join(dest, d) assert(FileTest.exists?(path), "Dir %s was not created" % path) assert(FileTest.directory?(path), "%s is not a directory" % d) end end def test_localrelativelinks dir = tempfile() Dir.mkdir(dir) source = File.join(dir, "source") File.open(source, "w") { |f| f.puts "yay" } dest = File.join(dir, "link") link = nil assert_nothing_raised { link = Puppet.type(:file).create( :path => dest, :ensure => "source" ) } assert_events([:link_created], link) assert(FileTest.symlink?(dest), "Did not create link") assert_equal("source", File.readlink(dest)) assert_equal("yay\n", File.read(dest)) end def test_recursivelinkingmissingtarget source = tempfile() dest = tempfile() objects = [] objects << Puppet.type(:exec).create( :command => "mkdir %s; touch %s/file" % [source, source], :path => ENV["PATH"] ) objects << Puppet.type(:file).create( :ensure => source, :path => dest, :recurse => true ) assert_apply(*objects) link = File.join(dest, "file") assert(FileTest.symlink?(link), "Did not make link") assert_equal(File.join(source, "file"), File.readlink(link)) end def test_backupmodes file = tempfile() newfile = tempfile() File.open(file, "w", 0411) { |f| f.puts "yayness" } obj = nil assert_nothing_raised { obj = Puppet::Type.type(:file).create( :path => file, :content => "rahness\n" ) } # user = group = nil # if Process.uid == 0 # user = nonrootuser # group = nonrootgroup # obj[:owner] = user.name # obj[:group] = group.name # File.chown(user.uid, group.gid, file) # end assert_apply(obj) backupfile = file + obj[:backup] @@tmpfiles << backupfile assert(FileTest.exists?(backupfile), "Backup file %s does not exist" % backupfile) assert_equal(0411, filemode(backupfile), "File mode is wrong for backupfile") # if Process.uid == 0 # assert_equal(user.uid, File.stat(backupfile).uid) # assert_equal(group.gid, File.stat(backupfile).gid) # end bucket = "bucket" bpath = tempfile() Dir.mkdir(bpath) Puppet::Type.type(:filebucket).create( :title => bucket, :path => bpath ) obj[:backup] = bucket obj[:content] = "New content" assert_apply(obj) bucketedpath = File.join(bpath, "18cc17fa3047fcc691fdf49c0a7f539a", "contents") assert_equal(0440, filemode(bucketedpath)) end def test_largefilechanges source = tempfile() dest = tempfile() # Now make a large file File.open(source, "w") { |f| 500.times { |i| f.puts "line %s" % i } } obj = Puppet::Type.type(:file).create( :title => dest, :source => source ) assert_events([:file_created], obj) File.open(source, File::APPEND|File::WRONLY) { |f| f.puts "another line" } assert_events([:file_changed], obj) # Now modify the dest file File.open(dest, File::APPEND|File::WRONLY) { |f| f.puts "one more line" } assert_events([:file_changed, :file_changed], obj) end def test_replacefilewithlink path = tempfile() link = tempfile() File.open(path, "w") { |f| f.puts "yay" } File.open(link, "w") { |f| f.puts "a file" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :ensure => path, :path => link ) } assert_events([:link_created], file) assert(FileTest.symlink?(link), "Link was not created") assert_equal(path, File.readlink(link), "Link was created incorrectly") end def test_replacedirwithlink path = tempfile() link = tempfile() File.open(path, "w") { |f| f.puts "yay" } Dir.mkdir(link) File.open(File.join(link, "yay"), "w") do |f| f.puts "boo" end file = nil assert_nothing_raised { file = Puppet.type(:file).create( :ensure => path, :path => link, :backup => false ) } # First run through without :force assert_events([], file) assert(FileTest.directory?(link), "Link replaced dir without force") assert_nothing_raised { file[:force] = true } assert_events([:link_created], file) assert(FileTest.symlink?(link), "Link was not created") assert_equal(path, File.readlink(link), "Link was created incorrectly") end def test_replace_links_with_files base = tempfile() Dir.mkdir(base) file = File.join(base, "file") link = File.join(base, "link") File.open(file, "w") { |f| f.puts "yayness" } File.symlink(file, link) obj = Puppet::Type.type(:file).create( :path => link, :ensure => "file" ) assert_apply(obj) assert_equal("yayness\n", File.read(file), "Original file got changed") assert_equal("file", File.lstat(link).ftype, "File is still a link") end def test_no_erase_linkedto_files base = tempfile() Dir.mkdir(base) dirs = {} %w{other source target}.each do |d| dirs[d] = File.join(base, d) Dir.mkdir(dirs[d]) end file = File.join(dirs["other"], "file") sourcefile = File.join(dirs["source"], "sourcefile") link = File.join(dirs["target"], "link") File.open(file, "w") { |f| f.puts "other" } File.open(sourcefile, "w") { |f| f.puts "source" } File.symlink(file, link) obj = Puppet::Type.type(:file).create( :path => dirs["target"], :ensure => "file", :source => dirs["source"], :recurse => true ) trans = assert_events([:file_created, :file_created], obj) newfile = File.join(dirs["target"], "sourcefile") assert(File.exists?(newfile), "File did not get copied") assert_equal(File.read(sourcefile), File.read(newfile), "File did not get copied correctly.") assert_equal("other\n", File.read(file), "Original file got changed") assert_equal("file", File.lstat(link).ftype, "File is still a link") end def test_replace_links dest = tempfile() otherdest = tempfile() link = tempfile() File.open(dest, "w") { |f| f.puts "boo" } File.open(otherdest, "w") { |f| f.puts "yay" } obj = Puppet::Type.type(:file).create( :path => link, :ensure => otherdest ) assert_apply(obj) assert_equal(otherdest, File.readlink(link), "Link did not get created") obj[:ensure] = dest assert_apply(obj) assert_equal(dest, File.readlink(link), "Link did not get changed") end def test_file_with_spaces dir = tempfile() Dir.mkdir(dir) source = File.join(dir, "file spaces") dest = File.join(dir, "another space") File.open(source, "w") { |f| f.puts :yay } obj = Puppet::Type.type(:file).create( :path => dest, :source => source ) assert(obj, "Did not create file") assert_apply(obj) assert(FileTest.exists?(dest), "File did not get created") end def test_present_matches_anything path = tempfile() file = Puppet::Type.newfile(:path => path, :ensure => :present) file.retrieve assert(! file.insync?, "File incorrectly in sync") # Now make a file File.open(path, "w") { |f| f.puts "yay" } file.retrieve assert(file.insync?, "File not in sync") # Now make a directory File.unlink(path) Dir.mkdir(path) file.retrieve assert(file.insync?, "Directory not considered 'present'") Dir.rmdir(path) # Now make a link file[:links] = :manage otherfile = tempfile() File.symlink(otherfile, path) file.retrieve assert(file.insync?, "Symlink not considered 'present'") File.unlink(path) # Now set some content, and make sure it works file[:content] = "yayness" assert_apply(file) assert_equal("yayness", File.read(path), "Content did not get set correctly") end # Make sure unmanaged files can be purged. def test_purge sourcedir = tempfile() destdir = tempfile() Dir.mkdir(sourcedir) Dir.mkdir(destdir) sourcefile = File.join(sourcedir, "sourcefile") dsourcefile = File.join(destdir, "sourcefile") localfile = File.join(destdir, "localfile") randfile = File.join(destdir, "random") File.open(sourcefile, "w") { |f| f.puts "funtest" } # this file should get removed File.open(randfile, "w") { |f| f.puts "footest" } lfobj = Puppet::Type.newfile(:path => localfile, :content => "rahtest") destobj = Puppet::Type.newfile(:path => destdir, :source => sourcedir, :recurse => true) assert_apply(lfobj, destobj) assert(FileTest.exists?(dsourcefile), "File did not get copied") assert(FileTest.exists?(localfile), "File did not get created") assert(FileTest.exists?(randfile), "File got prematurely purged") assert_nothing_raised { destobj[:purge] = true } assert_apply(lfobj, destobj) assert(FileTest.exists?(dsourcefile), "File got purged") assert(FileTest.exists?(localfile), "File got purged") assert(! FileTest.exists?(randfile), "File did not get purged") end end # $Id$ diff --git a/test/types/filebucket.rb b/test/types/filebucket.rb index e7e7e3e73..eb7ee59f7 100755 --- a/test/types/filebucket.rb +++ b/test/types/filebucket.rb @@ -1,158 +1,151 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../../../../language/trunk" -end - require 'puppet' -require 'test/unit' require 'fileutils' require 'puppettest' # $Id$ class TestFileBucket < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting # hmmm # this is complicated, because we store references to the created # objects in a central store def mkfile(hash) file = nil assert_nothing_raised { file = Puppet.type(:file).create(hash) } return file end def mkbucket(name,path) bucket = nil assert_nothing_raised { bucket = Puppet.type(:filebucket).create( :name => name, :path => path ) } @@tmpfiles.push path return bucket end def mktestfile # because luke's home directory is on nfs, it can't be used for testing # as root tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } @@tmpfiles.push tmpfile mkfile(:name => tmpfile) end def setup super begin initstorage rescue system("rm -rf %s" % Puppet[:statefile]) end end def initstorage Puppet::Storage.init Puppet::Storage.load end def clearstorage Puppet::Storage.store Puppet::Storage.clear end def test_simplebucket name = "yayness" bucketpath = tempfile() mkbucket(name, bucketpath) bucket = nil assert_nothing_raised { bucket = Puppet.type(:filebucket).bucket(name) } assert_instance_of(Puppet::Client::Dipper, bucket) md5 = nil newpath = tempfile() @@tmpfiles << newpath system("cp /etc/passwd %s" % newpath) assert_nothing_raised { md5 = bucket.backup(newpath) } assert(md5) assert(FileTest.directory?(File.join(bucketpath, md5)), "MD5 directory does not exist") newmd5 = nil # Just in case the file isn't writable File.chmod(0644, newpath) File.open(newpath, "w") { |f| f.puts ";lkjasdf;lkjasdflkjwerlkj134lkj" } assert_nothing_raised { newmd5 = bucket.backup(newpath) } assert(md5 != newmd5) assert_nothing_raised { bucket.restore(newpath, md5) } File.open(newpath) { |f| newmd5 = Digest::MD5.hexdigest(f.read) } assert_equal(md5, newmd5) end def test_fileswithbuckets name = "yayness" mkbucket(name, tempfile()) bucket = nil assert_nothing_raised { bucket = Puppet.type(:filebucket).bucket(name) } file = mktestfile() assert_nothing_raised { file[:backup] = name } opath = tempfile() @@tmpfiles << opath File.open(opath, "w") { |f| f.puts "yaytest" } origmd5 = File.open(file.name) { |f| newmd5 = Digest::MD5.hexdigest(f.read) } file[:source] = opath #assert_nothing_raised { # file[:backup] = true #} assert_apply(file) # so, we've now replaced the file with the opath file assert_equal( File.open(opath) { |f| newmd5 = Digest::MD5.hexdigest(f.read) }, File.open(file.name) { |f| newmd5 = Digest::MD5.hexdigest(f.read) } ) #File.chmod(0644, file.name) assert_nothing_raised { bucket.restore(file.name, origmd5) } assert_equal( origmd5, File.open(file.name) { |f| newmd5 = Digest::MD5.hexdigest(f.read) } ) end end diff --git a/test/types/fileignoresource.rb b/test/types/fileignoresource.rb index 4189c50e3..1340dbbc9 100644 --- a/test/types/fileignoresource.rb +++ b/test/types/fileignoresource.rb @@ -1,283 +1,275 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $:.unshift "../../../../language/trunk/lib" - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'cgi' -require 'test/unit' require 'fileutils' require 'puppettest' class TestFileIgnoreSources < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def setup super begin initstorage rescue system("rm -rf %s" % Puppet[:statefile]) end end #This is not needed unless using md5 (correct me if I'm wrong) def initstorage Puppet::Storage.init Puppet::Storage.load end def clearstorage Puppet::Storage.store Puppet::Storage.clear end def test_ignore_simple_source #Temp directory to run tests in path = tempfile() @@tmpfiles.push path #source directory sourcedir = "sourcedir" sourcefile1 = "sourcefile1" sourcefile2 = "sourcefile2" frompath = File.join(path,sourcedir) FileUtils.mkdir_p frompath topath = File.join(path,"destdir") FileUtils.mkdir topath #initialize variables before block tofile = nil trans = nil #create source files File.open(File.join(frompath,sourcefile1), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "yayness" } File.open(File.join(frompath,sourcefile2), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "even yayer" } #makes Puppet file Object assert_nothing_raised { tofile = Puppet.type(:file).create( :name => topath, :source => frompath, :recurse => true, :ignore => "sourcefile2" ) } #make a component and adds the file comp = Puppet.type(:component).create( :name => "component" ) comp.push tofile #make, evaluate transaction and sync the component assert_nothing_raised { trans = comp.evaluate } assert_nothing_raised { trans.evaluate } #topath should exist as a directory with sourcedir as a directory #This file should exist assert(FileTest.exists?(File.join(topath,sourcefile1))) #This file should not assert(!(FileTest.exists?(File.join(topath,sourcefile2)))) Puppet::Type.allclear end def test_ignore_with_wildcard #Temp directory to run tests in path = tempfile() @@tmpfiles.push path #source directory sourcedir = "sourcedir" subdir = "subdir" subdir2 = "subdir2" sourcefile1 = "sourcefile1" sourcefile2 = "sourcefile2" frompath = File.join(path,sourcedir) FileUtils.mkdir_p frompath FileUtils.mkdir_p(File.join(frompath, subdir)) FileUtils.mkdir_p(File.join(frompath, subdir2)) dir = Dir.glob(File.join(path,"**/*")) topath = File.join(path,"destdir") FileUtils.mkdir topath #initialize variables before block tofile = nil trans = nil #create source files dir.each { |dir| File.open(File.join(dir,sourcefile1), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "yayness" } File.open(File.join(dir,sourcefile2), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "even yayer" } } #makes Puppet file Object assert_nothing_raised { tofile = Puppet.type(:file).create( :name => topath, :source => frompath, :recurse => true, :ignore => "*2" ) } #make a component and adds the file comp = Puppet.type(:component).create( :name => "component" ) comp.push tofile #make, evaluate transaction and sync the component assert_nothing_raised { trans = comp.evaluate } assert_nothing_raised { trans.evaluate } #topath should exist as a directory with sourcedir as a directory #This file should exist assert(FileTest.exists?(File.join(topath,sourcefile1))) assert(FileTest.exists?(File.join(topath,subdir))) assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1))) #This file should not assert(!(FileTest.exists?(File.join(topath,sourcefile2)))) assert(!(FileTest.exists?(File.join(topath,subdir2)))) assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2)))) Puppet::Type.allclear end def test_ignore_array #Temp directory to run tests in path = tempfile() @@tmpfiles.push path #source directory sourcedir = "sourcedir" subdir = "subdir" subdir2 = "subdir2" subdir3 = "anotherdir" sourcefile1 = "sourcefile1" sourcefile2 = "sourcefile2" frompath = File.join(path,sourcedir) FileUtils.mkdir_p frompath FileUtils.mkdir_p(File.join(frompath, subdir)) FileUtils.mkdir_p(File.join(frompath, subdir2)) FileUtils.mkdir_p(File.join(frompath, subdir3)) sourcedir = Dir.glob(File.join(path,"**/*")) topath = File.join(path,"destdir") FileUtils.mkdir topath #initialize variables before block tofile = nil trans = nil #create source files sourcedir.each { |dir| File.open(File.join(dir,sourcefile1), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "yayness" } File.open(File.join(dir,sourcefile2), File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "even yayer" } } #makes Puppet file Object assert_nothing_raised { tofile = Puppet.type(:file).create( :name => topath, :source => frompath, :recurse => true, :ignore => ["*2", "an*"] # :ignore => ["*2", "an*", "nomatch"] ) } #make a component and adds the file comp = Puppet.type(:component).create( :name => "component" ) comp.push tofile #make, evaluate transaction and sync the component assert_nothing_raised { trans = comp.evaluate } assert_nothing_raised { trans.evaluate } #topath should exist as a directory with sourcedir as a directory # This file should exist # proper files in destination assert(FileTest.exists?(File.join(topath,sourcefile1)), "file1 not in destdir") assert(FileTest.exists?(File.join(topath,subdir)), "subdir1 not in destdir") assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1)), "file1 not in subdir") # proper files in source assert(FileTest.exists?(File.join(frompath,subdir)), "subdir not in source") assert(FileTest.exists?(File.join(frompath,subdir2)), "subdir2 not in source") assert(FileTest.exists?(File.join(frompath,subdir3)), "subdir3 not in source") # This file should not assert(!(FileTest.exists?(File.join(topath,sourcefile2))), "file2 in dest") assert(!(FileTest.exists?(File.join(topath,subdir2))), "subdir2 in dest") assert(!(FileTest.exists?(File.join(topath,subdir3))), "anotherdir in dest") assert(!(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile2))), "file2 in dest/sub") Puppet::Type.allclear end end # $Id$ diff --git a/test/types/filesources.rb b/test/types/filesources.rb index 009d1a35a..3cc546b40 100755 --- a/test/types/filesources.rb +++ b/test/types/filesources.rb @@ -1,652 +1,644 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $:.unshift "../../../../language/trunk/lib" - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'cgi' -require 'test/unit' require 'fileutils' require 'puppettest' class TestFileSources < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def setup super begin initstorage rescue system("rm -rf %s" % Puppet[:statefile]) end if defined? @port @port += 1 else @port = 8800 end end def initstorage Puppet::Storage.init Puppet::Storage.load end def clearstorage Puppet::Storage.store Puppet::Storage.clear end def test_newchild path = tempfile() @@tmpfiles.push path FileUtils.mkdir_p path File.open(File.join(path,"childtest"), "w") { |of| of.puts "yayness" } file = nil comp = nil trans = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => path ) } child = nil assert_nothing_raised { child = file.newchild("childtest", true) } assert(child) assert_raise(Puppet::DevError) { file.newchild(File.join(path,"childtest"), true) } end def test_simplelocalsource path = tempfile() @@tmpfiles.push path FileUtils.mkdir_p path frompath = File.join(path,"source") topath = File.join(path,"dest") fromfile = nil tofile = nil trans = nil File.open(frompath, File::WRONLY|File::CREAT|File::APPEND) { |of| of.puts "yayness" } assert_nothing_raised { tofile = Puppet.type(:file).create( :name => topath, :source => frompath ) } assert_apply(tofile) assert(FileTest.exists?(topath), "File #{topath} is missing") from = File.open(frompath) { |o| o.read } to = File.open(topath) { |o| o.read } assert_equal(from,to) @@tmpfiles.push path end def recursive_source_test(fromdir, todir) Puppet::Type.allclear initstorage tofile = nil trans = nil assert_nothing_raised { tofile = Puppet.type(:file).create( :path => todir, :recurse => true, :backup => false, :source => fromdir ) } assert_apply(tofile) assert(FileTest.exists?(todir), "Created dir %s does not exist" % todir) Puppet::Type.allclear end def run_complex_sources(networked = false) path = tempfile() @@tmpfiles.push path # first create the source directory FileUtils.mkdir_p path # okay, let's create a directory structure fromdir = File.join(path,"fromdir") Dir.mkdir(fromdir) FileUtils.cd(fromdir) { mkranddirsandfiles() } todir = File.join(path, "todir") source = fromdir if networked source = "puppet://localhost/%s%s" % [networked, fromdir] end recursive_source_test(source, todir) return [fromdir,todir] end def test_complex_sources_twice fromdir, todir = run_complex_sources assert_trees_equal(fromdir,todir) recursive_source_test(fromdir, todir) assert_trees_equal(fromdir,todir) end def test_sources_with_deleted_destfiles fromdir, todir = run_complex_sources # then delete some files assert(FileTest.exists?(todir)) missing_files = delete_random_files(todir) # and run recursive_source_test(fromdir, todir) missing_files.each { |file| assert(FileTest.exists?(file), "Deleted file %s is still missing" % file) } # and make sure they're still equal assert_trees_equal(fromdir,todir) end def test_sources_with_readonly_destfiles fromdir, todir = run_complex_sources assert(FileTest.exists?(todir)) readonly_random_files(todir) recursive_source_test(fromdir, todir) # and make sure they're still equal assert_trees_equal(fromdir,todir) end def test_sources_with_modified_dest_files fromdir, todir = run_complex_sources assert(FileTest.exists?(todir)) # then modify some files modify_random_files(todir) recursive_source_test(fromdir, todir) # and make sure they're still equal assert_trees_equal(fromdir,todir) end def test_sources_with_added_destfiles fromdir, todir = run_complex_sources assert(FileTest.exists?(todir)) # and finally, add some new files add_random_files(todir) recursive_source_test(fromdir, todir) fromtree = file_list(fromdir) totree = file_list(todir) assert(fromtree != totree, "Trees are incorrectly equal") # then remove our new files FileUtils.cd(todir) { %x{find . 2>/dev/null}.chomp.split(/\n/).each { |file| if file =~ /file[0-9]+/ File.unlink(file) end } } # and make sure they're still equal assert_trees_equal(fromdir,todir) end def test_RecursionWithAddedFiles basedir = tempfile() Dir.mkdir(basedir) @@tmpfiles << basedir file1 = File.join(basedir, "file1") file2 = File.join(basedir, "file2") subdir1 = File.join(basedir, "subdir1") file3 = File.join(subdir1, "file") File.open(file1, "w") { |f| 3.times { f.print rand(100) } } rootobj = nil assert_nothing_raised { rootobj = Puppet.type(:file).create( :name => basedir, :recurse => true, :check => %w{type owner} ) rootobj.evaluate } klass = Puppet.type(:file) assert(klass[basedir]) assert(klass[file1]) assert_nil(klass[file2]) File.open(file2, "w") { |f| 3.times { f.print rand(100) } } assert_nothing_raised { rootobj.evaluate } assert(klass[file2]) Dir.mkdir(subdir1) File.open(file3, "w") { |f| 3.times { f.print rand(100) } } assert_nothing_raised { rootobj.evaluate } assert(klass[file3]) end def mkfileserverconf(mounts) file = tempfile() File.open(file, "w") { |f| mounts.each { |path, name| f.puts "[#{name}]\n\tpath #{path}\n\tallow *\n" } } @@tmpfiles << file return file end def test_NetworkSources server = nil basedir = tempfile() @@tmpfiles << basedir Dir.mkdir(basedir) mounts = { "/" => "root" } fileserverconf = mkfileserverconf(mounts) Puppet[:confdir] = basedir Puppet[:vardir] = basedir Puppet[:autosign] = true Puppet[:masterport] = 8762 serverpid = nil assert_nothing_raised() { server = Puppet::Server.new( :Handlers => { :CA => {}, # so that certs autogenerate :FileServer => { :Config => fileserverconf } } ) } serverpid = fork { assert_nothing_raised() { #trap(:INT) { server.shutdown; Kernel.exit! } trap(:INT) { server.shutdown } server.start } } @@tmppids << serverpid sleep(1) fromdir, todir = run_complex_sources("root") assert_trees_equal(fromdir,todir) recursive_source_test(fromdir, todir) assert_trees_equal(fromdir,todir) assert_nothing_raised { system("kill -INT %s" % serverpid) } end def test_networkSourcesWithoutService server = nil Puppet[:autosign] = true Puppet[:masterport] = 8765 serverpid = nil assert_nothing_raised() { server = Puppet::Server.new( :Handlers => { :CA => {}, # so that certs autogenerate } ) } serverpid = fork { assert_nothing_raised() { #trap(:INT) { server.shutdown; Kernel.exit! } trap(:INT) { server.shutdown } server.start } } @@tmppids << serverpid sleep(1) name = File.join(tmpdir(), "nosourcefile") file = Puppet.type(:file).create( :source => "puppet://localhost/dist/file", :name => name ) assert_nothing_raised { file.retrieve } comp = newcomp("nosource", file) assert_nothing_raised { comp.evaluate } assert(!FileTest.exists?(name), "File with no source exists anyway") end def test_unmountedNetworkSources server = nil mounts = { "/" => "root", "/noexistokay" => "noexist" } fileserverconf = mkfileserverconf(mounts) Puppet[:autosign] = true Puppet[:masterport] = @port serverpid = nil assert_nothing_raised() { server = Puppet::Server.new( :Port => @port, :Handlers => { :CA => {}, # so that certs autogenerate :FileServer => { :Config => fileserverconf } } ) } serverpid = fork { assert_nothing_raised() { #trap(:INT) { server.shutdown; Kernel.exit! } trap(:INT) { server.shutdown } server.start } } @@tmppids << serverpid sleep(1) name = File.join(tmpdir(), "nosourcefile") file = Puppet.type(:file).create( :source => "puppet://localhost/noexist/file", :name => name ) assert_nothing_raised { file.retrieve } comp = newcomp("nosource", file) assert_nothing_raised { comp.evaluate } assert(!FileTest.exists?(name), "File with no source exists anyway") end def test_alwayschecksum from = tempfile() to = tempfile() File.open(from, "w") { |f| f.puts "yayness" } File.open(to, "w") { |f| f.puts "yayness" } file = nil # Now the files should be exactly the same, so we should not see attempts # at copying assert_nothing_raised { file = Puppet.type(:file).create( :path => to, :source => from ) } file.retrieve assert(file.is(:checksum), "File does not have a checksum state") assert_equal(0, file.evaluate.length, "File produced changes") end def test_sourcepaths files = [] 3.times { files << tempfile() } to = tempfile() File.open(files[-1], "w") { |f| f.puts "yee-haw" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => to, :source => files ) } comp = newcomp(file) assert_events([:file_created], comp) assert(File.exists?(to), "File does not exist") txt = nil File.open(to) { |f| txt = f.read.chomp } assert_equal("yee-haw", txt, "Contents do not match") end # Make sure that source-copying updates the checksum on the same run def test_checksumchange source = tempfile() dest = tempfile() File.open(dest, "w") { |f| f.puts "boo" } File.open(source, "w") { |f| f.puts "yay" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :source => source ) } file.retrieve assert_events([:file_changed], file) file.retrieve assert_events([], file) end # Make sure that source-copying updates the checksum on the same run def test_sourcebeatsensure source = tempfile() dest = tempfile() File.open(source, "w") { |f| f.puts "yay" } file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :ensure => "file", :source => source ) } file.retrieve assert_events([:file_created], file) file.retrieve assert_events([], file) assert_events([], file) end def test_sourcewithlinks source = tempfile() link = tempfile() dest = tempfile() File.open(source, "w") { |f| f.puts "yay" } File.symlink(source, link) file = nil assert_nothing_raised { file = Puppet.type(:file).create( :name => dest, :source => link ) } # Default to skipping links assert_events([], file) assert(! FileTest.exists?(dest), "Created link") # Now follow the links file[:links] = :follow assert_events([:file_created], file) assert(FileTest.file?(dest), "Destination is not a file") # Now copy the links #assert_raise(Puppet::FileServerError) { trans = nil assert_nothing_raised { file[:links] = :manage comp = newcomp(file) trans = comp.evaluate trans.evaluate } assert(trans.failed?(file), "Object did not fail to copy links") end def test_changes source = tempfile() dest = tempfile() File.open(source, "w") { |f| f.puts "yay" } obj = nil assert_nothing_raised { obj = Puppet.type(:file).create( :name => dest, :source => source ) } assert_events([:file_created], obj) assert_equal(File.read(source), File.read(dest), "Files are not equal") assert_events([], obj) File.open(source, "w") { |f| f.puts "boo" } assert_events([:file_changed], obj) assert_equal(File.read(source), File.read(dest), "Files are not equal") assert_events([], obj) File.open(dest, "w") { |f| f.puts "kaboom" } # There are two changes, because first the checksum is noticed, and # then the source causes a change assert_events([:file_changed, :file_changed], obj) assert_equal(File.read(source), File.read(dest), "Files are not equal") assert_events([], obj) end def test_file_source_with_space dir = tempfile() source = File.join(dir, "file with spaces") Dir.mkdir(dir) File.open(source, "w") { |f| f.puts "yayness" } newdir = tempfile() newpath = File.join(newdir, "file with spaces") file = Puppet::Type.newfile( :path => newdir, :source => dir, :recurse => true ) assert_apply(file) assert(FileTest.exists?(newpath), "Did not create file") assert_equal("yayness\n", File.read(newpath)) end # Make sure files aren't replaced when replace is false, but otherwise # are. def test_replace source = tempfile() File.open(source, "w") { |f| f.puts "yayness" } dest = tempfile() file = Puppet::Type.newfile( :path => dest, :source => source, :recurse => true ) assert_apply(file) assert(FileTest.exists?(dest), "Did not create file") assert_equal("yayness\n", File.read(dest)) # Now set :replace assert_nothing_raised { file[:replace] = false } File.open(source, "w") { |f| f.puts "funtest" } assert_apply(file) # Make sure it doesn't change. assert_equal("yayness\n", File.read(dest)) # Now set it to true and make sure it does change. assert_nothing_raised { file[:replace] = true } assert_apply(file) # Make sure it doesn't change. assert_equal("funtest\n", File.read(dest)) end end # $Id$ diff --git a/test/types/group.rb b/test/types/group.rb index 508b8436c..68893ff4d 100755 --- a/test/types/group.rb +++ b/test/types/group.rb @@ -1,175 +1,168 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'etc' require 'puppet/type' require 'puppettest' -require 'test/unit' class TestGroup < Test::Unit::TestCase - include TestPuppet + include PuppetTest - p = Puppet::Type.type(:group).provide :fake, :parent => TestPuppet::FakeProvider do + p = Puppet::Type.type(:group).provide :fake, :parent => PuppetTest::FakeProvider do @name = :fake apimethods :ensure, :gid def create @ensure = :present end def delete @ensure = :absent end def exists? if defined? @ensure and @ensure == :present true else false end end end FakeGroupProvider = p @@fakeproviders[:group] = p def setup super Puppet::Type.type(:group).defaultprovider = FakeGroupProvider end def teardown Puppet.type(:group).clear Puppet::Type.type(:group).defaultprovider = nil super end def mkgroup(name, hash = {}) group = nil hash[:name] = name assert_nothing_raised { group = Puppet.type(:group).create(hash) } return group end def groupnames %x{groups}.chomp.split(/ /) end def groupids Process.groups end def attrtest_ensure(group) group[:ensure] = :absent comp = newcomp("ensuretest", group) assert_apply(comp) assert_equal(:absent, group.provider.ensure, "Group is still present") group[:ensure] = :present assert_events([:group_created], comp) assert_equal(:present, group.provider.ensure, "Group is absent") group[:ensure] = :absent trans = assert_events([:group_removed], comp) assert_equal(:absent, group.provider.ensure, "Group is present") assert_rollback_events(trans, [:group_created], "group") assert_equal(:present, group.provider.ensure, "Group is absent") end # This is a bit odd, since we're not actually doing anything on the machine. # Just make sure we can set the gid and that it will work correctly. def attrtest_gid(group) # Check the validation. assert_nothing_raised { group[:gid] = "15" } assert_equal(15, group.should(:gid), "Did not convert gid to number") comp = newcomp(group) trans = assert_events([:group_modified], comp, "group") assert_equal(15, group.provider.gid, "GID was not changed") assert_nothing_raised { group[:gid] = 16 } assert_equal(16, group.should(:gid), "Did not keep gid as number") # Now switch to 16 trans = assert_events([:group_modified], comp, "group") assert_equal(16, group.provider.gid, "GID was not changed") # And then rollback assert_rollback_events(trans, [:group_modified], "group") assert_equal(15, group.provider.gid, "GID was not changed") end def test_owngroups groupnames().each { |group| gobj = nil comp = nil assert_nothing_raised { gobj = Puppet.type(:group).create( :name => group, :check => [:gid] ) } # Set a fake gid gobj.provider.gid = rand(100) assert_nothing_raised { gobj.retrieve } assert(gobj.is(:gid), "Failed to retrieve gid") } end def test_mkgroup gobj = nil comp = nil name = "pptestgr" assert_nothing_raised { gobj = Puppet.type(:group).create( :name => name, :ensure => :present ) comp = newcomp("groupmaker %s" % name, gobj) } trans = assert_events([:group_created], comp, "group") assert(gobj.provider.exists?, "Did not create group") tests = Puppet.type(:group).validstates gobj.retrieve tests.each { |test| if self.respond_to?("attrtest_%s" % test) self.send("attrtest_%s" % test, gobj) else #$stderr.puts "Not testing attr %s of group" % test end } assert_rollback_events(trans, [:group_removed], "group") assert(! gobj.provider.exists?, "Did not delete group") end end diff --git a/test/types/host.rb b/test/types/host.rb index 8af9e3e4a..db2c391bf 100755 --- a/test/types/host.rb +++ b/test/types/host.rb @@ -1,201 +1,194 @@ # Test host job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' class TestHost < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super # god i'm lazy @hosttype = Puppet.type(:host) @oldhosttype = @hosttype.filetype end def teardown Puppet::FileType.filetype(:ram).clear @hosttype.filetype = @oldhosttype Puppet.type(:file).clear super end # Here we just create a fake host type that answers to all of the methods # but does not modify our actual system. def mkfaketype @hosttype.filetype = Puppet::FileType.filetype(:ram) end def mkhost if defined? @hcount @hcount += 1 else @hcount = 1 end host = nil assert_nothing_raised { host = Puppet.type(:host).create( :name => "fakehost%s" % @hcount, :ip => "192.168.27.%s" % @hcount, :alias => "alias%s" % @hcount ) } return host end def test_simplehost mkfaketype host = nil assert_nothing_raised { assert_nil(Puppet.type(:host).retrieve) } assert_nothing_raised { host = Puppet.type(:host).create( :name => "culain", :ip => "192.168.0.3" ) } assert_nothing_raised { Puppet.type(:host).store } assert_nothing_raised { assert( Puppet.type(:host).to_file.include?( Puppet.type(:host).fileobj.read ), "File does not include all of our objects" ) } end def test_hostsparse fakedata("data/types/hosts").each { |file| @hosttype.path = file Puppet.info "Parsing %s" % file assert_nothing_raised { Puppet.type(:host).retrieve } text = Puppet.type(:host).fileobj.read dest = tempfile() @hosttype.path = dest # Now write it back out assert_nothing_raised { Puppet.type(:host).store } newtext = Puppet.type(:host).fileobj.read # Don't worry about difference in whitespace assert_equal(text.gsub(/\s+/, ' '), newtext.gsub(/\s+/, ' ')) @hosttype.clear } end def test_moddinghost mkfaketype host = mkhost() assert_events([:host_created], host) host.retrieve # This was a hard bug to track down. assert_instance_of(String, host.is(:ip)) host[:alias] = %w{madstop kirby yayness} assert_events([:host_changed], host) end def test_aliasisstate assert_equal(:state, @hosttype.attrtype(:alias)) end def test_multivalues host = mkhost assert_raise(Puppet::Error) { host[:alias] = "puppetmasterd yayness" } end def test_puppetalias host = mkhost() assert_nothing_raised { host[:alias] = "testing" } same = host.class["testing"] assert(same, "Could not retrieve by alias") end def test_removal mkfaketype host = mkhost() assert_nothing_raised { host[:ensure] = :present } assert_events([:host_created], host) host.retrieve assert(host.insync?) assert_nothing_raised { host[:ensure] = :absent } assert_events([:host_removed], host) host.retrieve assert_events([], host) end def test_modifyingfile hostfile = tempfile() Puppet.type(:host).path = hostfile hosts = [] names = [] 3.times { h = mkhost() #h[:ensure] = :present #h.retrieve hosts << h names << h.name } assert_apply(*hosts) hosts.clear Puppet.type(:host).clear newhost = mkhost() #newhost[:ensure] = :present names << newhost.name assert_apply(newhost) Puppet.type(:host).clear # Verify we can retrieve that info assert_nothing_raised("Could not retrieve after second write") { newhost.retrieve } # And verify that we have data for everything names.each { |name| host = Puppet.type(:host)[name] assert(host) assert(host[:ip]) } end end # $Id$ diff --git a/test/types/mount.rb b/test/types/mount.rb index 70170289e..e0838e072 100755 --- a/test/types/mount.rb +++ b/test/types/mount.rb @@ -1,294 +1,287 @@ # Test host job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' require 'puppet/type/parsedtype/mount' -require 'test/unit' require 'facter' class TestMounts < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @mounttype = Puppet.type(:mount) @oldfiletype = @mounttype.filetype end def teardown @mounttype.filetype = @oldfiletype Puppet.type(:file).clear super end # Here we just create a fake host type that answers to all of the methods # but does not modify our actual system. def mkfaketype pfile = tempfile() old = @mounttype.filetype @mounttype.filetype = Puppet::FileType.filetype(:ram) cleanup do @mounttype.filetype = old @mounttype.fileobj = nil end # Reset this, just in case @mounttype.fileobj = nil end def mkmount mount = nil if defined? @pcount @pcount += 1 else @pcount = 1 end args = { :path => "/fspuppet%s" % @pcount, :device => "/dev/dsk%s" % @pcount, } Puppet.type(:mount).fields.each do |field| unless args.include? field args[field] = "fake%s" % @pcount end end assert_nothing_raised { mount = Puppet.type(:mount).create(args) } return mount end def test_simplemount mkfaketype host = nil assert_nothing_raised { assert_nil(Puppet.type(:mount).retrieve) } mount = mkmount assert_nothing_raised { Puppet.type(:mount).store } assert_nothing_raised { assert( Puppet.type(:mount).to_file.include?( Puppet.type(:mount).fileobj.read ), "File does not include all of our objects" ) } end unless Facter["operatingsystem"].value == "Darwin" def test_mountsparse use_fake_fstab assert_nothing_raised { @mounttype.retrieve } # Now just make we've got some mounts we know will be there root = @mounttype["/"] assert(root, "Could not retrieve root mount") end def test_rootfs fs = nil use_fake_fstab assert_nothing_raised { Puppet.type(:mount).retrieve } assert_nothing_raised { fs = Puppet.type(:mount)["/"] } assert(fs, "Could not retrieve root fs") assert_nothing_raised { assert(fs.mounted?, "Root is considered not mounted") } end end # Make sure it reads and writes correctly. def test_readwrite use_fake_fstab assert_nothing_raised { Puppet::Type.type(:mount).retrieve } oldtype = Puppet::Type.type(:mount).filetype # Now switch to storing in ram mkfaketype fs = mkmount assert(Puppet::Type.type(:mount).filetype != oldtype) assert_events([:mount_created], fs) text = Puppet::Type.type(:mount).fileobj.read assert(text =~ /#{fs[:path]}/, "Text did not include new fs") fs[:ensure] = :absent assert_events([:mount_removed], fs) text = Puppet::Type.type(:mount).fileobj.read assert(text !~ /#{fs[:path]}/, "Text still includes new fs") fs[:ensure] = :present assert_events([:mount_created], fs) text = Puppet::Type.type(:mount).fileobj.read assert(text =~ /#{fs[:path]}/, "Text did not include new fs") fs[:options] = "rw,noauto" assert_events([:mount_changed], fs) end if Process.uid == 0 def test_mountfs fs = nil case Facter["hostname"].value when "culain": fs = "/ubuntu" when "atalanta": fs = "/mnt" when "figurehead": fs = "/cg4/net/depts" else $stderr.puts "No mount for mount testing; skipping" return end assert_nothing_raised { Puppet.type(:mount).retrieve } oldtext = Puppet::Type.type(:mount).fileobj.read ftype = Puppet::Type.type(:mount).filetype # Make sure the original gets reinstalled. if ftype == Puppet::FileType.filetype(:netinfo) cleanup do IO.popen("niload -r /mounts .", "w") do |file| file.puts oldtext end end else cleanup do Puppet::Type.type(:mount).fileobj.write(oldtext) end end obj = Puppet.type(:mount)[fs] assert(obj, "Could not retrieve %s object" % fs) current = nil assert_nothing_raised { current = obj.mounted? } if current # Make sure the original gets reinstalled. cleanup do unless obj.mounted? obj.mount end end end unless current assert_nothing_raised { obj.mount } end # Now copy all of the states' "is" values to the "should" values obj.each do |state| state.should = state.is end # Verify we can remove the mount assert_nothing_raised { obj[:ensure] = :absent } assert_events([:mount_removed], obj) assert_events([], obj) # And verify it's gone assert(!obj.mounted?, "Object is mounted after being removed") text = Puppet.type(:mount).fileobj.read assert(text !~ /#{fs}/, "Fstab still contains %s" % fs) assert_nothing_raised { obj[:ensure] = :present } assert_events([:mount_created], obj) assert_events([], obj) text = Puppet::Type.type(:mount).fileobj.read assert(text =~ /#{fs}/, "Fstab does not contain %s" % fs) assert(! obj.mounted?, "Object is mounted incorrectly") assert_nothing_raised { obj[:ensure] = :mounted } assert_events([:mount_mounted], obj) assert_events([], obj) text = Puppet::Type.type(:mount).fileobj.read assert(text =~ /#{fs}/, "Fstab does not contain %s" % fs) obj.retrieve assert(obj.mounted?, "Object is not mounted") unless current assert_nothing_raised { obj.unmount } end end end def use_fake_fstab os = Facter['operatingsystem'] if os == "Solaris" name = "solaris.fstab" elsif os == "FreeBSD" name = "freebsd.fstab" else # Catchall for other fstabs name = "linux.fstab" end fstab = fakefile(File::join("data/types/mount", name)) Puppet::Type.type(:mount).path = fstab end end # $Id$ diff --git a/test/types/package.rb b/test/types/package.rb index 51bfc5fa3..4d04dc147 100644 --- a/test/types/package.rb +++ b/test/types/package.rb @@ -1,498 +1,491 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'facter' $platform = Facter["operatingsystem"].value unless Puppet.type(:package).defaultprovider puts "No default package type for %s; skipping package tests" % $platform else class TestPackages < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def setup super #@list = Puppet.type(:package).getpkglist Puppet.type(:package).clear end # These are packages that we're sure will be installed def installedpkgs pkgs = nil case $platform when "SunOS" pkgs = %w{SMCossh} when "Debian": pkgs = %w{ssh openssl} when "Fedora": pkgs = %w{openssh} when "OpenBSD": pkgs = %w{vim} when "FreeBSD": pkgs = %w{sudo} when "Darwin": pkgs = %w{gettext} else Puppet.notice "No test package for %s" % $platform return [] end return pkgs end def modpkg(pkg) case $platform when "Solaris": pkg[:adminfile] = "/usr/local/pkg/admin_file" end end def mkpkgs(list = nil, useensure = true) list ||= tstpkgs() list.each { |pkg, source| hash = {:name => pkg} if useensure hash[:ensure] = "installed" end if source source = source[0] if source.is_a? Array hash[:source] = source end # Override the default package type for our test packages. if Facter["operatingsystem"].value == "Darwin" hash[:provider] = "darwinport" end obj = Puppet.type(:package).create(hash) assert(pkg, "Could not create package") modpkg(obj) yield obj } end def tstpkgs retval = [] case $platform when "Solaris": arch = Facter["hardwareisa"].value + Facter["operatingsystemrelease"].value case arch when "i3865.10": retval = {"SMCrdesk" => [ "/usr/local/pkg/rdesktop-1.3.1-sol10-intel-local", "/usr/local/pkg/rdesktop-1.4.1-sol10-x86-local" ]} when "sparc5.8": retval = {"SMCarc" => "/usr/local/pkg/arc-5.21e-sol8-sparc-local"} when "i3865.8": retval = {"SMCarc" => "/usr/local/pkg/arc-5.21e-sol8-intel-local"} end when "OpenBSD": retval = {"aalib" => "ftp://ftp.usa.openbsd.org/pub/OpenBSD/3.8/packages/i386/aalib-1.2-no_x11.tgz"} when "Debian": retval = {"zec" => nil} #when "RedHat": type = :rpm when "Fedora": retval = {"wv" => nil} when "CentOS": retval = {"enhost" => [ "/home/luke/rpm/RPMS/noarch/enhost-1.0.1-1.noarch.rpm", "/home/luke/rpm/RPMS/noarch/enhost-1.0.2-1.noarch.rpm" ]} when "Darwin": retval = {"aop" => nil} when "FreeBSD": retval = {"yahtzee" => nil} when "RedHat": retval = {"puppet" => "/home/luke/rpm/RPMS/i386/puppet-0.16.1-1.i386.rpm"} else Puppet.notice "No test packages for %s" % $platform end return retval end def mkpkgcomp(pkg) assert_nothing_raised { pkg = Puppet.type(:package).create(:name => pkg, :ensure => "present") } assert_nothing_raised { pkg.retrieve } comp = newcomp("package", pkg) return comp end def test_retrievepkg mkpkgs(installedpkgs()) { |obj| assert(obj, "could not create package") assert_nothing_raised { obj.retrieve } assert_instance_of(String, obj[:ensure], "Ensure did not return a version number") assert(obj[:ensure] =~ /[0-9.]/, "Ensure did not return a version number") } end def test_nosuchpkg obj = nil assert_nothing_raised { obj = Puppet.type(:package).create( :name => "thispackagedoesnotexist", :ensure => :installed ) } assert(obj, "Failed to create fake package") assert_nothing_raised { obj.retrieve } assert_equal(:absent, obj.is(:ensure), "Somehow retrieved unknown pkg's version") state = obj.state(:ensure) assert(state, "Could not retrieve ensure state") # Add a fake state, for those that need it file = tempfile() File.open(file, "w") { |f| f.puts :yayness } obj[:source] = file assert_raise(Puppet::Error, "Successfully installed nonexistent package") { state.sync } end def test_latestpkg mkpkgs { |pkg| next unless pkg.respond_to? :latest assert_nothing_raised { assert(pkg.latest, "Package %s did not return value for 'latest'" % pkg.name) } } end # Make sure our package type supports listing. def test_listing pkgtype = Puppet::Type.type(:package) assert_nothing_raised("Could not list packages") do count = 0 pkgtype.list.each do |pkg| assert_instance_of(Puppet::Type.type(:package), pkg) count += 1 end assert(count > 1, "Did not get any packages") end end unless Process.uid == 0 $stderr.puts "Run as root to perform package installation tests" else def test_installpkg mkpkgs { |pkg| # we first set install to 'true', and make sure something gets # installed assert_nothing_raised { pkg.retrieve } if hash = pkg.provider.query and hash[:ensure] != :absent Puppet.notice "Test package %s is already installed; please choose a different package for testing" % pkg next end comp = newcomp("package", pkg) assert_events([:package_installed], comp, "package") pkg.retrieve assert(pkg.insync?, "Package is not in sync") # then uninstall it assert_nothing_raised { pkg[:ensure] = "absent" } pkg.retrieve assert(! pkg.insync?, "Package is in sync") assert_events([:package_removed], comp, "package") # and now set install to 'latest' and verify it installs if pkg.respond_to?(:latest) assert_nothing_raised { pkg[:ensure] = "latest" } assert_events([:package_installed], comp, "package") pkg.retrieve assert(pkg.insync?, "After install, package is not insync") assert_nothing_raised { pkg[:ensure] = "absent" } pkg.retrieve assert(! pkg.insync?, "Package is insync") assert_events([:package_removed], comp, "package") end } end # Make sure that a default is used for 'ensure' def test_ensuredefault # Tell mkpkgs not to set 'ensure'. mkpkgs(nil, false) { |pkg| assert_nothing_raised { pkg.retrieve } assert(!pkg.insync?, "Package thinks it's in sync") assert_apply(pkg) pkg.retrieve assert(pkg.insync?, "Package does not think it's in sync") pkg[:ensure] = :absent assert_apply(pkg) } end def test_upgradepkg tstpkgs.each do |name, sources| unless sources and sources.is_a? Array $stderr.puts "Skipping pkg upgrade test for %s" % name next end first, second = sources unless FileTest.exists?(first) and FileTest.exists?(second) $stderr.puts "Could not find upgrade test pkgs; skipping" return end pkg = nil assert_nothing_raised { pkg = Puppet.type(:package).create( :name => name, :ensure => :latest, :source => first ) } assert(pkg, "Failed to create package %s" % name) modpkg(pkg) assert(pkg.provider.latest, "Could not retrieve latest value") assert_events([:package_installed], pkg) assert_nothing_raised { pkg.retrieve } assert(pkg.insync?, "Package is not in sync") pkg.clear assert_nothing_raised { pkg[:source] = second } assert_events([:package_changed], pkg) assert_nothing_raised { pkg.retrieve } assert(pkg.insync?, "Package is not in sync") assert_nothing_raised { pkg[:ensure] = :absent } assert_events([:package_removed], pkg) assert_nothing_raised { pkg.retrieve } assert(pkg.insync?, "Package is not in sync") end end # Stupid darwin, not supporting package uninstallation if Facter["operatingsystem"].value == "Darwin" and FileTest.exists? "/Users/luke/Documents/Puppet/pkgtesting.pkg" def test_darwinpkgs pkg = nil assert_nothing_raised { pkg = Puppet::Type.type(:package).create( :name => "pkgtesting", :source => "/Users/luke/Documents/Puppet/pkgtesting.pkg", :ensure => :present, :provider => :apple ) } assert_nothing_raised { pkg.retrieve } if pkg.insync? Puppet.notice "Test package is already installed; please remove it" next end # The file installed, and the receipt @@tmpfiles << "/tmp/file" @@tmpfiles << "/Library/Receipts/pkgtesting.pkg" assert_events([:package_installed], pkg, "package") assert_nothing_raised { pkg.retrieve } assert(pkg.insync?, "Package is not insync") assert(FileTest.exists?("/tmp/pkgtesting/file"), "File did not get created") end end # Yay, gems. They're special because any OS can test them. if Puppet::Type.type(:package).provider(:gem).suitable? def test_list_gems gems = nil assert_nothing_raised { gems = Puppet::Type.type(:package).provider(:gem).list } gems.each do |gem| assert_equal(:gem, gem[:provider], "Type was not set correctly") end end def test_install_gems gem = nil name = "wxrubylayouts" assert_nothing_raised { gem = Puppet::Type.newpackage( :name => name, :ensure => "0.0.2", :provider => :gem ) } assert_nothing_raised { gem.retrieve } if gem.is(:ensure) != :absent $stderr.puts "Cannot test gem installation; %s is already installed" % name return end assert_events([:package_installed], gem) assert_nothing_raised { gem.retrieve } assert_equal("0.0.2", gem.is(:ensure), "Incorrect version was installed") latest = nil assert_nothing_raised { latest = gem.provider.latest } assert(latest != gem[:ensure], "Did not correctly find latest value") gem[:ensure] = :latest assert_events([:package_changed], gem) gem.retrieve assert("0.0.2" != gem.is(:ensure), "Package was not updated.") gem[:ensure] = :absent assert_events([:package_removed], gem) end else $stderr.puts "Install gems for gem tests" def test_nogems_nofailures obj = nil assert_nothing_raised do Puppet::Type.newpackage( :name => "yayness", :provider => "gem", :ensure => "installed" ) end assert_nil(Puppet::Type.type(:package)["yayness"], "Invalid gem package got created") end end end if Puppet.type(:package).provider(:rpm).suitable? and FileTest.exists?("/home/luke/rpm/RPMS/i386/puppet-server-0.16.1-1.i386.rpm") # We have a special test here, because we don't actually want to install the # package, just make sure it's getting the "latest" value. def test_rpmlatest pkg = nil assert_nothing_raised { pkg = Puppet::Type.type(:package).create( :provider => :rpm, :name => "puppet-server", :source => "/home/luke/rpm/RPMS/i386/puppet-server-0.16.1-1.i386.rpm" ) } assert_equal("0.16.1-1", pkg.provider.latest, "RPM did not provide correct value for latest") end end def test_packagedefaults should = case Facter["operatingsystem"].value when "Debian": :apt when "Darwin": :apple when "RedHat": :rpm when "Fedora": :yum when "FreeBSD": :ports when "OpenBSD": :openbsd when "Solaris": :sun end default = Puppet.type(:package).defaultprovider assert(default, "No default package provider for %s" % Facter["operatingsystem"].value) if should assert_equal(should, default.name, "Incorrect default package format") end end end end # $Id$ diff --git a/test/types/parameter.rb b/test/types/parameter.rb index 902f1398e..e94fe914b 100644 --- a/test/types/parameter.rb +++ b/test/types/parameter.rb @@ -1,107 +1,100 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet/type' require 'puppettest' -require 'test/unit' class TestParameter < Test::Unit::TestCase - include TestPuppet + include PuppetTest def newparam(name = :fakeparam) assert_nothing_raised { param = Class.new(Puppet::Parameter) do @name = :fakeparam end param.initvars return param } end def newinst(param) assert_nothing_raised { return param.new } end # Test the basic newvalue stuff. def test_newvalue param = newparam() # Try it with both symbols and strings. assert_nothing_raised { param.newvalues(:one, "two") } inst = newinst(param) assert_nothing_raised { inst.value = "one" } assert_equal(:one, inst.value) assert_nothing_raised { inst.value = :two } assert_equal(:two, inst.value) assert_raise(ArgumentError) { inst.value = :three } assert_equal(:two, inst.value) end # Test using regexes. def test_regexvalues param = newparam assert_nothing_raised { param.newvalues(/^\d+$/) } assert(param.match?("14")) assert(param.match?(14)) inst = newinst(param) assert_nothing_raised { inst.value = 14 } assert_nothing_raised { inst.value = "14" } assert_raise(ArgumentError) { inst.value = "a14" } end # Test using both. Equality should beat matching. def test_regexesandnormals param = newparam assert_nothing_raised { param.newvalues(:one, /^\w+$/) } inst = newinst(param) assert_nothing_raised { inst.value = "one" } assert_equal(:one, inst.value, "Value used regex instead of equality") assert_nothing_raised { inst.value = "two" } assert_equal("two", inst.value, "Matched value didn't take") end end # $Id$ diff --git a/test/types/port.rb b/test/types/port.rb index debd7ed89..ad73e7d97 100755 --- a/test/types/port.rb +++ b/test/types/port.rb @@ -1,201 +1,194 @@ # Test host job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' require 'puppet/type/parsedtype/port' -require 'test/unit' require 'facter' class TestPort < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @porttype = Puppet.type(:port) @oldfiletype = @porttype.filetype end def teardown @porttype.filetype = @oldfiletype Puppet.type(:file).clear super end # Here we just create a fake host type that answers to all of the methods # but does not modify our actual system. def mkfaketype pfile = tempfile() @porttype.path = pfile end def mkport port = nil if defined? @pcount @pcount += 1 else @pcount = 1 end assert_nothing_raised { port = Puppet.type(:port).create( :name => "puppet%s" % @pcount, :number => "813%s" % @pcount, :protocols => "tcp", :description => "The port that Puppet runs on", :alias => "coolness%s" % @pcount ) } return port end def test_simpleport mkfaketype host = nil assert_nothing_raised { assert_nil(Puppet.type(:port).retrieve) } port = mkport assert_nothing_raised { Puppet.type(:port).store } assert_nothing_raised { assert( Puppet.type(:port).to_file.include?( Puppet.type(:port).fileobj.read ), "File does not include all of our objects" ) } end def test_portsparse fakedata("data/types/ports").each { |file| @porttype.path = file Puppet.info "Parsing %s" % file assert_nothing_raised { @porttype.retrieve } # Now just make we've got some ports we know will be there dns = @porttype["domain"] assert(dns, "Could not retrieve DNS port") assert_equal("53", dns.is(:number), "DNS number was wrong") %w{udp tcp}.each { |v| assert(dns.is(:protocols).include?(v), "DNS did not include proto %s" % v) } @porttype.clear } end def test_moddingport mkfaketype port = nil port = mkport assert_events([:port_created], port) port.retrieve port[:protocols] = %w{tcp udp} assert_events([:port_changed], port) end def test_multivalues port = mkport assert_raise(Puppet::Error) { port[:protocols] = "udp tcp" } assert_raise(Puppet::Error) { port[:alias] = "puppetmasterd yayness" } end def test_removal mkfaketype port = mkport() assert_nothing_raised { port[:ensure] = :present } assert_events([:port_created], port) port.retrieve assert(port.insync?) assert_nothing_raised { port[:ensure] = :absent } assert_events([:port_removed], port) port.retrieve assert_events([], port) end def test_modifyingfile mkfaketype() ports = [] names = [] 3.times { k = mkport() ports << k names << k.name } assert_apply(*ports) ports.clear Puppet.type(:port).clear newport = mkport() #newport[:ensure] = :present names << newport.name assert_apply(newport) Puppet.type(:port).clear # Verify we can retrieve that info assert_nothing_raised("Could not retrieve after second write") { newport.retrieve } # And verify that we have data for everything names.each { |name| port = Puppet.type(:port)[name] assert(port) port.retrieve assert(port[:number], "port %s has no number" % name) } end def test_addingstates mkfaketype port = mkport() assert_events([:port_created], port) port.delete(:alias) assert(! port.state(:alias)) assert_events([:port_changed], port) assert_nothing_raised { port.retrieve } assert_equal(:present, port.is(:ensure)) assert(port.state(:alias).is == :absent) port[:alias] = "yaytest" assert_events([:port_changed], port) port.retrieve assert(port.state(:alias).is == ["yaytest"]) end end # $Id$ diff --git a/test/types/query.rb b/test/types/query.rb index 121670012..fe5742490 100644 --- a/test/types/query.rb +++ b/test/types/query.rb @@ -1,102 +1,95 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = File.join(Dir.getwd(), "../..") -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestQuery < Test::Unit::TestCase - include TestPuppet + include PuppetTest # hmmm # this is complicated, because we store references to the created # objects in a central store def file assert_nothing_raised() { - cfile = File.join($puppetbase,"examples/root/etc/configfile") + cfile = exampledir("root/etc/configfile") unless Puppet.type(:file).has_key?(cfile) Puppet.type(:file).create( :path => cfile, :check => [:mode, :owner, :checksum] ) end @configfile = Puppet.type(:file)[cfile] } return @configfile end def service assert_nothing_raised() { unless Puppet.type(:service).has_key?("sleeper") Puppet.type(:service).create( :name => "sleeper", :provider => "init", - :path => File.join($puppetbase,"examples/root/etc/init.d"), + :path => exampledir("root/etc/init.d"), :hasstatus => true, :check => [:ensure] ) end @sleeper = Puppet.type(:service)["sleeper"] } return @sleeper end def component(name,*args) assert_nothing_raised() { @component = Puppet.type(:component).create(:name => name) } args.each { |arg| assert_nothing_raised() { @component.push arg } } return @component end def test_file yayfile = file() #p yayfile yayfile.eachstate { |state| assert_nil(state.is) } assert_nothing_raised() { yayfile.retrieve } assert_nothing_raised() { yayfile[:check] = :group } assert_nothing_raised() { yayfile.retrieve } end def test_service service = service() assert(service, "Did not get service object") service.eachstate { |state| assert_nil(state.is) } assert_nothing_raised() { service.retrieve } end def test_component component = component("a",file(),service()) assert_nothing_raised() { component.retrieve } end end diff --git a/test/types/schedule.rb b/test/types/schedule.rb index ded677fd2..b68540d84 100755 --- a/test/types/schedule.rb +++ b/test/types/schedule.rb @@ -1,335 +1,328 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' -require 'test/unit' require 'puppet/type/schedule' require 'puppettest' class TestSchedule < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @stype = Puppet::Type::Schedule # This will probably get overridden by different tests @now = Time.now Puppet[:ignoreschedules] = false end def mksched s = nil assert_nothing_raised { s = @stype.create( :name => "testsched" ) } s end def diff(unit, incr, method, count) diff = @now.to_i.send(method, incr * count) t = Time.at(diff) #Puppet.notice "%s: %s %s %s = %s" % # [unit, @now.send(unit), method, count, t] #t.strftime("%H:%M:%S") t end def month(method, count) diff(:hour, 3600 * 24 * 30, method, count) end def week(method, count) diff(:hour, 3600 * 24 * 7, method, count) end def day(method, count) diff(:hour, 3600 * 24, method, count) end def hour(method, count) diff(:hour, 3600, method, count) end def min(method, count) diff(:min, 60, method, count) end def sec(method, count) diff(:sec, 1, method, count) end def settimes unless defined? @@times @@times = [Time.now] # Make one with an edge year on each side ary = Time.now.to_a [1999, 2000, 2001].each { |y| ary[5] = y; @@times << Time.local(*ary) } # And with edge hours ary = Time.now.to_a #[23, 0].each { |h| ary[2] = h; @@times << Time.local(*ary) } # 23 hour ary[2] = 23 @@times << Time.local(*ary) # 0 hour, next day ary[2] = 0 @@times << addday(Time.local(*ary)) # And with edge minutes #[59, 0].each { |m| ary[1] = m; @@times << Time.local(*ary) } ary = Time.now.to_a ary[1] = 59; @@times << Time.local(*ary) ary[1] = 0 #if ary[2] == 23 @@times << Time.local(*ary) #else # @@times << addday(Time.local(*ary)) #end end Puppet.err @@times.inspect @@times.each { |time| @now = time yield time } @now = Time.now end def test_range s = mksched ary = @now.to_a ary[2] = 12 @now = Time.local(*ary) data = { true => [ # An hour previous, an hour after [hour("-", 1), hour("+", 1)], # an hour previous but a couple minutes later, and an hour plus [min("-", 57), hour("+", 1)] ], false => [ # five minutes from now, an hour from now [min("+", 5), hour("+", 1)], # an hour ago, 20 minutes ago [hour("-", 1), min("-", 20)] ] } data.each { |result, values| values = values.collect { |value| "%s - %s" % [value[0].strftime("%H:%M:%S"), value[1].strftime("%H:%M:%S")] } values.each { |value| assert_nothing_raised("Could not parse %s" % value) { s[:range] = value } assert_equal(result, s.match?(nil, @now), "%s matched %s incorrectly" % [value.inspect, @now]) } assert_nothing_raised("Could not parse %s" % [values]) { s[:range] = values } assert_equal(result, s.match?(nil, @now), "%s matched %s incorrectly" % [values.inspect, @now]) } end def test_period_by_distance previous = @now s = mksched assert_nothing_raised { s[:period] = :daily } assert(s.match?(day("-", 1)), "did not match minus a day") assert(s.match?(day("-", 2)), "did not match two days") assert(! s.match?(@now), "matched today") assert(! s.match?(hour("-", 11)), "matched minus 11 hours") # Now test hourly assert_nothing_raised { s[:period] = :hourly } assert(s.match?(hour("-", 1)), "did not match minus an hour") assert(s.match?(hour("-", 2)), "did not match two hours") assert(! s.match?(@now), "matched now") assert(! s.match?(min("-", 59)), "matched minus 11 hours") # and weekly assert_nothing_raised { s[:period] = :weekly } assert(s.match?(week("-", 1)), "did not match minus a week") assert(s.match?(day("-", 7)), "did not match minus 7 days") assert(s.match?(day("-", 8)), "did not match minus 8 days") assert(s.match?(week("-", 2)), "did not match two weeks") assert(! s.match?(@now), "matched now") assert(! s.match?(day("-", 6)), "matched minus 6 days") # and monthly assert_nothing_raised { s[:period] = :monthly } assert(s.match?(month("-", 1)), "did not match minus a month") assert(s.match?(week("-", 5)), "did not match minus 5 weeks") assert(s.match?(week("-", 7)), "did not match minus 7 weeks") assert(s.match?(day("-", 50)), "did not match minus 50 days") assert(s.match?(month("-", 2)), "did not match two months") assert(! s.match?(@now), "matched now") assert(! s.match?(week("-", 3)), "matched minus 3 weeks") assert(! s.match?(day("-", 20)), "matched minus 20 days") end # A shortened test... def test_period_by_number s = mksched assert_nothing_raised { s[:periodmatch] = :number } assert_nothing_raised { s[:period] = :daily } assert(s.match?(day("+", 1)), "didn't match plus a day") assert(s.match?(week("+", 1)), "didn't match plus a week") assert(! s.match?(@now), "matched today") assert(! s.match?(hour("-", 1)), "matched minus an hour") assert(! s.match?(hour("-", 2)), "matched plus two hours") # Now test hourly assert_nothing_raised { s[:period] = :hourly } assert(s.match?(hour("+", 1)), "did not match plus an hour") assert(s.match?(hour("+", 2)), "did not match plus two hours") assert(! s.match?(@now), "matched now") assert(! s.match?(sec("+", 20)), "matched plus 20 seconds") end def test_periodmatch_default s = mksched match = s[:periodmatch] assert(match, "Could not find periodmatch") assert_equal(:distance, match, "Periodmatch was %s" % match) end def test_scheduled_objects s = mksched s[:period] = :hourly f = nil path = tempfile() assert_nothing_raised { f = Puppet.type(:file).create( :name => path, :schedule => s.name, :ensure => "file" ) } assert(f.scheduled?, "File is not scheduled to run") assert_apply(f) assert(! f.scheduled?, "File is scheduled to run already") File.unlink(path) assert_apply(f) assert(! FileTest.exists?(path), "File was created when not scheduled") end def test_latebinding_schedules f = nil path = tempfile() assert_nothing_raised { f = Puppet.type(:file).create( :name => path, :schedule => "testsched", :ensure => "file" ) } s = mksched s[:period] = :hourly assert_nothing_raised { f.schedule } assert(f.scheduled?, "File is not scheduled to run") end # Verify that each of our default schedules exist def test_defaultschedules Puppet.type(:schedule).mkdefaultschedules %w{puppet hourly daily weekly monthly}.each { |period| assert(Puppet.type(:schedule)[period], "Could not find %s schedule" % period) } end def test_period_with_repeat previous = @now s = mksched s[:period] = :hourly assert_nothing_raised("Was not able to set periodmatch") { s[:periodmatch] = :number } assert_raise(Puppet::Error) { s[:repeat] = 2 } assert_nothing_raised("Was not able to reset periodmatch") { s[:periodmatch] = :distance } assert(! s.match?(min("-", 40)), "matched minus 40 minutes") assert_nothing_raised("Was not able to set period") { s[:repeat] = 2 } assert(! s.match?(min("-", 20)), "matched minus 20 minutes with half-hourly") assert(s.match?(min("-", 40)), "Did not match minus 40 with half-hourly") assert_nothing_raised("Was not able to set period") { s[:repeat] = 3 } assert(! s.match?(min("-", 15)), "matched minus 15 minutes with half-hourly") assert(s.match?(min("-", 25)), "Did not match minus 25 with half-hourly") end end # $Id$ diff --git a/test/types/service.rb b/test/types/service.rb index e936e8f84..f9d6251ad 100644 --- a/test/types/service.rb +++ b/test/types/service.rb @@ -1,307 +1,300 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet' require 'puppettest' -require 'test/unit' $skipsvcs = false case Facter["operatingsystem"].value when "Darwin", "OpenBSD": $skipsvcs = true end if $skipsvcs puts "Skipping service testing on %s" % Facter["operatingsystem"].value else #class TestInitService < Test::Unit::TestCase class TestInitService - include TestPuppet + include PuppetTest def setup super sleeper = nil - script = File.join($puppetbase,"examples/root/etc/init.d/sleeper") - @init = File.join($puppetbase,"examples/root/etc/init.d") + script = exampledir("root/etc/init.d/sleeper") + @init = exampledir("root/etc/init.d") @status = script + " status" end def teardown super stopservices end def tstsvcs case Facter["operatingsystem"].value.downcase when "solaris": return ["smtp", "xf"] when "redhat": return ["sshd"] end end def mksleeper(hash = {}) hash[:name] = "sleeper" - hash[:path] = File.join($puppetbase,"examples/root/etc/init.d") + hash[:path] = exampledir("root/etc/init.d") hash[:ensure] = true hash[:hasstatus] = true hash[:hasrestart] = true #hash[:type] = "init" assert_nothing_raised() { return Puppet.type(:service).create(hash) } end def cyclesleeper(sleeper) assert_nothing_raised() { sleeper.retrieve } assert(!sleeper.insync?()) comp = newcomp(sleeper) assert_events([:service_started], comp) assert_nothing_raised() { sleeper.retrieve } assert(sleeper.insync?) # test refreshing it assert_nothing_raised() { sleeper.refresh } assert(sleeper.respond_to?(:refresh)) # now stop it assert_nothing_raised() { sleeper[:ensure] = 0 } assert_nothing_raised() { sleeper.retrieve } assert(!sleeper.insync?()) assert_events([:service_stopped], comp) assert_nothing_raised() { sleeper.retrieve } assert(sleeper.insync?) end def test_processStartWithPattern sleeper = mksleeper(:pattern => "bin/sleeper") cyclesleeper(sleeper) end def test_processStartWithStatus sleeper = mksleeper(:hasstatus => true) cyclesleeper(sleeper) end def test_invalidpathsremoved sleeper = mksleeper() fakedir = [@init, "/thisdirnoexist"] sleeper[:path] = fakedir assert(! sleeper[:path].include?(fakedir)) end end class TestLocalService < Test::Unit::TestCase - include TestPuppet + include PuppetTest def teardown Puppet.type(:service).clear super end def mktestsvcs list = tstsvcs.collect { |svc,svcargs| args = svcargs.dup args[:name] = svc Puppet.type(:service).create(args) } end def tstsvcs case Facter["operatingsystem"].value.downcase when "solaris": case Facter["operatingsystemrelease"].value when "5.10": return {"smtp" => {}, "xfs" => {}} end when "debian": return {"hddtemp" => {:hasrestart => true}} when "centos": return {"cups" => {:hasstatus => true}} when "redhat": return {"saslauthd" => {:hasstatus => true}} end Puppet.notice "No test services for %s-%s" % [Facter["operatingsystem"].value, Facter["operatingsystemrelease"].value] return [] end def cycleservice(service) assert_nothing_raised() { service.retrieve } comp = newcomp("servicetst", service) service[:ensure] = true Puppet.info "Starting %s" % service.name assert_apply(service) # Some package systems background the work, so we need to give them # time to do their work. sleep(1.5) assert_nothing_raised() { service.retrieve } assert(service.insync?, "Service %s is not running" % service.name) # test refreshing it assert_nothing_raised() { service.refresh } # now stop it assert_nothing_raised() { service[:ensure] = :stopped } assert_nothing_raised() { service.retrieve } assert(!service.insync?(), "Service %s is not running" % service.name) Puppet.info "stopping %s" % service.name assert_events([:service_stopped], comp) sleep(1.5) assert_nothing_raised() { service.retrieve } assert(service.insync?, "Service %s has not stopped" % service.name) end def cycleenable(service) assert_nothing_raised() { service.retrieve } comp = newcomp("servicetst", service) service[:enable] = true Puppet.info "Enabling %s" % service.name assert_apply(service) # Some package systems background the work, so we need to give them # time to do their work. sleep(1.5) assert_nothing_raised() { service.retrieve } assert(service.insync?, "Service %s is not enabled" % service.name) # now stop it assert_nothing_raised() { service[:enable] = false } assert_nothing_raised() { service.retrieve } assert(!service.insync?(), "Service %s is not enabled" % service.name) Puppet.info "disabling %s" % service.name assert_events([:service_disabled], comp) sleep(1.5) assert_nothing_raised() { service.retrieve } assert(service.insync?, "Service %s has not been disabled" % service.name) end def test_status mktestsvcs.each { |svc| val = nil assert_nothing_raised("Could not get status") { val = svc.provider.status } assert_instance_of(Symbol, val) } end unless Process.uid == 0 puts "run as root to test service start/stop" else def test_servicestartstop mktestsvcs.each { |svc| startstate = nil assert_nothing_raised("Could not get status") { startstate = svc.provider.status } cycleservice(svc) svc[:ensure] = startstate assert_apply(svc) Puppet.type(:component).clear } end def test_serviceenabledisable mktestsvcs.each { |svc| assert(svc[:name], "Service has no name") startstate = nil svc[:check] = :enable assert_nothing_raised("Could not get status") { startstate = svc.provider.enabled? } cycleenable(svc) svc[:enable] = startstate assert_apply(svc) Puppet.type(:component).clear } end def test_serviceenableandrun mktestsvcs.each do |svc| startenable = nil startensure = nil svc[:check] = [:ensure, :enable] svc.retrieve assert_nothing_raised("Could not get status") { startenable = svc.state(:enable).is startensure = svc.state(:ensure).is } svc[:enable] = false svc[:ensure] = :stopped assert_apply(svc) sleep 1 svc.retrieve assert(svc.insync?, "Service did not sync both states") svc[:enable] = true svc[:ensure] = :running assert_apply(svc) sleep 1 svc.retrieve assert(svc.insync?, "Service did not sync both states") svc[:enable] = startenable svc[:ensure] = startensure assert_apply(svc) Puppet.type(:component).clear end end end end end # $Id$ diff --git a/test/types/sshkey.rb b/test/types/sshkey.rb index ff9adc336..e541a0bd6 100755 --- a/test/types/sshkey.rb +++ b/test/types/sshkey.rb @@ -1,182 +1,175 @@ # Test key job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' require 'puppet/type/parsedtype/sshkey' -require 'test/unit' require 'facter' class TestSSHKey < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super # god i'm lazy @sshtype = Puppet.type(:sshkey) @oldfiletype = @sshtype.filetype end def teardown Puppet::FileType.filetype(:ram).clear @sshtype.filetype = @oldfiletype Puppet.type(:file).clear super end # Here we just create a fake key type that answers to all of the methods # but does not modify our actual system. def mkfaketype @sshtype.filetype = Puppet::FileType.filetype(:ram) end def mkkey key = nil if defined? @kcount @kcount += 1 else @kcount = 1 end assert_nothing_raised { key = @sshtype.create( :name => "host%s.madstop.com" % @kcount, :key => "%sAAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=" % @kcount, :type => "ssh-dss", :alias => ["192.168.0.%s" % @kcount] ) } return key end def test_simplekey mkfaketype assert_nothing_raised { assert_nil(Puppet.type(:sshkey).retrieve) } key = mkkey assert_apply(key) assert_nothing_raised { Puppet.type(:sshkey).store } assert_nothing_raised { assert( Puppet.type(:sshkey).to_file.include?( Puppet.type(:sshkey).fileobj.read ), "File does not include all of our objects" ) } end def test_keysparse fakedata("data/types/sshkey").each { |file| @sshtype.path = file assert_nothing_raised { @sshtype.retrieve } @sshtype.clear } end def test_moddingkey mkfaketype key = mkkey() assert_events([:sshkey_created], key) key.retrieve key[:alias] = %w{madstop kirby yayness} Puppet.err :mark assert_events([:sshkey_changed], key) end def test_aliasisstate assert_equal(:state, @sshtype.attrtype(:alias)) end def test_multivalues key = mkkey assert_raise(Puppet::Error) { key[:alias] = "puppetmasterd yayness" } end def test_puppetalias key = mkkey() assert_nothing_raised { key[:alias] = "testing" } same = key.class["testing"] assert(same, "Could not retrieve by alias") end def test_removal mkfaketype sshkey = mkkey() assert_nothing_raised { sshkey[:ensure] = :present } assert_events([:sshkey_created], sshkey) sshkey.retrieve assert(sshkey.insync?) assert_nothing_raised { sshkey[:ensure] = :absent } assert_events([:sshkey_removed], sshkey) sshkey.retrieve assert_events([], sshkey) end def test_modifyingfile keyfile = tempfile() Puppet.type(:sshkey).path = keyfile keys = [] names = [] 3.times { k = mkkey() #h[:ensure] = :present #h.retrieve keys << k names << k.name } assert_apply(*keys) keys.clear Puppet.type(:sshkey).clear newkey = mkkey() #newkey[:ensure] = :present names << newkey.name assert_apply(newkey) Puppet.type(:sshkey).clear # Verify we can retrieve that info assert_nothing_raised("Could not retrieve after second write") { newkey.retrieve } # And verify that we have data for everything names.each { |name| key = Puppet.type(:sshkey)[name] assert(key) assert(key[:type]) } end end # $Id$ diff --git a/test/types/state.rb b/test/types/state.rb index 638372afe..c3ea0965f 100644 --- a/test/types/state.rb +++ b/test/types/state.rb @@ -1,131 +1,124 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet/type' require 'puppettest' -require 'test/unit' class TestState < Test::Unit::TestCase - include TestPuppet + include PuppetTest def newinst(state) inst = nil assert_nothing_raised { return state.new(:parent => nil) } end def newstate(name = :fakestate) assert_nothing_raised { state = Class.new(Puppet::State) do @name = :fakeparam end state.initvars return state } end def test_newvalue state = newstate() # These are bogus because they don't define events. :/ assert_nothing_raised { state.newvalue(:one) do @is = 1 end } assert_nothing_raised { state.newvalue("two") do @is = 2 end } inst = newinst(state) assert_nothing_raised { inst.should = "one" } assert_equal(:one, inst.should) ret = nil assert_nothing_raised { inst.set_one } assert_equal(1, inst.is) assert_nothing_raised { inst.should = :two } assert_equal(:two, inst.should) assert_nothing_raised { inst.set_two } assert_equal(2, inst.is) end def test_newstatevaluewithregexes state = newstate() assert_nothing_raised { state.newvalue(/^\w+$/) do @is = self.should.upcase return :regex_matched end } inst = newinst(state) assert_nothing_raised { inst.should = "yayness" } assert_equal("yayness", inst.should) assert_nothing_raised { inst.sync } assert_equal("yayness".upcase, inst.is) end def test_newvalue_event_option state = newstate() assert_nothing_raised do state.newvalue(:myvalue, :event => :fake_valued) do @is = :valued end state.newvalue(:other, :event => "fake_other") do @is = :valued end end inst = newinst(state) assert_nothing_raised { inst.should = :myvalue } ret = nil assert_nothing_raised { ret = inst.sync } assert_equal(:fake_valued, ret, "Event did not get returned correctly") assert_nothing_raised { inst.should = :other } assert_nothing_raised { ret = inst.sync } assert_equal(:fake_other, ret, "Event did not get returned correctly") end end # $Id$ diff --git a/test/types/symlink.rb b/test/types/symlink.rb index 408817cb7..8f3e1d598 100755 --- a/test/types/symlink.rb +++ b/test/types/symlink.rb @@ -1,120 +1,113 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestSymlink < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def mktmpfile # because luke's home directory is on nfs, it can't be used for testing # as root tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } @@tmpfiles.push tmpfile return tmpfile end def mktmpdir dir = File.join(tmpdir(), "puppetlinkdir") unless FileTest.exists?(dir) Dir.mkdir(dir) end @@tmpfiles.push dir return dir end def tmplink link = File.join(tmpdir(), "puppetlinktest") @@tmpfiles.push link return link end def newlink(hash = {}) hash[:name] = tmplink() unless hash.include?(:ensure) hash[:ensure] = mktmpfile() end link = Puppet.type(:symlink).create(hash) return link end def test_target link = nil file = mktmpfile() assert_nothing_raised() { link = newlink() } assert_nothing_raised() { link.retrieve } # we might already be in sync assert(!link.insync?()) assert_apply(link) assert_nothing_raised() { link.retrieve } assert(link.insync?()) end def test_recursion source = mktmpdir() FileUtils.cd(source) { mkranddirsandfiles() } link = nil assert_nothing_raised { link = newlink(:ensure => source, :recurse => true) } comp = newcomp(link) cycle(comp) path = link.name assert(FileTest.directory?(path), "Did not make %s" % path) list = file_list(path) FileUtils.cd(path) { list.each { |file| unless FileTest.directory?(file) assert(FileTest.symlink?(file), "file %s is not a symlink" % file) target = File.readlink(file) assert_equal(target,File.join(source,file.sub(/^\.\//,''))) end } } end def disabled_test_createdrecursion source = tempfile() file = File.join(source, "file") dest = tempfile() link = File.join(dest, "file") objects = [] objects << Puppet.type(:file).create( :path => source, :ensure => "directory" ) objects << Puppet.type(:file).create( :path => file, :ensure => "file" ) objects << Puppet.type(:symlink).create( :path => dest, :ensure => source, :recurse => true ) assert_apply(*objects) assert(FileTest.symlink?(link), "Link was not created") end end diff --git a/test/types/tidy.rb b/test/types/tidy.rb index dc5bc2d2d..74c6bceda 100755 --- a/test/types/tidy.rb +++ b/test/types/tidy.rb @@ -1,102 +1,95 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../../../../language/trunk" -end - require 'puppet' require 'puppettest' -require 'test/unit' # $Id$ class TestTidy < Test::Unit::TestCase - include FileTesting + include PuppetTest::FileTesting def mktmpfile # because luke's home directory is on nfs, it can't be used for testing # as root tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } @@tmpfiles.push tmpfile return tmpfile end def mktmpdir dir = File.join(tmpdir(), "puppetlinkdir") unless FileTest.exists?(dir) Dir.mkdir(dir) end @@tmpfiles.push dir return dir end def test_simpletidy dir = mktmpdir file = File.join(dir, "tidytesting") File.open(file, "w") { |f| f.puts rand(100) } tidy = Puppet.type(:tidy).create( :name => dir, :size => "1b", :recurse => true ) comp = newcomp("tidytesting", tidy) comp.finalize trans = nil assert_events([:file_tidied], comp) assert(!FileTest.exists?(file), "Tidied file still exists") end def test_tidydirs dir = mktmpdir file = File.join(dir, "tidytesting") File.open(file, "w") { |f| f.puts rand(100) } tidy = Puppet.type(:tidy).create( :name => dir, :size => "1b", :age => "1s", :rmdirs => true, :recurse => true ) sleep(2) assert_events([:file_tidied, :file_tidied], tidy) assert(!FileTest.exists?(file), "Tidied %s still exists" % file) assert(!FileTest.exists?(dir), "Tidied %s still exists" % dir) end def disabled_test_recursion source = mktmpdir() FileUtils.cd(source) { mkranddirsandfiles() } link = nil assert_nothing_raised { link = newlink(:target => source, :recurse => true) } comp = newcomp("linktest",link) cycle(comp) path = link.name list = file_list(path) FileUtils.cd(path) { list.each { |file| unless FileTest.directory?(file) assert(FileTest.symlink?(file)) target = File.readlink(file) assert_equal(target,File.join(source,file.sub(/^\.\//,''))) end } } end end diff --git a/test/types/type.rb b/test/types/type.rb index 010102ad9..f8785fd3b 100644 --- a/test/types/type.rb +++ b/test/types/type.rb @@ -1,757 +1,750 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppet/type' require 'puppettest' -require 'test/unit' class TestType < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_typemethods Puppet::Type.eachtype { |type| name = nil assert_nothing_raised("Searching for name for %s caused failure" % type.to_s) { name = type.name } assert(name, "Could not find name for %s" % type.to_s) assert_equal( type, Puppet::Type.type(name), "Failed to retrieve %s by name" % name ) # Skip types with no parameters or valid states #unless ! type.parameters.empty? or ! type.validstates.empty? # next #end assert_nothing_raised { assert( type.namevar, "Failed to retrieve namevar for %s" % name ) assert_not_nil( type.states, "States for %s are nil" % name ) assert_not_nil( type.validstates, "Valid states for %s are nil" % name ) } } end def test_stringvssymbols file = nil path = tempfile() assert_nothing_raised() { system("rm -f %s" % path) file = Puppet.type(:file).create( :path => path, :ensure => "file", :recurse => true, :checksum => "md5" ) } assert_nothing_raised() { file.retrieve } assert_nothing_raised() { file.evaluate } Puppet.type(:file).clear assert_nothing_raised() { system("rm -f %s" % path) file = Puppet.type(:file).create( "path" => path, "ensure" => "file", "recurse" => true, "checksum" => "md5" ) } assert_nothing_raised() { file.retrieve } assert_nothing_raised() { file[:path] } assert_nothing_raised() { file["path"] } assert_nothing_raised() { file[:recurse] } assert_nothing_raised() { file["recurse"] } assert_nothing_raised() { file.evaluate } end # This was supposed to test objects whose name was a state, but that # fundamentally doesn't make much sense, and we now don't have any such # types. def disabled_test_nameasstate # currently groups are the only objects with the namevar as a state group = nil assert_nothing_raised { group = Puppet.type(:group).create( :name => "testing" ) } assert_equal("testing", group.name, "Could not retrieve name") end # Verify that values get merged correctly def test_mergestatevalues file = tempfile() # Create the first version assert_nothing_raised { Puppet.type(:file).create( :path => file, :owner => ["root", "bin"] ) } # Make sure no other statements are allowed assert_raise(Puppet::Error) { Puppet.type(:file).create( :path => file, :group => "root" ) } end # Verify that aliasing works def test_aliasing file = tempfile() baseobj = nil assert_nothing_raised { baseobj = Puppet.type(:file).create( :name => file, :ensure => "file", :alias => ["funtest"] ) } # Verify our adding ourselves as an alias isn't an error. assert_nothing_raised { baseobj[:alias] = file } assert_instance_of(Puppet.type(:file), Puppet.type(:file)["funtest"], "Could not retrieve alias") end # Verify that requirements don't depend on file order def test_prereqorder one = tempfile() two = tempfile() twoobj = nil oneobj = nil assert_nothing_raised("Could not create prereq that doesn't exist yet") { twoobj = Puppet.type(:file).create( :name => two, :require => [:file, one] ) } assert_nothing_raised { oneobj = Puppet.type(:file).create( :name => one ) } comp = newcomp(twoobj, oneobj) assert_nothing_raised { comp.finalize } assert(twoobj.requires?(oneobj), "Requirement was not created") end # Verify that names are aliases, not equivalents def test_nameasalias file = nil # Create the parent dir, so we make sure autorequiring the parent dir works parentdir = tempfile() dir = Puppet.type(:file).create( :name => parentdir, :ensure => "directory" ) assert_apply(dir) path = File.join(parentdir, "subdir") name = "a test file" transport = Puppet::TransObject.new(name, "file") transport[:path] = path transport[:ensure] = "file" assert_nothing_raised { file = transport.to_type } assert_equal(path, file[:path]) assert_equal(name, file.title) assert_nothing_raised { file.retrieve } assert_apply(file) assert(Puppet.type(:file)[name], "Could not look up object by name") end def test_ensuredefault user = nil assert_nothing_raised { user = Puppet.type(:user).create( :name => "pptestAA", :check => [:uid] ) } # make sure we don't get :ensure for unmanaged files assert(! user.state(:ensure), "User got an ensure state") assert_nothing_raised { user = Puppet.type(:user).create( :name => "pptestAA", :comment => "Testingness" ) } # but make sure it gets added once we manage them assert(user.state(:ensure), "User did not add ensure state") assert_nothing_raised { user = Puppet.type(:user).create( :name => "pptestBB", :comment => "A fake user" ) } # and make sure managed objects start with them assert(user.state(:ensure), "User did not get an ensure state") end # Make sure removal works def test_remove objects = {} top = Puppet.type(:component).create(:name => "top") objects[top.class] = top base = tempfile() # now make a two-tier, 5 piece tree %w{a b}.each do |letter| name = "comp%s" % letter comp = Puppet.type(:component).create(:name => name) top.push comp objects[comp.class] = comp 5.times do |i| file = base + letter + i.to_s obj = Puppet.type(:file).create(:name => file, :ensure => "file") comp.push obj objects[obj.class] = obj end end assert_nothing_raised do top.remove end objects.each do |klass, obj| assert_nil(klass[obj.name], "object %s was not removed" % obj.name) end end # Verify that objects can't be their own children. def test_object_recursion comp = Puppet.type(:component).create(:name => "top") file = Puppet.type(:file).create(:path => tempfile, :ensure => :file) assert_raise(Puppet::DevError) do comp.push(comp) end assert_raise(Puppet::DevError) do file.push(file) end assert_raise(Puppet::DevError) do comp.parent = comp end assert_raise(Puppet::DevError) do file.parent = file end assert_nothing_raised { comp.push(file) } assert_raise(Puppet::DevError) do file.push(comp) end assert_raise(Puppet::DevError) do comp.parent = file end end def test_loadplugins names = %w{loadedplugin1 loadplugin2 loadplugin3} dirs = [] 3.times { dirs << tempfile() } # Set plugindest to something random Puppet[:plugindest] = tempfile() Puppet[:pluginpath] = dirs.join(":") names.each do |name| dir = dirs.shift Dir.mkdir(dir) # Create an extra file for later [name, name + "2ness"].each do |n| file = File.join(dir, n + ".rb") File.open(file, "w") do |f| f.puts %{Puppet::Type.newtype('#{n}') do newparam(:argument) do isnamevar end end } end end assert(Puppet::Type.type(name), "Did not get loaded plugin") assert_nothing_raised { Puppet::Type.type(name).create( :name => "myname" ) } end # Now make sure the plugindest got added to our pluginpath assert(Puppet[:pluginpath].split(":").include?(Puppet[:plugindest]), "Plugin dest did not get added to plugin path") # Now make sure it works with just a single path, using the extra files # created above. Puppet[:pluginpath] = Puppet[:pluginpath].split(":")[0] assert(Puppet::Type.type("loadedplugin12ness"), "Did not get loaded plugin") end def test_newtype_methods assert_nothing_raised { Puppet::Type.newtype(:mytype) do newparam(:wow) do isnamevar end end } assert(Puppet::Type.respond_to?(:newmytype), "new method did not get created") obj = nil assert_nothing_raised { obj = Puppet::Type.newmytype(:wow => "yay") } assert(obj.is_a?(Puppet::Type.type(:mytype)), "Obj is not the correct type") # Now make the type again, just to make sure it works on refreshing. assert_nothing_raised { Puppet::Type.newtype(:mytype) do newparam(:yay) do isnamevar end end } obj = nil # Make sure the old class was thrown away and only the new one is sitting # around. assert_raise(Puppet::Error) { obj = Puppet::Type.newmytype(:wow => "yay") } assert_nothing_raised { obj = Puppet::Type.newmytype(:yay => "yay") } # Now make sure that we don't replace existing, non-type methods parammethod = Puppet::Type.method(:newparam) assert_nothing_raised { Puppet::Type.newtype(:param) do newparam(:rah) do isnamevar end end } assert_equal(parammethod, Puppet::Type.method(:newparam), "newparam method got replaced by newtype") end def test_notify_metaparam file = Puppet::Type.newfile( :path => tempfile(), :notify => ["exec", "notifytest"], :ensure => :file ) path = tempfile() exec = Puppet::Type.newexec( :title => "notifytest", :path => "/usr/bin:/bin", :command => "touch #{path}", :refreshonly => true ) assert_apply(file, exec) assert(exec.requires?(file), "Notify did not correctly set up the requirement chain.") assert(FileTest.exists?(path), "Exec path did not get created.") end def test_before_metaparam file = Puppet::Type.newfile( :path => tempfile(), :before => ["exec", "beforetest"], :content => "yaytest" ) path = tempfile() exec = Puppet::Type.newexec( :title => "beforetest", :command => "/bin/cp #{file[:path]} #{path}" ) assert_apply(file, exec) assert(exec.requires?(file), "Before did not correctly set up the requirement chain.") assert(FileTest.exists?(path), "Exec path did not get created.") assert_equal("yaytest", File.read(path), "Exec did not correctly copy file.") end def test_newstate_options # Create a type with a fake provider providerclass = Class.new do def method_missing(method, *args) return method end end self.class.const_set("ProviderClass", providerclass) type = Puppet::Type.newtype(:mytype) do newparam(:name) do isnamevar end def provider @provider ||= ProviderClass.new @provider end end # Now make a state with no options. state = nil assert_nothing_raised do state = type.newstate(:noopts) do end end # Now create an instance obj = type.create(:name => :myobj) inst = state.new(:parent => obj) # And make sure it's correctly setting @is ret = nil assert_nothing_raised { ret = inst.retrieve } assert_equal(:noopts, inst.is) # Now create a state with a different way of doing it state = nil assert_nothing_raised do state = type.newstate(:setretrieve, :retrieve => :yayness) end inst = state.new(:parent => obj) # And make sure it's correctly setting @is ret = nil assert_nothing_raised { ret = inst.retrieve } assert_equal(:yayness, inst.is) end def test_name_vs_title path = tempfile() trans = nil assert_nothing_raised { trans = Puppet::TransObject.new(path, :file) } file = nil assert_nothing_raised { file = Puppet::Type.newfile(trans) } assert(file.respond_to?(:title), "No 'title' method") assert(file.respond_to?(:name), "No 'name' method") assert_equal(file.title, file.name, "Name and title were not marked equal") assert_nothing_raised { file.title = "My file" } assert_equal("My file", file.title) assert_equal(path, file.name) end # Make sure the title is sufficiently differentiated from the namevar. def test_title_at_creation_with_hash file = nil fileclass = Puppet::Type.type(:file) path = tempfile() assert_nothing_raised do file = fileclass.create( :title => "Myfile", :path => path ) end assert_equal("Myfile", file.title, "Did not get correct title") assert_equal(path, file[:name], "Did not get correct name") file = nil Puppet::Type.type(:file).clear # Now make sure we can specify both and still get the right answers assert_nothing_raised do file = fileclass.create( :title => "Myfile", :name => path ) end assert_instance_of(fileclass, file) assert_equal("Myfile", file.title, "Did not get correct title") assert_equal(path, file[:name], "Did not get correct name") end # Make sure the "create" class method behaves appropriately. def test_class_create title = "Myfile" validate = proc do |element| assert(element, "Did not create file") assert_instance_of(Puppet::Type.type(:file), element) assert_equal(title, element.title, "Title is not correct") end type = :file args = {:path => tempfile(), :owner => "root"} trans = Puppet::TransObject.new(title, type) args.each do |name, val| trans[name] = val end # First call it on the appropriate typeclass obj = nil assert_nothing_raised do obj = Puppet::Type.type(:file).create(trans) end validate.call(obj) # Now try it using the class method on Type oldid = obj.object_id obj = nil Puppet::Type.type(:file).clear assert_nothing_raised { obj = Puppet::Type.create(trans) } validate.call(obj) assert(oldid != obj.object_id, "Got same object back") # Now try the same things with hashes instead of a transobject oldid = obj.object_id obj = nil Puppet::Type.type(:file).clear hash = { :type => :file, :title => "Myfile", :path => tempfile(), :owner => "root" } # First call it on the appropriate typeclass obj = nil assert_nothing_raised do obj = Puppet::Type.type(:file).create(hash) end validate.call(obj) assert_equal(:file, obj.should(:type), "Type param did not pass through") assert(oldid != obj.object_id, "Got same object back") # Now try it using the class method on Type oldid = obj.object_id obj = nil Puppet::Type.type(:file).clear assert_nothing_raised { obj = Puppet::Type.create(hash) } validate.call(obj) assert(oldid != obj.object_id, "Got same object back") assert_nil(obj.should(:type), "Type param passed through") end def test_multiplenames obj = nil path = tempfile() assert_raise ArgumentError do obj = Puppet::Type.type(:file).create( :name => path, :path => path ) end end def test_title_and_name obj = nil path = tempfile() fileobj = Puppet::Type.type(:file) assert_nothing_raised do obj = fileobj.create( :title => "myfile", :path => path ) end assert_equal(obj, fileobj["myfile"], "Could not retrieve obj by title") assert_equal(obj, fileobj[path], "Could not retrieve obj by name") end # Make sure default providers behave correctly def test_defaultproviders # Make a fake type type = Puppet::Type.newtype(:defaultprovidertest) do newparam(:name) do end end basic = type.provide(:basic) do defaultfor :operatingsystem => :somethingelse, :operatingsystemrelease => :yayness end assert_equal(basic, type.defaultprovider) type.defaultprovider = nil greater = type.provide(:greater) do defaultfor :operatingsystem => Facter.value("operatingsystem") end assert_equal(greater, type.defaultprovider) end # Make sure that we can have multiple isomorphic objects with the same name, # but not with non-isomorphic objects. def test_isomorphic_names # First do execs, since they're not isomorphic. echo = Puppet::Util.binary "echo" exec1 = exec2 = nil assert_nothing_raised do exec1 = Puppet::Type.type(:exec).create( :title => "exec1", :command => "#{echo} funtest" ) end assert_nothing_raised do exec2 = Puppet::Type.type(:exec).create( :title => "exec2", :command => "#{echo} funtest" ) end assert_apply(exec1, exec2) # Now do files, since they are. This should fail. file1 = file2 = nil path = tempfile() assert_nothing_raised do file1 = Puppet::Type.type(:file).create( :title => "file1", :path => path, :content => "yayness" ) end # This will fail, but earlier systems will catch it. assert_raise(Puppet::Error) do file2 = Puppet::Type.type(:file).create( :title => "file2", :path => path, :content => "rahness" ) end assert(file1, "Did not create first file") assert_nil(file2, "Incorrectly created second file") end end # $Id$ diff --git a/test/types/user.rb b/test/types/user.rb index 008f39272..958cf9441 100755 --- a/test/types/user.rb +++ b/test/types/user.rb @@ -1,443 +1,436 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'etc' require 'puppet/type' require 'puppettest' -require 'test/unit' class TestUser < Test::Unit::TestCase - include TestPuppet + include PuppetTest - p = Puppet::Type.type(:user).provide :fake, :parent => TestPuppet::FakeProvider do + p = Puppet::Type.type(:user).provide :fake, :parent => PuppetTest::FakeProvider do @name = :fake apimethods def create @ensure = :present @model.eachstate do |state| next if state.name == :ensure state.sync end end def delete @ensure = :absent @model.eachstate do |state| send(state.name.to_s + "=", :absent) end end def exists? if defined? @ensure and @ensure == :present true else false end end end FakeUserProvider = p @@fakeproviders[:group] = p def findshell(old = nil) %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh /usr/bin/tcsh}.find { |shell| if old FileTest.exists?(shell) and shell != old else FileTest.exists?(shell) end } end def setup super Puppet::Type.type(:user).defaultprovider = FakeUserProvider end def teardown Puppet::Type.type(:user).defaultprovider = nil super end def mkuser(name) user = nil assert_nothing_raised { user = Puppet.type(:user).create( :name => name, :comment => "Puppet Testing User", :gid => Process.gid, :shell => findshell(), :home => "/home/%s" % name ) } assert(user, "Did not create user") return user end def attrtest_ensure(user) old = user.provider.ensure user[:ensure] = :absent comp = newcomp("ensuretest", user) assert_apply(user) assert(!user.provider.exists?, "User is still present") user[:ensure] = :present assert_events([:user_created], comp) assert(user.provider.exists?, "User is absent") user[:ensure] = :absent trans = assert_events([:user_removed], comp) assert_rollback_events(trans, [:user_created], "user") user[:ensure] = old assert_apply(user) end def attrtest_comment(user) user.retrieve old = user.provider.comment user[:comment] = "A different comment" comp = newcomp("commenttest", user) trans = assert_events([:user_changed], comp, "user") assert_equal("A different comment", user.provider.comment, "Comment was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.comment, "Comment was not reverted") end def attrtest_home(user) obj = nil comp = newcomp("hometest", user) old = user.provider.home user[:home] = old trans = assert_events([], comp, "user") user[:home] = "/tmp" trans = assert_events([:user_changed], comp, "user") assert_equal("/tmp", user.provider.home, "Home was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.home, "Home was not reverted") end def attrtest_shell(user) old = user.provider.shell comp = newcomp("shelltest", user) user[:shell] = old trans = assert_events([], comp, "user") newshell = findshell(old) unless newshell $stderr.puts "Cannot find alternate shell; skipping shell test" return end user[:shell] = newshell trans = assert_events([:user_changed], comp, "user") user.retrieve assert_equal(newshell, user.provider.shell, "Shell was not changed") assert_rollback_events(trans, [:user_changed], "user") user.retrieve assert_equal(old, user.provider.shell, "Shell was not reverted") end def attrtest_gid(user) obj = nil old = user.provider.gid comp = newcomp("gidtest", user) user.retrieve user[:gid] = old trans = assert_events([], comp, "user") newgid = %w{nogroup nobody staff users daemon}.find { |gid| begin group = Etc.getgrnam(gid) rescue ArgumentError => detail next end old != group.gid } unless newgid $stderr.puts "Cannot find alternate group; skipping gid test" return end # first test by name assert_nothing_raised("Failed to specify group by name") { user[:gid] = newgid } trans = assert_events([:user_changed], comp, "user") # then by id newgid = Etc.getgrnam(newgid).gid assert_nothing_raised("Failed to specify group by id") { user[:gid] = newgid } user.retrieve assert_events([], comp, "user") assert_equal(newgid, user.provider.gid, "GID was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.gid, "GID was not reverted") end def attrtest_uid(user) obj = nil comp = newcomp("uidtest", user) user.provider.uid = 1 old = 1 newuid = 1 while true newuid += 1 if newuid - old > 1000 $stderr.puts "Could not find extra test UID" return end begin newuser = Etc.getpwuid(newuid) rescue ArgumentError => detail break end end assert_nothing_raised("Failed to change user id") { user[:uid] = newuid } trans = assert_events([:user_changed], comp, "user") assert_equal(newuid, user.provider.uid, "UID was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.uid, "UID was not reverted") end def attrtest_groups(user) Etc.setgrent max = 0 while group = Etc.getgrent if group.gid > max and group.gid < 5000 max = group.gid end end groups = [] main = [] extra = [] 5.times do |i| i += 1 name = "pptstgr%s" % i groups << name if i < 3 main << name else extra << name end end assert(user[:membership] == :minimum, "Membership did not default correctly") assert_nothing_raised { user.retrieve } # Now add some of them to our user assert_nothing_raised { user[:groups] = extra } assert_nothing_raised { user.retrieve } # Some tests to verify that groups work correctly startig from nothing # Remove our user user[:ensure] = :absent assert_apply(user) assert_nothing_raised do user.retrieve end # And add it again user[:ensure] = :present assert_apply(user) # Make sure that the groups are a string, not an array assert(user.provider.groups.is_a?(String), "Incorrectly passed an array to groups") user.retrieve assert(user.state(:groups).is, "Did not retrieve group list") list = user.state(:groups).is assert_equal(extra.sort, list.sort, "Group list is not equal") # Now set to our main list of groups assert_nothing_raised { user[:groups] = main } assert_equal((main + extra).sort, user.state(:groups).should.sort) assert_nothing_raised { user.retrieve } assert(!user.insync?, "User is incorrectly in sync") assert_apply(user) assert_nothing_raised { user.retrieve } # We're not managing inclusively, so it should keep the old group # memberships and add the new ones list = user.state(:groups).is assert_equal((main + extra).sort, list.sort, "Group list is not equal") assert_nothing_raised { user[:membership] = :inclusive } assert_nothing_raised { user.retrieve } assert(!user.insync?, "User is incorrectly in sync") assert_events([:user_changed], user) assert_nothing_raised { user.retrieve } list = user.state(:groups).is assert_equal(main.sort, list.sort, "Group list is not equal") user.delete(:groups) end def test_autorequire file = tempfile() comp = nil user = nil group =nil home = nil ogroup = nil assert_nothing_raised { user = Puppet.type(:user).create( :name => "pptestu", :home => file, :gid => "pptestg", :groups => "yayness" ) home = Puppet.type(:file).create( :path => file, :ensure => "directory" ) group = Puppet.type(:group).create( :name => "pptestg" ) ogroup = Puppet.type(:group).create( :name => "yayness" ) comp = newcomp(user, group, home, ogroup) } comp.finalize comp.retrieve assert(user.requires?(group), "User did not require group") assert(user.requires?(home), "User did not require home dir") assert(user.requires?(ogroup), "User did not require other groups") end def test_simpleuser name = "pptest" user = mkuser(name) comp = newcomp("usercomp", user) trans = assert_events([:user_created], comp, "user") assert_equal(user.should(:comment), user.provider.comment, "Comment was not set correctly") assert_rollback_events(trans, [:user_removed], "user") assert(! user.provider.exists?, "User did not get deleted") end def test_allusermodelstates user = nil name = "pptest" user = mkuser(name) assert(! user.provider.exists?, "User %s is present" % name) comp = newcomp("usercomp", user) trans = assert_events([:user_created], comp, "user") user.retrieve assert_equal("Puppet Testing User", user.provider.comment, "Comment was not set") tests = Puppet.type(:user).validstates tests.each { |test| if self.respond_to?("attrtest_%s" % test) self.send("attrtest_%s" % test, user) else Puppet.err "Not testing attr %s of user" % test end } user[:ensure] = :absent assert_apply(user) end end # $Id$ diff --git a/test/types/yumrepo.rb b/test/types/yumrepo.rb index f88525d1e..4a377c3ed 100644 --- a/test/types/yumrepo.rb +++ b/test/types/yumrepo.rb @@ -1,110 +1,103 @@ # Test the yumrepo type -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' -require 'test/unit' require 'fileutils' class TestYumRepo < Test::Unit::TestCase - include TestPuppet + include PuppetTest def setup super @yumdir = tempfile() Dir.mkdir(@yumdir) @yumconf = File.join(@yumdir, "yum.conf") File.open(@yumconf, "w") do |f| f.print "[main]\nreposdir=#{@yumdir} /no/such/dir\n" end Puppet.type(:yumrepo).yumconf = @yumconf end # Modify one existing section def test_modify copy_datafiles devel = make_repo("development", { :descr => "New description" }) devel.retrieve assert_equal("development", devel[:name]) assert_equal('Fedora Core $releasever - Development Tree', devel.state(:descr).is) assert_equal('New description', devel.state(:descr).should) assert_apply(devel) inifile = Puppet.type(:yumrepo).read() assert_equal('New description', inifile['development']['name']) assert_equal('Fedora Core $releasever - $basearch - Base', inifile['base']['name']) assert_equal(['base', 'development', 'main'], all_sections(inifile)) end # Create a new section def test_create values = { :descr => "Fedora Core $releasever - $basearch - Base", :baseurl => "http://example.com/yum/$releasever/$basearch/os/", :enabled => "1", :gpgcheck => "1", :includepkgs => "absent", :gpgkey => "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora" } repo = make_repo("base", values) assert_apply(repo) inifile = Puppet.type(:yumrepo).read() sections = all_sections(inifile) assert_equal(['base', 'main'], sections) text = inifile["base"].format assert_equal(CREATE_EXP, text) end # Delete mirrorlist by setting it to :absent and enable baseurl def test_absent copy_datafiles baseurl = 'http://example.com/' devel = make_repo("development", { :mirrorlist => 'absent', :baseurl => baseurl }) devel.retrieve assert_apply(devel) inifile = Puppet.type(:yumrepo).read() sec = inifile["development"] assert_nil(sec["mirrorlist"]) assert_equal(baseurl, sec["baseurl"]) end def make_repo(name, hash={}) hash[:name] = name Puppet.type(:yumrepo).create(hash) end def all_sections(inifile) sections = [] inifile.each_section { |section| sections << section.name } return sections.sort end def copy_datafiles fakedata("data/types/yumrepos").select { |file| file =~ /\.repo$/ }.each { |src| dst = File::join(@yumdir, File::basename(src)) FileUtils::copy(src, dst) } end CREATE_EXP = <<'EOF' [base] name=Fedora Core $releasever - $basearch - Base baseurl=http://example.com/yum/$releasever/$basearch/os/ enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora EOF end diff --git a/test/types/zone.rb b/test/types/zone.rb index 4370c300d..46f411ef3 100755 --- a/test/types/zone.rb +++ b/test/types/zone.rb @@ -1,437 +1,430 @@ # Test host job creation, modification, and destruction -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = "../.." -end - require 'puppettest' require 'puppet' require 'puppet/type/zone' -require 'test/unit' require 'facter' class TestZone < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_nothing end # Zones can only be tested on solaris. if Facter["operatingsystem"].value == "Solaris" def setup super @@zones = [] end def teardown current = %x{zoneadm list -cp}.split("\n").inject({}) { |h, line| ary = line.split(":") h[ary[1]] = ary[2] h } Puppet::Type.type(:zone).clear # Get rid of any lingering zones @@zones.each do |zone| next unless current.include? zone obj = Puppet::Type.type(:zone).create(:name => zone) obj[:ensure] = :absent assert_apply(obj) end # We can't delete the temp files until the zones are stopped and removed. super end def mkzone(name) zone = nil base = tempfile() Dir.mkdir(base) File.chmod(0700, base) root = File.join(base, "zonebase") assert_nothing_raised { zone = Puppet::Type.type(:zone).create( :name => name, :path => root, :ensure => "configured" # don't want to install zones automatically ) } @@zones << name return zone end def test_list list = nil assert_nothing_raised { list = Puppet::Type.type(:zone).list } assert(! list.empty?, "Got no zones back") assert(list.find { |z| z[:name] == "global" }, "Could not find global zone") end def test_valueslice zone = mkzone("slicetest") state = zone.state(:ensure) slice = nil assert_nothing_raised { slice = state.class.valueslice(:absent, :installed).collect do |o| o[:name] end } assert_equal([:configured, :installed], slice) assert_nothing_raised { slice = state.class.valueslice(:running, :installed).collect do |o| o[:name] end } assert_equal(slice, [:installed]) end # Make sure the ensure stuff behaves as we expect def test_zoneensure zone = mkzone("ensurezone") state = zone.state(:ensure) assert(state, "Did not get ensure state") assert_nothing_raised { zone.retrieve } assert(! state.insync?, "State is somehow in sync") assert(state.up?, "State incorrectly thinks it is not moving up") zone.is = [:ensure, :configured] zone[:ensure] = :installed assert(state.up?, "State incorrectly thinks it is not moving up") zone[:ensure] = :absent assert(! state.up?, "State incorrectly thinks it is moving up") end # Make sure all mentioned methods actually exist. def test_zonemethods_exist methods = [] zone = mkzone("methodtest") state = zone.state(:ensure) assert_nothing_raised { state.class.valueslice(:absent, :running).each do |st| [:up, :down].each do |m| if st[m] methods << st[m] end end end } methods.each do |m| assert(Puppet::Type.type(:zone).method_defined?(m), "Zones do not define method %s" % m) end end # Make sure our state generates the correct text. def test_inherit_state zone = mkzone("configtesting") zone[:ensure] = :configured assert_nothing_raised { zone[:inherit] = "/usr" } state = zone.state(:inherit) assert(zone, "Did not get 'inherit' state") assert_equal("add inherit-pkg-dir\nset dir=/usr\nend", state.configtext, "Got incorrect config text") state.is = "/usr" assert_equal("", state.configtext, "Got incorrect config text") # Now we want multiple directories state.should = %w{/usr /sbin /lib} # The statements are sorted text = "add inherit-pkg-dir set dir=/lib end add inherit-pkg-dir set dir=/sbin end" assert_equal(text, state.configtext, "Got incorrect config text") state.is = %w{/usr /sbin /lib} state.should = %w{/usr /sbin} text = "remove inherit-pkg-dir dir=/lib" assert_equal(text, state.configtext, "Got incorrect config text") end if Process.uid == 0 # Make sure our ensure process actually works. def test_ensure_sync zone = mkzone("ensuretesting") zone[:ensure] = :configured zone.retrieve assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not insync") end def test_getconfig zone = mkzone("configtesting") base = tempfile() zone[:path] = base ip = "192.168.0.1" interface = "bge0" zone[:ip] = "#{interface}:#{ip}" IO.popen("zonecfg -z configtesting -f -", "w") do |f| f.puts %{create -b set zonepath=#{tempfile()} set autoboot=true add inherit-pkg-dir set dir=/lib end add inherit-pkg-dir set dir=/platform end add inherit-pkg-dir set dir=/sbin end add inherit-pkg-dir set dir=/opt/csw end add inherit-pkg-dir set dir=/usr end add net set address=#{ip} set physical=bge0 end } end assert_equal(0, $?, "Did not successfully create zone") #@@zones << "configtesting" assert_nothing_raised { zone.send(:getconfig) } # Now, make sure everything is right. assert_equal(%w{/sbin /usr /opt/csw /lib /platform}.sort, zone.is(:inherit).sort, "Inherited dirs did not get collected correctly." ) assert_equal(["#{interface}:#{ip}"], zone.is(:ip), "IP addresses did not get collected correctly.") assert_equal(:true, zone.is(:autoboot), "Autoboot did not get collected correctly.") end # Make sure we can do all the various and sundry configuring things. def test_configuring_zones zone = mkzone("configtesting") assert_nothing_raised { zone[:inherit] = "/usr" } zone[:ensure] = :configured zone.retrieve assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not insync") # Now add a new directory to inherit assert_nothing_raised { zone[:inherit] = ["/sbin", "/usr"] } assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not insync") assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /dir: \/sbin/, "sbin was not added") # And then remove it. assert_nothing_raised { zone[:inherit] = "/usr" } assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not insync") assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /dir: \/sbin/, "sbin was not removed") # Now add an ip adddress. Fortunately (or not), zonecfg doesn't verify # that the interface exists. zone[:ip] = "hme0:192.168.0.1" zone.retrieve assert(! zone.insync?, "Zone is marked as in sync") assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not in sync") assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.1/, "ip was not added") zone[:ip] = ["hme1:192.168.0.2", "hme0:192.168.0.1"] assert_apply(zone) zone.retrieve assert(zone.insync?, "Zone is not in sync") assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} =~ /192.168.0.2/, "ip was not added") zone[:ip] = ["hme1:192.168.0.2"] assert_apply(zone) zone.retrieve assert(%x{/usr/sbin/zonecfg -z #{zone[:name]} info} !~ /192.168.0.1/, "ip was not removed") end # Test creating and removing a zone, but only up to the configured state, # so it's faster. def test_smallcreate zone = mkzone("smallcreate") # Include a bunch of stuff so the zone isn't as large dirs = %w{/usr /sbin /lib /platform} %w{/opt/csw}.each do |dir| dirs << dir if FileTest.exists? dir end zone[:inherit] = dirs assert(zone, "Did not make zone") zone[:ensure] = :configured assert(! zone.insync?, "Zone is incorrectly in sync") assert_apply(zone) assert_nothing_raised { zone.retrieve } assert(zone.insync?, "Zone is incorrectly out of sync") zone[:ensure] = :absent assert_apply(zone) zone.retrieve assert_equal(:absent, zone.is(:ensure), "Zone is not absent") end # Just go through each method linearly and make sure it works. def test_each_method zone = mkzone("methodtesting") dirs = %w{/usr /sbin /lib /platform} %w{/opt/csw}.each do |dir| dirs << dir if FileTest.exists? dir end zone[:inherit] = dirs [[:configure, :configured], [:install, :installed], [:start, :running], [:stop, :installed], [:uninstall, :configured], [:unconfigure, :absent] ].each do |method, state| Puppet.info "Testing %s" % method assert_nothing_raised { zone.retrieve } assert_nothing_raised { zone.send(method) } assert_nothing_raised { zone.retrieve } assert_equal(state, zone.is(:ensure), "Method %s did not correctly set state %s" % [method, state]) end end def test_mkzone zone = mkzone("testmaking") # Include a bunch of stuff so the zone isn't as large dirs = %w{/usr /sbin /lib /platform} %w{/opt/csw}.each do |dir| dirs << dir if FileTest.exists? dir end zone[:inherit] = dirs assert(zone, "Did not make zone") [:configured, :installed, :running, :installed, :absent].each do |value| assert_nothing_raised { zone[:ensure] = value } assert(! zone.insync?, "Zone is incorrectly in sync") assert_apply(zone) assert_nothing_raised { zone.retrieve } assert(zone.insync?, "Zone is incorrectly out of sync") end zone.retrieve assert_equal(:absent, zone.is(:ensure), "Zone is not absent") end end end end # $Id$ diff --git a/test/util/classgen.rb b/test/util/classgen.rb index 7b1b4731c..7f3cb23ca 100755 --- a/test/util/classgen.rb +++ b/test/util/classgen.rb @@ -1,69 +1,62 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestPuppetUtilClassGen < Test::Unit::TestCase - include TestPuppet + include PuppetTest class FakeBase class << self attr_accessor :name end end class GenTest class << self include Puppet::Util::ClassGen end end def test_genclass hash = {} name = "yayness" klass = nil assert_nothing_raised { klass = GenTest.genclass(name, :hash => hash, :parent => FakeBase) do class << self attr_accessor :name end end } assert(klass.respond_to?(:name), "Class did not execute block") assert(hash.include?(klass.name), "Class did not get added to hash") end # Make sure we call a preinithook, if there is one. def test_inithooks newclass = Class.new(FakeBase) do class << self attr_accessor :preinited, :postinited end def self.preinit self.preinited = true end def self.postinit self.postinited = true end end klass = nil assert_nothing_raised { klass = GenTest.genclass(:funtest, :parent => newclass) } assert(klass.preinited, "prehook did not get called") assert(klass.postinited, "posthook did not get called") end end # $Id$ diff --git a/test/util/execution.rb b/test/util/execution.rb index ec56c84bb..932e03807 100755 --- a/test/util/execution.rb +++ b/test/util/execution.rb @@ -1,37 +1,30 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestPuppetUtilExecution < Test::Unit::TestCase - include TestPuppet + include PuppetTest def test_withenv ENV["testing"] = "yay" assert_nothing_raised do Puppet::Util::Execution.withenv :testing => "foo" do $ran = ENV["testing"] end end assert_equal("yay", ENV["testing"]) assert_equal("foo", $ran) ENV["rah"] = "yay" assert_raise(ArgumentError) do Puppet::Util::Execution.withenv :testing => "foo" do raise ArgumentError, "yay" end end assert_equal("yay", ENV["rah"]) end end # $Id$ diff --git a/test/util/package.rb b/test/util/package.rb index 2d7f633de..bb5cd3c85 100755 --- a/test/util/package.rb +++ b/test/util/package.rb @@ -1,30 +1,23 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppet/util/package' require 'puppettest' -require 'test/unit' class TestPuppetUtilPackage < Test::Unit::TestCase - include TestPuppet + include PuppetTest include Puppet::Util::Package def test_versioncmp ary = %w{ 1.1.6 2.3 1.1a 3.0 1.5 1 2.4 1.1-4 2.3.1 1.2 2.3.0 1.1-3 2.4b 2.4 2.40.2 2.3a.1 3.1 0002 1.1-5 1.1.a 1.06} newary = nil assert_nothing_raised do newary = ary.sort { |a, b| versioncmp(a,b) } end assert_equal(["0002", "1", "1.06", "1.1-3", "1.1-4", "1.1-5", "1.1.6", "1.1.a", "1.1a", "1.2", "1.5", "2.3", "2.3.0", "2.3.1", "2.3a.1", "2.4", "2.4", "2.4b", "2.40.2", "3.0", "3.1"], newary) end end # $Id$ diff --git a/test/util/utiltest.rb b/test/util/utiltest.rb index 481b8a9fe..b3a356429 100755 --- a/test/util/utiltest.rb +++ b/test/util/utiltest.rb @@ -1,368 +1,361 @@ -if __FILE__ == $0 - $:.unshift '..' - $:.unshift '../../lib' - $puppetbase = ".." -end - require 'puppet' require 'puppettest' -require 'test/unit' class TestPuppetUtil < Test::Unit::TestCase - include TestPuppet + include PuppetTest # we're getting corrupt files, probably because multiple processes # are reading or writing the file at once # so we need to test that def test_multiwrite file = tempfile() File.open(file, "w") { |f| f.puts "starting" } value = {:a => :b} threads = [] sync = Sync.new 9.times { |a| threads << Thread.new { 9.times { |b| assert_nothing_raised { sync.synchronize(Sync::SH) { Puppet::Util.readlock(file) { |f| f.read } } sleep 0.01 sync.synchronize(Sync::EX) { Puppet::Util.writelock(file) { |f| f.puts "%s %s" % [a, b] } } } } } } threads.each { |th| th.join } end # First verify we can convert a known user def test_gidbyname %x{groups}.split(" ").each { |group| gid = nil assert_nothing_raised { gid = Puppet::Util.gid(group) } assert(gid, "Could not retrieve gid for %s" % group) assert(Puppet.type(:group)[group], "Util did not create %s" % group) } end # Then verify we can retrieve a known group by gid def test_gidbyid %x{groups}.split(" ").each { |group| obj = Puppet.type(:group).create( :name => group, :check => [:gid] ) obj.retrieve id = obj.is(:gid) gid = nil assert_nothing_raised { gid = Puppet::Util.gid(id) } assert(gid, "Could not retrieve gid for %s" % group) assert_equal(id, gid, "Got mismatched ids") } end # Finally, verify that we can find groups by id even if we don't # know them def test_gidbyunknownid gid = nil group = Process.gid assert_nothing_raised { gid = Puppet::Util.gid(group) } assert(gid, "Could not retrieve gid for %s" % group) assert_equal(group, gid, "Got mismatched ids") end def user require 'etc' unless defined? @user obj = Etc.getpwuid(Process.uid) @user = obj.name end return @user end # And do it all over again for users # First verify we can convert a known user def test_uidbyname user = user() uid = nil assert_nothing_raised { uid = Puppet::Util.uid(user) } assert(uid, "Could not retrieve uid for %s" % user) assert_equal(Process.uid, uid, "UIDs did not match") assert(Puppet.type(:user)[user], "Util did not create %s" % user) end # Then verify we can retrieve a known user by uid def test_uidbyid user = user() obj = Puppet.type(:user).create( :name => user, :check => [:uid] ) obj.retrieve id = obj.is(:uid) uid = nil assert_nothing_raised { uid = Puppet::Util.uid(id) } assert(uid, "Could not retrieve uid for %s" % user) assert_equal(id, uid, "Got mismatched ids") end # Finally, verify that we can find users by id even if we don't # know them def test_uidbyunknownid uid = nil user = Process.uid assert_nothing_raised { uid = Puppet::Util.uid(user) } assert(uid, "Could not retrieve uid for %s" % user) assert_equal(user, uid, "Got mismatched ids") end def test_withumask oldmask = File.umask path = tempfile() # FIXME this fails on FreeBSD with a mode of 01777 Puppet::Util.withumask(000) do Dir.mkdir(path, 0777) end assert(File.stat(path).mode & 007777 == 0777, "File has the incorrect mode") assert_equal(oldmask, File.umask, "Umask was not reset") end def test_benchmark path = tempfile() str = "yayness" File.open(path, "w") do |f| f.print "yayness" end # First test it with the normal args assert_nothing_raised do val = nil result = Puppet::Util.benchmark(:notice, "Read file") do val = File.read(path) end assert_equal(str, val) assert_instance_of(Float, result) end # Now test it with a passed object assert_nothing_raised do val = nil Puppet::Util.benchmark(Puppet, :notice, "Read file") do val = File.read(path) end assert_equal(str, val) end end unless Process.uid == 0 $stderr.puts "Run as root to perform Utility tests" def test_nothing end else def mknverify(file, user, group = nil, id = false) if File.exists?(file) File.unlink(file) end args = [] unless user or group args << nil end if user if id args << user.uid else args << user.name end end if group if id args << group.gid else args << group.name end end gid = nil if group gid = group.gid else gid = Process.gid end uid = nil if user uid = user.uid else uid = Process.uid end assert_nothing_raised { Puppet::Util.asuser(*args) { assert_equal(Process.euid, uid, "UID is %s instead of %s" % [Process.euid, uid] ) assert_equal(Process.egid, gid, "GID is %s instead of %s" % [Process.egid, gid] ) system("touch %s" % file) } } if uid == 0 #Puppet.warning "Not testing user" else #Puppet.warning "Testing user %s" % uid assert(File.exists?(file), "File does not exist") assert_equal(File.stat(file).uid, uid, "File is owned by %s instead of %s" % [File.stat(file).uid, uid] ) #system("ls -l %s" % file) end # I'm skipping these, because it seems so system dependent. #if gid == 0 # #Puppet.warning "Not testing group" #else # Puppet.warning "Testing group %s" % gid.inspect # system("ls -l %s" % file) # assert_equal(gid, File.stat(file).gid, # "File group is %s instead of %s" % # [File.stat(file).gid, gid] # ) #end assert_nothing_raised { File.unlink(file) } end def test_asuser file = File.join(tmpdir, "asusertest") @@tmpfiles << file [ [nil], # Nothing [nonrootuser()], # just user, by name [nonrootuser(), nil, true], # user, by uid [nonrootuser(), nonrootgroup()], # user and group, by name [nonrootuser(), nonrootgroup(), true], # user and group, by id ].each { |ary| mknverify(file, *ary) } end # Verify that we get reset back to the right user def test_asuser_recovery begin Puppet::Util.asuser(nonrootuser()) { raise "an error" } rescue end assert(Process.euid == 0, "UID did not get reset") end end def test_proxy klass = Class.new do attr_accessor :hash class << self attr_accessor :ohash end end klass.send(:include, Puppet::Util) klass.ohash = {} inst = klass.new inst.hash = {} assert_nothing_raised do Puppet::Util.proxy klass, :hash, "[]", "[]=", :clear, :delete end assert_nothing_raised do Puppet::Util.classproxy klass, :ohash, "[]", "[]=", :clear, :delete end assert_nothing_raised do inst[:yay] = "boo" inst["cool"] = :yayness end [:yay, "cool"].each do |var| assert_equal(inst.hash[var], inst[var], "Var %s did not take" % var) end assert_nothing_raised do klass[:Yay] = "boo" klass["Cool"] = :yayness end [:Yay, "Cool"].each do |var| assert_equal(inst.hash[var], inst[var], "Var %s did not take" % var) end end def test_symbolize ret = nil assert_nothing_raised { ret = Puppet::Util.symbolize("yayness") } assert_equal(:yayness, ret) assert_nothing_raised { ret = Puppet::Util.symbolize(:yayness) } assert_equal(:yayness, ret) assert_nothing_raised { ret = Puppet::Util.symbolize(43) } assert_equal(43, ret) assert_nothing_raised { ret = Puppet::Util.symbolize(nil) } assert_equal(nil, ret) end end # $Id$