← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jtv/maas/kill-pserv-api into lp:maas

 

Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/kill-pserv-api into lp:maas with lp:~jtv/maas/disable-pserv-api as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jtv/maas/kill-pserv-api/+merge/119856

This removes the obsolete, Cobbler-affine API that I disabled in an earlier branch.

Not much happening here, really, despite the big diff.  Mostly just deleting files.


Jeroen
-- 
https://code.launchpad.net/~jtv/maas/kill-pserv-api/+merge/119856
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/kill-pserv-api into lp:maas.
=== removed file 'src/provisioningserver/api.py'
--- src/provisioningserver/api.py	2012-08-16 08:14:05 +0000
+++ src/provisioningserver/api.py	1970-01-01 00:00:00 +0000
@@ -1,286 +0,0 @@
-# Copyright 2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Provisioning API for external use."""
-
-from __future__ import (
-    absolute_import,
-    print_function,
-    unicode_literals,
-    )
-
-__metaclass__ = type
-__all__ = [
-    "ProvisioningAPI",
-    ]
-
-from functools import partial
-from itertools import (
-    chain,
-    count,
-    izip,
-    repeat,
-    )
-
-from maasserver.utils import map_enum
-from provisioningserver.enum import POWER_TYPE
-from provisioningserver.interfaces import IProvisioningAPI
-from provisioningserver.utils import deferred
-from twisted.internet.defer import (
-    inlineCallbacks,
-    returnValue,
-    )
-from zope.interface import implements
-
-
-POWER_TYPE_VALUES = set(map_enum(POWER_TYPE).values())
-
-
-def postprocess_mapping(mapping, function):
-    """Apply `function` to each value in `mapping`, returned in a new dict."""
-    return {
-        key: function(value)
-        for key, value in mapping.items()
-        }
-
-
-def cobbler_to_papi_node(data):
-    """Convert a Cobbler representation of a system to a PAPI node."""
-    interfaces = data.get("interfaces", {})
-    mac_addresses = (
-        interface["mac_address"]
-        for interface in interfaces.itervalues())
-    return {
-        "name": data["name"],
-        "hostname": data["hostname"],
-        "profile": data["profile"],
-        "mac_addresses": [
-            mac_address.strip()
-            for mac_address in mac_addresses
-            if mac_address and not mac_address.isspace()
-            ],
-        "netboot_enabled": data.get("netboot_enabled"),
-        "power_type": data["power_type"],
-        }
-
-cobbler_mapping_to_papi_nodes = partial(
-    postprocess_mapping, function=cobbler_to_papi_node)
-
-
-def cobbler_to_papi_profile(data):
-    """Convert a Cobbler representation of a profile to a PAPI profile."""
-    return {
-        "name": data["name"],
-        "distro": data["distro"],
-        }
-
-cobbler_mapping_to_papi_profiles = partial(
-    postprocess_mapping, function=cobbler_to_papi_profile)
-
-
-def cobbler_to_papi_distro(data):
-    """Convert a Cobbler representation of a distro to a PAPI distro."""
-    return {
-        "name": data["name"],
-        "initrd": data["initrd"],
-        "kernel": data["kernel"],
-        }
-
-cobbler_mapping_to_papi_distros = partial(
-    postprocess_mapping, function=cobbler_to_papi_distro)
-
-
-def gen_cobbler_interface_deltas(interfaces, hostname, mac_addresses):
-    """Generate `modify_system` dicts for use with `xapi_object_edit`.
-
-    This takes `interfaces` - the current state of a system's interfaces - and
-    generates the operations required to transform it into a list of
-    interfaces containing exactly `mac_addresses`.
-
-    :param interfaces: A dict of interface-names -> interface-configurations.
-    :param hostname: The hostname of the system.
-    :param mac_addresses: A collection of desired MAC addresses.
-    """
-    # A lazy list of ethernet interface names, used for constructing the
-    # target configuration. Names will be allocated in order, eth0 for the
-    # first MAC address, eth1 for the second, and so on.
-    eth_names = ("eth%d" % num for num in count(0))
-
-    # Allocate DNS names in order too, `hostname` for the first interface, and
-    # to the empty string for the rest. Cobbler will complain (in its default
-    # config) if a dns_name is duplicated. Setting the dns_name for only a
-    # single interface and keeping dns_name on the first interface at all
-    # times also makes things slightly easier to reason about.
-    dns_names = chain([hostname], repeat(""))
-
-    # Calculate comparable mappings of the current interface configuration and
-    # the desired interface configuration.
-    interfaces_from = {
-        interface_name: {
-            "interface": interface_name,
-            "mac_address": interface["mac_address"],
-            "dns_name": interface.get("dns_name", ""),
-            }
-        for interface_name, interface
-        in interfaces.items()
-        }
-    interfaces_to = {
-        interface_name: {
-            "interface": interface_name,
-            "mac_address": mac_address,
-            "dns_name": dns_name,
-            }
-        for interface_name, mac_address, dns_name
-        in izip(eth_names, mac_addresses, dns_names)
-        }
-
-    # If we're removing all MAC addresses, we need to leave one unconfigured
-    # interface behind to satisfy Cobbler's data model constraints.
-    if len(mac_addresses) == 0:
-        interfaces_to["eth0"] = {
-            "interface": "eth0",
-            "mac_address": "",
-            "dns_name": "",
-            }
-
-    # Go through interfaces, generating deltas from `interfaces_from` to
-    # `interfaces_to`. This is done in sorted order to make testing easier.
-    interface_names = set().union(interfaces_from, interfaces_to)
-    for interface_name in sorted(interface_names):
-        interface_from = interfaces_from.get(interface_name)
-        interface_to = interfaces_to.get(interface_name)
-        if interface_to is None:
-            assert interface_from is not None
-            yield {"interface": interface_name, "delete_interface": True}
-        elif interface_from is None:
-            assert interface_to is not None
-            yield interface_to
-        elif interface_to != interface_from:
-            yield interface_to
-        else:
-            pass  # No change.
-
-
-class ProvisioningAPI:
-
-    implements(IProvisioningAPI)
-
-    def __init__(self, session):
-        super(ProvisioningAPI, self).__init__()
-        self.session = session
-
-    def sync(self):
-        """Request Cobbler to sync and return when it's finished."""
-        return self.session.call(
-            "sync", self.session.token_placeholder)
-
-    @inlineCallbacks
-    def add_distro(self, name, initrd, kernel):
-        assert isinstance(name, basestring)
-        assert isinstance(initrd, basestring)
-        assert isinstance(kernel, basestring)
-        yield self.sync()
-
-    @inlineCallbacks
-    def add_profile(self, name, distro):
-        assert isinstance(name, basestring)
-        assert isinstance(distro, basestring)
-        yield self.sync()
-
-    @inlineCallbacks
-    def add_node(self, name, hostname, profile, power_type, preseed_data):
-        assert isinstance(name, basestring)
-        assert isinstance(hostname, basestring)
-        assert isinstance(profile, basestring)
-        assert power_type in POWER_TYPE_VALUES
-        assert isinstance(preseed_data, basestring)
-        yield self.sync()
-
-    @inlineCallbacks
-    def modify_distros(self, deltas):
-        yield self.sync()
-
-    @inlineCallbacks
-    def modify_profiles(self, deltas):
-        yield self.sync()
-
-    @inlineCallbacks
-    def modify_nodes(self, deltas):
-        yield self.sync()
-
-    @inlineCallbacks
-    def get_objects_by_name(self, object_type, names):
-        """Get `object_type` objects by name.
-
-        :param object_type: The type of object to look for.
-        :type object_type:
-            :class:`provisioningserver.cobblerclient.CobblerObjectType`
-        :param names: A list of names to search for.
-        :type names: list
-        """
-        assert all(isinstance(name, basestring) for name in names)
-        objects_by_name = {}
-        for name in names:
-            values = yield object_type(self.session, name).get_values()
-            if values is not None:
-                objects_by_name[name] = values
-        returnValue(objects_by_name)
-
-    @deferred
-    def get_distros_by_name(self, names):
-        pass
-
-    @deferred
-    def get_profiles_by_name(self, names):
-        pass
-
-    @deferred
-    def get_nodes_by_name(self, names):
-        pass
-
-    @inlineCallbacks
-    def delete_objects_by_name(self, object_type, names):
-        """Delete `object_type` objects by name.
-
-        :param object_type: The type of object to delete.
-        :type object_type:
-            :class:`provisioningserver.cobblerclient.CobblerObjectType`
-        :param names: A list of names to search for.
-        :type names: list
-        """
-        assert all(isinstance(name, basestring) for name in names)
-        for name in names:
-            yield object_type(self.session, name).delete()
-        yield self.sync()
-
-    @deferred
-    def delete_distros_by_name(self, names):
-        pass
-
-    @deferred
-    def delete_profiles_by_name(self, names):
-        pass
-
-    @deferred
-    def delete_nodes_by_name(self, names):
-        pass
-
-    @deferred
-    def get_distros(self):
-        pass
-
-    @deferred
-    def get_profiles(self):
-        pass
-
-    @deferred
-    def get_nodes(self):
-        pass
-
-    @deferred
-    def start_nodes(self, names):
-        pass
-
-    @deferred
-    def stop_nodes(self, names):
-        pass

