← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/maas/real-cobbler into lp:maas

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/real-cobbler into lp:maas.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/real-cobbler/+merge/97813

Shaving a yak for another ongoing branch.  We have tests that are run against a fake cobbler but also optionally against a real one, but now I need to add more of those.

What I do here is not a full-blown generic framework for doing that.  But it does extract a coherent portion of the work: a Cobbler “test session factory” that helps you explain to the unit-test framework whether to run your tests against a real Cobbler, and if so, produces the sessions for you.

How is that not a complete framework?  Well, Gavin came up with some helpers for producing Cobbler-side objects and automatically cleaning them up afterwards.  It would be great to generalize that, but I didn't find it necessary for this particular case.  (Unless Cobbler suddenly starts accepting a random auth token, but for now I'm willing to take the chance.)
-- 
https://code.launchpad.net/~jtv/maas/real-cobbler/+merge/97813
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/real-cobbler into lp:maas.
=== added file 'src/provisioningserver/testing/realcobbler.py'
--- src/provisioningserver/testing/realcobbler.py	1970-01-01 00:00:00 +0000
+++ src/provisioningserver/testing/realcobbler.py	2012-03-16 09:07:30 +0000
@@ -0,0 +1,67 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Set up test sessions against real Cobblers."""
+
+from __future__ import (
+    print_function,
+    unicode_literals,
+    )
+
+__metaclass__ = type
+__all__ = [
+    'RealCobbler',
+    ]
+
+from os import environ
+from urlparse import urlparse
+
+from provisioningserver.cobblerclient import CobblerSession
+
+
+class RealCobbler:
+    """Factory for test sessions on a real Cobbler instance, if available.
+
+    To enable tests, set the PSERV_TEST_COBBLER_URL environment variable to
+    point to the real Cobbler instance you want to test against.  The URL
+    should include username and password if required.
+
+    Warning: this will mess with your Cobbler database.  Never do this with
+    a production machine.
+    """
+
+    env_var = 'PSERV_TEST_COBBLER_URL'
+
+    help_text = """
+        Set %s to the URL for a Cobbler instance to test against,
+        e.g. http://username:password@localhost/cobbler_api.
+        WARNING: this will modify your Cobbler database.
+        """.lstrip() % env_var
+
+    def __init__(self):
+        self.url = environ.get(self.env_var)
+        if self.url is not None:
+            urlparts = urlparse(self.url)
+            self.username = urlparts.username or 'cobbler'
+            self.password = urlparts.password or ''
+
+    def is_available(self):
+        """Is a real Cobbler available for tests?
+
+        Use this to disable real-Cobbler tests if no real Cobbler is
+        available: annotate them with
+
+        @testtools.skipIf(
+            not real_cobbler.is_available(), RealCobbler.help_text)
+        """
+        return self.url is not None
+
+    def get_session(self):
+        """Obtain a session on the real Cobbler.
+
+        Returns None if no real Cobbler is available.
+        """
+        if self.is_available():
+            return CobblerSession(self.url, self.username, self.password)
+        else:
+            return None

=== modified file 'src/provisioningserver/tests/test_api.py'
--- src/provisioningserver/tests/test_api.py	2012-03-15 22:43:55 +0000
+++ src/provisioningserver/tests/test_api.py	2012-03-16 09:07:30 +0000
@@ -23,11 +23,9 @@
     count,
     islice,
     )
-from os import environ
 from random import randint
 from time import time
 from unittest import skipIf
-from urlparse import urlparse
 
 from maasserver.testing.enum import map_enum
 from provisioningserver.api import (
@@ -38,14 +36,12 @@
     postprocess_mapping,
     ProvisioningAPI,
     )
-from provisioningserver.cobblerclient import (
-    CobblerSession,
-    CobblerSystem,
-    )
+from provisioningserver.cobblerclient import CobblerSystem
 from provisioningserver.enum import POWER_TYPE
 from provisioningserver.interfaces import IProvisioningAPI
 from provisioningserver.testing.fakeapi import FakeAsynchronousProvisioningAPI
 from provisioningserver.testing.fakecobbler import make_fake_cobbler_session
+from provisioningserver.testing.realcobbler import RealCobbler
 from testtools import TestCase
 from testtools.deferredruntest import AsynchronousDeferredRunTest
 from twisted.internet.defer import (
@@ -649,17 +645,9 @@
     Includes by inheritance all the tests in :class:`ProvisioningAPITests`.
     """
 
-    url = environ.get("PSERV_TEST_COBBLER_URL")
+    real_cobbler = RealCobbler()
 
-    @skipIf(
-        url is None,
-        "Set PSERV_TEST_COBBLER_URL to the URL for a Cobbler "
-        "instance to test against, e.g. http://username:password";
-        "@localhost/cobbler_api. Warning: this will modify your "
-        "Cobbler database.")
+    @skipIf(not real_cobbler.is_available(), RealCobbler.help_text)
     def get_provisioning_api(self):
         """Return a connected :class:`ProvisioningAPI`."""
-        urlparts = urlparse(self.url)
-        cobbler_session = CobblerSession(
-            self.url, urlparts.username, urlparts.password)
-        return ProvisioningAPI(cobbler_session)
+        return ProvisioningAPI(self.real_cobbler.get_session())