This is an automated email from the ASF dual-hosted git repository.

PsiACE pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git


The following commit(s) were added to refs/heads/trunk by this push:
     new b3cca53cf Remove Linode APIv3 support (#2132)
b3cca53cf is described below

commit b3cca53cfad8f115fb5f17b67e713447bb9b9dc4
Author: Zhiwei Liang <[email protected]>
AuthorDate: Thu May 7 13:06:48 2026 -0400

    Remove Linode APIv3 support (#2132)
    
    Signed-off-by: Zhiwei Liang <[email protected]>
    Co-authored-by: Miguel Caballer Fernandez <[email protected]>
---
 libcloud/common/linode.py                          | 144 +---
 libcloud/compute/drivers/linode.py                 | 721 +--------------------
 libcloud/dns/drivers/linode.py                     | 293 +--------
 .../fixtures/linode/_avail_datacenters.json        |  36 -
 .../fixtures/linode/_avail_distributions.json      | 246 -------
 .../compute/fixtures/linode/_avail_kernels.json    | 146 -----
 .../fixtures/linode/_avail_linodeplans.json        | 158 -----
 libcloud/test/compute/fixtures/linode/_batch.json  |  22 -
 .../compute/fixtures/linode/_linode_disk_list.json |  28 -
 .../compute/fixtures/linode/_linode_ip_list.json   |  20 -
 .../test/compute/fixtures/linode/_linode_list.json |  33 -
 libcloud/test/compute/test_linode.py               | 208 ------
 libcloud/test/compute/test_linode_v4.py            |   3 +
 .../test/dns/fixtures/linode/create_domain.json    |   7 -
 .../linode/create_domain_validation_error.json     |  10 -
 .../test/dns/fixtures/linode/create_resource.json  |   7 -
 .../test/dns/fixtures/linode/delete_domain.json    |   7 -
 .../linode/delete_domain_does_not_exist.json       |  10 -
 .../test/dns/fixtures/linode/delete_resource.json  |   7 -
 .../linode/delete_resource_does_not_exist.json     |  10 -
 libcloud/test/dns/fixtures/linode/domain_list.json |  36 -
 libcloud/test/dns/fixtures/linode/get_record.json  |  18 -
 .../fixtures/linode/get_record_does_not_exist.json |  10 -
 libcloud/test/dns/fixtures/linode/get_zone.json    |  21 -
 .../fixtures/linode/get_zone_does_not_exist.json   |  10 -
 .../test/dns/fixtures/linode/resource_list.json    |  30 -
 .../linode/resource_list_does_not_exist.json       |  10 -
 .../test/dns/fixtures/linode/update_domain.json    |   7 -
 .../test/dns/fixtures/linode/update_resource.json  |   7 -
 libcloud/test/dns/test_linode.py                   | 316 ---------
 libcloud/test/dns/test_linode_v4.py                |   3 +
 31 files changed, 12 insertions(+), 2572 deletions(-)

diff --git a/libcloud/common/linode.py b/libcloud/common/linode.py
index 7f0d0e48f..fb1fe24ec 100644
--- a/libcloud/common/linode.py
+++ b/libcloud/common/linode.py
@@ -20,11 +20,7 @@ from libcloud.common.types import LibcloudError, 
InvalidCredsError
 
 __all__ = [
     "API_HOST",
-    "API_ROOT",
     "DEFAULT_API_VERSION",
-    "LinodeException",
-    "LinodeResponse",
-    "LinodeConnection",
     "LinodeResponseV4",
     "LinodeConnectionV4",
     "LinodeExceptionV4",
@@ -34,151 +30,13 @@ __all__ = [
 
 # Endpoint for the Linode API
 API_HOST = "api.linode.com"
-API_ROOT = "/"
-
 
 DEFAULT_API_VERSION = "4.0"
 
-# Constants that map a RAM figure to a PlanID (updated 2014-08-25)
-LINODE_PLAN_IDS = {
-    1024: "1",
-    2048: "2",
-    4096: "4",
-    8192: "6",
-    16384: "7",
-    32768: "8",
-    49152: "9",
-    65536: "10",
-    98304: "12",
-}
-
 # Available filesystems for disk creation
-LINODE_DISK_FILESYSTEMS = ["ext3", "ext4", "swap", "raw"]
 LINODE_DISK_FILESYSTEMS_V4 = ["ext3", "ext4", "swap", "raw", "initrd"]
 
 
-class LinodeException(Exception):
-    """Error originating from the Linode API
-
-    This class wraps a Linode API error, a list of which is available in the
-    API documentation.  All Linode API errors are a numeric code and a
-    human-readable description.
-    """
-
-    def __init__(self, code, message):
-        self.code = code
-        self.message = message
-        self.args = (code, message)
-
-    def __str__(self):
-        return "(%u) %s" % (self.code, self.message)
-
-    def __repr__(self):
-        return "<LinodeException code %u '%s'>" % (self.code, self.message)
-
-
-class LinodeResponse(JsonResponse):
-    """
-    Linode API response
-
-    Wraps the HTTP response returned by the Linode API.
-
-    libcloud does not take advantage of batching, so a response will always
-    reflect the above format. A few weird quirks are caught here as well.
-    """
-
-    objects = None
-
-    def __init__(self, response, connection):
-        """Instantiate a LinodeResponse from the HTTP response
-
-        :keyword response: The raw response returned by urllib
-        :return: parsed :class:`LinodeResponse`"""
-        self.errors = []
-        super().__init__(response, connection)
-
-        self.invalid = LinodeException(0xFF, "Invalid JSON received from 
server")
-
-        # Move parse_body() to here;  we can't be sure of failure until we've
-        # parsed the body into JSON.
-        self.objects, self.errors = self.parse_body()
-
-        if not self.success():
-            # Raise the first error, as there will usually only be one
-            raise self.errors[0]
-
-    def parse_body(self):
-        """Parse the body of the response into JSON objects
-
-        If the response chokes the parser, action and data will be returned as
-        None and errorarray will indicate an invalid JSON exception.
-
-        :return: ``list`` of objects and ``list`` of errors"""
-        js = super().parse_body()
-
-        try:
-            if isinstance(js, dict):
-                # solitary response - promote to list
-                js = [js]
-            ret = []
-            errs = []
-            for obj in js:
-                if "DATA" not in obj or "ERRORARRAY" not in obj or "ACTION" 
not in obj:
-                    ret.append(None)
-                    errs.append(self.invalid)
-                    continue
-                ret.append(obj["DATA"])
-                errs.extend(self._make_excp(e) for e in obj["ERRORARRAY"])
-            return (ret, errs)
-        except Exception:
-            return (None, [self.invalid])
-
-    def success(self):
-        """Check the response for success
-
-        The way we determine success is by the presence of an error in
-        ERRORARRAY.  If one is there, we assume the whole request failed.
-
-        :return: ``bool`` indicating a successful request"""
-        return len(self.errors) == 0
-
-    def _make_excp(self, error):
-        """Convert an API error to a LinodeException instance
-
-        :keyword error: JSON object containing ``ERRORCODE`` and
-        ``ERRORMESSAGE``
-        :type error: dict"""
-        if "ERRORCODE" not in error or "ERRORMESSAGE" not in error:
-            return None
-        if error["ERRORCODE"] == 4:
-            return InvalidCredsError(error["ERRORMESSAGE"])
-        return LinodeException(error["ERRORCODE"], error["ERRORMESSAGE"])
-
-
-class LinodeConnection(ConnectionKey):
-    """
-    A connection to the Linode API
-
-    Wraps SSL connections to the Linode API, automagically injecting the
-    parameters that the API needs for each request.
-    """
-
-    host = API_HOST
-    responseCls = LinodeResponse
-
-    def add_default_params(self, params):
-        """
-        Add parameters that are necessary for every request
-
-        This method adds ``api_key`` and ``api_responseFormat`` to
-        the request.
-        """
-        params["api_key"] = self.key
-        # Be explicit about this in case the default changes.
-        params["api_responseFormat"] = "json"
-        return params
-
-
 class LinodeExceptionV4(Exception):
     def __init__(self, message):
         self.message = message
@@ -187,7 +45,7 @@ class LinodeExceptionV4(Exception):
         return "%s" % self.message
 
     def __repr__(self):
-        return "<LinodeException '%s'>" % self.message
+        return "<LinodeExceptionV4 '%s'>" % self.message
 
 
 class LinodeResponseV4(JsonResponse):
diff --git a/libcloud/compute/drivers/linode.py 
b/libcloud/compute/drivers/linode.py
index 81862cdb5..b8da22ea4 100644
--- a/libcloud/compute/drivers/linode.py
+++ b/libcloud/compute/drivers/linode.py
@@ -16,22 +16,16 @@
 """libcloud driver for the Linode(R) API
 
 This driver implements all libcloud functionality for the Linode API.
-Since the API is a bit more fine-grained, create_node abstracts a significant
-amount of work (and may take a while to run).
 
 Linode home page                    http://www.linode.com/
-Linode API documentation            http://www.linode.com/api/
-Alternate bindings for reference    http://github.com/tjfontaine/linode-python
+Linode API documentation            https://www.linode.com/docs/api/
 
 Linode(R) is a registered trademark of Linode, LLC.
 
 """
 
-import os
 import re
 import binascii
-import itertools
-from copy import copy
 from datetime import datetime
 
 from libcloud.utils.py3 import httplib
@@ -43,19 +37,12 @@ from libcloud.compute.base import (
     NodeDriver,
     NodeLocation,
     StorageVolume,
-    NodeAuthSSHKey,
-    NodeAuthPassword,
 )
 from libcloud.common.linode import (
-    API_ROOT,
-    LINODE_PLAN_IDS,
     DEFAULT_API_VERSION,
-    LINODE_DISK_FILESYSTEMS,
     LINODE_DISK_FILESYSTEMS_V4,
     LinodeDisk,
-    LinodeException,
     LinodeIPAddress,
-    LinodeConnection,
     LinodeExceptionV4,
     LinodeConnectionV4,
 )
@@ -85,9 +72,7 @@ class LinodeNodeDriver(NodeDriver):
         **kwargs,
     ):
         if cls is LinodeNodeDriver:
-            if api_version == "3.0":
-                cls = LinodeNodeDriverV3
-            elif api_version == "4.0":
+            if api_version == "4.0":
                 cls = LinodeNodeDriverV4
             else:
                 raise NotImplementedError(
@@ -96,708 +81,6 @@ class LinodeNodeDriver(NodeDriver):
         return super().__new__(cls)
 
 
-class LinodeNodeDriverV3(LinodeNodeDriver):
-    """libcloud driver for the Linode API
-
-    Rough mapping of which is which:
-
-    - list_nodes              linode.list
-    - reboot_node             linode.reboot
-    - destroy_node            linode.delete
-    - create_node             linode.create, linode.update,
-                              linode.disk.createfromdistribution,
-                              linode.disk.create, linode.config.create,
-                              linode.ip.addprivate, linode.boot
-    - list_sizes              avail.linodeplans
-    - list_images             avail.distributions
-    - list_locations          avail.datacenters
-    - list_volumes            linode.disk.list
-    - destroy_volume          linode.disk.delete
-
-    For more information on the Linode API, be sure to read the reference:
-
-        http://www.linode.com/api/
-    """
-
-    connectionCls = LinodeConnection
-    _linode_plan_ids = LINODE_PLAN_IDS
-    _linode_disk_filesystems = LINODE_DISK_FILESYSTEMS
-    features = {"create_node": ["ssh_key", "password"]}
-
-    def __init__(
-        self,
-        key,
-        secret=None,
-        secure=True,
-        host=None,
-        port=None,
-        api_version=None,
-        region=None,
-        **kwargs,
-    ):
-        """Instantiate the driver with the given API key
-
-        :param   key: the API key to use (required)
-        :type    key: ``str``
-
-        :rtype: ``None``
-        """
-        self.datacenter = None
-        NodeDriver.__init__(self, key)
-
-    # Converts Linode's state from DB to a NodeState constant.
-    LINODE_STATES = {
-        (-2): NodeState.UNKNOWN,  # Boot Failed
-        (-1): NodeState.PENDING,  # Being Created
-        0: NodeState.PENDING,  # Brand New
-        1: NodeState.RUNNING,  # Running
-        2: NodeState.STOPPED,  # Powered Off
-        3: NodeState.REBOOTING,  # Shutting Down
-        4: NodeState.UNKNOWN,  # Reserved
-    }
-
-    def list_nodes(self):
-        """
-        List all Linodes that the API key can access
-
-        This call will return all Linodes that the API key in use has access
-         to.
-        If a node is in this list, rebooting will work; however, creation and
-        destruction are a separate grant.
-
-        :return: List of node objects that the API key can access
-        :rtype: ``list`` of :class:`Node`
-        """
-        params = {"api_action": "linode.list"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_nodes(data)
-
-    def start_node(self, node):
-        """
-        Boot the given Linode
-
-        """
-        params = {"api_action": "linode.boot", "LinodeID": node.id}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def stop_node(self, node):
-        """
-        Shutdown the given Linode
-
-        """
-        params = {"api_action": "linode.shutdown", "LinodeID": node.id}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def reboot_node(self, node):
-        """
-        Reboot the given Linode
-
-        Will issue a shutdown job followed by a boot job, using the last booted
-        configuration.  In most cases, this will be the only configuration.
-
-        :param      node: the Linode to reboot
-        :type       node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {"api_action": "linode.reboot", "LinodeID": node.id}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def destroy_node(self, node):
-        """Destroy the given Linode
-
-        Will remove the Linode from the account and issue a prorated credit. A
-        grant for removing Linodes from the account is required, otherwise this
-        method will fail.
-
-        In most cases, all disk images must be removed from a Linode before the
-        Linode can be removed; however, this call explicitly skips those
-        safeguards. There is no going back from this method.
-
-        :param       node: the Linode to destroy
-        :type        node: :class:`Node`
-
-        :rtype: ``bool``
-        """
-        params = {
-            "api_action": "linode.delete",
-            "LinodeID": node.id,
-            "skipChecks": True,
-        }
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def create_node(
-        self,
-        name,
-        image,
-        size,
-        auth,
-        location=None,
-        ex_swap=None,
-        ex_rsize=None,
-        ex_kernel=None,
-        ex_payment=None,
-        ex_comment=None,
-        ex_private=False,
-        lconfig=None,
-        lroot=None,
-        lswap=None,
-    ):
-        """Create a new Linode, deploy a Linux distribution, and boot
-
-        This call abstracts much of the functionality of provisioning a Linode
-        and getting it booted.  A global grant to add Linodes to the account is
-        required, as this call will result in a billing charge.
-
-        Note that there is a safety valve of 5 Linodes per hour, in order to
-        prevent a runaway script from ruining your day.
-
-        :keyword name: the name to assign the Linode (mandatory)
-        :type    name: ``str``
-
-        :keyword image: which distribution to deploy on the Linode (mandatory)
-        :type    image: :class:`NodeImage`
-
-        :keyword size: the plan size to create (mandatory)
-        :type    size: :class:`NodeSize`
-
-        :keyword auth: an SSH key or root password (mandatory)
-        :type    auth: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword`
-
-        :keyword location: which datacenter to create the Linode in
-        :type    location: :class:`NodeLocation`
-
-        :keyword ex_swap: size of the swap partition in MB (128)
-        :type    ex_swap: ``int``
-
-        :keyword ex_rsize: size of the root partition in MB (plan size - swap).
-        :type    ex_rsize: ``int``
-
-        :keyword ex_kernel: a kernel ID from avail.kernels (Latest 2.6 Stable).
-        :type    ex_kernel: ``str``
-
-        :keyword ex_payment: one of 1, 12, or 24; subscription length (1)
-        :type    ex_payment: ``int``
-
-        :keyword ex_comment: a small comment for the configuration (libcloud)
-        :type    ex_comment: ``str``
-
-        :keyword ex_private: whether or not to request a private IP (False)
-        :type    ex_private: ``bool``
-
-        :keyword lconfig: what to call the configuration (generated)
-        :type    lconfig: ``str``
-
-        :keyword lroot: what to call the root image (generated)
-        :type    lroot: ``str``
-
-        :keyword lswap: what to call the swap space (generated)
-        :type    lswap: ``str``
-
-        :return: Node representing the newly-created Linode
-        :rtype: :class:`Node`
-        """
-        auth = self._get_and_check_auth(auth)
-
-        # Pick a location (resolves LIBCLOUD-41 in JIRA)
-        if location:
-            chosen = location.id
-        elif self.datacenter:
-            chosen = self.datacenter
-        else:
-            raise LinodeException(0xFB, "Need to select a datacenter first")
-
-        # Step 0: Parameter validation before we purchase
-        # We're especially careful here so we don't fail after purchase, rather
-        # than getting halfway through the process and having the API fail.
-
-        # Plan ID
-        plans = self.list_sizes()
-        if size.id not in [p.id for p in plans]:
-            raise LinodeException(0xFB, "Invalid plan ID -- avail.plans")
-
-        # Payment schedule
-        payment = "1" if not ex_payment else str(ex_payment)
-        if payment not in ["1", "12", "24"]:
-            raise LinodeException(0xFB, "Invalid subscription (1, 12, 24)")
-
-        ssh = None
-        root = None
-        # SSH key and/or root password
-        if isinstance(auth, NodeAuthSSHKey):
-            ssh = auth.pubkey  # pylint: disable=no-member
-        elif isinstance(auth, NodeAuthPassword):
-            root = auth.password
-
-        if not ssh and not root:
-            raise LinodeException(0xFB, "Need SSH key or root password")
-        if root is not None and len(root) < 6:
-            raise LinodeException(0xFB, "Root password is too short")
-
-        # Swap size
-        try:
-            swap = 128 if not ex_swap else int(ex_swap)
-        except Exception:
-            raise LinodeException(0xFB, "Need an integer swap size")
-
-        # Root partition size
-        imagesize = (size.disk - swap) if not ex_rsize else int(ex_rsize)
-        if (imagesize + swap) > size.disk:
-            raise LinodeException(0xFB, "Total disk images are too big")
-
-        # Distribution ID
-        distros = self.list_images()
-        if image.id not in [d.id for d in distros]:
-            raise LinodeException(0xFB, "Invalid distro -- 
avail.distributions")
-
-        # Kernel
-        if ex_kernel:
-            kernel = ex_kernel
-        else:
-            if image.extra["64bit"]:
-                # For a list of available kernel ids, see
-                # https://www.linode.com/kernels/
-                kernel = 138
-            else:
-                kernel = 137
-        params = {"api_action": "avail.kernels"}
-        kernels = self.connection.request(API_ROOT, params=params).objects[0]
-        if kernel not in [z["KERNELID"] for z in kernels]:
-            raise LinodeException(0xFB, "Invalid kernel -- avail.kernels")
-
-        # Comments
-        comments = (
-            "Created by Apache libcloud <https://www.libcloud.org>"
-            if not ex_comment
-            else ex_comment
-        )
-
-        # Step 1: linode.create
-        params = {
-            "api_action": "linode.create",
-            "DatacenterID": chosen,
-            "PlanID": size.id,
-            "PaymentTerm": payment,
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode = {"id": data["LinodeID"]}
-
-        # Step 1b. linode.update to rename the Linode
-        params = {
-            "api_action": "linode.update",
-            "LinodeID": linode["id"],
-            "Label": name,
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        # Step 1c. linode.ip.addprivate if it was requested
-        if ex_private:
-            params = {"api_action": "linode.ip.addprivate", "LinodeID": 
linode["id"]}
-            self.connection.request(API_ROOT, params=params)
-
-        # Step 1d. Labels
-        # use the linode id as the name can be up to 63 chars and the labels
-        # are limited to 48 chars
-        label = {
-            "lconfig": "[%s] Configuration Profile" % linode["id"],
-            "lroot": "[{}] {} Disk Image".format(linode["id"], image.name),
-            "lswap": "[%s] Swap Space" % linode["id"],
-        }
-
-        if lconfig:
-            label["lconfig"] = lconfig
-
-        if lroot:
-            label["lroot"] = lroot
-
-        if lswap:
-            label["lswap"] = lswap
-
-        # Step 2: linode.disk.createfromdistribution
-        if not root:
-            root = binascii.b2a_base64(os.urandom(8)).decode("ascii").strip()
-
-        params = {
-            "api_action": "linode.disk.createfromdistribution",
-            "LinodeID": linode["id"],
-            "DistributionID": image.id,
-            "Label": label["lroot"],
-            "Size": imagesize,
-            "rootPass": root,
-        }
-        if ssh:
-            params["rootSSHKey"] = ssh
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["rootimage"] = data["DiskID"]
-
-        # Step 3: linode.disk.create for swap
-        params = {
-            "api_action": "linode.disk.create",
-            "LinodeID": linode["id"],
-            "Label": label["lswap"],
-            "Type": "swap",
-            "Size": swap,
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["swapimage"] = data["DiskID"]
-
-        # Step 4: linode.config.create for main profile
-        disks = "{},{},,,,,,,".format(linode["rootimage"], linode["swapimage"])
-        params = {
-            "api_action": "linode.config.create",
-            "LinodeID": linode["id"],
-            "KernelID": kernel,
-            "Label": label["lconfig"],
-            "Comments": comments,
-            "DiskList": disks,
-        }
-        if ex_private:
-            params["helper_network"] = True
-            params["helper_distro"] = True
-
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        linode["config"] = data["ConfigID"]
-
-        # Step 5: linode.boot
-        params = {
-            "api_action": "linode.boot",
-            "LinodeID": linode["id"],
-            "ConfigID": linode["config"],
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        # Make a node out of it and hand it back
-        params = {"api_action": "linode.list", "LinodeID": linode["id"]}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        nodes = self._to_nodes(data)
-
-        if len(nodes) == 1:
-            node = nodes[0]
-            if getattr(auth, "generated", False):
-                node.extra["password"] = auth.password
-            return node
-
-        return None
-
-    def ex_resize_node(self, node, size):
-        """Resizes a Linode from one plan to another
-
-        Immediately shuts the Linode down, charges/credits the account,
-        and issue a migration to another host server.
-        Requires a size (numeric), which is the desired PlanID available from
-        avail.LinodePlans()
-        After resize is complete the node needs to be booted
-        """
-
-        params = {"api_action": "linode.resize", "LinodeID": node.id, 
"PlanID": size}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def ex_start_node(self, node):
-        # NOTE: This method is here for backward compatibility reasons after
-        # this method was promoted to be part of the standard compute API in
-        # Libcloud v2.7.0
-        return self.start_node(node=node)
-
-    def ex_stop_node(self, node):
-        # NOTE: This method is here for backward compatibility reasons after
-        # this method was promoted to be part of the standard compute API in
-        # Libcloud v2.7.0
-        return self.stop_node(node=node)
-
-    def ex_rename_node(self, node, name):
-        """Renames a node"""
-
-        params = {"api_action": "linode.update", "LinodeID": node.id, "Label": 
name}
-        self.connection.request(API_ROOT, params=params)
-        return True
-
-    def list_sizes(self, location=None):
-        """
-        List available Linode plans
-
-        Gets the sizes that can be used for creating a Linode.  Since available
-        Linode plans vary per-location, this method can also be passed a
-        location to filter the availability.
-
-        :keyword location: the facility to retrieve plans in
-        :type    location: :class:`NodeLocation`
-
-        :rtype: ``list`` of :class:`NodeSize`
-        """
-        params = {"api_action": "avail.linodeplans"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        sizes = []
-        for obj in data:
-            n = NodeSize(
-                id=obj["PLANID"],
-                name=obj["LABEL"],
-                ram=obj["RAM"],
-                disk=(obj["DISK"] * 1024),
-                bandwidth=obj["XFER"],
-                price=obj["PRICE"],
-                driver=self.connection.driver,
-            )
-            sizes.append(n)
-        return sizes
-
-    def list_images(self):
-        """
-        List available Linux distributions
-
-        Retrieve all Linux distributions that can be deployed to a Linode.
-
-        :rtype: ``list`` of :class:`NodeImage`
-        """
-        params = {"api_action": "avail.distributions"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        distros = []
-        for obj in data:
-            i = NodeImage(
-                id=obj["DISTRIBUTIONID"],
-                name=obj["LABEL"],
-                driver=self.connection.driver,
-                extra={"pvops": obj["REQUIRESPVOPSKERNEL"], "64bit": 
obj["IS64BIT"]},
-            )
-            distros.append(i)
-        return distros
-
-    def list_locations(self):
-        """
-        List available facilities for deployment
-
-        Retrieve all facilities that a Linode can be deployed in.
-
-        :rtype: ``list`` of :class:`NodeLocation`
-        """
-        params = {"api_action": "avail.datacenters"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        nl = []
-        for dc in data:
-            country = None
-            if "USA" in dc["LOCATION"]:
-                country = "US"
-            elif "UK" in dc["LOCATION"]:
-                country = "GB"
-            elif "JP" in dc["LOCATION"]:
-                country = "JP"
-            else:
-                country = "??"
-            nl.append(NodeLocation(dc["DATACENTERID"], dc["LOCATION"], 
country, self))
-        return nl
-
-    def linode_set_datacenter(self, dc):
-        """
-        Set the default datacenter for Linode creation
-
-        Since Linodes must be created in a facility, this function sets the
-        default that :class:`create_node` will use.  If a location keyword is
-        not passed to :class:`create_node`, this method must have already been
-        used.
-
-        :keyword dc: the datacenter to create Linodes in unless specified
-        :type    dc: :class:`NodeLocation`
-
-        :rtype: ``bool``
-        """
-        did = dc.id
-        params = {"api_action": "avail.datacenters"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        for datacenter in data:
-            if did == dc["DATACENTERID"]:
-                self.datacenter = did
-                return
-
-        dcs = ", ".join([d["DATACENTERID"] for d in data])
-        self.datacenter = None
-        raise LinodeException(0xFD, "Invalid datacenter (use one of %s)" % dcs)
-
-    def destroy_volume(self, volume):
-        """
-        Destroys disk volume for the Linode. Linode id is to be provided as
-        extra["LinodeId"] within :class:`StorageVolume`. It can be retrieved
-        by :meth:`libcloud.compute.drivers.linode.LinodeNodeDriver\
-                 .ex_list_volumes`.
-
-        :param volume: Volume to be destroyed
-        :type volume: :class:`StorageVolume`
-
-        :rtype: ``bool``
-        """
-        if not isinstance(volume, StorageVolume):
-            raise LinodeException(0xFD, "Invalid volume instance")
-
-        if volume.extra["LINODEID"] is None:
-            raise LinodeException(0xFD, "Missing LinodeID")
-
-        params = {
-            "api_action": "linode.disk.delete",
-            "LinodeID": volume.extra["LINODEID"],
-            "DiskID": volume.id,
-        }
-        self.connection.request(API_ROOT, params=params)
-
-        return True
-
-    def ex_create_volume(self, size, name, node, fs_type):
-        """
-        Create disk for the Linode.
-
-        :keyword    size: Size of volume in megabytes (required)
-        :type       size: ``int``
-
-        :keyword    name: Name of the volume to be created
-        :type       name: ``str``
-
-        :keyword    node: Node to attach volume to.
-        :type       node: :class:`Node`
-
-        :keyword    fs_type: The formatted type of this disk. Valid types are:
-                             ext3, ext4, swap, raw
-        :type       fs_type: ``str``
-
-
-        :return: StorageVolume representing the newly-created volume
-        :rtype: :class:`StorageVolume`
-        """
-        # check node
-        if not isinstance(node, Node):
-            raise LinodeException(0xFD, "Invalid node instance")
-
-        # check space available
-        total_space = node.extra["TOTALHD"]
-        existing_volumes = self.ex_list_volumes(node)
-        used_space = 0
-        for volume in existing_volumes:
-            used_space = used_space + volume.size
-
-        available_space = total_space - used_space
-        if available_space < size:
-            raise LinodeException(
-                0xFD,
-                "Volume size too big. Available space\
-                    %d" % available_space,
-            )
-
-        # check filesystem type
-        if fs_type not in self._linode_disk_filesystems:
-            raise LinodeException(0xFD, "Not valid filesystem type")
-
-        params = {
-            "api_action": "linode.disk.create",
-            "LinodeID": node.id,
-            "Label": name,
-            "Type": fs_type,
-            "Size": size,
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        volume = data["DiskID"]
-        # Make a volume out of it and hand it back
-        params = {
-            "api_action": "linode.disk.list",
-            "LinodeID": node.id,
-            "DiskID": volume,
-        }
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_volumes(data)[0]
-
-    def ex_list_volumes(self, node, disk_id=None):
-        """
-        List existing disk volumes for for given Linode.
-
-        :keyword    node: Node to list disk volumes for. (required)
-        :type       node: :class:`Node`
-
-        :keyword    disk_id: Id for specific disk volume. (optional)
-        :type       disk_id: ``int``
-
-        :rtype: ``list`` of :class:`StorageVolume`
-        """
-        if not isinstance(node, Node):
-            raise LinodeException(0xFD, "Invalid node instance")
-
-        params = {"api_action": "linode.disk.list", "LinodeID": node.id}
-        # Add param if disk_id was specified
-        if disk_id is not None:
-            params["DiskID"] = disk_id
-
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        return self._to_volumes(data)
-
-    def _to_volumes(self, objs):
-        """
-        Convert returned JSON volumes into StorageVolume instances
-
-        :keyword    objs: ``list`` of JSON dictionaries representing the
-                         StorageVolumes
-        :type       objs: ``list``
-
-        :return: ``list`` of :class:`StorageVolume`s
-        """
-        volumes = {}
-        for o in objs:
-            vid = o["DISKID"]
-            volumes[vid] = vol = StorageVolume(
-                id=vid,
-                name=o["LABEL"],
-                size=int(o["SIZE"]),
-                driver=self.connection.driver,
-            )
-            vol.extra = copy(o)
-        return list(volumes.values())
-
-    def _to_nodes(self, objs):
-        """Convert returned JSON Linodes into Node instances
-
-        :keyword objs: ``list`` of JSON dictionaries representing the Linodes
-        :type objs: ``list``
-        :return: ``list`` of :class:`Node`s"""
-
-        # Get the IP addresses for the Linodes
-        nodes = {}
-        batch = []
-        for o in objs:
-            lid = o["LINODEID"]
-            nodes[lid] = n = Node(
-                id=lid,
-                name=o["LABEL"],
-                public_ips=[],
-                private_ips=[],
-                state=self.LINODE_STATES[o["STATUS"]],
-                driver=self.connection.driver,
-            )
-            n.extra = copy(o)
-            n.extra["PLANID"] = self._linode_plan_ids.get(o.get("TOTALRAM"))
-            batch.append({"api_action": "linode.ip.list", "LinodeID": lid})
-
-        # Avoid batch limitation
-        ip_answers = []
-        args = [iter(batch)] * 25
-
-        for twenty_five in itertools.zip_longest(*args):
-            twenty_five = [q for q in twenty_five if q]
-            params = {
-                "api_action": "batch",
-                "api_requestArray": json.dumps(twenty_five),
-            }
-            req = self.connection.request(API_ROOT, params=params)
-            if not req.success() or len(req.objects) == 0:
-                return None
-            ip_answers.extend(req.objects)
-
-        # Add the returned IPs to the nodes and return them
-        for ip_list in ip_answers:
-            for ip in ip_list:
-                lid = ip["LINODEID"]
-                which = nodes[lid].public_ips if ip["ISPUBLIC"] == 1 else 
nodes[lid].private_ips
-                which.append(ip["IPADDRESS"])
-        return list(nodes.values())
-
-
 class LinodeNodeDriverV4(LinodeNodeDriver):
     connectionCls = LinodeConnectionV4
     _linode_disk_filesystems = LINODE_DISK_FILESYSTEMS_V4
diff --git a/libcloud/dns/drivers/linode.py b/libcloud/dns/drivers/linode.py
index b2f609f25..5639a14a4 100644
--- a/libcloud/dns/drivers/linode.py
+++ b/libcloud/dns/drivers/linode.py
@@ -18,15 +18,11 @@ __all__ = ["LinodeDNSDriver"]
 from datetime import datetime
 
 from libcloud.dns.base import Zone, Record, DNSDriver
-from libcloud.dns.types import Provider, RecordType, ZoneDoesNotExistError, 
RecordDoesNotExistError
+from libcloud.dns.types import Provider, RecordType
 from libcloud.utils.py3 import httplib
-from libcloud.utils.misc import get_new_obj, merge_valid_keys
+from libcloud.utils.misc import merge_valid_keys
 from libcloud.common.linode import (
-    API_ROOT,
     DEFAULT_API_VERSION,
-    LinodeResponse,
-    LinodeException,
-    LinodeConnection,
     LinodeResponseV4,
     LinodeExceptionV4,
     LinodeConnectionV4,
@@ -38,17 +34,6 @@ except ImportError:
     import json
 
 
-VALID_ZONE_EXTRA_PARAMS = [
-    "SOA_Email",
-    "Refresh_sec",
-    "Retry_sec",
-    "Expire_sec",
-    "status",
-    "master_ips",
-]
-
-VALID_RECORD_EXTRA_PARAMS = ["Priority", "Weight", "Port", "Protocol", 
"TTL_sec"]
-
 VALID_ZONE_EXTRA_PARAMS_V4 = [
     "description",
     "expire_sec",
@@ -88,9 +73,7 @@ class LinodeDNSDriver(DNSDriver):
         **kwargs,
     ):
         if cls is LinodeDNSDriver:
-            if api_version == "3.0":
-                cls = LinodeDNSDriverV3
-            elif api_version == "4.0":
+            if api_version == "4.0":
                 cls = LinodeDNSDriverV4
             else:
                 raise NotImplementedError(
@@ -99,276 +82,6 @@ class LinodeDNSDriver(DNSDriver):
         return super().__new__(cls)
 
 
-class LinodeDNSResponse(LinodeResponse):
-    def _make_excp(self, error):
-        result = super()._make_excp(error)
-        if isinstance(result, LinodeException) and result.code == 5:
-            context = self.connection.context
-
-            if context["resource"] == "zone":
-                result = ZoneDoesNotExistError(
-                    value="", driver=self.connection.driver, 
zone_id=context["id"]
-                )
-
-            elif context["resource"] == "record":
-                result = RecordDoesNotExistError(
-                    value="", driver=self.connection.driver, 
record_id=context["id"]
-                )
-        return result
-
-
-class LinodeDNSConnection(LinodeConnection):
-    responseCls = LinodeDNSResponse
-
-
-class LinodeDNSDriverV3(LinodeDNSDriver):
-    connectionCls = LinodeDNSConnection
-
-    RECORD_TYPE_MAP = {
-        RecordType.NS: "NS",
-        RecordType.MX: "MX",
-        RecordType.A: "A",
-        RecordType.AAAA: "AAAA",
-        RecordType.CNAME: "CNAME",
-        RecordType.TXT: "TXT",
-        RecordType.SRV: "SRV",
-    }
-
-    def list_zones(self):
-        params = {"api_action": "domain.list"}
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zones = self._to_zones(data)
-        return zones
-
-    def list_records(self, zone):
-        params = {"api_action": "domain.resource.list", "DOMAINID": zone.id}
-
-        self.connection.set_context(context={"resource": "zone", "id": 
zone.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        records = self._to_records(items=data, zone=zone)
-        return records
-
-    def get_zone(self, zone_id):
-        params = {"api_action": "domain.list", "DomainID": zone_id}
-        self.connection.set_context(context={"resource": "zone", "id": 
zone_id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zones = self._to_zones(data)
-
-        if len(zones) != 1:
-            raise ZoneDoesNotExistError(value="", driver=self, zone_id=zone_id)
-
-        return zones[0]
-
-    def get_record(self, zone_id, record_id):
-        zone = self.get_zone(zone_id=zone_id)
-        params = {
-            "api_action": "domain.resource.list",
-            "DomainID": zone_id,
-            "ResourceID": record_id,
-        }
-        self.connection.set_context(context={"resource": "record", "id": 
record_id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        records = self._to_records(items=data, zone=zone)
-
-        if len(records) != 1:
-            raise RecordDoesNotExistError(value="", driver=self, 
record_id=record_id)
-
-        return records[0]
-
-    def create_zone(self, domain, type="master", ttl=None, extra=None):
-        """
-        Create a new zone.
-
-        API docs: http://www.linode.com/api/dns/domain.create
-        """
-        params = {"api_action": "domain.create", "Type": type, "Domain": 
domain}
-
-        if ttl:
-            params["TTL_sec"] = ttl
-
-        merged = merge_valid_keys(params=params, 
valid_keys=VALID_ZONE_EXTRA_PARAMS, extra=extra)
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-        zone = Zone(
-            id=data["DomainID"],
-            domain=domain,
-            type=type,
-            ttl=ttl,
-            extra=merged,
-            driver=self,
-        )
-        return zone
-
-    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
-        """
-        Update an existing zone.
-
-        API docs: http://www.linode.com/api/dns/domain.update
-        """
-        params = {"api_action": "domain.update", "DomainID": zone.id}
-
-        if type:
-            params["Type"] = type
-
-        if domain:
-            params["Domain"] = domain
-
-        if ttl:
-            params["TTL_sec"] = ttl
-
-        merged = merge_valid_keys(params=params, 
valid_keys=VALID_ZONE_EXTRA_PARAMS, extra=extra)
-        self.connection.request(API_ROOT, params=params).objects[0]
-        updated_zone = get_new_obj(
-            obj=zone,
-            klass=Zone,
-            attributes={"domain": domain, "type": type, "ttl": ttl, "extra": 
merged},
-        )
-        return updated_zone
-
-    def create_record(self, name, zone, type, data, extra=None):
-        """
-        Create a new record.
-
-        API docs: http://www.linode.com/api/dns/domain.resource.create
-        """
-        params = {
-            "api_action": "domain.resource.create",
-            "DomainID": zone.id,
-            "Name": name,
-            "Target": data,
-            "Type": self.RECORD_TYPE_MAP[type],
-        }
-        merged = merge_valid_keys(params=params, 
valid_keys=VALID_RECORD_EXTRA_PARAMS, extra=extra)
-
-        result = self.connection.request(API_ROOT, params=params).objects[0]
-        record = Record(
-            id=result["ResourceID"],
-            name=name,
-            type=type,
-            data=data,
-            extra=merged,
-            zone=zone,
-            driver=self,
-            ttl=merged.get("TTL_sec", None),
-        )
-        return record
-
-    def update_record(self, record, name=None, type=None, data=None, 
extra=None):
-        """
-        Update an existing record.
-
-        API docs: http://www.linode.com/api/dns/domain.resource.update
-        """
-        params = {
-            "api_action": "domain.resource.update",
-            "ResourceID": record.id,
-            "DomainID": record.zone.id,
-        }
-
-        if name:
-            params["Name"] = name
-
-        if data:
-            params["Target"] = data
-
-        if type is not None:
-            params["Type"] = self.RECORD_TYPE_MAP[type]
-
-        merged = merge_valid_keys(params=params, 
valid_keys=VALID_RECORD_EXTRA_PARAMS, extra=extra)
-
-        self.connection.request(API_ROOT, params=params).objects[0]
-        updated_record = get_new_obj(
-            obj=record,
-            klass=Record,
-            attributes={"name": name, "data": data, "type": type, "extra": 
merged},
-        )
-        return updated_record
-
-    def delete_zone(self, zone):
-        params = {"api_action": "domain.delete", "DomainID": zone.id}
-
-        self.connection.set_context(context={"resource": "zone", "id": 
zone.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-
-        return "DomainID" in data
-
-    def delete_record(self, record):
-        params = {
-            "api_action": "domain.resource.delete",
-            "DomainID": record.zone.id,
-            "ResourceID": record.id,
-        }
-
-        self.connection.set_context(context={"resource": "record", "id": 
record.id})
-        data = self.connection.request(API_ROOT, params=params).objects[0]
-
-        return "ResourceID" in data
-
-    def _to_zones(self, items):
-        """
-        Convert a list of items to the Zone objects.
-        """
-        zones = []
-
-        for item in items:
-            zones.append(self._to_zone(item))
-
-        return zones
-
-    def _to_zone(self, item):
-        """
-        Build an Zone object from the item dictionary.
-        """
-        extra = {
-            "SOA_Email": item["SOA_EMAIL"],
-            "status": item["STATUS"],
-            "description": item["DESCRIPTION"],
-        }
-        zone = Zone(
-            id=item["DOMAINID"],
-            domain=item["DOMAIN"],
-            type=item["TYPE"],
-            ttl=item["TTL_SEC"],
-            driver=self,
-            extra=extra,
-        )
-        return zone
-
-    def _to_records(self, items, zone=None):
-        """
-        Convert a list of items to the Record objects.
-        """
-        records = []
-
-        for item in items:
-            records.append(self._to_record(item=item, zone=zone))
-
-        return records
-
-    def _to_record(self, item, zone=None):
-        """
-        Build a Record object from the item dictionary.
-        """
-        extra = {
-            "protocol": item["PROTOCOL"],
-            "ttl_sec": item["TTL_SEC"],
-            "port": item["PORT"],
-            "weight": item["WEIGHT"],
-            "priority": item["PRIORITY"],
-        }
-        type = self._string_to_record_type(item["TYPE"])
-        record = Record(
-            id=item["RESOURCEID"],
-            name=item["NAME"],
-            type=type,
-            data=item["TARGET"],
-            zone=zone,
-            driver=self,
-            ttl=item["TTL_SEC"],
-            extra=extra,
-        )
-        return record
-
-
 class LinodeDNSResponseV4(LinodeResponseV4):
     pass
 
diff --git a/libcloud/test/compute/fixtures/linode/_avail_datacenters.json 
b/libcloud/test/compute/fixtures/linode/_avail_datacenters.json
deleted file mode 100644
index eb169623b..000000000
--- a/libcloud/test/compute/fixtures/linode/_avail_datacenters.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "LOCATION": "Dallas, TX, USA",
-      "DATACENTERID": 2,
-      "ABBR": "dallas"
-    },
-    {
-      "LOCATION": "Fremont, CA, USA",
-      "DATACENTERID": 3,
-      "ABBR": "fremont"
-    },
-    {
-      "LOCATION": "Atlanta, GA, USA",
-      "DATACENTERID": 4,
-      "ABBR": "atlanta"
-    },
-    {
-      "LOCATION": "Newark, NJ, USA",
-      "DATACENTERID": 6,
-      "ABBR": "newark"
-    },
-    {
-      "LOCATION": "London, England, UK",
-      "DATACENTERID": 7,
-      "ABBR": "london"
-    },
-    {
-      "LOCATION": "Tokyo, JP",
-      "DATACENTERID": 8,
-      "ABBR": "tokyo"
-    }
-  ],
-  "ACTION": "avail.datacenters"
-}
\ No newline at end of file
diff --git a/libcloud/test/compute/fixtures/linode/_avail_distributions.json 
b/libcloud/test/compute/fixtures/linode/_avail_distributions.json
deleted file mode 100644
index f1bdee61b..000000000
--- a/libcloud/test/compute/fixtures/linode/_avail_distributions.json
+++ /dev/null
@@ -1,246 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 112,
-      "IS64BIT": 1,
-      "LABEL": "Arch Linux 2013.06",
-      "MINIMAGESIZE": 500,
-      "CREATE_DT": "2013-06-06 02:45:11.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 89,
-      "IS64BIT": 1,
-      "LABEL": "CentOS 6.2",
-      "MINIMAGESIZE": 800,
-      "CREATE_DT": "2011-07-19 11:38:20.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 78,
-      "IS64BIT": 1,
-      "LABEL": "Debian 6",
-      "MINIMAGESIZE": 550,
-      "CREATE_DT": "2011-02-08 16:54:31.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 109,
-      "IS64BIT": 1,
-      "LABEL": "Debian 7",
-      "MINIMAGESIZE": 660,
-      "CREATE_DT": "2013-05-08 11:31:32.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 114,
-      "IS64BIT": 1,
-      "LABEL": "Fedora 19",
-      "MINIMAGESIZE": 750,
-      "CREATE_DT": "2013-08-26 15:29:21.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 53,
-      "IS64BIT": 1,
-      "LABEL": "Gentoo",
-      "MINIMAGESIZE": 1000,
-      "CREATE_DT": "2009-04-04 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 115,
-      "IS64BIT": 1,
-      "LABEL": "openSUSE 12.3",
-      "MINIMAGESIZE": 1024,
-      "CREATE_DT": "2013-09-19 10:49:09.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 87,
-      "IS64BIT": 1,
-      "LABEL": "Slackware 13.37",
-      "MINIMAGESIZE": 600,
-      "CREATE_DT": "2011-06-05 15:11:59.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 65,
-      "IS64BIT": 1,
-      "LABEL": "Ubuntu 10.04 LTS",
-      "MINIMAGESIZE": 450,
-      "CREATE_DT": "2010-04-29 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 99,
-      "IS64BIT": 1,
-      "LABEL": "Ubuntu 12.04 LTS",
-      "MINIMAGESIZE": 600,
-      "CREATE_DT": "2012-04-26 17:25:16.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 111,
-      "IS64BIT": 1,
-      "LABEL": "Ubuntu 13.04",
-      "MINIMAGESIZE": 770,
-      "CREATE_DT": "2013-05-08 11:31:32.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 113,
-      "IS64BIT": 0,
-      "LABEL": "Arch Linux 2013.06 32bit",
-      "MINIMAGESIZE": 500,
-      "CREATE_DT": "2013-06-06 02:45:11.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 88,
-      "IS64BIT": 0,
-      "LABEL": "CentOS 6.2 32bit",
-      "MINIMAGESIZE": 800,
-      "CREATE_DT": "2011-07-19 11:38:20.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 77,
-      "IS64BIT": 0,
-      "LABEL": "Debian 6 32bit",
-      "MINIMAGESIZE": 550,
-      "CREATE_DT": "2011-02-08 16:54:31.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 108,
-      "IS64BIT": 0,
-      "LABEL": "Debian 7 32bit",
-      "MINIMAGESIZE": 660,
-      "CREATE_DT": "2013-05-08 11:31:32.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 72,
-      "IS64BIT": 0,
-      "LABEL": "Gentoo 32bit",
-      "MINIMAGESIZE": 1000,
-      "CREATE_DT": "2010-09-13 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 86,
-      "IS64BIT": 0,
-      "LABEL": "Slackware 13.37 32bit",
-      "MINIMAGESIZE": 600,
-      "CREATE_DT": "2011-06-05 15:11:59.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 64,
-      "IS64BIT": 0,
-      "LABEL": "Ubuntu 10.04 LTS 32bit",
-      "MINIMAGESIZE": 450,
-      "CREATE_DT": "2010-04-29 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 98,
-      "IS64BIT": 0,
-      "LABEL": "Ubuntu 12.04 LTS 32bit",
-      "MINIMAGESIZE": 600,
-      "CREATE_DT": "2012-04-26 17:25:16.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 110,
-      "IS64BIT": 0,
-      "LABEL": "Ubuntu 13.04 32bit",
-      "MINIMAGESIZE": 770,
-      "CREATE_DT": "2013-05-08 11:31:32.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 105,
-      "IS64BIT": 1,
-      "LABEL": "Arch Linux 2012.10",
-      "MINIMAGESIZE": 500,
-      "CREATE_DT": "2012-10-22 15:00:49.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 60,
-      "IS64BIT": 1,
-      "LABEL": "CentOS 5.6 64bit",
-      "MINIMAGESIZE": 950,
-      "CREATE_DT": "2009-08-17 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 100,
-      "IS64BIT": 1,
-      "LABEL": "Fedora 17",
-      "MINIMAGESIZE": 800,
-      "CREATE_DT": "2012-05-31 16:03:49.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 97,
-      "IS64BIT": 1,
-      "LABEL": "openSUSE 12.1",
-      "MINIMAGESIZE": 1000,
-      "CREATE_DT": "2012-04-13 11:43:30.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 107,
-      "IS64BIT": 1,
-      "LABEL": "Ubuntu 12.10",
-      "MINIMAGESIZE": 660,
-      "CREATE_DT": "2012-11-06 11:51:25.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 104,
-      "IS64BIT": 0,
-      "LABEL": "Arch Linux 2012.10 32bit",
-      "MINIMAGESIZE": 500,
-      "CREATE_DT": "2012-10-22 15:00:49.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 59,
-      "IS64BIT": 0,
-      "LABEL": "CentOS 5.6 32bit",
-      "MINIMAGESIZE": 950,
-      "CREATE_DT": "2009-08-17 00:00:00.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 101,
-      "IS64BIT": 0,
-      "LABEL": "Fedora 17 32bit",
-      "MINIMAGESIZE": 800,
-      "CREATE_DT": "2012-05-31 16:03:49.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 96,
-      "IS64BIT": 0,
-      "LABEL": "openSUSE 12.1 32bit",
-      "MINIMAGESIZE": 1000,
-      "CREATE_DT": "2012-04-13 11:43:30.0"
-    },
-    {
-      "REQUIRESPVOPSKERNEL": 1,
-      "DISTRIBUTIONID": 106,
-      "IS64BIT": 0,
-      "LABEL": "Ubuntu 12.10 32bit",
-      "MINIMAGESIZE": 660,
-      "CREATE_DT": "2012-11-06 11:51:25.0"
-    }
-  ],
-  "ACTION": "avail.distributions"
-}
\ No newline at end of file
diff --git a/libcloud/test/compute/fixtures/linode/_avail_kernels.json 
b/libcloud/test/compute/fixtures/linode/_avail_kernels.json
deleted file mode 100644
index 9552c46c5..000000000
--- a/libcloud/test/compute/fixtures/linode/_avail_kernels.json
+++ /dev/null
@@ -1,146 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "ACTION": "avail.kernels",
-  "DATA": [
-    {
-      "LABEL": "Latest 2.6 Stable (2.6.18.8-linode19)",
-      "ISXEN": 1,
-      "KERNELID": 60
-    },
-    {
-      "LABEL": "2.6.18.8-linode19",
-      "ISXEN": 1,
-      "KERNELID": 103
-    },
-    {
-      "LABEL": "2.6.30.5-linode20",
-      "ISXEN": 1,
-      "KERNELID": 105
-    },
-    {
-      "LABEL": "Latest 2.6 Stable (2.6.18.8-x86_64-linode7)",
-      "ISXEN": 1,
-      "KERNELID": 107
-    },
-    {
-      "LABEL": "2.6.18.8-x86_64-linode7",
-      "ISXEN": 1,
-      "KERNELID": 104
-    },
-    {
-      "LABEL": "2.6.30.5-x86_64-linode8",
-      "ISXEN": 1,
-      "KERNELID": 106
-    },
-    {
-      "LABEL": "pv-grub-x86_32",
-      "ISXEN": 1,
-      "KERNELID": 92
-    },
-    {
-      "LABEL": "pv-grub-x86_64",
-      "ISXEN": 1,
-      "KERNELID": 95
-    },
-    {
-      "LABEL": "Recovery - Finnix (kernel)",
-      "ISXEN": 1,
-      "KERNELID": 61
-    },
-    {
-      "LABEL": "2.6.18.8-domU-linode7",
-      "ISXEN": 1,
-      "KERNELID": 81
-    },
-    {
-      "LABEL": "2.6.18.8-linode10",
-      "ISXEN": 1,
-      "KERNELID": 89
-    },
-    {
-      "LABEL": "2.6.18.8-linode16",
-      "ISXEN": 1,
-      "KERNELID": 98
-    },
-    {
-      "LABEL": "2.6.24.4-linode8",
-      "ISXEN": 1,
-      "KERNELID": 84
-    },
-    {
-      "LABEL": "2.6.25-linode9",
-      "ISXEN": 1,
-      "KERNELID": 88
-    },
-    {
-      "LABEL": "2.6.25.10-linode12",
-      "ISXEN": 1,
-      "KERNELID": 90
-    },
-    {
-      "LABEL": "2.6.26-linode13",
-      "ISXEN": 1,
-      "KERNELID": 91
-    },
-    {
-      "LABEL": "2.6.27.4-linode14",
-      "ISXEN": 1,
-      "KERNELID": 93
-    },
-    {
-      "LABEL": "2.6.28-linode15",
-      "ISXEN": 1,
-      "KERNELID": 96
-    },
-    {
-      "LABEL": "2.6.28.3-linode17",
-      "ISXEN": 1,
-      "KERNELID": 99
-    },
-    {
-      "LABEL": "2.6.29-linode18",
-      "ISXEN": 1,
-      "KERNELID": 101
-    },
-    {
-      "LABEL": "2.6.16.38-x86_64-linode2",
-      "ISXEN": 1,
-      "KERNELID": 85
-    },
-    {
-      "LABEL": "2.6.18.8-x86_64-linode1",
-      "ISXEN": 1,
-      "KERNELID": 86
-    },
-    {
-      "LABEL": "2.6.27.4-x86_64-linode3",
-      "ISXEN": 1,
-      "KERNELID": 94
-    },
-    {
-      "LABEL": "2.6.28-x86_64-linode4",
-      "ISXEN": 1,
-      "KERNELID": 97
-    },
-    {
-      "LABEL": "2.6.28.3-x86_64-linode5",
-      "ISXEN": 1,
-      "KERNELID": 100
-    },
-    {
-      "LABEL": "2.6.29-x86_64-linode6",
-      "ISXEN": 1,
-      "KERNELID": 102
-    },
-    {
-      "LABEL": "3.9.3-x86-linode52",
-      "ISXEN": 1,
-      "KERNELID": 137
-    },
-    {
-      "LABEL": "3.9.3-x86_64-linode33",
-      "ISXEN": 1,
-      "KERNELID": 138
-    }
-  ]
-}
\ No newline at end of file
diff --git a/libcloud/test/compute/fixtures/linode/_avail_linodeplans.json 
b/libcloud/test/compute/fixtures/linode/_avail_linodeplans.json
deleted file mode 100644
index ac2488934..000000000
--- a/libcloud/test/compute/fixtures/linode/_avail_linodeplans.json
+++ /dev/null
@@ -1,158 +0,0 @@
-{
-    "ERRORARRAY": [],
-    "DATA": [{
-        "CORES": 1,
-        "PRICE": 10.00,
-        "RAM": 1024,
-        "XFER": 2000,
-        "PLANID": 1,
-        "LABEL": "Linode 1024",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 24,
-        "HOURLY": 0.0150
-    }, {
-        "CORES": 2,
-        "PRICE": 20.00,
-        "RAM": 2048,
-        "XFER": 3000,
-        "PLANID": 2,
-        "LABEL": "Linode 2048",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 48,
-        "HOURLY": 0.0300
-    }, {
-        "CORES": 4,
-        "PRICE": 40.00,
-        "RAM": 4096,
-        "XFER": 4000,
-        "PLANID": 4,
-        "LABEL": "Linode 4096",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 96,
-        "HOURLY": 0.0600
-    }, {
-        "CORES": 6,
-        "PRICE": 80.00,
-        "RAM": 8192,
-        "XFER": 8000,
-        "PLANID": 6,
-        "LABEL": "Linode 8192",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 192,
-        "HOURLY": 0.1200
-    }, {
-        "CORES": 8,
-        "PRICE": 160.00,
-        "RAM": 16384,
-        "XFER": 16000,
-        "PLANID": 7,
-        "LABEL": "Linode 16384",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 384,
-        "HOURLY": 0.2400
-    }, {
-        "CORES": 12,
-        "PRICE": 320.00,
-        "RAM": 32768,
-        "XFER": 20000,
-        "PLANID": 8,
-        "LABEL": "Linode 32768",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 768,
-        "HOURLY": 0.4800
-    }, {
-        "CORES": 16,
-        "PRICE": 480.00,
-        "RAM": 49152,
-        "XFER": 20000,
-        "PLANID": 9,
-        "LABEL": "Linode 49152",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 1152,
-        "HOURLY": 0.7200
-    }, {
-        "CORES": 20,
-        "PRICE": 640.00,
-        "RAM": 65536,
-        "XFER": 20000,
-        "PLANID": 10,
-        "LABEL": "Linode 65536",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 1536,
-        "HOURLY": 0.9600
-    }, {
-        "CORES": 20,
-        "PRICE": 960.00,
-        "RAM": 98304,
-        "XFER": 20000,
-        "PLANID": 12,
-        "LABEL": "Linode 98304",
-        "AVAIL": {
-            "3": 500,
-            "2": 500,
-            "7": 500,
-            "6": 500,
-            "4": 500,
-            "8": 500
-        },
-        "DISK": 1920,
-        "HOURLY": 1.4400
-    }],
-    "ACTION": "avail.linodeplans"
-}
diff --git a/libcloud/test/compute/fixtures/linode/_batch.json 
b/libcloud/test/compute/fixtures/linode/_batch.json
deleted file mode 100644
index 36e28f905..000000000
--- a/libcloud/test/compute/fixtures/linode/_batch.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-  {
-    "ERRORARRAY": [],
-    "DATA": [
-      {
-        "IPADDRESSID": 5384,
-        "RDNS_NAME": "li22-54.members.linode.com",
-        "LINODEID": 8098,
-        "ISPUBLIC": 1,
-        "IPADDRESS": "66.228.43.47"
-      },
-      {
-        "IPADDRESSID": 5575,
-        "RDNS_NAME": "li22-245.members.linode.com",
-        "LINODEID": 8098,
-        "ISPUBLIC": 1,
-        "IPADDRESS": "75.127.96.245"
-      }
-    ],
-    "ACTION": "linode.ip.list"
-  }
-]
diff --git a/libcloud/test/compute/fixtures/linode/_linode_disk_list.json 
b/libcloud/test/compute/fixtures/linode/_linode_disk_list.json
deleted file mode 100644
index 8ec05a9f1..000000000
--- a/libcloud/test/compute/fixtures/linode/_linode_disk_list.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-"ERRORARRAY":[],
-"ACTION":"linode.disk.list",
-"DATA":[
-        {
-            "UPDATE_DT":"2009-06-30 13:19:00.0",
-            "DISKID":55319,
-            "LABEL":"test label",
-            "TYPE":"ext3",
-            "LINODEID":8098,
-            "ISREADONLY":0,
-            "STATUS":1,
-            "CREATE_DT":"2008-04-04 10:08:06.0",
-            "SIZE":4096
-        },
-        {
-            "UPDATE_DT":"2009-07-18 12:53:043.0",
-            "DISKID":55320,
-            "LABEL":"256M Swap Image",
-            "TYPE":"swap",
-            "LINODEID":8098,
-            "ISREADONLY":0,
-            "STATUS":1,
-            "CREATE_DT":"2008-04-04 10:08:06.0",
-            "SIZE":256
-        }
-    ]
-}
diff --git a/libcloud/test/compute/fixtures/linode/_linode_ip_list.json 
b/libcloud/test/compute/fixtures/linode/_linode_ip_list.json
deleted file mode 100644
index 33a969ca6..000000000
--- a/libcloud/test/compute/fixtures/linode/_linode_ip_list.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "ACTION": "linode.ip.list",
-    "DATA": [
-        {
-            "IPADDRESS": "66.228.43.47",
-            "IPADDRESSID": 5384,
-            "ISPUBLIC": 1,
-            "LINODEID": 8098,
-            "RDNS_NAME": "li22-54.members.linode.com"
-        },
-        {
-            "IPADDRESS": "75.127.96.245",
-            "IPADDRESSID": 5575,
-            "ISPUBLIC": 1,
-            "LINODEID": 8098,
-            "RDNS_NAME": "li22-245.members.linode.com"
-        }
-    ],
-    "ERRORARRAY": []
-}
diff --git a/libcloud/test/compute/fixtures/linode/_linode_list.json 
b/libcloud/test/compute/fixtures/linode/_linode_list.json
deleted file mode 100644
index 345f7cadb..000000000
--- a/libcloud/test/compute/fixtures/linode/_linode_list.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "ALERT_CPU_ENABLED": 1,
-      "ALERT_BWIN_ENABLED": 1,
-      "ALERT_BWQUOTA_ENABLED": 1,
-      "BACKUPWINDOW": 0,
-      "ALERT_DISKIO_THRESHOLD": 1000,
-      "DISTRIBUTIONVENDOR": "Debian",
-      "WATCHDOG": 1,
-      "DATACENTERID": 6,
-      "STATUS": 1,
-      "ALERT_DISKIO_ENABLED": 1,
-      "CREATE_DT": "2012-05-04 19:31:30.0",
-      "TOTALHD": 49152,
-      "ALERT_BWQUOTA_THRESHOLD": 80,
-      "TOTALRAM": 2048,
-      "ALERT_BWIN_THRESHOLD": 5,
-      "LINODEID": 8098,
-      "ALERT_BWOUT_THRESHOLD": 5,
-      "ALERT_BWOUT_ENABLED": 1,
-      "BACKUPSENABLED": 1,
-      "ALERT_CPU_THRESHOLD": 90,
-      "PLANID": "2",
-      "BACKUPWEEKLYDAY": 0,
-      "LABEL": "api-node3",
-      "LPM_DISPLAYGROUP": "test",
-      "TOTALXFER": 3000
-    }
-  ],
-  "ACTION": "linode.list"
-}
diff --git a/libcloud/test/compute/test_linode.py 
b/libcloud/test/compute/test_linode.py
deleted file mode 100644
index bbe635448..000000000
--- a/libcloud/test/compute/test_linode.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Maintainer: Jed Smith <[email protected]>
-# Based upon code written by Alex Polvi <[email protected]>
-#
-
-import sys
-import unittest
-
-from libcloud.test import MockHttp
-from libcloud.utils.py3 import httplib
-from libcloud.compute.base import Node, StorageVolume, NodeAuthSSHKey, 
NodeAuthPassword
-from libcloud.test.compute import TestCaseMixin
-from libcloud.test.file_fixtures import ComputeFileFixtures
-from libcloud.compute.drivers.linode import LinodeNodeDriver
-
-
-class LinodeTest(unittest.TestCase, TestCaseMixin):
-    # The Linode test suite
-
-    def setUp(self):
-        LinodeNodeDriver.connectionCls.conn_class = LinodeMockHttp
-        LinodeMockHttp.use_param = "api_action"
-        self.driver = LinodeNodeDriver("foo", api_version="3.0")
-
-    def test_list_nodes(self):
-        nodes = self.driver.list_nodes()
-        self.assertEqual(len(nodes), 1)
-        node = nodes[0]
-        self.assertEqual(node.id, "8098")
-        self.assertEqual(node.name, "api-node3")
-        self.assertEqual(node.extra["PLANID"], "2")
-        self.assertTrue("75.127.96.245" in node.public_ips)
-        self.assertEqual(node.private_ips, [])
-
-    def test_reboot_node(self):
-        # An exception would indicate failure
-        node = self.driver.list_nodes()[0]
-        self.driver.reboot_node(node)
-
-    def test_destroy_node(self):
-        # An exception would indicate failure
-        node = self.driver.list_nodes()[0]
-        self.driver.destroy_node(node)
-
-    def test_create_node_password_auth(self):
-        # Will exception on failure
-        self.driver.create_node(
-            name="Test",
-            location=self.driver.list_locations()[0],
-            size=self.driver.list_sizes()[0],
-            image=self.driver.list_images()[6],
-            auth=NodeAuthPassword("test123"),
-        )
-
-    def test_create_node_ssh_key_auth(self):
-        # Will exception on failure
-        node = self.driver.create_node(
-            name="Test",
-            location=self.driver.list_locations()[0],
-            size=self.driver.list_sizes()[0],
-            image=self.driver.list_images()[6],
-            auth=NodeAuthSSHKey("foo"),
-        )
-        self.assertTrue(isinstance(node, Node))
-
-    def test_list_sizes(self):
-        sizes = self.driver.list_sizes()
-        self.assertEqual(len(sizes), 9)
-        for size in sizes:
-            self.assertEqual(size.ram, int(size.name.split(" ")[1]))
-
-    def test_list_images(self):
-        images = self.driver.list_images()
-        self.assertEqual(len(images), 30)
-
-    def test_create_node_response(self):
-        # should return a node object
-        node = self.driver.create_node(
-            name="node-name",
-            location=self.driver.list_locations()[0],
-            size=self.driver.list_sizes()[0],
-            image=self.driver.list_images()[0],
-            auth=NodeAuthPassword("foobar"),
-        )
-        self.assertTrue(isinstance(node, Node))
-
-    def test_destroy_volume(self):
-        # Will exception on failure
-        node = self.driver.list_nodes()[0]
-        volume = StorageVolume(
-            id=55648,
-            name="test",
-            size=1024,
-            driver=self.driver,
-            extra={"LINODEID": node.id},
-        )
-        self.driver.destroy_volume(volume)
-
-    def test_ex_create_volume(self):
-        # should return a StorageVolume object
-        node = self.driver.list_nodes()[0]
-        volume = self.driver.ex_create_volume(
-            size=4096, name="Another test image", node=node, fs_type="ext4"
-        )
-        self.assertTrue(isinstance(volume, StorageVolume))
-
-    def test_ex_list_volumes(self):
-        # should return list of StorageVolume objects
-        node = self.driver.list_nodes()[0]
-        volumes = self.driver.ex_list_volumes(node=node)
-
-        self.assertTrue(isinstance(volumes, list))
-        self.assertTrue(isinstance(volumes[0], StorageVolume))
-        self.assertEqual(len(volumes), 2)
-
-
-class LinodeMockHttp(MockHttp):
-    fixtures = ComputeFileFixtures("linode")
-
-    def _avail_datacenters(self, method, url, body, headers):
-        body = self.fixtures.load("_avail_datacenters.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _avail_linodeplans(self, method, url, body, headers):
-        body = self.fixtures.load("_avail_linodeplans.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _avail_distributions(self, method, url, body, headers):
-        body = self.fixtures.load("_avail_distributions.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_create(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.create","DATA":{"LinodeID":8098}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_disk_create(self, method, url, body, headers):
-        body = (
-            
'{"ERRORARRAY":[],"ACTION":"linode.disk.create","DATA":{"JobID":1298,"DiskID":55647}}'
-        )
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_disk_delete(self, method, url, body, headers):
-        body = (
-            
'{"ERRORARRAY":[],"ACTION":"linode.disk.delete","DATA":{"JobID":1298,"DiskID":55648}}'
-        )
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_disk_createfromdistribution(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.disk.createFromDistribution","DATA":{"JobID":1298,"DiskID":55647}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_disk_list(self, method, url, body, headers):
-        body = self.fixtures.load("_linode_disk_list.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_delete(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.delete","DATA":{"LinodeID":8098}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_update(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.update","DATA":{"LinodeID":8098}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_reboot(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.reboot","DATA":{"JobID":1305}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _avail_kernels(self, method, url, body, headers):
-        body = self.fixtures.load("_avail_kernels.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_boot(self, method, url, body, headers):
-        body = '{"ERRORARRAY":[],"ACTION":"linode.boot","DATA":{"JobID":1300}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_config_create(self, method, url, body, headers):
-        body = 
'{"ERRORARRAY":[],"ACTION":"linode.config.create","DATA":{"ConfigID":31239}}'
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_list(self, method, url, body, headers):
-        body = self.fixtures.load("_linode_list.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _linode_ip_list(self, method, url, body, headers):
-        body = self.fixtures.load("_linode_ip_list.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _batch(self, method, url, body, headers):
-        body = self.fixtures.load("_batch.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-
-if __name__ == "__main__":
-    sys.exit(unittest.main())
diff --git a/libcloud/test/compute/test_linode_v4.py 
b/libcloud/test/compute/test_linode_v4.py
index ed5d5d2e5..2bae27938 100644
--- a/libcloud/test/compute/test_linode_v4.py
+++ b/libcloud/test/compute/test_linode_v4.py
@@ -47,6 +47,9 @@ class LinodeTestsV4(unittest.TestCase, TestCaseMixin):
     def test_unknown_api_version(self):
         self.assertRaises(NotImplementedError, LinodeNodeDriver, "foo", 
api_version="2.0")
 
+    def test_removed_api_version(self):
+        self.assertRaises(NotImplementedError, LinodeNodeDriver, "foo", 
api_version="3.0")
+
     def test_correct_class_is_used(self):
         self.assertIsInstance(self.driver, LinodeNodeDriverV4)
 
diff --git a/libcloud/test/dns/fixtures/linode/create_domain.json 
b/libcloud/test/dns/fixtures/linode/create_domain.json
deleted file mode 100644
index a9eef97a0..000000000
--- a/libcloud/test/dns/fixtures/linode/create_domain.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "ACTION": "domain.create",
-  "DATA": {
-    "DomainID": 5094
-  }
-}
\ No newline at end of file
diff --git 
a/libcloud/test/dns/fixtures/linode/create_domain_validation_error.json 
b/libcloud/test/dns/fixtures/linode/create_domain_validation_error.json
deleted file mode 100644
index 3c7059724..000000000
--- a/libcloud/test/dns/fixtures/linode/create_domain_validation_error.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 8,
-      "ERRORMESSAGE": "The domain 'linode.com' already exists in our database. 
 Please open a ticket if you think this is in error."
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.create"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/create_resource.json 
b/libcloud/test/dns/fixtures/linode/create_resource.json
deleted file mode 100644
index 0fa3738e3..000000000
--- a/libcloud/test/dns/fixtures/linode/create_resource.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": {
-    "ResourceID": 3585100
-  },
-  "ACTION": "domain.resource.create"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/delete_domain.json 
b/libcloud/test/dns/fixtures/linode/delete_domain.json
deleted file mode 100644
index ff39a38ed..000000000
--- a/libcloud/test/dns/fixtures/linode/delete_domain.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "ACTION": "domain.delete",
-  "DATA": {
-    "DomainID": 5123
-  }
-}
\ No newline at end of file
diff --git 
a/libcloud/test/dns/fixtures/linode/delete_domain_does_not_exist.json 
b/libcloud/test/dns/fixtures/linode/delete_domain_does_not_exist.json
deleted file mode 100644
index 8965baa6e..000000000
--- a/libcloud/test/dns/fixtures/linode/delete_domain_does_not_exist.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 5,
-      "ERRORMESSAGE": "Object not found"
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.delete"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/delete_resource.json 
b/libcloud/test/dns/fixtures/linode/delete_resource.json
deleted file mode 100644
index 7f7af2adb..000000000
--- a/libcloud/test/dns/fixtures/linode/delete_resource.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": {
-    "ResourceID": 3585141
-  },
-  "ACTION": "domain.resource.delete"
-}
\ No newline at end of file
diff --git 
a/libcloud/test/dns/fixtures/linode/delete_resource_does_not_exist.json 
b/libcloud/test/dns/fixtures/linode/delete_resource_does_not_exist.json
deleted file mode 100644
index b6969aa64..000000000
--- a/libcloud/test/dns/fixtures/linode/delete_resource_does_not_exist.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 5,
-      "ERRORMESSAGE": "Object not found"
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.resource.delete"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/domain_list.json 
b/libcloud/test/dns/fixtures/linode/domain_list.json
deleted file mode 100644
index ac88b9b5e..000000000
--- a/libcloud/test/dns/fixtures/linode/domain_list.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "ACTION": "domain.list",
-  "DATA": [
-    {
-      "DOMAINID": 5093,
-      "DESCRIPTION": "",
-      "EXPIRE_SEC": 0,
-      "RETRY_SEC": 0,
-      "STATUS": 1,
-      "LPM_DISPLAYGROUP": "thing",
-      "MASTER_IPS": "",
-      "REFRESH_SEC": 0,
-      "SOA_EMAIL": "[email protected]",
-      "TTL_SEC": 0,
-      "DOMAIN": "linode.com",
-      "AXFR_IPS": "none",
-      "TYPE": "master"
-    },
-    {
-      "DOMAINID": 5094,
-      "DESCRIPTION": "",
-      "EXPIRE_SEC": 0,
-      "RETRY_SEC": 0,
-      "STATUS": 1,
-      "LPM_DISPLAYGROUP": "",
-      "MASTER_IPS": "2600:3c03::f03c:91ff:feae:e071;66.228.43.47;",
-      "REFRESH_SEC": 0,
-      "SOA_EMAIL": "",
-      "TTL_SEC": 0,
-      "DOMAIN": "0.c.d.7.0.6.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa",
-      "AXFR_IPS": "2600:3c03::f03c:91ff:feae:e071;66.228.43.47;",
-      "TYPE": "slave"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/get_record.json 
b/libcloud/test/dns/fixtures/linode/get_record.json
deleted file mode 100644
index 4d5b0eb59..000000000
--- a/libcloud/test/dns/fixtures/linode/get_record.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "DOMAINID": 5093,
-      "PORT": 80,
-      "RESOURCEID": 3585100,
-      "NAME": "www",
-      "WEIGHT": 5,
-      "TTL_SEC": 0,
-      "TARGET": "127.0.0.1",
-      "PRIORITY": 10,
-      "PROTOCOL": "",
-      "TYPE": "a"
-    }
-  ],
-  "ACTION": "domain.resource.list"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/get_record_does_not_exist.json 
b/libcloud/test/dns/fixtures/linode/get_record_does_not_exist.json
deleted file mode 100644
index c2c1fb499..000000000
--- a/libcloud/test/dns/fixtures/linode/get_record_does_not_exist.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 5,
-      "ERRORMESSAGE": "Object not found"
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.resource.list"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/get_zone.json 
b/libcloud/test/dns/fixtures/linode/get_zone.json
deleted file mode 100644
index e9387122f..000000000
--- a/libcloud/test/dns/fixtures/linode/get_zone.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "DOMAINID": 5093,
-      "DESCRIPTION": "",
-      "EXPIRE_SEC": 0,
-      "RETRY_SEC": 0,
-      "STATUS": 1,
-      "LPM_DISPLAYGROUP": "thing",
-      "MASTER_IPS": "",
-      "REFRESH_SEC": 0,
-      "SOA_EMAIL": "[email protected]",
-      "TTL_SEC": 0,
-      "DOMAIN": "linode.com",
-      "AXFR_IPS": "none",
-      "TYPE": "master"
-    }
-  ],
-  "ACTION": "domain.list"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/get_zone_does_not_exist.json 
b/libcloud/test/dns/fixtures/linode/get_zone_does_not_exist.json
deleted file mode 100644
index ea18547f5..000000000
--- a/libcloud/test/dns/fixtures/linode/get_zone_does_not_exist.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 5,
-      "ERRORMESSAGE": "Object not found"
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.list"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/resource_list.json 
b/libcloud/test/dns/fixtures/linode/resource_list.json
deleted file mode 100644
index 2ed18cd82..000000000
--- a/libcloud/test/dns/fixtures/linode/resource_list.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": [
-    {
-      "DOMAINID": 5093,
-      "PORT": 80,
-      "RESOURCEID": 3585100,
-      "NAME": "mc",
-      "WEIGHT": 5,
-      "TTL_SEC": 0,
-      "TARGET": "127.0.0.1",
-      "PRIORITY": 10,
-      "PROTOCOL": "",
-      "TYPE": "a"
-    },
-    {
-      "DOMAINID": 5093,
-      "PORT": 25565,
-      "RESOURCEID": 3585141,
-      "NAME": "_minecraft._udp",
-      "WEIGHT": 5,
-      "TTL_SEC": 0,
-      "TARGET": "mc.linode.com",
-      "PRIORITY": 10,
-      "PROTOCOL": "udp",
-      "TYPE": "srv"
-    }
-  ],
-  "ACTION": "domain.resource.list"
-}
\ No newline at end of file
diff --git 
a/libcloud/test/dns/fixtures/linode/resource_list_does_not_exist.json 
b/libcloud/test/dns/fixtures/linode/resource_list_does_not_exist.json
deleted file mode 100644
index c2c1fb499..000000000
--- a/libcloud/test/dns/fixtures/linode/resource_list_does_not_exist.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "ERRORARRAY": [
-    {
-      "ERRORCODE": 5,
-      "ERRORMESSAGE": "Object not found"
-    }
-  ],
-  "DATA": {},
-  "ACTION": "domain.resource.list"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/update_domain.json 
b/libcloud/test/dns/fixtures/linode/update_domain.json
deleted file mode 100644
index f695f4c10..000000000
--- a/libcloud/test/dns/fixtures/linode/update_domain.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": {
-    "DomainID": 5093
-  },
-  "ACTION": "domain.update"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/fixtures/linode/update_resource.json 
b/libcloud/test/dns/fixtures/linode/update_resource.json
deleted file mode 100644
index 7f88aabe6..000000000
--- a/libcloud/test/dns/fixtures/linode/update_resource.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "ERRORARRAY": [],
-  "DATA": {
-    "ResourceID": 3585100
-  },
-  "ACTION": "domain.resource.update"
-}
\ No newline at end of file
diff --git a/libcloud/test/dns/test_linode.py b/libcloud/test/dns/test_linode.py
deleted file mode 100644
index 7e6b3439b..000000000
--- a/libcloud/test/dns/test_linode.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-
-import sys
-import unittest
-
-from libcloud.test import MockHttp
-from libcloud.dns.types import RecordType, ZoneDoesNotExistError, 
RecordDoesNotExistError
-from libcloud.utils.py3 import httplib
-from libcloud.test.secrets import DNS_PARAMS_LINODE, DNS_KEYWORD_PARAMS_LINODE
-from libcloud.common.linode import LinodeException
-from libcloud.dns.drivers.linode import LinodeDNSDriver, LinodeDNSDriverV3
-from libcloud.test.file_fixtures import DNSFileFixtures
-
-
-class LinodeTests(unittest.TestCase):
-    def setUp(self):
-        LinodeDNSDriverV3.connectionCls.conn_class = LinodeMockHttp
-        LinodeMockHttp.use_param = "api_action"
-        LinodeMockHttp.type = None
-        self.driver = LinodeDNSDriver(*DNS_PARAMS_LINODE, 
**DNS_KEYWORD_PARAMS_LINODE)
-
-    def assertHasKeys(self, dictionary, keys):
-        for key in keys:
-            self.assertTrue(key in dictionary, 'key "%s" not in dictionary' % 
(key))
-
-    def test_list_record_types(self):
-        record_types = self.driver.list_record_types()
-        self.assertEqual(len(record_types), 7)
-        self.assertTrue(RecordType.A in record_types)
-
-    def test_list_zones_success(self):
-        zones = self.driver.list_zones()
-        self.assertEqual(len(zones), 2)
-
-        zone = zones[0]
-        self.assertEqual(zone.id, "5093")
-        self.assertEqual(zone.type, "master")
-        self.assertEqual(zone.domain, "linode.com")
-        self.assertIsNone(zone.ttl)
-        self.assertHasKeys(zone.extra, ["description", "SOA_Email", "status"])
-
-    def test_list_records_success(self):
-        zone = self.driver.list_zones()[0]
-        records = self.driver.list_records(zone=zone)
-        self.assertEqual(len(records), 2)
-
-        arecord = records[0]
-        self.assertEqual(arecord.id, "3585100")
-        self.assertEqual(arecord.name, "mc")
-        self.assertEqual(arecord.type, RecordType.A)
-        self.assertEqual(arecord.data, "127.0.0.1")
-        self.assertHasKeys(arecord.extra, ["protocol", "ttl_sec", "port", 
"weight"])
-
-        srvrecord = records[1]
-        self.assertEqual(srvrecord.id, "3585141")
-        self.assertEqual(srvrecord.name, "_minecraft._udp")
-        self.assertEqual(srvrecord.type, RecordType.SRV)
-        self.assertEqual(srvrecord.data, "mc.linode.com")
-        self.assertHasKeys(srvrecord.extra, ["protocol", "ttl_sec", "port", 
"priority", "weight"])
-
-    def test_list_records_zone_does_not_exist(self):
-        zone = self.driver.list_zones()[0]
-
-        LinodeMockHttp.type = "ZONE_DOES_NOT_EXIST"
-        try:
-            self.driver.list_records(zone=zone)
-        except ZoneDoesNotExistError as e:
-            self.assertEqual(e.zone_id, zone.id)
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_get_zone_success(self):
-        LinodeMockHttp.type = "GET_ZONE"
-
-        zone = self.driver.get_zone(zone_id="5093")
-        self.assertEqual(zone.id, "5093")
-        self.assertEqual(zone.type, "master")
-        self.assertEqual(zone.domain, "linode.com")
-        self.assertIsNone(zone.ttl)
-        self.assertHasKeys(zone.extra, ["description", "SOA_Email", "status"])
-
-    def test_get_zone_does_not_exist(self):
-        LinodeMockHttp.type = "GET_ZONE_DOES_NOT_EXIST"
-
-        try:
-            self.driver.get_zone(zone_id="4444")
-        except ZoneDoesNotExistError as e:
-            self.assertEqual(e.zone_id, "4444")
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_get_record_success(self):
-        LinodeMockHttp.type = "GET_RECORD"
-        record = self.driver.get_record(zone_id="1234", record_id="3585100")
-        self.assertEqual(record.id, "3585100")
-        self.assertEqual(record.name, "www")
-        self.assertEqual(record.type, RecordType.A)
-        self.assertEqual(record.data, "127.0.0.1")
-        self.assertHasKeys(record.extra, ["protocol", "ttl_sec", "port", 
"weight"])
-
-    def test_get_record_zone_does_not_exist(self):
-        LinodeMockHttp.type = "GET_RECORD_ZONE_DOES_NOT_EXIST"
-
-        try:
-            self.driver.get_record(zone_id="444", record_id="3585100")
-        except ZoneDoesNotExistError:
-            pass
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_get_record_record_does_not_exist(self):
-        LinodeMockHttp.type = "GET_RECORD_RECORD_DOES_NOT_EXIST"
-
-        try:
-            self.driver.get_record(zone_id="4441", record_id="3585100")
-        except RecordDoesNotExistError:
-            pass
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_create_zone_success(self):
-        zone = self.driver.create_zone(domain="foo.bar.com", type="master", 
ttl=None, extra=None)
-        self.assertEqual(zone.id, "5094")
-        self.assertEqual(zone.domain, "foo.bar.com")
-
-    def test_create_zone_validaton_error(self):
-        LinodeMockHttp.type = "VALIDATION_ERROR"
-
-        try:
-            self.driver.create_zone(domain="foo.bar.com", type="master", 
ttl=None, extra=None)
-        except LinodeException:
-            pass
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_update_zone_success(self):
-        zone = self.driver.list_zones()[0]
-        updated_zone = self.driver.update_zone(
-            zone=zone,
-            domain="libcloud.org",
-            ttl=10,
-            extra={"SOA_Email": "[email protected]"},
-        )
-
-        self.assertEqual(zone.extra["SOA_Email"], "[email protected]")
-
-        self.assertEqual(updated_zone.id, zone.id)
-        self.assertEqual(updated_zone.domain, "libcloud.org")
-        self.assertEqual(updated_zone.type, zone.type)
-        self.assertEqual(updated_zone.ttl, 10)
-        self.assertEqual(updated_zone.extra["SOA_Email"], "[email protected]")
-        self.assertEqual(updated_zone.extra["status"], zone.extra["status"])
-        self.assertEqual(updated_zone.extra["description"], 
zone.extra["description"])
-
-    def test_create_record_success(self):
-        zone = self.driver.list_zones()[0]
-        record = self.driver.create_record(
-            name="www", zone=zone, type=RecordType.A, data="127.0.0.1"
-        )
-
-        self.assertEqual(record.id, "3585100")
-        self.assertEqual(record.name, "www")
-        self.assertEqual(record.zone, zone)
-        self.assertEqual(record.type, RecordType.A)
-        self.assertEqual(record.data, "127.0.0.1")
-
-    def test_update_record_success(self):
-        zone = self.driver.list_zones()[0]
-        record = self.driver.list_records(zone=zone)[0]
-        updated_record = self.driver.update_record(
-            record=record, name="www", type=RecordType.AAAA, data="::1"
-        )
-
-        self.assertEqual(record.data, "127.0.0.1")
-
-        self.assertEqual(updated_record.id, record.id)
-        self.assertEqual(updated_record.name, "www")
-        self.assertEqual(updated_record.zone, record.zone)
-        self.assertEqual(updated_record.type, RecordType.AAAA)
-        self.assertEqual(updated_record.data, "::1")
-
-    def test_delete_zone_success(self):
-        zone = self.driver.list_zones()[0]
-        status = self.driver.delete_zone(zone=zone)
-        self.assertTrue(status)
-
-    def test_delete_zone_does_not_exist(self):
-        zone = self.driver.list_zones()[0]
-
-        LinodeMockHttp.type = "ZONE_DOES_NOT_EXIST"
-
-        try:
-            self.driver.delete_zone(zone=zone)
-        except ZoneDoesNotExistError as e:
-            self.assertEqual(e.zone_id, zone.id)
-        else:
-            self.fail("Exception was not thrown")
-
-    def test_delete_record_success(self):
-        zone = self.driver.list_zones()[0]
-        record = self.driver.list_records(zone=zone)[0]
-        status = self.driver.delete_record(record=record)
-        self.assertTrue(status)
-
-    def test_delete_record_does_not_exist(self):
-        zone = self.driver.list_zones()[0]
-        record = self.driver.list_records(zone=zone)[0]
-
-        LinodeMockHttp.type = "RECORD_DOES_NOT_EXIST"
-
-        try:
-            self.driver.delete_record(record=record)
-        except RecordDoesNotExistError as e:
-            self.assertEqual(e.record_id, record.id)
-        else:
-            self.fail("Exception was not thrown")
-
-
-class LinodeMockHttp(MockHttp):
-    fixtures = DNSFileFixtures("linode")
-
-    def _domain_list(self, method, url, body, headers):
-        body = self.fixtures.load("domain_list.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_resource_list(self, method, url, body, headers):
-        body = self.fixtures.load("resource_list.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _ZONE_DOES_NOT_EXIST_domain_resource_list(self, method, url, body, 
headers):
-        body = self.fixtures.load("resource_list_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_ZONE_domain_list(self, method, url, body, headers):
-        body = self.fixtures.load("get_zone.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_ZONE_DOES_NOT_EXIST_domain_list(self, method, url, body, headers):
-        body = self.fixtures.load("get_zone_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_domain_list(self, method, url, body, headers):
-        body = self.fixtures.load("get_zone.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_domain_resource_list(self, method, url, body, headers):
-        body = self.fixtures.load("get_record.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_ZONE_DOES_NOT_EXIST_domain_list(self, method, url, body, 
headers):
-        body = self.fixtures.load("get_zone_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_ZONE_DOES_NOT_EXIST_domain_resource_list(self, method, 
url, body, headers):
-        body = self.fixtures.load("get_record_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_RECORD_DOES_NOT_EXIST_domain_list(self, method, url, body, 
headers):
-        body = self.fixtures.load("get_zone.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _GET_RECORD_RECORD_DOES_NOT_EXIST_domain_resource_list(self, method, 
url, body, headers):
-        body = self.fixtures.load("get_record_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_create(self, method, url, body, headers):
-        body = self.fixtures.load("create_domain.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _VALIDATION_ERROR_domain_create(self, method, url, body, headers):
-        body = self.fixtures.load("create_domain_validation_error.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_update(self, method, url, body, headers):
-        body = self.fixtures.load("update_domain.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_resource_create(self, method, url, body, headers):
-        body = self.fixtures.load("create_resource.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_resource_update(self, method, url, body, headers):
-        body = self.fixtures.load("update_resource.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_delete(self, method, url, body, headers):
-        body = self.fixtures.load("delete_domain.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _ZONE_DOES_NOT_EXIST_domain_delete(self, method, url, body, headers):
-        body = self.fixtures.load("delete_domain_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _domain_resource_delete(self, method, url, body, headers):
-        body = self.fixtures.load("delete_resource.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _RECORD_DOES_NOT_EXIST_domain_resource_delete(self, method, url, body, 
headers):
-        body = self.fixtures.load("delete_resource_does_not_exist.json")
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-
-if __name__ == "__main__":
-    sys.exit(unittest.main())
diff --git a/libcloud/test/dns/test_linode_v4.py 
b/libcloud/test/dns/test_linode_v4.py
index 3b461f74c..df20b360a 100644
--- a/libcloud/test/dns/test_linode_v4.py
+++ b/libcloud/test/dns/test_linode_v4.py
@@ -35,6 +35,9 @@ class LinodeTests(unittest.TestCase):
     def test_unknown_api_version(self):
         self.assertRaises(NotImplementedError, LinodeDNSDriver, "foo", 
api_version="2.0")
 
+    def test_removed_api_version(self):
+        self.assertRaises(NotImplementedError, LinodeDNSDriver, "foo", 
api_version="3.0")
+
     def test_list_zones(self):
         zones = self.driver.list_zones()
         self.assertEqual(len(zones), 3)


Reply via email to