summaryrefslogtreecommitdiffstats
path: root/test/network/server
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2007-02-08 02:22:57 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2007-02-08 02:22:57 +0000
commita216df2bcb304ad379e152f2f59ef7d942f54f3b (patch)
treeeef3289c588cf44373fe959619d732c5a05ab7b5 /test/network/server
parent7e07e3dc843798bdbc7a03428ca054adaff2fb72 (diff)
downloadpuppet-a216df2bcb304ad379e152f2f59ef7d942f54f3b.tar.gz
puppet-a216df2bcb304ad379e152f2f59ef7d942f54f3b.tar.xz
puppet-a216df2bcb304ad379e152f2f59ef7d942f54f3b.zip
Okay, last file moves for the night. The test code has been moved to match the lib directory, and I have moved a couple of things into network/ instead of network/server, since they did not belong as much.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2180 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'test/network/server')
-rwxr-xr-xtest/network/server/authconfig.rb53
-rwxr-xr-xtest/network/server/authstore.rb211
-rwxr-xr-xtest/network/server/bucket.rb259
-rwxr-xr-xtest/network/server/ca.rb233
-rwxr-xr-xtest/network/server/fileserver.rb1024
-rwxr-xr-xtest/network/server/logger.rb179
-rwxr-xr-xtest/network/server/master.rb346
-rwxr-xr-xtest/network/server/report.rb185
-rwxr-xr-xtest/network/server/resource.rb296
-rwxr-xr-xtest/network/server/rights.rb37
-rwxr-xr-xtest/network/server/runner.rb106
-rwxr-xr-xtest/network/server/server.rb197
12 files changed, 3126 insertions, 0 deletions
diff --git a/test/network/server/authconfig.rb b/test/network/server/authconfig.rb
new file mode 100755
index 000000000..c48282973
--- /dev/null
+++ b/test/network/server/authconfig.rb
@@ -0,0 +1,53 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+
+require 'puppet/network/authconfig'
+
+class TestAuthConfig < Test::Unit::TestCase
+ 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::Network::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/network/server/authstore.rb b/test/network/server/authstore.rb
new file mode 100755
index 000000000..0dc804079
--- /dev/null
+++ b/test/network/server/authstore.rb
@@ -0,0 +1,211 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+
+require 'puppet/network/authstore'
+
+class TestAuthStore < Test::Unit::TestCase
+ include PuppetTest
+ def mkstore
+ store = nil
+ assert_nothing_raised {
+ store = Puppet::Network::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::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::AuthStoreError) {
+ store.allow("domain.*.com")
+ }
+
+ assert(!store.allowed?("very.long.domain.name.com", "1.2.3.4"),
+ "Long hostname allowed")
+
+ assert_raise(Puppet::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::AuthStoreError) {
+ # store.allow("192.168.674.0")
+ #}
+
+ assert_raise(Puppet::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/network/server/bucket.rb b/test/network/server/bucket.rb
new file mode 100755
index 000000000..c76e35be2
--- /dev/null
+++ b/test/network/server/bucket.rb
@@ -0,0 +1,259 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'base64'
+
+class TestBucket < Test::Unit::TestCase
+ 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::Network::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::Network::Server::FileBucket.new(
+ :Bucket => @bucket
+ )
+ }
+
+ #sleep(30)
+ assert_nothing_raised {
+ client = Puppet::Network::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::Network::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::Network::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/network/server/ca.rb b/test/network/server/ca.rb
new file mode 100755
index 000000000..31b4994a5
--- /dev/null
+++ b/test/network/server/ca.rb
@@ -0,0 +1,233 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppet/network/server/ca'
+require 'puppet/sslcertificates'
+
+# $Id$
+
+if ARGV.length > 0 and ARGV[0] == "short"
+ $short = true
+else
+ $short = false
+end
+
+class TestCA < Test::Unit::TestCase
+ 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::Network::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::Network::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::Network::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::Network::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::Network::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::Network::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/network/server/fileserver.rb b/test/network/server/fileserver.rb
new file mode 100755
index 000000000..4186f0e3b
--- /dev/null
+++ b/test/network/server/fileserver.rb
@@ -0,0 +1,1024 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/server/fileserver'
+
+class TestFileServer < Test::Unit::TestCase
+ 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::Network::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 {
+ 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::Network::Server::FileServer.new(
+ :Local => true,
+ :Config => false
+ )
+ }
+
+ assert_raise(Puppet::Network::Server::FileServerError) {
+ server.mount("/tmp", "invalid+name")
+ }
+
+ assert_raise(Puppet::Network::Server::FileServerError) {
+ server.mount("/tmp", "invalid-name")
+ }
+
+ assert_raise(Puppet::Network::Server::FileServerError) {
+ server.mount("/tmp", "invalid name")
+ }
+
+ assert_raise(Puppet::Network::Server::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::Network::Server::FileServer::CHECKPARAMS
+
+ # and make our fileserver
+ assert_nothing_raised {
+ server = Puppet::Network::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::Network::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::Network::Server::FileServer::CHECKPARAMS
+
+ assert_nothing_raised {
+ server = Puppet::Network::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::Network::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::Network::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::Network::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::Network::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 = tstdir()
+ files = mktestfiles(testdir)
+
+ file = nil
+ checks = Puppet::Network::Server::FileServer::CHECKPARAMS
+
+ assert_nothing_raised {
+ server = Puppet::Network::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::Network::Server::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)
+ Dir.mkdir(path)
+ 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::Network::Server::FileServer.new(
+ :Local => false,
+ :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::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::Network::Server::FileServer.new(
+ :Local => true,
+ :Config => conffile
+ )
+ }
+
+ assert_raise(Puppet::Network::Server::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::Network::Server::FileServerError,
+ "Invalid config %s did not raise error" % i) {
+ server = Puppet::Network::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::Network::Server::FileServer.new(
+ :Local => false,
+ :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::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::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::Network::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::Network::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::Network::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::Network::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::Network::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::Network::Server::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
+
+ # Test that the fileserver expands the %h and %d things.
+ def test_fileserver_expansion
+ server = nil
+ assert_nothing_raised {
+ server = Puppet::Network::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/network/server/logger.rb b/test/network/server/logger.rb
new file mode 100755
index 000000000..7298062ca
--- /dev/null
+++ b/test/network/server/logger.rb
@@ -0,0 +1,179 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'base64'
+require 'cgi'
+
+class TestLogger < Test::Unit::TestCase
+ include PuppetTest::ServerTest
+
+ def setup
+ super
+ #Puppet[:debug] = true
+ Puppet::Util::Log.newdestination :console
+ end
+
+ # Test the log driver manually
+ def test_localaddlog
+ logger = nil
+ assert_nothing_raised {
+ logger = Puppet::Network::Server::Logger.new
+ }
+
+ msg = nil
+ assert_nothing_raised {
+ msg = Puppet::Util::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::Network::Server::Logger.new
+ }
+
+ msg = nil
+ assert_nothing_raised {
+ msg = Puppet::Util::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::Network::Client::LogClient.new(:Logger => true)
+ }
+
+ msg = nil
+ assert_nothing_raised {
+ msg = Puppet::Util::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::Util::Log.newdestination clientlog
+ Puppet::Util::Log.close(:syslog)
+
+ # For testing
+ Puppet[:autosign] = true
+
+ logger = nil
+ # Create our server
+ assert_nothing_raised {
+ logger = Puppet::Network::Server.new(
+ :Port => @@port,
+ :Handlers => {
+ :CA => {}, # so that certs autogenerate
+ :Logger => {}
+ }
+ )
+ }
+
+ # Start our server
+ serverpid = fork {
+ Puppet::Util::Log.close(clientlog)
+ Puppet::Util::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::Network::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::Util::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::Util::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/network/server/master.rb b/test/network/server/master.rb
new file mode 100755
index 000000000..797e75e3d
--- /dev/null
+++ b/test/network/server/master.rb
@@ -0,0 +1,346 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/server'
+
+class TestMaster < Test::Unit::TestCase
+ 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::Network::Server::Master.new(
+ :Manifest => file,
+ :UseNodes => false,
+ :Local => true
+ )
+ }
+
+ # and our client
+ assert_nothing_raised() {
+ client = Puppet::Network::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::Network::Server::Master.new(
+ :Manifest => file,
+ :UseNodes => false,
+ :Local => true
+ )
+ }
+ assert_nothing_raised() {
+ client = Puppet::Network::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::Network::Server::Master.new(
+ :Manifest => manifest,
+ :UseNodes => false,
+ :Local => true
+ )
+ }
+ assert_nothing_raised() {
+ client = Puppet::Network::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")
+
+ Puppet.config.use(:puppet)
+ 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::Network::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.value("hostname")
+
+ 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::Network::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
+
+ # Make sure we're correctly doing clientname manipulations.
+ # Testing to make sure we always get a hostname and IP address.
+ def test_clientname
+ master = nil
+ file = tempfile()
+
+ File.open(file, "w") { |f|
+ f.puts %{
+ node yay { file { "/something": ensure => file, mode => 755 } }
+}
+ }
+ # create our master
+ assert_nothing_raised() {
+ # this is the default server setup
+ master = Puppet::Network::Server::Master.new(
+ :Manifest => file,
+ :UseNodes => true,
+ :Local => true
+ )
+ }
+
+ Puppet[:node_name] = "cert"
+ # First act like we're local
+ fakename = nil
+ fakeip = nil
+
+ name = ip = nil
+ facts = Facter.to_hash
+ assert_nothing_raised do
+ name, ip = master.clientname(fakename, fakeip, facts)
+ end
+
+ assert(facts["hostname"], "Removed hostname fact")
+ assert(facts["ipaddress"], "Removed ipaddress fact")
+
+ assert_equal(facts["hostname"], name)
+ assert_equal(facts["ipaddress"], ip)
+
+ # Now set them to something real, and make sure we get them back
+ fakename = "yayness"
+ fakeip = "192.168.0.1"
+ facts = Facter.to_hash
+ assert_nothing_raised do
+ name, ip = master.clientname(fakename, fakeip, facts)
+ end
+
+ assert(facts["hostname"], "Removed hostname fact")
+ assert(facts["ipaddress"], "Removed ipaddress fact")
+
+ assert_equal(fakename, name)
+ assert_equal(fakeip, ip)
+ end
+
+ if Puppet.features.rails?
+ def test_freshness_connect_update
+ Puppet::Rails.init
+ Puppet[:storeconfigs] = true
+
+ # this is the default server setup
+ master = Puppet::Network::Server::Master.new(
+ :Code => "",
+ :UseNodes => true,
+ :Local => true
+ )
+
+ # Create a host
+ Puppet::Rails::Host.new(:name => "test", :ip => "192.168.0.3").save
+
+ assert_nothing_raised("Failed to update last_connect for unknown host") do
+ master.freshness("created",'192.168.0.1')
+ end
+
+ # Make sure it created the host
+ created = Puppet::Rails::Host.find_by_name("created")
+ assert(created, "Freshness did not create host")
+ assert(created.last_freshcheck,
+ "Did not set last_freshcheck on created host")
+ assert_equal("192.168.0.1", created.ip,
+ "Did not set IP address on created host")
+
+ # Now check on the existing host
+ assert_nothing_raised("Failed to update last_connect for unknown host") do
+ master.freshness("test",'192.168.0.2')
+ end
+
+ # Recreate it, so we're not using the cached object.
+ host = Puppet::Rails::Host.find_by_name("test")
+
+ # Make sure it created the host
+ assert(host.last_freshcheck,
+ "Did not set last_freshcheck on existing host")
+ assert_equal("192.168.0.3", host.ip,
+ "Overrode IP on found host")
+ end
+ end
+end
+
+# $Id$
+
diff --git a/test/network/server/report.rb b/test/network/server/report.rb
new file mode 100755
index 000000000..f61d9f6d4
--- /dev/null
+++ b/test/network/server/report.rb
@@ -0,0 +1,185 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/server/report'
+require 'puppettest/reporttesting'
+
+class TestReportServer < Test::Unit::TestCase
+ include PuppetTest
+ include PuppetTest::Reporttesting
+
+ Report = Puppet::Network::Server::Report
+ Puppet::Util.logmethods(self)
+
+ def mkserver
+ server = nil
+ assert_nothing_raised {
+ server = Puppet::Network::Server::Report.new()
+ }
+ server
+ end
+
+ def mkclient(server = nil)
+ server ||= mkserver()
+ client = nil
+ assert_nothing_raised {
+ client = Puppet::Network::Client::Reporter.new(:Report => server)
+ }
+
+ client
+ 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::Network::Server::Report.newreport(:myreport) do
+ def process(report)
+ $myreportrun = true
+ return report
+ end
+ end
+ }
+ }
+ Puppet[:reports] = "myreport"
+
+ # Create a server
+ server = Puppet::Network::Server::Report.new
+
+ report = nil
+ assert_nothing_raised {
+ report = Puppet::Network::Server::Report.report(:myreport)
+ }
+ assert(report, "Did not get report")
+
+ end
+
+ def test_process
+ server = Puppet::Network::Server::Report.new
+
+ # We have to run multiple reports to make sure there's no conflict
+ reports = []
+ $run = []
+ 5.times do |i|
+ name = "processtest%s" % i
+ reports << name
+
+ Report.newreport(name) do
+ def process
+ $run << self.report_name
+ end
+ end
+ end
+ Puppet[:reports] = reports.collect { |r| r.to_s }.join(",")
+
+ report = fakereport
+
+ retval = nil
+ assert_nothing_raised {
+ retval = server.send(:process, YAML.dump(report))
+ }
+
+ reports.each do |name|
+ assert($run.include?(name.intern), "Did not run %s" % name)
+ end
+
+ # Now make sure our server doesn't die on missing reports
+ Puppet[:reports] = "fakereport"
+ assert_nothing_raised {
+ retval = server.send(:process, YAML.dump(report))
+ }
+ end
+
+ # Make sure reports can specify whether to use yaml or not
+ def test_useyaml
+ server = Puppet::Network::Server::Report.new
+
+ Report.newreport(:yamlyes, :useyaml => true) do
+ def process(report)
+ $yamlyes = :yesyaml
+ end
+ end
+
+ Report.newreport(:yamlno) do
+ def process
+ $yamlno = :noyaml
+ end
+ end
+
+ Puppet[:reports] = "yamlyes, yamlno"
+
+ report = fakereport
+ yaml = YAML.dump(report)
+
+ assert_nothing_raised do
+ server.send(:process, yaml)
+ end
+
+ assert_equal(:noyaml, $yamlno, "YAML was used for non-yaml report")
+ assert_equal(:yesyaml, $yamlyes, "YAML was not used for yaml report")
+ end
+
+ def test_reports
+ Puppet[:reports] = "myreport"
+
+ # Create a server
+ server = Puppet::Network::Server::Report.new
+
+ {"myreport" => ["myreport"],
+ " fake, another, yay " => ["fake", "another", "yay"]
+ }.each do |str, ary|
+ Puppet[:reports] = str
+ assert_equal(ary, server.send(:reports))
+ end
+ end
+
+ def test_newreport
+ name = :newreporttest
+ assert_nothing_raised do
+ Report.newreport(name) do
+ attr_accessor :processed
+
+ def process(report)
+ @processed = report
+ end
+ end
+ end
+
+ assert(Report.report(name), "Did not get report")
+ assert_instance_of(Module, Report.report(name))
+
+ obj = "yay"
+ obj.extend(Report.report(name))
+
+ assert_nothing_raised do
+ obj.process("yay")
+ end
+
+ assert_equal("yay", obj.processed)
+ end
+
+ # Make sure we get a list of all reports
+ def test_report_list
+ list = nil
+ assert_nothing_raised do
+ list = Puppet::Network::Server::Report.reports
+ end
+
+ [:rrdgraph, :store, :tagmail].each do |name|
+ assert(list.include?(name), "Did not load %s" % name)
+ end
+ end
+end
+
+# $Id$
+
diff --git a/test/network/server/resource.rb b/test/network/server/resource.rb
new file mode 100755
index 000000000..579bc609a
--- /dev/null
+++ b/test/network/server/resource.rb
@@ -0,0 +1,296 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/server/resource'
+require 'base64'
+require 'cgi'
+
+class TestResourceServer < Test::Unit::TestCase
+ 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::Network::Server::Resource.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 |property|
+ assert(object.should(property), "Did not retrieve %s" % property)
+ end
+
+ ignore.each do |property|
+ assert(! object.should(property), "Incorrectly retrieved %s" % property)
+ 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::Network::Server::Resource.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 |property|
+ assert(object.should(property), "Did not retrieve %s" % property)
+ end
+
+ ignore.each do |property|
+ assert(! object.should(property), "Incorrectly retrieved %s" % property)
+ 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(basedir,
+ # "test/data/types/ports/1")
+ #Puppet.err Puppet::Type::ParsedType::Port.path
+ server = nil
+ assert_nothing_raised do
+ server = Puppet::Network::Server::Resource.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::Network::Server::Resource.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
+
+ bucket = Puppet::TransBucket.new
+ bucket.type = "file"
+ bucket.push filetrans
+
+ 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)
+ objects = nil
+ assert_nothing_raised("Could not reload yaml") {
+ YAML::load(Base64.decode64(yaml))
+ }
+
+ # The server is supposed to accept yaml and execute it.
+ assert_nothing_raised {
+ server.apply(yaml)
+ }
+ assert(FileTest.exists?(file), "File did not get recreated from YAML")
+ end
+end
+
+# $Id$
diff --git a/test/network/server/rights.rb b/test/network/server/rights.rb
new file mode 100755
index 000000000..cee0fb9aa
--- /dev/null
+++ b/test/network/server/rights.rb
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/rights'
+
+class TestRights < Test::Unit::TestCase
+ include PuppetTest
+
+ def test_rights
+ store = nil
+ assert_nothing_raised {
+ store = Puppet::Network::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/network/server/runner.rb b/test/network/server/runner.rb
new file mode 100755
index 000000000..ce782298a
--- /dev/null
+++ b/test/network/server/runner.rb
@@ -0,0 +1,106 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppet/network/server/runner'
+require 'puppettest'
+
+class TestServerRunner < Test::Unit::TestCase
+ include PuppetTest
+
+ def mkclient(file)
+ master = nil
+ client = nil
+ # create our master
+ assert_nothing_raised() {
+ # this is the default server setup
+ master = Puppet::Network::Server::Master.new(
+ :Manifest => file,
+ :UseNodes => false,
+ :Local => true
+ )
+ }
+
+ # and our client
+ assert_nothing_raised() {
+ client = Puppet::Network::Client::MasterClient.new(
+ :Master => master
+ )
+ }
+
+ client
+ end
+
+ def test_runner
+ FileUtils.mkdir_p(Puppet[:statedir])
+ 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::Network::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],
+ ["with no tags",
+ "", 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/network/server/server.rb b/test/network/server/server.rb
new file mode 100755
index 000000000..3e5e7b717
--- /dev/null
+++ b/test/network/server/server.rb
@@ -0,0 +1,197 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppettest'
+require 'puppet/network/server'
+
+if ARGV.length > 0 and ARGV[0] == "short"
+ $short = true
+else
+ $short = false
+end
+
+class TestServer < Test::Unit::TestCase
+ 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::Network::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::Network::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::Network::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::Network::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::Network::Client::StatusClient.new(
+ :Server => "localhost",
+ :Port => @@port
+ )
+ }
+ client
+ end
+
+ def mk_status_server
+ server = nil
+ assert_nothing_raised() {
+ server = Puppet::Network::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
+
+# $Id$