=== modified file 'src/provisioningserver/plugin.py'
--- src/provisioningserver/plugin.py	2012-08-16 08:14:05 +0000
+++ src/provisioningserver/plugin.py	2012-08-16 08:14:05 +0000
@@ -14,7 +14,6 @@
 
 from provisioningserver.amqpclient import AMQFactory
 from provisioningserver.config import Config
-from provisioningserver.remote import ProvisioningAPI_XMLRPC
 from provisioningserver.services import (
     LogService,
     OOPSService,
@@ -33,10 +32,7 @@
 from twisted.cred.checkers import ICredentialsChecker
 from twisted.cred.credentials import IUsernamePassword
 from twisted.cred.error import UnauthorizedLogin
-from twisted.cred.portal import (
-    IRealm,
-    Portal,
-    )
+from twisted.cred.portal import IRealm
 from twisted.internet.defer import (
     inlineCallbacks,
     returnValue,
@@ -46,10 +42,6 @@
     log,
     usage,
     )
-from twisted.web.guard import (
-    BasicCredentialFactory,
-    HTTPAuthSessionWrapper,
-    )
 from twisted.web.resource import (
     IResource,
     Resource,
@@ -124,17 +116,6 @@
         oops_reporter = oops_config["reporter"]
         return OOPSService(log_service, oops_dir, oops_reporter)
 
-    def _makeProvisioningAPI(self, cobbler_session, config):
-        """Construct an :class:`IResource` for the Provisioning API."""
-        papi_xmlrpc = ProvisioningAPI_XMLRPC(cobbler_session)
-        papi_realm = ProvisioningRealm(papi_xmlrpc)
-        papi_checker = SingleUsernamePasswordChecker(
-            config["username"], config["password"])
-        papi_portal = Portal(papi_realm, [papi_checker])
-        papi_creds = BasicCredentialFactory(b"MAAS Provisioning API")
-        papi_root = HTTPAuthSessionWrapper(papi_portal, [papi_creds])
-        return papi_root
-
     def _makeSiteService(self, papi_xmlrpc, config):
         """Create the site service."""
         site_root = Resource()

=== removed file 'src/provisioningserver/remote.py'
--- src/provisioningserver/remote.py	2012-04-16 10:00:51 +0000
+++ src/provisioningserver/remote.py	1970-01-01 00:00:00 +0000
@@ -1,34 +0,0 @@
-# Copyright 2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Provisioning API over XML-RPC."""
-
-from __future__ import (
-    absolute_import,
-    print_function,
-    unicode_literals,
-    )
-
-__metaclass__ = type
-__all__ = [
-    "ProvisioningAPI_XMLRPC",
-    ]
-
-from provisioningserver.api import ProvisioningAPI
-from provisioningserver.interfaces import (
-    IProvisioningAPI,
-    IProvisioningAPI_XMLRPC,
-    )
-from provisioningserver.utils import xmlrpc_export
-from twisted.web.xmlrpc import XMLRPC
-from zope.interface import implements
-
-
-@xmlrpc_export(IProvisioningAPI)
-class ProvisioningAPI_XMLRPC(XMLRPC, ProvisioningAPI):
-
-    implements(IProvisioningAPI_XMLRPC)
-
-    def __init__(self, session):
-        XMLRPC.__init__(self, allowNone=True, useDateTime=True)
-        ProvisioningAPI.__init__(self, session)

=== removed file 'src/provisioningserver/tests/test_api.py'
--- src/provisioningserver/tests/test_api.py	2012-08-16 08:14:05 +0000
+++ src/provisioningserver/tests/test_api.py	1970-01-01 00:00:00 +0000
@@ -1,569 +0,0 @@
-# Copyright 2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests for `provisioningserver.api`.
-
-Also tests `provisioningserver.testing.fakeapi`.
-"""
-
-from __future__ import (
-    absolute_import,
-    print_function,
-    unicode_literals,
-    )
-
-__metaclass__ = type
-__all__ = []
-
-from abc import (
-    ABCMeta,
-    abstractmethod,
-    )
-
-from maastesting.factory import factory
-from provisioningserver.api import (
-    cobbler_to_papi_distro,
-    cobbler_to_papi_node,
-    cobbler_to_papi_profile,
-    gen_cobbler_interface_deltas,
-    postprocess_mapping,
-    )
-from provisioningserver.interfaces import IProvisioningAPI
-from provisioningserver.testing.factory import ProvisioningFakeFactory
-from testtools import TestCase
-from testtools.deferredruntest import AsynchronousDeferredRunTest
-from twisted.internet.defer import inlineCallbacks
-from zope.interface.verify import verifyObject
-
-
-class TestFunctions(TestCase):
-    """Tests for the free functions in `provisioningserver.api`."""
-
-    def test_postprocess_mapping(self):
-        data = {
-            "sad": "wings",
-            "of": "destiny",
-            }
-        expected = {
-            "sad": "Wings",
-            "of": "Destiny",
-            }
-        observed = postprocess_mapping(data, unicode.capitalize)
-        self.assertEqual(expected, observed)
-
-    def test_cobbler_to_papi_node(self):
-        data = {
-            "name": "iced",
-            "profile": "earth",
-            "hostname": "dystopia",
-            "interfaces": {
-                "eth0": {"mac_address": "12:34:56:78:9a:bc"},
-                "eth1": {"mac_address": "  "},
-                "eth2": {"mac_address": ""},
-                "eth3": {"mac_address": None},
-                },
-            "power_type": "virsh",
-            "netboot_enabled": False,
-            "ju": "nk",
-            }
-        expected = {
-            "name": "iced",
-            "profile": "earth",
-            "hostname": "dystopia",
-            "mac_addresses": ["12:34:56:78:9a:bc"],
-            "netboot_enabled": False,
-            "power_type": "virsh",
-            }
-        observed = cobbler_to_papi_node(data)
-        self.assertEqual(expected, observed)
-
-    def test_cobbler_to_papi_node_without_interfaces(self):
-        data = {
-            "name": "iced",
-            "profile": "earth",
-            "hostname": "darksaga",
-            "power_type": "ether_wake",
-            "netboot_enabled": True,
-            "ju": "nk",
-            }
-        expected = {
-            "name": "iced",
-            "profile": "earth",
-            "hostname": "darksaga",
-            "mac_addresses": [],
-            "netboot_enabled": True,
-            "power_type": "ether_wake",
-            }
-        observed = cobbler_to_papi_node(data)
-        self.assertEqual(expected, observed)
-
-    def test_cobbler_to_papi_profile(self):
-        data = {
-            "name": "paradise",
-            "distro": "lost",
-            "draconian": "times",
-            }
-        expected = {
-            "name": "paradise",
-            "distro": "lost",
-            }
-        observed = cobbler_to_papi_profile(data)
-        self.assertEqual(expected, observed)
-
-    def test_cobbler_to_papi_distro(self):
-        data = {
-            "name": "strapping",
-            "initrd": "young",
-            "kernel": "lad",
-            "alien": "city",
-            }
-        expected = {
-            "name": "strapping",
-            "initrd": "young",
-            "kernel": "lad",
-            }
-        observed = cobbler_to_papi_distro(data)
-        self.assertEqual(expected, observed)
-
-
-class TestInterfaceDeltas(TestCase):
-
-    def test_gen_cobbler_interface_deltas_set_1_mac(self):
-        # Specifying a single MAC address results in a delta to configure
-        # eth0. The dns_name of the interface is also updated.
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "",
-                "dns_name": "colony",
-                },
-            }
-        hostname = "clayman"
-        mac_addresses = [
-            "12:34:56:78:90:12",
-            ]
-        expected = [
-            {"interface": "eth0",
-             "mac_address": mac_addresses[0],
-             "dns_name": hostname},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, hostname, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-    def test_gen_cobbler_interface_deltas_set_2_macs(self):
-        # Specifying multiple MAC addresses results in deltas to configure a
-        # corresponding number of interfaces. The dns_name of the first
-        # interface is updated to the given hostname; subsequent interfaces
-        # have an empty dns_name.
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "",
-                },
-            }
-        hostname = "crowbar"
-        mac_addresses = [
-            "11:11:11:11:11:11",
-            "22:22:22:22:22:22",
-            ]
-        expected = [
-            {"interface": "eth0",
-             "mac_address": mac_addresses[0],
-             "dns_name": hostname},
-            {"interface": "eth1",
-             "mac_address": mac_addresses[1],
-             "dns_name": ""},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, hostname, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-    def test_gen_cobbler_interface_deltas_remove_first_mac(self):
-        # Removing the first MAC address causes the MAC addressese of
-        # subsequent interfaces to be shifted down (i.e. eth1's mac --> eth0),
-        # and the last interface to be deleted.
-        dns_name = "lifesblood"
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "11:11:11:11:11:11",
-                "dns_name": dns_name,
-                },
-            "eth1": {
-                "mac_address": "22:22:22:22:22:22",
-                },
-            }
-        mac_addresses = [
-            current_interfaces["eth1"]["mac_address"],
-            ]
-        expected = [
-            {"interface": "eth0",
-             "mac_address": mac_addresses[0],
-             "dns_name": "lifesblood"},
-            {"interface": "eth1",
-             "delete_interface": True},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, dns_name, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-    def test_gen_cobbler_interface_deltas_remove_last_mac(self):
-        # Removing the last MAC address causes the last interface to be
-        # deleted.
-        dns_name = "lifesblood"
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "11:11:11:11:11:11",
-                "dns_name": dns_name,
-                },
-            "eth1": {
-                "mac_address": "22:22:22:22:22:22",
-                },
-            }
-        mac_addresses = [
-            current_interfaces["eth0"]["mac_address"],
-            ]
-        expected = [
-            {"interface": "eth1",
-             "delete_interface": True},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, dns_name, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-    def test_gen_cobbler_interface_deltas_modify_first_mac(self):
-        # Changing the first MAC address modifies the eth0 interface.
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "11:11:11:11:11:11",
-                },
-            "eth1": {
-                "mac_address": "22:22:22:22:22:22",
-                },
-            }
-        hostname = "necrophagist"
-        mac_addresses = [
-            "33:33:33:33:33:33",
-            current_interfaces["eth1"]["mac_address"],
-            ]
-        expected = [
-            {"interface": "eth0",
-             "mac_address": mac_addresses[0],
-             "dns_name": hostname},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, hostname, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-    def test_gen_cobbler_interface_deltas_remove_all_macs(self):
-        # Removing all MAC addresses results in a delta to remove all but the
-        # first interface. The first interface is instead deconfigured; this
-        # is necessary to satisfy the Cobbler data model.
-        current_interfaces = {
-            "eth0": {
-                "mac_address": "11:11:11:11:11:11",
-                },
-            "eth1": {
-                "mac_address": "22:22:22:22:22:22",
-                },
-            }
-        hostname = "empiricism"
-        mac_addresses = []
-        expected = [
-            {"interface": "eth0",
-             "mac_address": "",
-             "dns_name": ""},
-            {"interface": "eth1",
-             "delete_interface": True},
-            ]
-        observed = gen_cobbler_interface_deltas(
-            current_interfaces, hostname, mac_addresses)
-        self.assertItemsEqual(expected, observed)
-
-
-class ProvisioningAPITests(ProvisioningFakeFactory):
-    """Tests for `provisioningserver.api.ProvisioningAPI`.
-
-    Abstract base class.  To exercise these tests, derive a test case from
-    this class as well as from TestCase.  Provide it with a
-    ``get_provisioning_api`` method that returns an :class:`IProvisioningAPI`
-    implementation that you want to test against.
-    """
-
-    __metaclass__ = ABCMeta
-
-    run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=5)
-
-    @abstractmethod
-    def get_provisioning_api(self):
-        """Create a real, or faked, ProvisoningAPI to run tests against.
-
-        Override this in the test case that exercises this scenario.
-        """
-
-    def test_ProvisioningAPI_interfaces(self):
-        papi = self.get_provisioning_api()
-        verifyObject(IProvisioningAPI, papi)
-
-    @inlineCallbacks
-    def test_add_distro(self):
-        # Create a distro via the Provisioning API.
-        papi = self.get_provisioning_api()
-        distro_name = yield self.add_distro(papi)
-        distros = yield papi.get_distros_by_name([distro_name])
-        self.assertItemsEqual([distro_name], distros)
-
-    @inlineCallbacks
-    def test_add_profile(self):
-        # Create a profile via the Provisioning API.
-        papi = self.get_provisioning_api()
-        profile_name = yield self.add_profile(papi)
-        profiles = yield papi.get_profiles_by_name([profile_name])
-        self.assertItemsEqual([profile_name], profiles)
-
-    @inlineCallbacks
-    def test_add_node(self):
-        # Create a system/node via the Provisioning API.
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi, hostname="enthroned")
-        nodes = yield papi.get_nodes_by_name([node_name])
-        self.assertItemsEqual([node_name], nodes)
-        node = nodes[node_name]
-        self.assertEqual("enthroned", node["hostname"])
-        self.assertEqual("ether_wake", node["power_type"])
-        self.assertEqual([], node["mac_addresses"])
-
-    @inlineCallbacks
-    def _test_add_object_twice(self, method):
-        # Adding an object twice is allowed.
-        papi = self.get_provisioning_api()
-        object_name1 = yield method(papi)
-        object_name2 = yield method(papi, object_name1)
-        self.assertEqual(object_name1, object_name2)
-
-    def test_add_distro_twice(self):
-        return self._test_add_object_twice(self.add_distro)
-
-    def test_add_profile_twice(self):
-        return self._test_add_object_twice(self.add_profile)
-
-    def test_add_node_twice(self):
-        return self._test_add_object_twice(self.add_node)
-
-    @inlineCallbacks
-    def test_modify_distros(self):
-        papi = self.get_provisioning_api()
-        distro_name = yield self.add_distro(papi)
-        values = yield papi.get_distros_by_name([distro_name])
-        # The kernel and initrd settings differ.
-        self.assertNotEqual(
-            values[distro_name]["kernel"],
-            values[distro_name]["initrd"])
-        # Swap the initrd and kernel settings.
-        initrd_new = values[distro_name]["kernel"]
-        kernel_new = values[distro_name]["initrd"]
-        yield papi.modify_distros(
-            {distro_name: {"initrd": initrd_new, "kernel": kernel_new}})
-        values = yield papi.get_distros_by_name([distro_name])
-        self.assertEqual(initrd_new, values[distro_name]["initrd"])
-        self.assertEqual(kernel_new, values[distro_name]["kernel"])
-
-    @inlineCallbacks
-    def test_modify_profiles(self):
-        papi = self.get_provisioning_api()
-        distro1_name = yield self.add_distro(papi)
-        distro2_name = yield self.add_distro(papi)
-        profile_name = yield self.add_profile(papi, None, distro1_name)
-        yield papi.modify_profiles({profile_name: {"distro": distro2_name}})
-        values = yield papi.get_profiles_by_name([profile_name])
-        self.assertEqual(distro2_name, values[profile_name]["distro"])
-
-    @inlineCallbacks
-    def test_modify_nodes(self):
-        papi = self.get_provisioning_api()
-        distro_name = yield self.add_distro(papi)
-        profile1_name = yield self.add_profile(papi, None, distro_name)
-        profile2_name = yield self.add_profile(papi, None, distro_name)
-        node_name = yield self.add_node(papi, None, profile1_name)
-        yield papi.modify_nodes({node_name: {"profile": profile2_name}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertEqual(profile2_name, values[node_name]["profile"])
-
-    @inlineCallbacks
-    def test_modify_nodes_set_mac_addresses(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        mac_address = factory.getRandomMACAddress()
-        yield papi.modify_nodes(
-            {node_name: {"mac_addresses": [mac_address]}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertEqual(
-            [mac_address], values[node_name]["mac_addresses"])
-
-    @inlineCallbacks
-    def test_modify_nodes_remove_mac_addresses(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        mac_address1 = factory.getRandomMACAddress()
-        mac_address2 = factory.getRandomMACAddress()
-        mac_addresses_from = [mac_address1, mac_address2]
-        mac_addresses_to = [mac_address2]
-        yield papi.modify_nodes(
-            {node_name: {"mac_addresses": mac_addresses_from}})
-        yield papi.modify_nodes(
-            {node_name: {"mac_addresses": mac_addresses_to}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertEqual(
-            [mac_address2], values[node_name]["mac_addresses"])
-
-    @inlineCallbacks
-    def test_modify_nodes_set_netboot_enabled(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        yield papi.modify_nodes({node_name: {"netboot_enabled": False}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertFalse(values[node_name]["netboot_enabled"])
-        yield papi.modify_nodes({node_name: {"netboot_enabled": True}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertTrue(values[node_name]["netboot_enabled"])
-
-    @inlineCallbacks
-    def test_modify_nodes_remove_all_mac_addresses(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        mac_address = factory.getRandomMACAddress()
-        yield papi.modify_nodes(
-            {node_name: {"mac_addresses": [mac_address]}})
-        yield papi.modify_nodes(
-            {node_name: {"mac_addresses": []}})
-        values = yield papi.get_nodes_by_name([node_name])
-        self.assertEqual(
-            [], values[node_name]["mac_addresses"])
-
-    @inlineCallbacks
-    def test_delete_distros_by_name(self):
-        # Create a distro via the Provisioning API.
-        papi = self.get_provisioning_api()
-        distro_name = yield self.add_distro(papi)
-        # Delete it again via the Provisioning API.
-        yield papi.delete_distros_by_name([distro_name])
-        # It has gone, checked via the Cobbler session.
-        distros = yield papi.get_distros_by_name([distro_name])
-        self.assertEqual({}, distros)
-
-    @inlineCallbacks
-    def test_delete_profiles_by_name(self):
-        # Create a profile via the Provisioning API.
-        papi = self.get_provisioning_api()
-        profile_name = yield self.add_profile(papi)
-        # Delete it again via the Provisioning API.
-        yield papi.delete_profiles_by_name([profile_name])
-        # It has gone, checked via the Cobbler session.
-        profiles = yield papi.get_profiles_by_name([profile_name])
-        self.assertEqual({}, profiles)
-
-    @inlineCallbacks
-    def test_delete_nodes_by_name(self):
-        # Create a node via the Provisioning API.
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        # Delete it again via the Provisioning API.
-        yield papi.delete_nodes_by_name([node_name])
-        # It has gone, checked via the Cobbler session.
-        nodes = yield papi.get_nodes_by_name([node_name])
-        self.assertEqual({}, nodes)
-
-    @inlineCallbacks
-    def test_get_distros(self):
-        papi = self.get_provisioning_api()
-        distros_before = yield papi.get_distros()
-        # Create some distros via the Provisioning API.
-        distros_expected = set()
-        for num in range(3):
-            distro_name = yield self.add_distro(papi)
-            distros_expected.add(distro_name)
-        distros_after = yield papi.get_distros()
-        distros_created = set(distros_after) - set(distros_before)
-        self.assertSetEqual(distros_expected, distros_created)
-
-    @inlineCallbacks
-    def test_get_profiles(self):
-        papi = self.get_provisioning_api()
-        distro_name = yield self.add_distro(papi)
-        profiles_before = yield papi.get_profiles()
-        # Create some profiles via the Provisioning API.
-        profiles_expected = set()
-        for num in range(3):
-            profile_name = yield self.add_profile(papi, None, distro_name)
-            profiles_expected.add(profile_name)
-        profiles_after = yield papi.get_profiles()
-        profiles_created = set(profiles_after) - set(profiles_before)
-        self.assertSetEqual(profiles_expected, profiles_created)
-
-    @inlineCallbacks
-    def test_get_nodes_returns_all_nodes(self):
-        papi = self.get_provisioning_api()
-        profile_name = yield self.add_profile(papi)
-        node_names = set()
-        for num in range(3):
-            node_name = yield self.add_node(papi, None, profile_name)
-            node_names.add(node_name)
-        nodes = yield papi.get_nodes()
-        self.assertSetEqual(node_names, node_names.intersection(nodes))
-
-    @inlineCallbacks
-    def test_get_nodes_includes_node_attributes(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        nodes = yield papi.get_nodes()
-        self.assertIn(node_name, nodes)
-        self.assertIn('name', nodes[node_name])
-        self.assertIn('profile', nodes[node_name])
-        self.assertIn('mac_addresses', nodes[node_name])
-
-    @inlineCallbacks
-    def test_get_nodes_by_name(self):
-        papi = self.get_provisioning_api()
-        nodes = yield papi.get_nodes_by_name([])
-        self.assertEqual({}, nodes)
-        # Create a node via the Provisioning API.
-        node_name = yield self.add_node(papi)
-        nodes = yield papi.get_nodes_by_name([node_name])
-        # The response contains keys for all systems found.
-        self.assertItemsEqual([node_name], nodes)
-
-    @inlineCallbacks
-    def test_get_distros_by_name(self):
-        papi = self.get_provisioning_api()
-        distros = yield papi.get_distros_by_name([])
-        self.assertEqual({}, distros)
-        # Create a distro via the Provisioning API.
-        distro_name = yield self.add_distro(papi)
-        distros = yield papi.get_distros_by_name([distro_name])
-        # The response contains keys for all distributions found.
-        self.assertItemsEqual([distro_name], distros)
-
-    @inlineCallbacks
-    def test_get_profiles_by_name(self):
-        papi = self.get_provisioning_api()
-        profiles = yield papi.get_profiles_by_name([])
-        self.assertEqual({}, profiles)
-        # Create a profile via the Provisioning API.
-        profile_name = yield self.add_profile(papi)
-        profiles = yield papi.get_profiles_by_name([profile_name])
-        # The response contains keys for all profiles found.
-        self.assertItemsEqual([profile_name], profiles)
-
-    @inlineCallbacks
-    def test_stop_nodes(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        yield papi.stop_nodes([node_name])
-        # The test is that we get here without error.
-        pass
-
-    @inlineCallbacks
-    def test_start_nodes(self):
-        papi = self.get_provisioning_api()
-        node_name = yield self.add_node(papi)
-        yield papi.start_nodes([node_name])
-        # The test is that we get here without error.
-        pass

=== removed file 'src/provisioningserver/tests/test_remote.py'
--- src/provisioningserver/tests/test_remote.py	2012-08-16 08:14:05 +0000
+++ src/provisioningserver/tests/test_remote.py	1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
-# Copyright 2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tests for `provisioningserver.remote`."""
-
-from __future__ import (
-    absolute_import,
-    print_function,
-    unicode_literals,
-    )
-
-__metaclass__ = type
-__all__ = []
-
-from provisioningserver.interfaces import (
-    IProvisioningAPI,
-    IProvisioningAPI_XMLRPC,
-    )
-from provisioningserver.remote import ProvisioningAPI_XMLRPC
-from testtools import TestCase
-from testtools.deferredruntest import SynchronousDeferredRunTest
-from zope.interface.verify import verifyObject
-
-
-class TestProvisioningAPI_XMLRPC(TestCase):
-    """Tests for `provisioningserver.remote.ProvisioningAPI_XMLRPC`."""
-
-    run_tests_with = SynchronousDeferredRunTest
-
-    def test_ProvisioningAPI_init(self):
-        dummy_session = object()
-        papi_xmlrpc = ProvisioningAPI_XMLRPC(dummy_session)
-        self.assertIs(dummy_session, papi_xmlrpc.session)
-        self.assertTrue(papi_xmlrpc.allowNone)
-        self.assertTrue(papi_xmlrpc.useDateTime)
-
-    def test_ProvisioningAPI_interfaces(self):
-        dummy_session = object()
-        papi_xmlrpc = ProvisioningAPI_XMLRPC(dummy_session)
-        verifyObject(IProvisioningAPI, papi_xmlrpc)
-        verifyObject(IProvisioningAPI_XMLRPC, papi_xmlrpc)