summaryrefslogtreecommitdiffstats
path: root/tests/tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tests.py')
-rw-r--r--tests/tests.py286
1 files changed, 266 insertions, 20 deletions
diff --git a/tests/tests.py b/tests/tests.py
index 99ba0b9..4060eef 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -2,22 +2,13 @@
#
# Michael DeHaan <mdehaan@redhat.com>
-TRY_GRAPH = False
-HAS_GRAPH = False
-
-if TRY_GRAPH:
- try:
- import pycallgraph_mod as pycallgraph
- HAS_GRAPH = True
- except:
- pass
-
import sys
import unittest
import os
import subprocess
import tempfile
import shutil
+import traceback
from cobbler.cexceptions import *
@@ -25,6 +16,7 @@ from cobbler import settings
from cobbler import collection_distros
from cobbler import collection_profiles
from cobbler import collection_systems
+import cobbler.modules.authz_ownership as authz_module
from cobbler import api
@@ -54,11 +46,11 @@ class BootTest(unittest.TestCase):
except:
pass
- self.fk_initrd = os.path.join(self.topdir, FAKE_INITRD)
+ self.fk_initrd = os.path.join(self.topdir, FAKE_INITRD)
self.fk_initrd2 = os.path.join(self.topdir, FAKE_INITRD2)
self.fk_initrd3 = os.path.join(self.topdir, FAKE_INITRD3)
- self.fk_kernel = os.path.join(self.topdir, FAKE_KERNEL)
+ self.fk_kernel = os.path.join(self.topdir, FAKE_KERNEL)
self.fk_kernel2 = os.path.join(self.topdir, FAKE_KERNEL2)
self.fk_kernel3 = os.path.join(self.topdir, FAKE_KERNEL3)
@@ -75,9 +67,6 @@ class BootTest(unittest.TestCase):
shutil.rmtree(self.topdir,ignore_errors=True)
self.api = None
- if HAS_GRAPH:
- pycallgraph.save_dot("%s.dot" % self.__class__.__name__)
-
def make_basic_config(self):
distro = self.api.new_distro()
self.assertTrue(distro.set_name("testdistro0"))
@@ -85,7 +74,7 @@ class BootTest(unittest.TestCase):
self.assertTrue(distro.set_initrd(self.fk_initrd))
self.assertTrue(self.api.add_distro(distro))
self.assertTrue(self.api.find_distro(name="testdistro0"))
-
+
profile = self.api.new_profile()
self.assertTrue(profile.set_name("testprofile0"))
self.assertTrue(profile.set_distro("testdistro0"))
@@ -96,10 +85,271 @@ class BootTest(unittest.TestCase):
system = self.api.new_system()
self.assertTrue(system.set_name("drwily.rdu.redhat.com"))
self.assertTrue(system.set_mac_address("BB:EE:EE:EE:EE:FF","intf0"))
+ self.assertTrue(system.set_ip_address("192.51.51.50","intf0"))
self.assertTrue(system.set_profile("testprofile0"))
self.assertTrue(self.api.add_system(system))
self.assertTrue(self.api.find_system(name="drwily.rdu.redhat.com"))
+ repo = self.api.new_repo()
+ try:
+ os.makedirs("/tmp/test_example_cobbler_repo")
+ except:
+ pass
+ fd = open("/tmp/test_example_cobbler_repo/test.file", "w+")
+ fd.write("hello!")
+ fd.close()
+ self.assertTrue(repo.set_name("test_repo"))
+ self.assertTrue(repo.set_mirror("/tmp/test_example_cobbler_repo"))
+ self.assertTrue(self.api.repos().add(repo))
+
+class DuplicateNamesAndIpPrevention(BootTest):
+
+ """
+ The command line (and WebUI) have checks to prevent new system
+ additions from conflicting with existing systems and overwriting
+ them inadvertantly. This class tests that code. NOTE: General API
+ users will /not/ encounter these checks.
+ """
+
+ def test_duplicate_prevention(self):
+
+ # find things we are going to test with
+ distro1 = self.api.find_distro(name="testdistro0")
+ profile1 = self.api.find_profile(name="testprofile0")
+ system1 = self.api.find_system(name="drwily.rdu.redhat.com")
+ repo1 = self.api.find_repo(name="test_repo")
+
+ # make sure we can't overwrite a previous distro with
+ # the equivalent of an "add" (not an edit) on the
+ # command line.
+ distro2 = self.api.new_distro()
+ self.assertTrue(distro2.set_name("testdistro0"))
+ self.assertTrue(distro2.set_kernel(self.fk_kernel))
+ self.assertTrue(distro2.set_initrd(self.fk_initrd))
+ self.assertTrue(distro2.set_owners("canary"))
+ # this should fail
+ try:
+ self.api.add_distro(distro2,check_for_duplicate_names=True)
+ self.assertTrue(1==2,"distro add should fail")
+ except CobblerException:
+ pass
+ except:
+ self.assertTrue(1==2,"exception type")
+ # we caught the exception but make doubly sure there was no write
+ distro_check = self.api.find_distro(name="testdistro0")
+ self.assertTrue("canary" not in distro_check.owners)
+
+ # repeat the check for profiles
+ profile2 = self.api.new_profile()
+ self.assertTrue(profile2.set_name("testprofile0"))
+ self.assertTrue(profile2.set_distro("testdistro0"))
+ # this should fail
+ try:
+ self.api.add_profile(profile2,check_for_duplicate_names=True)
+ self.assertTrue(1==2,"profile add should fail")
+ except CobblerException:
+ pass
+ except:
+ traceback.print_exc()
+ self.assertTrue(1==2,"exception type")
+
+ # repeat the check for systems (just names this time)
+ system2 = self.api.new_system()
+ self.assertTrue(system2.set_name("drwily.rdu.redhat.com"))
+ self.assertTrue(system2.set_profile("testprofile0"))
+ # this should fail
+ try:
+ self.api.add_system(system2,check_for_duplicate_names=True)
+ self.assertTrue(1==2,"system add should fail")
+ except CobblerException:
+ pass
+ except:
+ traceback.print_exc()
+ self.assertTrue(1==2,"exception type")
+
+ # repeat the check for repos
+ repo2 = self.api.new_repo()
+ self.assertTrue(repo2.set_name("test_repo"))
+ self.assertTrue(repo2.set_mirror("http://imaginary"))
+ # self.failUnlessRaises(CobblerException,self.api.add_repo,[repo,check_for_duplicate_names=True])
+ try:
+ self.api.add_repo(repo2,check_for_duplicate_names=True)
+ self.assertTrue(1==2,"repo add should fail")
+ except CobblerException:
+ pass
+ except:
+ self.assertTrue(1==2,"exception type")
+
+ # now one more check to verify we can't add a system
+ # of a different name but duplicate netinfo.
+ system3 = self.api.new_system()
+ self.assertTrue(system3.set_name("unused_name"))
+ self.assertTrue(system3.set_profile("testprofile0"))
+ # MAC is initially accepted
+ self.assertTrue(system3.set_mac_address("BB:EE:EE:EE:EE:FF","intf3"))
+ # can't add as this MAC already exists!
+
+ #self.failUnlessRaises(CobblerException,self.api.add_system,[system3,check_for_duplicate_names=True,check_for_duplicate_netinfo=True)
+ try:
+ self.api.add_system(system3,check_for_duplicate_names=True,check_for_duplicate_netinfo=True)
+ except CobblerException:
+ pass
+ except:
+ traceback.print_exc()
+ self.assertTrue(1==2,"wrong exception type")
+
+ # set the MAC to a different value and try again
+ self.assertTrue(system3.set_mac_address("FF:EE:EE:EE:EE:DD","intf3"))
+ # it should work
+ self.assertTrue(self.api.add_system(system3,check_for_duplicate_names=True,check_for_duplicate_netinfo=True))
+ # now set the IP so that collides
+ self.assertTrue(system3.set_ip_address("192.51.51.50","intf6"))
+ # this should also fail
+
+ # self.failUnlessRaises(CobblerException,self.api.add_system,[system3,check_for_duplicate_names=True,check_for_duplicate_netinfo=True)
+ try:
+ self.api.add_system(system3,check_for_duplicate_names=True,check_for_duplicate_netinfo=True)
+ self.assertTrue(1==2,"system add should fail")
+ except CobblerException:
+ pass
+ except:
+ self.assertTrue(1==2,"wrong exception type")
+
+ # fix the IP and Mac back
+ self.assertTrue(system3.set_ip_address("192.86.75.30","intf6"))
+ self.assertTrue(system3.set_mac_address("AE:BE:DE:CE:AE:EE","intf3"))
+ # now it works again
+ # note that we will not check for duplicate names as we want
+ # to test this as an 'edit' operation.
+ self.assertTrue(self.api.add_system(system3,check_for_duplicate_names=False,check_for_duplicate_netinfo=True))
+
+ # FIXME: note -- how netinfo is handled when doing renames/copies/edits
+ # is more involved and we probably should add tests for that also.
+
+class Ownership(BootTest):
+
+ def test_ownership_params(self):
+
+ fd = open("/tmp/test_cobbler_kickstart","w+")
+ fd.write("")
+ fd.close()
+
+ # find things we are going to test with
+ distro = self.api.find_distro(name="testdistro0")
+ profile = self.api.find_profile(name="testprofile0")
+ system = self.api.find_system(name="drwily.rdu.redhat.com")
+ repo = self.api.find_repo(name="test_repo")
+
+ # as we didn't specify an owner for objects, the default
+ # ownership should be as specified in settings
+ default_owner = self.api.settings().default_ownership
+ for obj in [ distro, profile, system, repo ]:
+ self.assertTrue(obj is not None)
+ self.assertEquals(obj.owners, default_owner, "default owner for %s" % obj)
+
+ # verify we can test things
+ self.assertTrue(distro.set_owners(["superlab","basement1"]))
+ self.assertTrue(profile.set_owners(["superlab","basement1"]))
+ self.assertTrue(profile.set_kickstart("/tmp/test_cobbler_kickstart"))
+ self.assertTrue(system.set_owners(["superlab","basement1","basement3"]))
+ self.assertTrue(repo.set_owners([]))
+ self.api.add_distro(distro)
+ self.api.add_profile(profile)
+ self.api.add_system(system)
+ self.api.add_repo(repo)
+
+ # now edit the groups file. We won't test the full XMLRPC
+ # auth stack here, but just the module in question
+
+ authorize = authz_module.authorize
+
+ # if the users.conf file exists, back it up for the tests
+ if os.path.exists("/etc/cobbler/users.conf"):
+ shutil.copyfile("/etc/cobbler/users.conf","/tmp/cobbler_ubak")
+
+ fd = open("/etc/cobbler/users.conf","w+")
+ fd.write("\n")
+ fd.write("[admins]\n")
+ fd.write("admin1 = 1\n")
+ fd.write("\n")
+ fd.write("[superlab]\n")
+ fd.write("superlab1 = 1\n")
+ fd.write("superlab2 = 1\n")
+ fd.write("\n")
+ fd.write("[basement]\n")
+ fd.write("basement1 = 1\n")
+ fd.write("basement2 = 1\n")
+ fd.write("basement3 = 1\n")
+ fd.close()
+
+
+ xo = self.api.find_distro("testdistro0")
+ xn = "testdistro0"
+ ro = self.api.find_repo("test_repo")
+ rn = "test_repo"
+
+ # WARNING: complex test explanation follows!
+ # we must ensure those who can edit the kickstart are only those
+ # who can edit all objects that depend on the said kickstart
+ # in this test, superlab & basement1 can edit test_profile0
+ # superlab & basement1/3 can edit test_system0
+ # the systems share a common kickstart record (in this case
+ # explicitly set, which is a bit arbitrary as they are parent/child
+ # nodes, but the concept is not limited to this).
+ # Therefore the correct result is that the following users can edit:
+ # admin1, superlab1, superlab2
+ # And these folks can't
+ # basement1, basement2
+ # Basement2 is rejected because the kickstart is shared by something
+ # basmeent2 can not edit.
+
+ for user in [ "admin1", "superlab1", "superlab2", "basement1" ]:
+ self.assertTrue(1==authorize(self.api, user, "modify_kickstart", "/tmp/test_cobbler_kickstart"), "%s can modify_kickstart" % user)
+
+ for user in [ "basement2", "dne" ]:
+ self.assertTrue(0==authorize(self.api, user, "modify_kickstart", "/tmp/test_cobbler_kickstart"), "%s can modify_kickstart" % user)
+
+ # ensure admin1 can edit (he's an admin) and do other tasks
+ # same applies to basement1 who is explicitly added as a user
+ # and superlab1 who is in a group in the ownership list
+ for user in ["admin1","superlab1","basement1"]:
+ self.assertTrue(1==authorize(self.api, user, "save_distro", xo),"%s can save_distro" % user)
+ self.assertTrue(1==authorize(self.api, user, "modify_distro", xo),"%s can modify_distro" % user)
+ self.assertTrue(1==authorize(self.api, user, "copy_distro", xo),"%s can copy_distro" % user)
+ self.assertTrue(1==authorize(self.api, user, "remove_distro", xn),"%s can remove_distro" % user)
+
+ # ensure all users in the file can sync
+ for user in [ "admin1", "superlab1", "basement1", "basement2" ]:
+ self.assertTrue(1==authorize(self.api, user, "sync"))
+
+ # make sure basement2 can't edit (not in group)
+ # and same goes for "dne" (does not exist in users.conf)
+
+ for user in [ "basement2", "dne" ]:
+ self.assertTrue(0==authorize(self.api, user, "save_distro", xo), "user %s cannot save_distro" % user)
+ self.assertTrue(0==authorize(self.api, user, "modify_distro", xo), "user %s cannot modify_distro" % user)
+ self.assertTrue(0==authorize(self.api, user, "remove_distro", xn), "user %s cannot remove_distro" % user)
+
+ # basement2 is in the file so he can still copy
+ self.assertTrue(1==authorize(self.api, "basement2", "copy_distro", xo), "basement2 can copy_distro")
+
+ # dne can not copy or sync either (not in the users.conf)
+ self.assertTrue(0==authorize(self.api, "dne", "copy_distro", xo), "dne cannot copy_distro")
+ self.assertTrue(0==authorize(self.api, "dne", "sync"), "dne cannot sync")
+
+ # unlike the distro testdistro0, testrepo0 is unowned
+ # so any user in the file will be able to edit it.
+ for user in [ "admin1", "superlab1", "basement1", "basement2" ]:
+ self.assertTrue(1==authorize(self.api, user, "save_repo", ro), "user %s can save_repo" % user)
+
+ # though dne is still not listed and will be denied
+ self.assertTrue(0==authorize(self.api, "dne", "save_repo", ro), "dne cannot save_repo")
+
+ # if we survive, restore the users file as module testing is done
+ if os.path.exists("/tmp/cobbler_ubak"):
+ shutil.copyfile("/etc/cobbler/users.conf","/tmp/cobbler_ubak")
+
+
class MultiNIC(BootTest):
def test_multi_nic_support(self):
@@ -577,14 +827,10 @@ if __name__ == "__main__":
if not os.path.exists("setup.py"):
print "tests: must invoke from top level directory"
sys.exit(1)
- if HAS_GRAPH:
- pycallgraph.start_trace()
loader = unittest.defaultTestLoader
test_module = __import__("tests") # self import considered harmful?
tests = loader.loadTestsFromModule(test_module)
runner = unittest.TextTestRunner()
runner.run(tests)
- if HAS_GRAPH:
- pycallgraph.make_graph('cg_dot.png', tool='dot')
sys.exit(0)