diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-02-08 02:22:57 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2007-02-08 02:22:57 +0000 |
| commit | a216df2bcb304ad379e152f2f59ef7d942f54f3b (patch) | |
| tree | eef3289c588cf44373fe959619d732c5a05ab7b5 /test/network/server/fileserver.rb | |
| parent | 7e07e3dc843798bdbc7a03428ca054adaff2fb72 (diff) | |
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/fileserver.rb')
| -rwxr-xr-x | test/network/server/fileserver.rb | 1024 |
1 files changed, 1024 insertions, 0 deletions
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$ + |
