diff --git a/HACKING b/HACKING index 74c9b310..5d713839 100644 --- a/HACKING +++ b/HACKING @@ -25,12 +25,17 @@ to see a code coverage report. One useful way to manually test virt-manager's UI is using libvirt's unit test driver. From the source directory, Launch virt-manager like: - virt-manager --connect test://$PWD/tests/testdriver.xml + virt-manager --connect test://$PWD/tests/testdriver.xml This testdriver has many fake XML definitions that can be used to see each bit of virt-manager's UI. It also enables testing the various wizards without having to alter your host virt config. +Also, there's a few standalone specialty tests: + + python setup.py test_urls : Test fetching media from distro URLs + python setup.py test_initrd_inject: Test --initrd-inject + Submitting patches ================== diff --git a/setup.py b/setup.py index 11248829..d61381c4 100755 --- a/setup.py +++ b/setup.py @@ -461,7 +461,8 @@ class TestCommand(TestBaseCommand): testfiles = [] for t in glob.glob(os.path.join(self._dir, 'tests', '*.py')): if (t.endswith("__init__.py") or - t.endswith("test_urls.py")): + t.endswith("test_urls.py") or + t.endswith("test_inject.py")): continue base = os.path.basename(t) @@ -509,6 +510,34 @@ class TestURLFetch(TestBaseCommand): TestBaseCommand.run(self) +class TestInitrdInject(TestBaseCommand): + description = "Test initrd inject with real kernels, fetched from URLs" + + user_options = TestBaseCommand.user_options + [ + ("distro=", None, "Comma separated list of distros to test, from " + "the tests internal URL dictionary.") + ] + + def initialize_options(self): + TestBaseCommand.initialize_options(self) + self.distro = "" + + def finalize_options(self): + TestBaseCommand.finalize_options(self) + orig = str(self.distro) + if not orig: + self.distro = [] + else: + self.distro = orig.split(",") + + def run(self): + self._testfiles = ["tests.test_inject"] + if self.distro: + import tests + tests.INITRD_TEST_DISTROS += self.distro + TestBaseCommand.run(self) + + class CheckPylint(Command): user_options = [] description = "Check code using pylint and pep8" @@ -598,5 +627,6 @@ setup( 'rpm': my_rpm, 'test': TestCommand, 'test_urls' : TestURLFetch, + 'test_initrd_inject' : TestInitrdInject, } ) diff --git a/tests/__init__.py b/tests/__init__.py index 967b4135..d6e45b54 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -71,3 +71,6 @@ virtconvert = _import("virtconvert", "virt-convert") # Variable used to store a local iso or dir path to check for a distro # Specified via 'python setup.py test_urls --path" URLTEST_LOCAL_MEDIA = [] + +# Used to implement test_initrd_inject --distro +INITRD_TEST_DISTROS = [] diff --git a/tests/clitest.py b/tests/clitest.py index 5814440c..472028b2 100644 --- a/tests/clitest.py +++ b/tests/clitest.py @@ -34,6 +34,10 @@ from tests import utils os.environ["VIRTCONV_TEST_NO_DISK_CONVERSION"] = "1" os.environ["LANG"] = "en_US.UTF-8" +# Used to ensure consistent SDL xml output +os.environ["HOME"] = "/tmp" +os.environ["DISPLAY"] = ":3.4" + _defaultconn = utils.open_testdefault() # Location @@ -895,9 +899,6 @@ def cleanup(): class CLITests(unittest.TestCase): - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - def setUp(self): global curtest curtest += 1 diff --git a/tests/inject-data/new-kickstart.ks b/tests/inject-data/new-kickstart.ks new file mode 100644 index 00000000..b68991c2 --- /dev/null +++ b/tests/inject-data/new-kickstart.ks @@ -0,0 +1,7 @@ +# Used for F18 and earlier + +keyboard us +lang en_US +network --bootproto=dhcp --onboot=on + +url --url http://HEY-THIS-IS-OUR-BAD-KICKSTART-URL.com/ diff --git a/tests/inject-data/old-kickstart.ks b/tests/inject-data/old-kickstart.ks new file mode 100644 index 00000000..0acf0bc0 --- /dev/null +++ b/tests/inject-data/old-kickstart.ks @@ -0,0 +1,5 @@ +# Used for F17 and earlier + +keyboard us +lang en_US +network --bootproto=ITREADTHEKICKSTART --onboot=on diff --git a/tests/test_inject.py b/tests/test_inject.py new file mode 100755 index 00000000..5275e7ba --- /dev/null +++ b/tests/test_inject.py @@ -0,0 +1,183 @@ +#!/usr/bin/python + +import atexit +import os +import sys +import unittest + +import urlgrabber + +from tests import INITRD_TEST_DISTROS +from tests import utils + +from virtinst import Guest +from virtinst import urlfetcher +from virtinst.distroinstaller import _perform_initrd_injections + +cleanup = [] +_alldistros = {} + +testconn = utils.open_testdefault() +guest = Guest(testconn) +guest.os.os_type = "hvm" +guest.os.arch = "x86_64" +meter = urlgrabber.progress.TextMeter(fo=sys.stdout) + +DEVFEDORA_URL = "http://download.fedoraproject.org/pub/fedora/linux/development/%s/%s/os/" +OLD_FEDORA_URL = "https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/%s/Fedora/%s/os/" +FEDORA_URL = "http://download.fedoraproject.org/pub/fedora/linux/releases/%s/Fedora/%s/os/" + + +def prompt(): + sys.stdout.write("(press enter to continue)") + return sys.stdin.readline() + + +class Distro(object): + def __init__(self, name, url, ks2=False, virtio=True): + self.name = name + self.url = url + self.virtio = virtio + + self.ks = "tests/inject-data/old-kickstart.ks" + if ks2: + self.ks = "tests/inject-data/new-kickstart.ks" + + self.kernel = None + self.initrd = None + + + + +def _add(*args, **kwargs): + _d = Distro(*args, **kwargs) + _alldistros[_d.name] = _d + + +_add("centos-4.9", "http://vault.centos.org/4.9/os/x86_64", + ks2=True, virtio=False) +_add("centos-5-latest", "http://ftp.linux.ncsu.edu/pub/CentOS/5/os/x86_64/") +_add("centos-6-latest", "http://ftp.linux.ncsu.edu/pub/CentOS/6/os/x86_64/") +_add("fedora-14", OLD_FEDORA_URL % ("14", "x86_64")) +_add("fedora-15", OLD_FEDORA_URL % ("15", "x86_64")) +_add("fedora-16", OLD_FEDORA_URL % ("16", "x86_64")) +_add("fedora-17", OLD_FEDORA_URL % ("17", "x86_64")) +_add("fedora-18", FEDORA_URL % ("18", "x86_64"), ks2=True) +_add("fedora-19", FEDORA_URL % ("19", "x86_64"), ks2=True) +_add("fedora-20", DEVFEDORA_URL % ("20", "x86_64"), ks2=True) + + +def exit_cleanup(): + for f in cleanup or []: + try: + os.unlink(f) + except: + pass +atexit.register(exit_cleanup) + + +def _fetch_distro(distro): + print "Fetching distro=%s" % distro.name + + fetcher = urlfetcher.fetcherForURI(distro.url, "/tmp", meter) + try: + fetcher.prepareLocation() + store = urlfetcher.getDistroStore(guest, fetcher) + kernel, initrd, ignore = store.acquireKernel(guest) + cleanup.append(kernel) + cleanup.append(initrd) + distro.kernel = kernel + distro.initrd = initrd + finally: + fetcher.cleanupLocation() + + +def _test_distro(distro): + originitrd = distro.initrd + kernel = distro.kernel + newinitrd = originitrd + ".copy" + injectfile = distro.ks + + os.system("cp -f %s %s" % (originitrd, newinitrd)) + cleanup.append(newinitrd) + _perform_initrd_injections(newinitrd, [injectfile], ".") + + nic = distro.virtio and "virtio" or "rtl8139" + append = "-append \"ks=file:/%s\"" % os.path.basename(injectfile) + print os.environ["DISPLAY"] + cmd = ("sudo qemu-kvm -enable-kvm -name %s " + "-cpu host -m 1500 -sdl " + "-net bridge,br=virbr0 -net nic,model=%s " + "-kernel %s -initrd %s %s" % + (distro.name, nic, kernel, newinitrd, append)) + print "\n\n" + cmd + os.system(cmd) + + +_printinitrd = False +_printfetch = False + + +class FetchTests(unittest.TestCase): + def setUp(self): + global _printfetch + if _printfetch: + return + print """ + + + +This is an interactive test. + +First step is we need to go and fetch a bunch of distro kernel/initrd +from public trees. This is going to take a while. Let it run then come +back later and we will be waiting to continue. + +""" + prompt() + _printfetch = True + + +class InjectTests(unittest.TestCase): + def setUp(self): + global _printinitrd + if _printinitrd: + return + print """ + + + +Okay, we have all the media. We are going to perform the initrd injection +of some stock kickstarts, then manually launch a qemu instance to verify +it's working. How you know it's working depends on the distro (look at +the qemu window title): + +RHEL4: Makes its way to the text installer, then chokes on our bogus URI +http://HEY-THIS-IS-OUR-BAD-KICKSTART-URL.com/ + +RHEL5, RHEL6, Fedora < 17: You'll get an error about a bogus bootproto +ITREADTHEKICKSTART. This means anaconda read our busted kickstart. + +Fedora >= 17: Chokes on the bogus URI in the early console screen when +fetching the installer squashfs image. + +""" + prompt() + _printinitrd = True + + +def _make_tests(): + def _make_fetch_cb(_d): + return lambda s: _fetch_distro(_d) + def _make_check_cb(_d): + return lambda s: _test_distro(_d) + + distros = INITRD_TEST_DISTROS or _alldistros.keys() + idx = 0 + for d in distros: + dobj = _alldistros[d] + idx += 1 + setattr(FetchTests, "testFetch%.3d" % idx, _make_fetch_cb(dobj)) + setattr(InjectTests, "testInitrd%.3d" % idx, _make_check_cb(dobj)) + +_make_tests() diff --git a/tests/utils.py b/tests/utils.py index 237f66ef..0bd3d070 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -30,10 +30,6 @@ from virtinst import VirtualVideoDevice # pylint: disable=W0212 # Access to protected member, needed to unittest stuff -# Used to ensure consistent SDL xml output -os.environ["HOME"] = "/tmp" -os.environ["DISPLAY"] = ":3.4" - _capsprefix = ",caps=%s/tests/capabilities-xml/" % os.getcwd() defaulturi = "__virtinst_test__test:///default,predictable" testuri = "test:///%s/tests/testdriver.xml" % os.getcwd() @@ -209,6 +205,8 @@ def get_basic_fullyvirt_guest(typ="xen", installer=None): g.installer.cdrom = True gdev = VirtualGraphics(_conn) gdev.type = "sdl" + gdev.display = ":3.4" + gdev.xauth = "/tmp/.Xauthority" g.add_device(gdev) g.features.pae = False g.vcpus = 5 diff --git a/tests/xmlconfig.py b/tests/xmlconfig.py index e4041b9a..e81f3af3 100644 --- a/tests/xmlconfig.py +++ b/tests/xmlconfig.py @@ -842,6 +842,8 @@ class TestXMLConfig(unittest.TestCase): gdev3 = virtinst.VirtualGraphics(g.conn) gdev3.type = "sdl" + gdev3.xauth = "/tmp/.Xauthority" + gdev3.display = ":3.4" gdev4 = virtinst.VirtualGraphics(g.conn) gdev4.type = "spice" gdev4.passwdValidTo = "foobar"