diff --git a/demos/compute_demo.py b/demos/compute_demo.py
index e9f120f..37ad482 100644
--- a/demos/compute_demo.py
+++ b/demos/compute_demo.py
@@ -36,7 +36,7 @@ sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__),
 
 from libcloud.common.types import InvalidCredsError
 from libcloud.compute.types import Provider
-from libcloud.providers import get_driver
+from libcloud.compute.providers import get_driver
 
 from pprint import pprint
 
diff --git a/demos/google_compute_engine/demo.py b/demos/google_compute_engine/demo.py
new file mode 100644
index 0000000..f32af5e
--- /dev/null
+++ b/demos/google_compute_engine/demo.py
@@ -0,0 +1,119 @@
+# 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.
+
+import libcloud.test.secrets as secrets
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+from pprint import pprint
+
+# Set up your compute driver
+GoogleComputeEngine = get_driver(Provider.GCE)
+
+# Instantiate your compute driver with the required credentials. For Google
+# Compute Engine, these are (ssh_username, ssh_private_key_file, project).
+ssh_username, ssh_private_key_file, project = getattr(secrets,
+                                                      'GCE_PARAMS',
+                                                      ())
+driver = GoogleComputeEngine(ssh_username, ssh_private_key_file, project)
+
+# Get the list of available images.
+images = driver.list_images()
+print "List of images:"
+pprint(images)
+print "\n"
+
+# Get the list of available sizes (machine types).
+sizes = driver.list_sizes()
+print "List of sizes (machine types):"
+pprint(sizes)
+print "\n"
+
+# Get the list of available locations.
+locations = driver.list_locations()
+print "List of locations:"
+pprint(locations)
+print "\n"
+
+# Create a new node, 'new_node_name', using a machine type, image, and location
+# from the list of available machine types, images, and locations.
+image = images[-1]
+size = sizes[0]
+location = locations[0]
+new_node_name = 'my-new-node'
+node = driver.create_node(new_node_name, size, image, location)
+print "Creating a new node:", node.name
+pprint(node)
+print "\n"
+
+# Print metadata for node. This will contain a script if bootstrapping node
+# with a startup script.
+print "Metadata for:", node.name
+pprint(node.extra['metadata'])
+print "\n"
+
+# Get the list of nodes in your cluster.
+nodes = driver.list_nodes()
+print "List of nodes:"
+pprint(nodes)
+print "\n"
+
+# To see the following command take effect, ssh into 'new_node_name'.
+# Restarting 'new_node_name'.
+ret = driver.reboot_node(node)
+if ret:
+    print "Successfully rebooted:", node.name
+else:
+    print "Unsuccessful in rebooting:", node.name
+pprint(node)
+print "\n"
+
+# To see the following command take effect, ssh into 'new_node_name'.
+# Deleting 'new_node_name'.
+ret = driver.destroy_node(node)
+if ret:
+    print "Successfully deleted:", node.name
+else:
+    print "Unsuccessful in deleting:", node.name
+pprint(node)
+print "\n"
+
+# Create a new node, 'new_node_name', using a machine type, image, and location
+# from the list of available machine types, images, and locations.
+# The node will be bootstrapped by running a desired script on first
+# initialization.
+script = ''  # Full path to your bootstrap script.
+node = driver.deploy_node(node.name, size, image, location, script)
+print "Creating a new node:", node.name, " and deploying it with script \
+from", script
+pprint(node)
+print "\n"
+
+# Print metadata for node.
+print "Metadata for:", node.name
+pprint(node.extra['metadata'])
+print "\n"
+
+# Delete all nodes in cluster.
+print "Deleting all nodes in cluster.\n"
+for node in driver.list_nodes():
+    node.destroy()
+
+# Get the list of nodes in your cluster. This should return an empty list.
+nodes = driver.list_nodes()
+print "List of nodes:"
+pprint(nodes)
+print "\n"
diff --git a/libcloud/compute/drivers/__init__.py b/libcloud/compute/drivers/__init__.py
index 6b71f02..9d8f291 100644
--- a/libcloud/compute/drivers/__init__.py
+++ b/libcloud/compute/drivers/__init__.py
@@ -37,4 +37,5 @@ __all__ = [
     'vcloud',
     'voxel',
     'vpsnet',
+    'gce',
 ]
diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py
new file mode 100644
index 0000000..12f1df2
--- /dev/null
+++ b/libcloud/compute/drivers/gce.py
@@ -0,0 +1,384 @@
+# 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.
+
+"""
+Libcloud driver for Google Compute Engine.
+
+Google Compute Engine home page:
+cloud.google.com/products/compute-engine.html
+
+Google Compute Engine documentation:
+developers.google.com/compute/docs
+"""
+
+import getpass
+import os
+import paramiko
+import sys
+
+from gcelib import gce, gce_util, shortcuts
+
+from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeLocation
+from libcloud.compute.base import NodeSize
+from libcloud.compute.providers import Provider
+from libcloud.compute.types import NodeState
+
+
+class GoogleComputeEngineNodeDriver(NodeDriver):
+    """
+    Google Compute Engine Node Driver
+    """
+    api_name = 'gce'
+    type = Provider.GCE
+    name = 'GoogleComputeEngine'
+
+    NODE_STATE_MAP = {
+        "PROVISIONING": NodeState.PENDING,
+        "STAGING": NodeState.PENDING,
+        "RUNNING": NodeState.RUNNING,
+        "STOPPED": NodeState.TERMINATED,
+        "TERMINATED": NodeState.TERMINATED
+    }
+
+    def __init__(self, ssh_username=None, ssh_private_key_file=None,
+                 project=None, key=None):
+        """
+        @param      ssh_username: The username that can be used to log into
+        Google Compute Engine nodes in a cluster (required).
+        @type       ssh_username: C{str}
+
+        @param      ssh_private_key_file: The fully qualified path to the ssh
+        private key file (required).
+        @type       ssh_private_key_file: C{str}
+
+        @param      project: The name of the Google Compute Engine project
+        (required).
+        @type       project: C{str}
+
+        @rtype: None
+        """
+        super(GoogleComputeEngineNodeDriver, self).__init__(key)
+        self.credentials = gce_util.get_credentials()
+
+        if project:
+            self.project = project
+        else:
+            print "Please specify the project in your Driver's constructor."
+            sys.exit(1)
+
+        if ssh_username:
+            self.ssh_username = ssh_username
+        else:
+            print "Please specify your ssh username in your Driver's \
+                constructor."
+            sys.exit(1)
+
+        if ssh_private_key_file:
+            self.ssh_private_key_file = ssh_private_key_file
+        else:
+            print "Please specify your ssh private key file in your Driver's \
+            constructor."
+            sys.exit(1)
+
+        self.default_zone = 'us-central1-a'
+        self.default_image = 'projects/google/images/ubuntu-12-04-v20120621'
+        self.default_machine_type = 'n1-standard-1'
+
+        self.SSHClient = paramiko.SSHClient()
+        self.gcelib_instance = gce.get_api(self.credentials,
+                                           default_project=self.project,
+                                           default_zone=self.default_zone,
+                                           default_image=self.default_image,
+                                           default_machine_type=
+                                           self.default_machine_type)
+
+    def list_nodes(self):
+        """
+        List all Google Compute Engine nodes associated with the current
+        project.
+
+        @rtype: C{list} of L{Node}
+        """
+        list_nodes = []
+
+        for instance in self.gcelib_instance.all_instances():
+            node = self._to_node(instance)
+            list_nodes.append(node)
+
+        return list_nodes
+
+    def list_images(self):
+        """
+        List all available Google Compute Engine distribution images.
+
+        @rtype: C{list} of L{NodeImage}
+        """
+        list_images = []
+
+        for img in self.gcelib_instance.list_images(project='google'):
+            image = self._to_node_image(img)
+            list_images.append(image)
+
+        return list_images
+
+    def list_sizes(self, location=None):
+        """
+        List all available Google Compute Engine node sizes (machine types).
+
+        @keyword location: The location at which to list sizes (optional).
+        @type    location: L{NodeLocation}
+
+        @rtype: C{list} of L{NodeSize}
+        """
+        list_sizes = []
+
+        for machine_type in self.gcelib_instance.list_machine_types():
+            size = self._to_node_size(machine_type)
+            list_sizes.append(size)
+
+        return list_sizes
+
+    def list_locations(self):
+        """
+        List all available Google Compute Engine zones.
+
+        @rtype: C{list} of L{NodeLocation}
+        """
+        list_locations = []
+
+        for zone in self.gcelib_instance.list_zones():
+            location = self._to_node_location(zone)
+            list_locations.append(location)
+
+        return list_locations
+
+    def create_node(self, name, size, image, location):
+        """
+        Create a new Google Compute Engine node.
+
+        @param      name: The name of the new Google Compute Engine node
+        (required).
+        @type       name: C{str}
+
+        @param      size: The size of resources allocated to this node
+        (required).
+        @type       size: L{NodeSize}
+
+        @param      image: The OS Image to boot on this node (required).
+        @type       image: L{NodeImage}
+
+        @param      location: The zone in which to create this node
+        (required).
+        @type       location: L{NodeLocation}
+
+        @rtype: L{Node}
+        """
+        self.gcelib_instance.insert_instance(name=name, machineType=size.name,
+                                             image=image.name,
+                                             zone=location.name,
+                                             project=self.project,
+                                             metadata=None)
+
+        return self._get_node(name)
+
+    def reboot_node(self, node):
+        """
+        Reboot the given Google Compute Engine node.
+
+        @param      node: The Google Compute Engine node to reboot (required).
+        @type       node: L{Node}
+
+        @rtype: C{bool}
+        """
+        ssh_username = self.ssh_username
+        ssh_private_key = self.ssh_private_key_file
+        ssh_host = node.private_ips[0]
+
+        ssh_private_key_file = os.path.expanduser(ssh_private_key)
+        ssh_private_key_pass = ""
+
+        try:
+            pkey = paramiko.RSAKey.from_private_key_file(ssh_private_key_file,
+                                                         ssh_private_key_pass)
+        except paramiko.SSHException:
+            prompt = 'Enter passphrase for key \'' + ssh_private_key_file + \
+                '\': '
+            ssh_private_key_pass = getpass.getpass(prompt=prompt)
+            pkey = paramiko.RSAKey.from_private_key_file(ssh_private_key_file,
+                                                         ssh_private_key_pass)
+        try:
+            ssh_client = self.SSHClient
+            ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+            ssh_client.connect(ssh_host, username=ssh_username, pkey=pkey)
+            ssh_client.exec_command('sudo reboot')
+            ssh_client.close()
+            return True
+        except Exception:
+            return False
+
+    def destroy_node(self, node):
+        """
+        Destroy the given Google Compute Engine node.
+
+        @param      node: The Google Compute Engine node to destroy (required).
+        @type       node: L{Node}
+
+        @rtype: C{bool}
+        """
+        try:
+            self.gcelib_instance.delete_instance(node.name)
+            return True
+        except Exception:
+            return False
+
+    def deploy_node(self, name, size, image, location, script):
+        """
+        Create a new Google Compute Engine node, and run a startup script on
+        initialization
+
+        @param      name: The name of the new Google Compute Engine node
+        (required).
+        @type       name: C{str}
+
+        @param      size: The size of resources allocated to this node
+        (required).
+        @type       size: L{NodeSize}
+
+        @param      image: The OS Image to boot on this node (required).
+        @type       image: L{NodeImage}
+
+        @param      location: The zone in which to create this node
+        (required).
+        @type       location: L{NodeLocation}
+
+        @param      script: The fully qualified local path to the startup
+        script to run on node initialization (required).
+        @type       script: C{string}
+
+        @rtype: L{Node}
+        """
+        startup_script = shortcuts.metadata({'startup-script':
+                                             open(script).read()})
+
+        self.gcelib_instance.insert_instance(name=name, machineType=size.name,
+                                             image=image.name,
+                                             zone=location.name,
+                                             project=self.project,
+                                             metadata=startup_script)
+
+        return self._get_node(name)
+
+    def _get_node(self, name):
+        """
+        Get the Google Compute Engine node associated with name.
+
+        @param      name: The name of the Google Compute Engine node to be
+        returned (required).
+        @type       name: C{str}
+
+        @rtype: L{Node}
+        """
+        gcelib_instance = self.gcelib_instance.get_instance(name)
+        if gcelib_instance is None:
+            return gcelib_instance
+        else:
+            return self._to_node(gcelib_instance)
+
+    def _to_node(self, node):
+        """
+        Convert the gcelib node into a Node.
+
+        @param      node: The gcelib node to be converted into a Node
+        (required).
+        @type       node: C{gcelib node}
+
+        @rtype: L{Node}
+        """
+        public_ips = []
+        private_ips = []
+        extra = {}
+
+        extra['status'] = node.status
+        extra['machine_type'] = node.machineType
+        extra['description'] = node.description
+        extra['zone'] = node.zone
+        extra['image'] = node.image
+        extra['disks'] = node.disks
+        extra['networkInterfaces'] = node.networkInterfaces
+        extra['id'] = node.id
+        extra['selfLink'] = node.selfLink
+        extra['name'] = node.name
+        extra['metadata'] = node.metadata
+
+        for network_interface in node.networkInterfaces:
+            public_ips.append(network_interface.networkIP)
+            for access_config in network_interface.accessConfigs:
+                private_ips.append(access_config.natIP)
+
+        return Node(id=node.id, name=node.name,
+                    state=self.NODE_STATE_MAP[node.status],
+                    public_ips=public_ips, private_ips=private_ips,
+                    driver=self, size=node.machineType, image=node.image,
+                    extra=extra)
+
+    def _to_node_image(self, image):
+        """
+        Convert the gcelib image into a NodeImage.
+
+        @param      node: The gcelib image to be converted into a NodeImage.
+        @type       node: C{gcelib image}
+
+        @rtype: L{NodeImage}
+        """
+        extra = {}
+        extra['preferredKernel'] = image.preferredKernel
+        extra['description'] = image.description
+        extra['creationTimestamp'] = image.creationTimestamp
+
+        return NodeImage(id=image.id, name=image.selfLink, driver=self,
+                         extra=extra)
+
+    def _to_node_location(self, location):
+        """
+        Convert the gcelib location into a NodeLocation.
+
+        @param      node: The gcelib location to be converted into a
+        NodeLocation (required).
+        @type       node: C{gcelib location}
+
+        @rtype: L{NodeLocation}
+        """
+        return NodeLocation(id=location.id, name=location.name, country='US',
+                            driver=self)
+
+    def _to_node_size(self, machine_type):
+        """
+        Convert the gcelib machine type into a NodeSize.
+
+        @param      node: The gcelib machine type to be converted into a
+        NodeSize (required).
+        @type       node: C{gcelib machine type}
+
+        @rtype: L{NodeSize}
+        """
+        try:
+            price = self._get_size_price(size_id=machine_type.name)
+        except KeyError:
+            price = None
+
+        return NodeSize(id=machine_type.id, name=machine_type.name,
+                        ram=machine_type.memoryMb,
+                        disk=machine_type.imageSpaceGb, bandwidth=0,
+                        price=price, driver=self)
diff --git a/libcloud/compute/providers.py b/libcloud/compute/providers.py
index 32b291e..b82cefe 100644
--- a/libcloud/compute/providers.py
+++ b/libcloud/compute/providers.py
@@ -122,7 +122,9 @@ DRIVERS = {
     Provider.VCL:
         ('libcloud.compute.drivers.vcl', 'VCLNodeDriver'),
     Provider.KTUCLOUD:
-        ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver')
+        ('libcloud.compute.drivers.ktucloud', 'KTUCloudNodeDriver'),
+    Provider.GCE:
+        ('libcloud.compute.drivers.gce', 'GoogleComputeEngineNodeDriver')
 }
 
 
diff --git a/libcloud/compute/types.py b/libcloud/compute/types.py
index 80f228a..e2d6b11 100644
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@ -70,6 +70,7 @@ class Provider(object):
     @cvar VCL: VCL driver
     @cvar KTUCLOUD: kt ucloud driver
     @cvar GRIDSPOT: Gridspot driver
+    @cvar GCE: Google Compute Engine driver
     """
     DUMMY = 0
     EC2 = 1  # deprecated name
@@ -124,6 +125,7 @@ class Provider(object):
     RACKSPACE_NOVA_LON = 48
     GRIDSPOT = 49
     RACKSPACE_NOVA_ORD = 50
+    GCE = 51
 
 
 class NodeState(object):
diff --git a/libcloud/data/pricing.json b/libcloud/data/pricing.json
index a79f00e..19e20af 100644
--- a/libcloud/data/pricing.json
+++ b/libcloud/data/pricing.json
@@ -204,6 +204,17 @@
 
         "vps_net": {
             "1": 0.416
+        },
+
+        "gce": {
+            "n1-standard-1-d": 0.145,
+            "n1-standard-2-d": 0.290,
+            "n1-standard-4-d": 0.580,
+            "n1-standard-8-d": 1.160,
+            "n1-standard-1": 0.145,
+            "n1-standard-2": 0.290,
+            "n1-standard-4": 0.580,
+            "n1-standard-8": 1.160
         }
     },
 
diff --git a/libcloud/test/compute/fixtures/gce/deploy_instance.json b/libcloud/test/compute/fixtures/gce/deploy_instance.json
new file mode 100644
index 0000000..a832315
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/deploy_instance.json
@@ -0,0 +1,36 @@
+{
+    "status": "RUNNING",
+    "kind": "compute#instance",
+    "machineType": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-1",
+    "description": "",
+    "zone": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central1-a",
+    "image": "https://www.googleapis.com/compute/v1beta12/projects/google/images/centos-6-2-v20120326",
+    "disks": [{
+        "index": 0,
+        "kind": "compute#attachedDisk",
+        "type": "EPHEMERAL",
+        "mode": "READ_WRITE"
+    }],
+    "name": "foonode2",
+    "networkInterfaces": [{
+        "networkIP": "10.240.64.235",
+        "kind": "compute#networkInterface",
+        "accessConfigs": [{
+            "kind": "compute#accessConfig",
+            "type": "ONE_TO_ONE_NAT",
+            "name": "External NAT",
+            "natIP": "8.35.199.60"
+        }],
+        "network": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/networks/default",
+        "name": "nic0"
+    }],
+    "id": "12990402818933463403",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/instances/foonoden",
+    "metadata": {
+        "items": [{
+            "value": "#! /bin/bash\n# Installs apache and a custom homepage\n\napt-get update\napt-get install -y apache2\ncat <<EOF > /var/www/index.html\n<html><body><h1>Hello World</h1>\n<p>This page was created from a simple start up script!</p>\n</body></html>\nEOF\n",
+            "key": "startup-script"
+        }],
+        "kind": "compute#metadata"
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/deploy_instance_fail.json b/libcloud/test/compute/fixtures/gce/deploy_instance_fail.json
new file mode 100644
index 0000000..7f70fc4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/deploy_instance_fail.json
@@ -0,0 +1,9 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'projects/googler' was not found"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/insert_instance.json b/libcloud/test/compute/fixtures/gce/insert_instance.json
new file mode 100644
index 0000000..334f2b6
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/insert_instance.json
@@ -0,0 +1,29 @@
+{
+    "status": "RUNNING",
+    "kind": "compute#instance",
+    "machineType": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-1",
+    "description": "",
+    "zone": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central1-a",
+    "image": "https://www.googleapis.com/compute/v1beta12/projects/google/images/centos-6-2-v20120326",
+    "disks": [{
+        "index": 0,
+        "kind": "compute#attachedDisk",
+        "type": "EPHEMERAL",
+        "mode": "READ_WRITE"
+    }],
+    "name": "foonode",
+    "id": "12989505666010310007",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/instances/foonode",
+    "networkInterfaces": [{
+        "networkIP": "10.240.15.80",
+        "kind": "compute#networkInterface",
+        "accessConfigs": [{
+            "kind": "compute#accessConfig",
+            "type": "ONE_TO_ONE_NAT",
+            "name": "External NAT",
+            "natIP": "8.35.199.60"
+        }],
+        "network": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/networks/default",
+        "name": "nic0"
+    }]
+}
diff --git a/libcloud/test/compute/fixtures/gce/insert_instance_fail.json b/libcloud/test/compute/fixtures/gce/insert_instance_fail.json
new file mode 100644
index 0000000..7f70fc4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/insert_instance_fail.json
@@ -0,0 +1,9 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'projects/googler' was not found"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/install-apache.sh b/libcloud/test/compute/fixtures/gce/install-apache.sh
new file mode 100644
index 0000000..93d70c2
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/install-apache.sh
@@ -0,0 +1,10 @@
+#! /bin/bash
+# Installs apache and a custom homepage
+
+apt-get update
+apt-get install -y apache2
+cat <<EOF > /var/www/index.html
+<html><body><h1>Hello World</h1>
+<p>This page was created from a simple start up script!</p>
+</body></html>
+EOF
diff --git a/libcloud/test/compute/fixtures/gce/list_images.json b/libcloud/test/compute/fixtures/gce/list_images.json
new file mode 100644
index 0000000..99a9a58
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_images.json
@@ -0,0 +1,79 @@
+[{
+    "kind": "compute#image",
+    "name": "centos-6-2-v20120611",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20120611",
+    "description": "CentOS 6.2; Created Mon, 11 Jun 2012 13:15:44 +0000",
+    "creationTimestamp": "2012-06-18T18:05:30.664",
+    "id": "12917726455664967299",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/centos-6-2-v20120611",
+    "sourceType": "RAW"
+}, {
+    "kind": "compute#image",
+    "name": "centos-6-2-v20120621",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20120621",
+    "description": "CentOS 6.2; Created Thu, 21 Jun 2012 14:22:21 +0000",
+    "creationTimestamp": "2012-06-22T05:59:56.392",
+    "id": "12920641029336858796",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/centos-6-2-v20120621",
+    "sourceType": "RAW"
+}, {
+    "kind": "compute#image",
+    "name": "ubuntu-10-04-v20110728",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20110728",
+    "description": "DEPRECATED. Standard minimal Ubuntu 10.04.01 LTS image; Created Thu, 28 Jul 2011 16:45:51 +0000",
+    "creationTimestamp": "2012-07-16T22:18:50.405",
+    "id": "12941198995845323366",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-10-04-v20110728",
+    "sourceType": "RAW"
+}, {
+    "kind": "compute#image",
+    "name": "ubuntu-10-04-v20110929",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20110929",
+    "description": "DEPRECATED. Standard minimal Ubuntu 10.04.01 LTS image; Created Fri, 30 Sep 2011 23:03:27 +0000",
+    "creationTimestamp": "2012-07-16T22:10:06.063",
+    "id": "12941193941298090457",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-10-04-v20110929",
+    "sourceType": "RAW"
+}, {
+    "kind": "compute#image",
+    "name": "ubuntu-10-04-v20111128",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20111123",
+    "description": "DEPRECATED. Standard minimal Ubuntu 10.04.01 LTS image; Created Mon, 28 Nov 2011 22:26:27 +0000",
+    "creationTimestamp": "2012-07-16T22:12:37.523",
+    "id": "12941195401341520479",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-10-04-v20111128",
+    "sourceType": "RAW"
+}, {
+    "kind": "compute#image",
+    "name": "ubuntu-10-04-v20120106",
+    "rawDisk": {
+        "containerType": "TAR",
+        "source": ""
+    },
+    "preferredKernel": "https://www.googleapis.com/compute/v1beta12/projects/google/kernels/gce-20120106",
+    "description": "DEPRECATED. Standard minimal Ubuntu 10.04.01 LTS image; Created Tue, 10 Jan 2012 18:25:24 +0000",
+    "creationTimestamp": "2012-07-16T22:15:18.811",
+    "id": "12941196956151834933",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-10-04-v20120106",
+    "sourceType": "RAW"
+}]
diff --git a/libcloud/test/compute/fixtures/gce/list_images_fail.json b/libcloud/test/compute/fixtures/gce/list_images_fail.json
new file mode 100644
index 0000000..e5fffc9
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_images_fail.json
@@ -0,0 +1,15 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'projects/googler' was not found"
+        }, {
+            "domain": "global",
+            "reason": "invalidParameter",
+            "message": "Invalid unsigned integer value: '-1'.",
+            "locationType": "parameter",
+            "location": "maxResults"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/list_locations.json b/libcloud/test/compute/fixtures/gce/list_locations.json
new file mode 100644
index 0000000..1c72296
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_locations.json
@@ -0,0 +1,29 @@
+[{
+    "status": "UP",
+    "kind": "compute#zone",
+    "description": "us-central1-a",
+    "maintenanceWindows": [{
+        "endTime": "2012-10-28T08:00:00.000",
+        "beginTime": "2012-10-14T08:00:00.000",
+        "name": "2012-10-14-planned-outage",
+        "description": "maintenance zone"
+    }],
+    "creationTimestamp": "2012-05-15T22:15:19.012",
+    "id": "12889558432979476247",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central1-a",
+    "name": "us-central1-a"
+}, {
+    "status": "UP",
+    "kind": "compute#zone",
+    "description": "us-central2-a",
+    "maintenanceWindows": [{
+        "endTime": "2012-12-02T08:00:00.000",
+        "beginTime": "2012-11-11T08:00:00.000",
+        "name": "2012-11-11-planned-outage",
+        "description": "maintenance zone"
+    }],
+    "creationTimestamp": "2012-05-15T22:17:05.592",
+    "id": "12889559460378820818",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central2-a",
+    "name": "us-central2-a"
+}]
diff --git a/libcloud/test/compute/fixtures/gce/list_locations_fail.json b/libcloud/test/compute/fixtures/gce/list_locations_fail.json
new file mode 100644
index 0000000..e5fffc9
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_locations_fail.json
@@ -0,0 +1,15 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'projects/googler' was not found"
+        }, {
+            "domain": "global",
+            "reason": "invalidParameter",
+            "message": "Invalid unsigned integer value: '-1'.",
+            "locationType": "parameter",
+            "location": "maxResults"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/list_machine_types.json b/libcloud/test/compute/fixtures/gce/list_machine_types.json
new file mode 100644
index 0000000..63ce584
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_machine_types.json
@@ -0,0 +1,106 @@
+[{
+    "guestCpus": 2,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "ephemeralDisks": [{
+        "diskGb": 870
+    }],
+    "maximumPersistentDisksSizeGb": "256",
+    "description": "2 vCPUs, 7.5 GB RAM, a 10 GB ephemeral root disk, and an extra 870 GB ephemeral disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-2-d",
+    "memoryMb": 7680,
+    "creationTimestamp": "2012-06-07T20:49:19.448",
+    "id": "12908559582417967837",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-2-d",
+    "hostCpus": 2
+}, {
+    "guestCpus": 4,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "maximumPersistentDisksSizeGb": "512",
+    "description": "4 vCPUs, 15 GB RAM, and a 10 GB ephemeral root disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-4",
+    "memoryMb": 15360,
+    "creationTimestamp": "2012-06-07T20:49:40.050",
+    "id": "12908559692070444049",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-4",
+    "hostCpus": 4
+}, {
+    "guestCpus": 4,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "ephemeralDisks": [{
+        "diskGb": 1770
+    }],
+    "maximumPersistentDisksSizeGb": "512",
+    "description": "4 vCPUs, 15 GB RAM, a 10 GB ephemeral root disk, and an extra 1770 GB ephemeral disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-4-d",
+    "memoryMb": 15360,
+    "creationTimestamp": "2012-06-07T20:50:05.677",
+    "id": "12908559991903153608",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-4-d",
+    "hostCpus": 4
+}, {
+    "guestCpus": 8,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "maximumPersistentDisksSizeGb": "1024",
+    "description": "8 vCPUs, 30 GB RAM, and a 10 GB ephemeral root disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-8",
+    "memoryMb": 30720,
+    "creationTimestamp": "2012-06-07T20:50:42.334",
+    "id": "12908560197989714867",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-8",
+    "hostCpus": 8
+}, {
+    "guestCpus": 8,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "ephemeralDisks": [{
+        "diskGb": 1770
+    }, {
+        "diskGb": 1770
+    }],
+    "maximumPersistentDisksSizeGb": "1024",
+    "description": "8 vCPUs, 30 GB RAM, a 10 GB ephemeral root disk, and 2 extra 1770 GB ephemeral disks",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-8-d",
+    "memoryMb": 30720,
+    "creationTimestamp": "2012-06-07T20:51:19.936",
+    "id": "12908560709887590691",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-8-d",
+    "hostCpus": 8
+}, {
+    "guestCpus": 1,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "maximumPersistentDisksSizeGb": "128",
+    "description": "1 vCPU, 3.75 GB RAM, and a 10 GB ephemeral root disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-1",
+    "memoryMb": 3840,
+    "creationTimestamp": "2012-06-07T20:48:14.670",
+    "id": "12907738072351752276",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-1",
+    "hostCpus": 1
+}, {
+    "guestCpus": 1,
+    "imageSpaceGb": 10,
+    "kind": "compute#machineType",
+    "ephemeralDisks": [{
+        "diskGb": 420
+    }],
+    "maximumPersistentDisksSizeGb": "128",
+    "description": "1 vCPU, 3.75 GB RAM, a 10 GB ephemeral root disk, and an extra 420 GB ephemeral disk",
+    "maximumPersistentDisks": 16,
+    "name": "n1-standard-1-d",
+    "memoryMb": 3840,
+    "creationTimestamp": "2012-06-07T20:48:34.258",
+    "id": "12908559201265214706",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-1-d",
+    "hostCpus": 1
+}]
diff --git a/libcloud/test/compute/fixtures/gce/list_machine_types_fail.json b/libcloud/test/compute/fixtures/gce/list_machine_types_fail.json
new file mode 100644
index 0000000..7001ed8
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_machine_types_fail.json
@@ -0,0 +1,15 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'projects/googler' was not found"
+        }, {
+            "domain": "global",
+            "reason": "invalidParameter",
+            "message": "Invalid unsigned integer value: 'a'.",
+            "locationType": "parameter",
+            "location": "maxResults"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/fixtures/gce/list_nodes.json b/libcloud/test/compute/fixtures/gce/list_nodes.json
new file mode 100644
index 0000000..e8f0d4c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_nodes.json
@@ -0,0 +1,57 @@
+[{
+    "status": "RUNNING",
+    "kind": "compute#instance",
+    "machineType": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-1",
+    "description": "",
+    "zone": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central1-a",
+    "image": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-12-04-v20120621",
+    "disks": [{
+        "index": 0,
+        "kind": "compute#attachedDisk",
+        "type": "EPHEMERAL",
+        "mode": "READ_WRITE"
+    }],
+    "name": "foo",
+    "id": "12987935077537528637",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/instances/goo",
+    "networkInterfaces": [{
+        "networkIP": "10.240.125.236",
+        "kind": "compute#networkInterface",
+        "accessConfigs": [{
+            "kind": "compute#accessConfig",
+            "type": "ONE_TO_ONE_NAT",
+            "name": "External NAT",
+            "natIP": "173.255.124.43"
+        }],
+        "network": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/networks/default",
+        "name": "nic0"
+    }]
+}, {
+    "status": "RUNNING",
+    "kind": "compute#instance",
+    "machineType": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/machine-types/n1-standard-2",
+    "description": "",
+    "zone": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/us-central1-a",
+    "image": "https://www.googleapis.com/compute/v1beta12/projects/google/images/ubuntu-12-04-v20120621",
+    "disks": [{
+        "index": 0,
+        "kind": "compute#attachedDisk",
+        "type": "EPHEMERAL",
+        "mode": "READ_WRITE"
+    }],
+    "name": "bar",
+    "id": "12982866885143643382",
+    "selfLink": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/instances/hello",
+    "networkInterfaces": [{
+        "networkIP": "10.240.235.139",
+        "kind": "compute#networkInterface",
+        "accessConfigs": [{
+            "kind": "compute#accessConfig",
+            "type": "ONE_TO_ONE_NAT",
+            "name": "External NAT",
+            "natIP": "173.255.116.186"
+        }],
+        "network": "https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/networks/default",
+        "name": "nic0"
+    }]
+}]
diff --git a/libcloud/test/compute/fixtures/gce/list_nodes_fail.json b/libcloud/test/compute/fixtures/gce/list_nodes_fail.json
new file mode 100644
index 0000000..4029c97
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/list_nodes_fail.json
@@ -0,0 +1,13 @@
+{
+    "error": {
+        "errors": [{
+            "domain": "global",
+            "reason": "notFound",
+            "message": "The resource 'google.com:ziyadm-devconsol' was not found"
+        }, {
+            "domain": "global",
+            "reason": "invalid",
+            "message": "Invalid value for field 'resource.zone': 'https://www.googleapis.com/compute/v1beta12/projects/google.com:ziyadm-devconsole/zones/hello'.  Must be the URL to a Compute resource of the correct type"
+        }]
+    }
+}
diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py
new file mode 100644
index 0000000..dca2d0d
--- /dev/null
+++ b/libcloud/test/compute/test_gce.py
@@ -0,0 +1,428 @@
+# 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.
+
+import json
+import sys
+import unittest
+import libcloud.test.secrets as secrets
+
+from libcloud.compute.drivers.gce import GoogleComputeEngineNodeDriver
+from libcloud.test.file_fixtures import ComputeFileFixtures
+
+
+class MockAccessConfig:
+    def __init__(self, natIP):
+        self.natIP = natIP
+
+
+class MockImage:
+    def __init__(self, id, selfLink, preferredKernel, description,
+                 creationTimestamp):
+        self.id = id
+        self.selfLink = selfLink
+        self.preferredKernel = preferredKernel
+        self.description = description
+        self.creationTimestamp = creationTimestamp
+
+
+class MockInstance:
+    def __init__(self, status, kind, machineType, description, zone, image,
+                 disks, networkInterfaces, id, selfLink, name, metadata):
+        self.status = status
+        self.kind = kind
+        self.machineType = machineType
+        self.description = description
+        self.zone = zone
+        self.image = image
+        self.disks = disks
+        self.networkInterfaces = networkInterfaces
+        self.id = id
+        self.selfLink = selfLink
+        self.name = name
+        self.metadata = metadata
+
+
+class MockLocation:
+    def __init__(self, id, name, country):
+        self.id = id
+        self.name = name
+        self.country = country
+
+
+class MockMachine:
+    def __init__(self, id, name, memoryMb, imageSpaceGb, bandwidth, price):
+        self.id = id
+        self.name = name
+        self.memoryMb = memoryMb
+        self.imageSpaceGb = imageSpaceGb
+        self.bandwidth = bandwidth
+        self.price = price
+
+
+class MockNetworkIP:
+    def __init__(self, networkIP, accessConfigs):
+        self.networkIP = networkIP
+        self.accessConfigs = accessConfigs
+
+
+class MockSSHClient():
+    def __init__(self):
+        self.testTypes = {
+            'reboot_instance': 'PASS'
+        }
+
+    def set_missing_host_key_policy(self, host_key_policy):
+        pass
+
+    def connect(self, host, username=None, pkey=None):
+        pass
+
+    def close(self):
+        pass
+
+    def exec_command(self, command):
+        if self.testTypes['reboot_instance'] == 'PASS':
+            return
+        else:
+            raise Exception
+
+
+class MockGcelibInstance:
+    fixtures = ComputeFileFixtures('gce')
+
+    def __init__(self):
+        self.testTypes = {
+            'list_nodes': 'PASS',
+            'list_images': 'PASS',
+            'list_machine_types': 'PASS',
+            'list_locations': 'PASS',
+            'insert_instance': 'PASS',
+            'deploy_instance': 'PASS'
+        }
+
+    def load_fixtures(self, method_name, test_type):
+        fixture_file_name = method_name
+
+        if test_type == 'FAIL':
+            fixture_file_name += '_fail'
+        fixture_file_name += '.json'
+
+        return json.loads(self.fixtures.load(fixture_file_name))
+
+    def all_instances(self):
+        method_name = 'list_nodes'
+        instance_list = self.load_fixtures(method_name,
+                                           self.testTypes[method_name])
+        list_mock_instances = []
+
+        for instance in instance_list:
+            if instance == 'error':
+                continue
+            else:
+                mock_network_interface = self._get_mock_network_interfaces(
+                    instance)
+                mock_instance = self._to_mock_instance(
+                    instance, mock_network_interface)
+                list_mock_instances.append(mock_instance)
+
+        return list_mock_instances
+
+    def list_images(self, project):
+        method_name = 'list_images'
+        image_list = self.load_fixtures(method_name,
+                                        self.testTypes[method_name])
+        list_mock_images = []
+
+        for image in image_list:
+            if image == 'error':
+                continue
+            else:
+                mock_image = self._to_mock_image(image)
+                list_mock_images.append(mock_image)
+
+        return list_mock_images
+
+    def list_machine_types(self):
+        method_name = 'list_machine_types'
+        machine_type_list = self.load_fixtures(method_name,
+                                               self.testTypes[method_name])
+        list_mock_machine_types = []
+
+        for machine in machine_type_list:
+            if machine == 'error':
+                continue
+            else:
+                mock_machine = self._to_mock_machine(machine)
+                list_mock_machine_types.append(mock_machine)
+
+        return list_mock_machine_types
+
+    def list_zones(self):
+        method_name = 'list_locations'
+        location_list = self.load_fixtures(method_name,
+                                           self.testTypes[method_name])
+        list_mock_locations = []
+
+        for location in location_list:
+            if location == 'error':
+                continue
+            else:
+                mock_location = self._to_mock_location(location)
+                list_mock_locations.append(mock_location)
+
+        return list_mock_locations
+
+    def get_instance(self, mock_instance):
+        if mock_instance == 'foonode2':
+            method_name = 'deploy_instance'
+        else:
+            method_name = 'insert_instance'
+        instance_data = self.load_fixtures(method_name,
+                                           self.testTypes[method_name])
+
+        if instance_data.get('error', None) is None:
+            mock_network_interface = self._get_mock_network_interfaces(
+                instance_data)
+            return self._to_mock_instance(instance_data,
+                                          mock_network_interface)
+        else:
+            return None
+
+    def insert_instance(self, name, machineType, image, zone, project,
+                        metadata):
+        return
+
+    def delete_instance(self, instance):
+        list_nodes = self.all_instances()
+        node_to_destory = list_nodes[0]
+        assert node_to_destory.name == instance
+
+        if self.testTypes['delete_instance'] == 'PASS':
+            return
+        else:
+            raise Exception
+
+    def _get_mock_network_interfaces(self, mock_instance):
+        mock_network_interfaces = []
+
+        for mock_network_interface in mock_instance['networkInterfaces']:
+            mock_access_configs = []
+            for mock_access_config in mock_network_interface['accessConfigs']:
+                mock_access_configs.append(
+                    MockAccessConfig(mock_access_config))
+                mock_network_interfaces.append(
+                    MockNetworkIP(mock_network_interface['networkIP'],
+                                  mock_access_configs))
+
+        return mock_network_interfaces
+
+    def _to_mock_instance(self, mock_instance, mock_network_interfaces):
+        mock_instance.setdefault('metadata', None)
+
+        return MockInstance(mock_instance['status'], mock_instance['kind'],
+                            mock_instance['machineType'], ['description'],
+                            mock_instance['zone'], mock_instance['image'],
+                            mock_instance['disks'], mock_network_interfaces,
+                            mock_instance['id'], mock_instance['selfLink'],
+                            mock_instance['name'], mock_instance['metadata'])
+
+    def _to_mock_image(self, mock_image):
+        return MockImage(mock_image['id'], mock_image['selfLink'],
+                         mock_image['preferredKernel'],
+                         mock_image['description'],
+                         mock_image['creationTimestamp'])
+
+    def _to_mock_location(self, mock_location):
+        mock_location['country'] = 'US'
+
+        return MockLocation(mock_location['id'], mock_location['name'],
+                            mock_location['country'])
+
+    def _to_mock_machine(self, mock_machine):
+        mock_machine['bandwidth'] = 0
+        mock_machine['price'] = '123'
+
+        return MockMachine(mock_machine['id'], mock_machine['name'],
+                           mock_machine['memoryMb'],
+                           mock_machine['imageSpaceGb'],
+                           mock_machine['bandwidth'],
+                           mock_machine['price'])
+
+
+# TODO(zmir): Determine if there is a way to programmatically generate all test
+# cases, and mock types, and subsequently, automate the entire testing suite
+# for gce.
+class GoogleComputeEngineTest(unittest.TestCase):
+    def setUp(self):
+        ssh_username, ssh_private_key_file, project = getattr(secrets,
+                                                              'GCE_PARAMS',
+                                                              ())
+        self.driver = GoogleComputeEngineNodeDriver(ssh_username,
+                                                    ssh_private_key_file,
+                                                    project)
+        self.driver.SSHClient = MockSSHClient()
+        self.driver.gcelib_instance = MockGcelibInstance()
+
+    def test_list_nodes(self):
+        self.driver.gcelib_instance.testTypes['list_nodes'] = 'PASS'
+        list_nodes = self.driver.list_nodes()
+        self.assertEqual(len(list_nodes), 2)
+
+        node1, node2 = list_nodes[0], list_nodes[1]
+        self.assertEqual(node1.name, 'foo')
+        self.assertEqual(node2.name, 'bar')
+        self.assertEqual(node1.state, 0)
+        self.assertEqual(node2.state, 0)
+        self.assertEqual(node1.size.split('/')[-1], 'n1-standard-1')
+        self.assertEqual(node2.size.split('/')[-1], 'n1-standard-2')
+
+        self.driver.gcelib_instance.testTypes['list_nodes'] = 'FAIL'
+        list_nodes = self.driver.list_nodes()
+        self.assertEqual(len(list_nodes), 0)
+
+    def test_list_images(self):
+        self.driver.gcelib_instance.testTypes['list_images'] = 'PASS'
+        list_images = self.driver.list_images()
+        self.assertEqual(len(list_images), 6)
+
+        image1, image2 = list_images[0], list_images[-1]
+        self.assertEqual(image1.name.split('/')[-1], 'centos-6-2-v20120611')
+        self.assertEqual(image2.name.split('/')[-1], 'ubuntu-10-04-v20120106')
+        self.assertEqual(image1.id, '12917726455664967299')
+        self.assertEqual(image2.id, '12941196956151834933')
+
+        self.driver.gcelib_instance.testTypes['list_images'] = 'FAIL'
+        list_images = self.driver.list_images()
+        self.assertEqual(len(list_images), 0)
+
+    def test_list_sizes(self):
+        self.driver.gcelib_instance.testTypes['list_machine_types'] = 'PASS'
+        list_sizes = self.driver.list_sizes()
+        self.assertEqual(len(list_sizes), 7)
+
+        size1, size2 = list_sizes[0], list_sizes[-1]
+        self.assertEqual(size1.name, 'n1-standard-2-d')
+        self.assertEqual(size2.name, 'n1-standard-1-d')
+        self.assertEqual(size1.ram, 7680)
+        self.assertEqual(size2.ram, 3840)
+        self.assertEqual(size1.id, '12908559582417967837')
+        self.assertEqual(size2.id, '12908559201265214706')
+
+        self.driver.gcelib_instance.testTypes['list_machine_types'] = 'FAIL'
+        list_sizes = self.driver.list_sizes()
+        self.assertEqual(len(list_sizes), 0)
+
+    def test_list_locations(self):
+        self.driver.gcelib_instance.testTypes['list_machine_types'] = 'PASS'
+        list_locations = self.driver.list_locations()
+        self.assertEqual(len(list_locations), 2)
+
+        location1, location2 = list_locations
+        self.assertEqual(location1.name, 'us-central1-a')
+        self.assertEqual(location2.name, 'us-central2-a')
+        self.assertEqual(location1.id, '12889558432979476247')
+        self.assertEqual(location2.id, '12889559460378820818')
+        self.assertEqual(location1.country, 'US')
+        self.assertEqual(location2.country, 'US')
+
+        self.driver.gcelib_instance.testTypes['list_locations'] = 'FAIL'
+        list_locations = self.driver.list_locations()
+        self.assertEqual(len(list_locations), 0)
+
+    def test_create_node(self):
+        node_name = 'foonode'
+        node_size = self.driver.list_sizes()[0]
+        node_image = self.driver.list_images()[0]
+        node_location = self.driver.list_locations()[0]
+
+        self.driver.gcelib_instance.testTypes['insert_instance'] = 'PASS'
+        new_node = self.driver.create_node(node_name, node_size, node_image,
+                                           node_location)
+
+        new_node_image = new_node.image.split('/')[-1]
+        new_node_zone = new_node.extra['zone'].split('/')[-1]
+        new_node_machine_type = new_node.extra['machineType'].split('/')[-1]
+
+        self.assertEqual(new_node.name, 'foonode')
+        self.assertEqual(new_node.id, '12989505666010310007')
+        self.assertEqual(new_node.state, 0)
+        self.assertEqual(new_node_image, 'centos-6-2-v20120326')
+        self.assertEqual(new_node_zone, 'us-central1-a')
+        self.assertEqual(new_node_machine_type, 'n1-standard-1')
+
+        self.driver.gcelib_instance.testTypes['insert_instance'] = 'FAIL'
+        new_node = self.driver.create_node(node_name, node_size, node_image,
+                                           node_location)
+        self.assertEqual(new_node, None)
+
+    def test_reboot_node(self):
+        self.driver.SSHClient.testTypes['reboot_instance'] = 'PASS'
+        node_to_reboot = self.driver.list_nodes()[0]
+        ret = self.driver.reboot_node(node_to_reboot)
+        self.assertTrue(ret)
+
+        self.driver.SSHClient.testTypes['reboot_instance'] = 'FAIL'
+        node_to_reboot = self.driver.list_nodes()[0]
+        ret = self.driver.reboot_node(node_to_reboot)
+        self.assertFalse(ret)
+
+    def test_deploy_node(self):
+        node_name = 'foonode2'
+        node_size = self.driver.list_sizes()[0]
+        node_image = self.driver.list_images()[0]
+        node_location = self.driver.list_locations()[0]
+        script_location = \
+            'libcloud/test/compute/fixtures/gce/install-apache.sh'
+
+        self.driver.gcelib_instance.testTypes['deploy_instance'] = 'PASS'
+        new_node = self.driver.deploy_node(node_name,
+                                           node_size,
+                                           node_image,
+                                           node_location,
+                                           script_location)
+
+        new_node_image = new_node.image.split('/')[-1]
+        new_node_zone = new_node.extra['zone'].split('/')[-1]
+        new_node_machine_type = new_node.extra['machineType'].split('/')[-1]
+
+        self.assertEqual(new_node.name, 'foonode2')
+        self.assertEqual(new_node.id, '12990402818933463403')
+        self.assertEqual(new_node.state, 0)
+        self.assertEqual(new_node_image, 'centos-6-2-v20120326')
+        self.assertEqual(new_node_zone, 'us-central1-a')
+        self.assertEqual(new_node_machine_type, 'n1-standard-1')
+
+        self.driver.gcelib_instance.testTypes['deploy_instance'] = 'FAIL'
+        new_node = self.driver.deploy_node(node_name,
+                                           node_size,
+                                           node_image,
+                                           node_location,
+                                           script_location)
+        self.assertEqual(new_node, None)
+
+    def test_destroy_node(self):
+        list_nodes = self.driver.list_nodes()
+        node_to_destroy = list_nodes[0]
+
+        self.driver.gcelib_instance.testTypes['delete_instance'] = 'PASS'
+        ret = self.driver.destroy_node(node_to_destroy)
+        self.assertTrue(ret)
+
+        self.driver.gcelib_instance.testTypes['delete_instance'] = 'FAIL'
+        ret = self.driver.destroy_node(node_to_destroy)
+        self.assertFalse(ret)
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())
