You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/11/09 19:17:05 UTC

[6/8] jclouds-labs-google git commit: * Rewrites InstanceTemplate as NewInstance, strictly from docs. * Rewrites Metadata to have the same shape as in json, avoid really complicated json parser. * Rewrites GoogleComputeEngineServiceAdapter.createNodeW

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
deleted file mode 100644
index 6549823..0000000
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
+++ /dev/null
@@ -1,551 +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.
- */
-package org.jclouds.googlecomputeengine.compute;
-
-import static com.google.common.base.Throwables.propagate;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_BOOT_DISK_SUFFIX;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
-import static org.jclouds.googlecomputeengine.domain.Instance.Status.RUNNING;
-import static org.jclouds.googlecomputeengine.domain.Instance.Status.TERMINATED;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_CENTOS_IMAGES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_CENTOS_IMAGES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_DEBIAN_IMAGES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_DEBIAN_IMAGES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_PROJECT_IMAGES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_PROJECT_IMAGES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_CENTRAL1B_INSTANCES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_CENTRAL1B_INSTANCES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_INSTANCES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_INSTANCES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_CENTRAL1B_MACHINE_TYPES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_CENTRAL1B_MACHINE_TYPES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_MACHINE_TYPES_REQUEST;
-import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_MACHINE_TYPES_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.NetworkApiExpectTest.GET_NETWORK_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_RESPONSE;
-import static org.jclouds.googlecomputeengine.features.RegionApiExpectTest.LIST_REGIONS_REQ;
-import static org.jclouds.util.Strings2.toStringAndClose;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.domain.Location;
-import org.jclouds.domain.LocationScope;
-import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
-import org.jclouds.googlecomputeengine.features.InstanceApiExpectTest;
-import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineServiceExpectTest;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-@Test(groups = "unit", testName = "GoogleComputeEngineServiceExpectTest")
-public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngineServiceExpectTest {
-   private static final String OPERATIONS_URL_PREFIX = BASE_URL + "/myproject/zones/us-central1-a/operations";
-
-   private static final HttpRequest GET_ZONE_OPERATION_REQUEST = HttpRequest
-           .builder()
-           .method("GET")
-           .endpoint(OPERATIONS_URL_PREFIX + "/operation-1354084865060-4cf88735faeb8-bbbb12cb")
-           .addHeader("Accept", "application/json")
-           .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-   private static final HttpResponse GET_ZONE_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
-           .payload(staticPayloadFromResource("/zone_operation.json")).build();
-
-   private HttpRequest INSERT_NETWORK_REQUEST = HttpRequest
-           .builder()
-           .method("POST")
-           .endpoint(BASE_URL + "/myproject/global/networks")
-           .addHeader("Accept", APPLICATION_JSON)
-           .addHeader("Authorization", "Bearer " + TOKEN)
-           .payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test\",\"IPv4Range\":\"10.0.0.0/8\"}",
-                   APPLICATION_JSON))
-           .build();
-
-   private HttpResponse GET_NETWORK_RESPONSE = HttpResponse.builder().statusCode(200)
-           .payload(payloadFromStringWithContentType("{\n" +
-                   " \"kind\": \"compute#network\",\n" +
-                   " \"id\": \"13024414170909937976\",\n" +
-                   " \"creationTimestamp\": \"2012-10-24T20:13:19.967\",\n" +
-                   " \"selfLink\": \"https://www.googleapis" +
-                   ".com/compute/v1/projects/myproject/global/networks/jclouds-test\",\n" +
-                   " \"name\": \"jclouds-test\",\n" +
-                   " \"description\": \"test network\",\n" +
-                   " \"IPv4Range\": \"10.0.0.0/8\",\n" +
-                   " \"gatewayIPv4\": \"10.0.0.1\"\n" +
-                   "}", APPLICATION_JSON)).build();
-
-   private HttpResponse SUCCESSFUL_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
-           .payload(payloadFromResource("/operation.json")).build();
-
-   private HttpRequest SET_TAGS_REQUEST = HttpRequest.builder()
-           .method("POST")
-           .endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-1/setTags")
-           .addHeader("Accept", APPLICATION_JSON)
-           .addHeader("Authorization", "Bearer " + TOKEN)
-           .payload(payloadFromStringWithContentType("{\"items\":[\"aTag\"],\"fingerprint\":\"abcd\"}",
-                   APPLICATION_JSON))
-           .build();
-
-   private HttpResponse SET_TAGS_RESPONSE = HttpResponse.builder().statusCode(200)
-           .payload(payloadFromResource("/operation.json")).build();
-
-   private HttpResponse getInstanceResponseForInstanceAndNetworkAndStatus(String instanceName, String networkName,
-                                                                          String status) throws IOException {
-      return HttpResponse.builder().statusCode(200)
-              .payload(payloadFromStringWithContentType(
-                      replaceInstanceNameNetworkAndStatusOnResource("/instance_get.json",
-                              instanceName, networkName, status),
-                      APPLICATION_JSON)).build();
-   }
-
-   /** Reduce work implementing this test, by only using one region, zone! */
-   private final HttpResponse singleRegionSingleZoneResponse = HttpResponse.builder().statusCode(200).payload(
-         "{\"items\":[" + payloadFromResource("/region_get.json").getRawContent().toString()
-               .replace("\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-b\"", "")
-               + "]}")
-         .build();
-
-   private HttpResponse getListInstancesResponseForSingleInstanceAndNetworkAndStatus(String instanceName,
-                                                                                     String networkName,
-                                                                                     String status) {
-      return HttpResponse.builder().statusCode(200)
-              .payload(payloadFromStringWithContentType(
-                      replaceInstanceNameNetworkAndStatusOnResource("/instance_list.json",
-                              instanceName, networkName, status),
-                      APPLICATION_JSON)).build();
-   }
-
-   private HttpResponse getDiskResponseForInstance(String instanceName) {
-      return HttpResponse.builder().statusCode(200)
-                         .payload(payloadFromStringWithContentType(
-                               replaceDiskNameOnResource("/disk_get.json", instanceName + "-" + GCE_BOOT_DISK_SUFFIX),
-                               APPLICATION_JSON)).build();
-   }
-
-   private String replaceDiskNameOnResource(String resourceName, String diskName) {
-      try {
-         return toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("testimage1", diskName);
-      } catch (IOException e) {
-         throw propagate(e);
-      }
-   }
-
-   private String replaceInstanceNameNetworkAndStatusOnResource(String resourceName, String instanceName,
-                                                                String networkName, String status) {
-      try {
-         return toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("test-0", instanceName)
-               .replace("default", networkName).replace("RUNNING", status);
-      } catch (IOException e) {
-         throw propagate(e);
-      }
-   }
-
-   private HttpRequest createDiskRequestForInstance(String instanceName) {
-      return HttpRequest
-              .builder()
-              .method("POST")
-              .endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN)
-              .payload(payloadFromStringWithContentType("{\"name\":\"" + instanceName + "-" + GCE_BOOT_DISK_SUFFIX + "\","
-                                                        + "\"sizeGb\":10,"
-                                                        + "\"sourceImage\":\"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140718\"}",
-                                                        APPLICATION_JSON)).build();
-   }
-
-   private HttpRequest getDiskRequestForInstance(String instanceName) {
-      return HttpRequest
-              .builder()
-              .method("GET")
-              .endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks/" + instanceName + "-" + GCE_BOOT_DISK_SUFFIX)
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-   }
-
-   private HttpRequest createInstanceRequestForInstance(String instanceName, String groupName, String networkName,
-         String publicKey) {
-      return HttpRequest.builder().method("POST")
-            .endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances")
-            .addHeader("Accept", APPLICATION_JSON).addHeader("Authorization", "Bearer " + TOKEN).payload(
-                  payloadFromStringWithContentType("{\"name\":\"" + instanceName
-                              + "\",\"machineType\":\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/machineTypes/f1-micro\",\"serviceAccounts\":[],\"disks\":[{\"type\":\"PERSISTENT\",\"mode\":\"READ_WRITE\",\"source\":\"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks/"
-                              + instanceName + "-" + GCE_BOOT_DISK_SUFFIX
-                              + "\",\"autoDelete\":true,\"boot\":true}],\"networkInterfaces\":[{\"network\":\"https://www.googleapis.com/compute/v1/projects/myproject/global/networks/"
-                              + networkName
-                              + "\",\"accessConfigs\":[{\"type\":\"ONE_TO_ONE_NAT\"}]}],\"metadata\":{\"kind\":\"compute#metadata\",\"items\":[{\"key\":\"sshKeys\",\"value\":\"jclouds:"
-                              + publicKey + " jclouds@localhost\"},{\"key\":\"jclouds-group\",\"value\":\"" + groupName
-                              + "\"},{\"key\":\"jclouds-image\",\"value\":\"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140718\"},{\"key\":\"jclouds-delete-boot-disk\",\"value\":\"true\"}]}}",
-                        APPLICATION_JSON)).build();
-   }
-
-   private HttpRequest getInstanceRequestForInstance(String instanceName) {
-      return HttpRequest
-              .builder()
-              .method("GET")
-              .endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/" + instanceName)
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-   }
-
-   @Override
-   protected Properties setupProperties() {
-      Properties overrides = super.setupProperties();
-      overrides.put("google-compute-engine.identity", "myproject");
-      overrides.put(GCE_IMAGE_PROJECTS, "debian-cloud,centos-cloud");
-      try {
-         overrides.put("google-compute-engine.credential",
-               toStringAndClose(this.getClass().getResourceAsStream("/testpk.pem")));
-      } catch (IOException e) {
-         propagate(e);
-      }
-      return overrides;
-   }
-
-   @Test(enabled = false)
-   public void testThrowsAuthorizationException() throws Exception {
-
-      Properties properties = new Properties();
-      properties.setProperty("oauth.identity", "MOMMA");
-      properties.setProperty("oauth.credential", "MiA");
-
-      ComputeService client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse>of(), createModule(),
-              properties);
-      Template template = client.templateBuilder().build();
-      Template toMatch = client.templateBuilder().imageId(template.getImage().getId()).build();
-      assertEquals(toMatch.getImage(), template.getImage());
-   }
-
-   @Test
-   public void testTemplateMatch() throws Exception {
-      ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
-              <HttpRequest, HttpResponse>builder()
-              .put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
-              .put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
-              .put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
-              .put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
-              .put(LIST_DEBIAN_IMAGES_REQUEST, LIST_DEBIAN_IMAGES_RESPONSE)
-              .put(LIST_CENTOS_IMAGES_REQUEST, LIST_CENTOS_IMAGES_RESPONSE)
-              .put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
-              .put(LIST_CENTRAL1B_MACHINE_TYPES_REQUEST, LIST_CENTRAL1B_MACHINE_TYPES_RESPONSE)
-              .build();
-
-      ComputeService client = requestsSendResponses(requestResponseMap);
-      Template template = client.templateBuilder().build();
-      Hardware defaultSize = client.templateBuilder().build().getHardware();
-
-      Hardware smallest = client.templateBuilder().smallest().build().getHardware();
-      assertEquals(defaultSize, smallest);
-
-      Hardware fastest = client.templateBuilder().fastest().build().getHardware();
-      assertNotNull(fastest);
-
-      assertEquals(client.listHardwareProfiles().size(), 3);
-
-      Template toMatch = client.templateBuilder()
-              .imageId(template.getImage().getId())
-              .build();
-      assertEquals(toMatch.getImage(), template.getImage());
-   }
-
-   @Test
-   public void testNetworksAndFirewallDeletedWhenAllGroupNodesAreTerminated() throws IOException {
-
-      HttpRequest deleteNodeRequest = HttpRequest.builder()
-              .method("DELETE")
-              .endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-delete-networks")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpRequest deleteFirewallRequest = HttpRequest.builder()
-              .method("DELETE")
-              .endpoint(BASE_URL + "/myproject/global/firewalls/jclouds-test-delete")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpRequest getNetworkRequest = HttpRequest.builder()
-              .method("GET")
-              .endpoint(BASE_URL + "/myproject/global/networks/jclouds-test-delete")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse getNetworkResponse = HttpResponse.builder().statusCode(200)
-              .payload(staticPayloadFromResource("/GoogleComputeEngineServiceExpectTest/network_get.json")).build();
-
-      HttpRequest listFirewallsRequest = HttpRequest.builder()
-              .method("GET")
-              .endpoint(BASE_URL + "/myproject/global/firewalls")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse listFirewallsResponse = HttpResponse.builder().statusCode(200)
-              .payload(staticPayloadFromResource("/GoogleComputeEngineServiceExpectTest/firewall_list.json")).build();
-
-      HttpRequest deleteNetworkReqquest = HttpRequest.builder()
-              .method("DELETE")
-              .endpoint(BASE_URL + "/myproject/global/networks/jclouds-test-delete")
-              .addHeader("Accept", APPLICATION_JSON)
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpRequest deleteDiskRequest = HttpRequest.builder()
-            .method("DELETE")
-            .endpoint(BASE_URL + "/myproject/zones/us-central1-a/disks/test")
-            .addHeader("Accept", APPLICATION_JSON)
-            .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
-              .add(requestForScopes(COMPUTE_READONLY_SCOPE))
-              .add(GET_PROJECT_REQUEST)
-              .add(getInstanceRequestForInstance("test-delete-networks"))
-              .add(LIST_REGIONS_REQ)
-              .add(LIST_MACHINE_TYPES_REQUEST)
-              .add(LIST_PROJECT_IMAGES_REQUEST)
-              .add(LIST_DEBIAN_IMAGES_REQUEST)
-              .add(LIST_CENTOS_IMAGES_REQUEST)
-              .add(getInstanceRequestForInstance("test-delete-networks"))
-              .add(requestForScopes(COMPUTE_SCOPE))
-              .add(deleteNodeRequest)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(deleteDiskRequest)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(getInstanceRequestForInstance("test-delete-networks"))
-              .add(LIST_INSTANCES_REQUEST)
-              .add(getNetworkRequest)
-              .add(listFirewallsRequest)
-              .add(deleteFirewallRequest)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(deleteNetworkReqquest)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .build();
-
-      List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
-              .add(TOKEN_RESPONSE)
-              .add(GET_PROJECT_RESPONSE)
-              .add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", RUNNING.name()))
-              .add(singleRegionSingleZoneResponse)
-              .add(LIST_MACHINE_TYPES_RESPONSE)
-              .add(LIST_PROJECT_IMAGES_RESPONSE)
-              .add(LIST_DEBIAN_IMAGES_RESPONSE)
-              .add(LIST_CENTOS_IMAGES_RESPONSE)
-              .add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", RUNNING.name()))
-              .add(TOKEN_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", TERMINATED.name()))
-              .add(getListInstancesResponseForSingleInstanceAndNetworkAndStatus("test-delete-networks",
-                      "test-network", TERMINATED.name()))
-              .add(getNetworkResponse)
-              .add(listFirewallsResponse)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .build();
-
-      ComputeService client = orderedRequestsSendResponses(orderedRequests, orderedResponses);
-      client.destroyNode("us-central1-a/test-delete-networks");
-   }
-
-   public void listAssignableLocations() throws Exception {
-      ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
-              <HttpRequest, HttpResponse>builder()
-              .put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
-              .put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
-              .put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
-              .build();
-
-      ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
-
-      Set<? extends Location> locations = apiWhenServersExist.listAssignableLocations();
-
-      assertNotNull(locations);
-      assertEquals(locations.size(), 1);
-      Location firstZone  = locations.iterator().next();
-      assertEquals(firstZone.getId(), "us-central1-a");
-      assertEquals(firstZone.getDescription(), "us-central1-a");
-      assertEquals(firstZone.getScope(), LocationScope.ZONE);
-
-      assertEquals(firstZone.getParent().getId(), "us-central1");
-      assertEquals(firstZone.getParent().getDescription(), "us-central1");
-      assertEquals(firstZone.getParent().getScope(), LocationScope.REGION);
-
-      // Google intentionally does not document locations!
-      assertTrue(firstZone.getIso3166Codes().isEmpty());
-      assertTrue(firstZone.getParent().getIso3166Codes().isEmpty());
-   }
-
-   public void listNodes() throws Exception {
-
-      ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
-            <HttpRequest, HttpResponse>builder()
-            .put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
-            .put(GET_PROJECT_REQUEST, GET_PROJECT_RESPONSE)
-            .put(LIST_REGIONS_REQ, singleRegionSingleZoneResponse)
-            .put(LIST_INSTANCES_REQUEST, LIST_INSTANCES_RESPONSE)
-            .put(LIST_CENTRAL1B_INSTANCES_REQUEST, LIST_CENTRAL1B_INSTANCES_RESPONSE)
-            .put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
-            .put(LIST_DEBIAN_IMAGES_REQUEST, LIST_DEBIAN_IMAGES_RESPONSE)
-            .put(LIST_CENTOS_IMAGES_REQUEST, LIST_CENTOS_IMAGES_RESPONSE)
-            .put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
-            .put(LIST_CENTRAL1B_MACHINE_TYPES_REQUEST, LIST_CENTRAL1B_MACHINE_TYPES_RESPONSE)
-            .build();
-
-      ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
-
-      assertNotNull(apiWhenServersExist.listNodes());
-      assertEquals(apiWhenServersExist.listNodes().size(), 1);
-      assertEquals(apiWhenServersExist.listNodes().iterator().next().getId(), "us-central1-a/test-0");
-      assertEquals(apiWhenServersExist.listNodes().iterator().next().getName(), "test-0");
-   }
-
-   @Test
-   public void testCreateNodeWhenNetworkNorFirewallExistDoesNotExist() throws RunNodesException, IOException {
-      String payload = toStringAndClose(InstanceApiExpectTest.class.getResourceAsStream("/instance_get.json"));
-      payload = payload.replace("test-0", "test-1");
-
-      HttpResponse getInstanceResponse = HttpResponse.builder().statusCode(200)
-              .payload(payloadFromStringWithContentType(payload, APPLICATION_JSON)).build();
-
-      HttpRequest getFirewallRequest = HttpRequest
-                 .builder()
-                 .method("GET")
-                 .endpoint(BASE_URL + "/myproject/global/firewalls/jclouds-test-port-22")
-                 .addHeader("Accept", APPLICATION_JSON)
-                 .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpRequest insertFirewallRequest = HttpRequest
-                 .builder()
-                 .method("POST")
-                 .endpoint(BASE_URL + "/myproject/global/firewalls")
-                 .addHeader("Accept", APPLICATION_JSON)
-                 .addHeader("Authorization", "Bearer " + TOKEN)
-                 .payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test-port-22\",\"network\":\"https://www.googleapis" +
-                         ".com/compute/v1/projects/myproject/global/networks/jclouds-test\"," +
-                         "\"sourceRanges\":[\"10.0.0.0/8\",\"0.0.0.0/0\"],\"sourceTags\":[\"aTag\"],\"targetTags\":[\"jclouds-test-port-22\"],\"allowed\":[{\"IPProtocol\":\"tcp\"," +
-                         "\"ports\":[\"22\"]}," +
-                         "{\"IPProtocol\":\"udp\",\"ports\":[\"22\"]}]}",
-                         APPLICATION_JSON))
-                 .build();
-
-      HttpRequest setTagsRequest = HttpRequest
-                 .builder()
-                 .method("POST")
-                 .endpoint(BASE_URL + "/myproject/zones/us-central1-a/instances/test-1/setTags")
-                 .addHeader("Accept", APPLICATION_JSON)
-                 .addHeader("Authorization", "Bearer " + TOKEN)
-                 .payload(payloadFromStringWithContentType("{\"items\":[\"jclouds-test-port-22\"],\"fingerprint\":\"abcd\"}",
-                         APPLICATION_JSON))
-                 .build();
-
-      List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
-              .add(requestForScopes(COMPUTE_READONLY_SCOPE))
-              .add(GET_PROJECT_REQUEST)
-              .add(LIST_REGIONS_REQ)
-              .add(LIST_PROJECT_IMAGES_REQUEST)
-              .add(LIST_DEBIAN_IMAGES_REQUEST)
-              .add(LIST_CENTOS_IMAGES_REQUEST)
-              .add(LIST_MACHINE_TYPES_REQUEST)
-              .add(GET_NETWORK_REQUEST)
-              .add(GET_NETWORK_REQUEST)
-              .add(requestForScopes(COMPUTE_SCOPE))
-              .add(INSERT_NETWORK_REQUEST)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(GET_NETWORK_REQUEST)
-              .add(getFirewallRequest)
-              .add(insertFirewallRequest)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(LIST_INSTANCES_REQUEST)
-              .add(createDiskRequestForInstance("test-1"))
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(getDiskRequestForInstance("test-1"))
-              .add(createInstanceRequestForInstance("test-1", "test", "jclouds-test", openSshKey))
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(getInstanceRequestForInstance("test-1"))
-              .add(SET_TAGS_REQUEST)
-              .add(GET_ZONE_OPERATION_REQUEST)
-              .add(getInstanceRequestForInstance("test-1"))
-              .add(setTagsRequest)
-              .add(LIST_PROJECT_IMAGES_REQUEST)
-              .add(LIST_DEBIAN_IMAGES_REQUEST)
-              .add(LIST_CENTOS_IMAGES_REQUEST)
-              .add(setTagsRequest)
-              .build();
-
-      List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
-              .add(TOKEN_RESPONSE)
-              .add(GET_PROJECT_RESPONSE)
-              .add(singleRegionSingleZoneResponse)
-              .add(LIST_PROJECT_IMAGES_RESPONSE)
-              .add(LIST_DEBIAN_IMAGES_RESPONSE)
-              .add(LIST_CENTOS_IMAGES_RESPONSE)
-              .add(LIST_MACHINE_TYPES_RESPONSE)
-              .add(HttpResponse.builder().statusCode(404).build())
-              .add(HttpResponse.builder().statusCode(404).build())
-              .add(TOKEN_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(GET_NETWORK_RESPONSE)
-              .add(HttpResponse.builder().statusCode(404).build())
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(LIST_INSTANCES_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(getDiskResponseForInstance("test-1"))
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(getInstanceResponse)
-              .add(SET_TAGS_RESPONSE)
-              .add(GET_ZONE_OPERATION_RESPONSE)
-              .add(getInstanceResponse)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(LIST_PROJECT_IMAGES_RESPONSE)
-              .add(LIST_DEBIAN_IMAGES_RESPONSE)
-              .add(LIST_CENTOS_IMAGES_RESPONSE)
-              .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .build();
-
-      ComputeService computeService = orderedRequestsSendResponses(orderedRequests, orderedResponses);
-
-      GoogleComputeEngineTemplateOptions options = computeService.templateOptions().as(GoogleComputeEngineTemplateOptions.class);
-      options.tags(ImmutableSet.of("aTag"));
-      NodeMetadata node = getOnlyElement(computeService.createNodesInGroup("test", 1, options));
-      assertEquals(node.getImageId(), "debian-7-wheezy-v20140718");
-   }
-}
-

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceMockTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceMockTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceMockTest.java
new file mode 100644
index 0000000..fc2e3db
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceMockTest.java
@@ -0,0 +1,288 @@
+/*
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static org.jclouds.googlecomputeengine.domain.Instance.Status.RUNNING;
+import static org.jclouds.googlecomputeengine.domain.Instance.Status.TERMINATED;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+
+@Test(groups = "unit", testName = "GoogleComputeEngineServiceMockTest", singleThreaded = true)
+public class GoogleComputeEngineServiceMockTest extends BaseGoogleComputeEngineApiMockTest {
+
+   public void templateMatch() throws Exception {
+      server.enqueue(jsonResponse("/project.json"));
+      server.enqueue(singleRegionSingleZoneResponse());
+      server.enqueue(jsonResponse("/image_list.json"));
+      server.enqueue(jsonResponse("/image_list_debian.json")); // per GCE_IMAGE_PROJECTS = "debian-cloud"
+      server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
+
+      ComputeService computeService = computeService();
+
+      Template template = computeService.templateBuilder().build();
+      Hardware defaultSize = computeService.templateBuilder().build().getHardware();
+
+      Hardware smallest = computeService.templateBuilder().smallest().build().getHardware();
+      assertEquals(defaultSize, smallest);
+
+      Hardware fastest = computeService.templateBuilder().fastest().build().getHardware();
+      assertNotNull(fastest);
+
+      assertEquals(computeService.listHardwareProfiles().size(), 3);
+
+      Template toMatch = computeService.templateBuilder().imageId(template.getImage().getId()).build();
+      assertEquals(toMatch.getImage(), template.getImage());
+
+      assertSent(server, "GET", "/projects/party");
+      assertSent(server, "GET", "/projects/party/regions");
+      assertSent(server, "GET", "/projects/party/global/images");
+      assertSent(server, "GET", "/projects/debian-cloud/global/images");
+      assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
+   }
+
+   public void networksAndFirewallDeletedWhenAllGroupNodesAreTerminated() throws IOException, InterruptedException {
+      server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", RUNNING));
+      server.enqueue(jsonResponse("/project.json"));
+      server.enqueue(singleRegionSingleZoneResponse());
+      server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
+      server.enqueue(jsonResponse("/operation.json"));
+      server.enqueue(jsonResponse("/zone_operation.json"));
+      server.enqueue(instanceWithNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
+      server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-delete-networks", "test-network", TERMINATED));
+      server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/network_get.json"));
+      server.enqueue(jsonResponse("/GoogleComputeEngineServiceExpectTest/firewall_list.json"));
+      server.enqueue(jsonResponse("/operation.json"));
+      server.enqueue(jsonResponse("/zone_operation.json"));
+      server.enqueue(jsonResponse("/operation.json"));
+      server.enqueue(jsonResponse("/zone_operation.json"));
+
+      ComputeService computeService = computeService();
+      computeService.destroyNode(url("/jclouds/zones/us-central1-a/instances/test-delete-networks"));
+
+      assertSent(server, "GET", "/jclouds/zones/us-central1-a/instances/test-delete-networks");
+      assertSent(server, "GET", "/projects/party");
+      assertSent(server, "GET", "/projects/party/regions");
+      assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
+      assertSent(server, "DELETE", "/jclouds/zones/us-central1-a/instances/test-delete-networks");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-delete-networks");
+      assertSent(server, "GET", "/projects/party/aggregated/instances");
+      assertSent(server, "GET", "/projects/party/global/networks/jclouds-test-delete");
+      assertSent(server, "GET", "/projects/party/global/firewalls");
+      assertSent(server, "DELETE", "/projects/party/global/firewalls/jclouds-test-delete");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
+      assertSent(server, "DELETE", "/projects/party/global/networks/jclouds-test-delete");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
+   }
+
+   public void listAssignableLocations() throws Exception {
+      server.enqueue(jsonResponse("/project.json"));
+      server.enqueue(singleRegionSingleZoneResponse());
+
+      ComputeService computeService = computeService();
+
+      Set<? extends Location> locations = computeService.listAssignableLocations();
+
+      assertNotNull(locations);
+      assertEquals(locations.size(), 1);
+      Location firstZone = locations.iterator().next();
+      assertEquals(firstZone.getId(), "us-central1-a");
+      assertEquals(firstZone.getDescription(), url("/projects/party/zones/us-central1-a"));
+      assertEquals(firstZone.getScope(), LocationScope.ZONE);
+
+      assertEquals(firstZone.getParent().getId(), "us-central1");
+      assertEquals(firstZone.getParent().getDescription(), url("/projects/party/regions/us-central1"));
+      assertEquals(firstZone.getParent().getScope(), LocationScope.REGION);
+
+     // Google intentionally does not document locations!
+      assertTrue(firstZone.getIso3166Codes().isEmpty());
+      assertTrue(firstZone.getParent().getIso3166Codes().isEmpty());
+
+      assertSent(server, "GET", "/projects/party");
+      assertSent(server, "GET", "/projects/party/regions");
+   }
+
+   public void listNodes() throws Exception {
+      server.enqueue(jsonResponse("/project.json"));
+      server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
+      server.enqueue(singleRegionSingleZoneResponse());
+      server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
+
+      Set<? extends ComputeMetadata> nodes = computeService().listNodes();
+      assertEquals(nodes.size(), 1);
+      NodeMetadata node = (NodeMetadata) nodes.iterator().next();
+      assertNull(node.getImageId()); // not pre-cached by createNodes
+
+      assertSent(server, "GET", "/projects/party");
+      assertSent(server, "GET", "/projects/party/aggregated/instances");
+      assertSent(server, "GET", "/projects/party/regions");
+      assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
+   }
+
+   public void createNodeWhenNetworkNorFirewallExistDoesNotExist() throws Exception {
+      server.enqueue(jsonResponse("/project.json"));
+      server.enqueue(singleRegionSingleZoneResponse());
+      server.enqueue(jsonResponse("/image_list.json"));
+      server.enqueue(jsonResponse("/image_list_debian.json")); // per GCE_IMAGE_PROJECTS = "debian-cloud"
+      server.enqueue(jsonResponse("/aggregated_machinetype_list.json"));
+      server.enqueue(new MockResponse().setResponseCode(404)); // Network
+      server.enqueue(new MockResponse().setResponseCode(404)); // Network again?
+      server.enqueue(jsonResponse("/operation.json")); // Create Network
+      server.enqueue(jsonResponse("/zone_operation.json"));
+      server.enqueue(jsonResponse("/network_get.json"));
+      server.enqueue(new MockResponse().setResponseCode(404)); // Firewall
+      server.enqueue(jsonResponse("/operation.json")); // Create Firewall
+      server.enqueue(jsonResponse("/zone_operation.json"));
+      server.enqueue(aggregatedListWithInstanceNetworkAndStatus("test-0", "test-network", RUNNING));
+      server.enqueue(jsonResponse("/operation.json")); // Create Instance
+      server.enqueue(instanceWithNetworkAndStatus("test-1", "test-network", RUNNING));
+
+      ComputeService computeService = computeService();
+
+      GoogleComputeEngineTemplateOptions options = computeService.templateOptions()
+            .as(GoogleComputeEngineTemplateOptions.class).tags(ImmutableSet.of("aTag")).blockUntilRunning(false);
+
+      Template template = computeService.templateBuilder().options(options).build();
+      NodeMetadata node = getOnlyElement(computeService.createNodesInGroup("test", 1, template));
+
+      // prove our caching works.
+      assertEquals(node.getImageId(), template.getImage().getId());
+
+      assertSent(server, "GET", "/projects/party");
+      assertSent(server, "GET", "/projects/party/regions");
+      assertSent(server, "GET", "/projects/party/global/images");
+      assertSent(server, "GET", "/projects/debian-cloud/global/images");
+      assertSent(server, "GET", "/projects/party/aggregated/machineTypes");
+      assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
+      assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
+      assertSent(server, "POST", "/projects/party/global/networks",
+            "{\"name\":\"jclouds-test\",\"IPv4Range\":\"10.0.0.0/8\"}");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
+      assertSent(server, "GET", "/projects/party/global/networks/jclouds-test");
+      assertSent(server, "GET", "/projects/party/global/firewalls/jclouds-test-port-22");
+      assertSent(server, "POST", "/projects/party/global/firewalls", "" //
+            + "{" //
+            + "  \"name\": \"jclouds-test-port-22\"," //
+            + "  \"network\": \"" + url("/projects/party/networks/jclouds-test") + "\","//
+            + "  \"sourceRanges\": [" //
+            + "    \"10.0.0.0/8\","//
+            + "    \"0.0.0.0/0\"" //
+            + "  ]," //
+            + "  \"sourceTags\": [" //
+            + "    \"aTag\"" //
+            + "  ]," //
+            + "  \"targetTags\": [" //
+            + "    \"jclouds-test-port-22\"" //
+            + "  ]," //
+            + "  \"allowed\": [" //
+            + "    {" //
+            + "      \"IPProtocol\": \"tcp\"," //
+            + "      \"ports\": [" //
+            + "        \"22\"" //
+            + "      ]" //
+            + "    }," //
+            + "    {" //
+            + "      \"IPProtocol\": \"udp\"," //
+            + "      \"ports\": [" //
+            + "        \"22\""//
+            + "      ]" //
+            + "    }" //
+            + "  ]" //
+            + "}");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/operations/operation-1354084865060");
+      assertSent(server, "GET", "/projects/party/aggregated/instances");
+      assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances", "" //
+            + "{" //
+            + "  \"machineType\": \"" + template.getHardware().getId() + "\"," //
+            + "  \"name\": \"test-1\"," //
+            + "  \"networkInterfaces\": [" //
+            + "    {" //
+            + "      \"network\": \"" + url("/projects/party/networks/jclouds-test") + "\"," //
+            + "      \"accessConfigs\": [" //
+            + "        \"ONE_TO_ONE_NAT\"" //
+            + "      ]" //
+            + "    }" //
+            + "  ]," //
+            + "  \"disks\": [" //
+            + "    {" //
+            + "      \"type\": \"PERSISTENT\"," //
+            + "      \"initializeParams\": {" //
+            + "        \"sourceImage\": \"" + template.getImage().getId() + "\"" //
+            + "      }," //
+            + "      \"boot\": true," //
+            + "      \"autoDelete\": true" //
+            + "    }" //
+            + "  ]," //
+            + "  \"description\": \"test\"," //
+            + "  \"tags\": {" //
+            + "    \"items\": [" //
+            + "      \"aTag\"," //
+            + "      \"jclouds-test-port-22\"" //
+            + "    ]" //
+            + "  }," //
+            + "  \"metadata\": {" //
+            + "    \"items\": [" //
+            + "      {" //
+            + "        \"key\": \"jclouds-group\"," //
+            + "        \"value\": \"test\"" //
+            + "      }" //
+            + "    ]" //
+            + "  }" //
+            + "}");
+      assertSent(server, "GET", "/projects/party/zones/us-central1-a/instances/test-1");
+   }
+
+   private MockResponse instanceWithNetworkAndStatus(String instanceName, String networkName, Instance.Status status) {
+      return new MockResponse().setBody(
+            stringFromResource("/instance_get.json").replace("test-0", instanceName).replace("default", networkName)
+                  .replace("RUNNING", status.toString()));
+   }
+
+   private MockResponse aggregatedListWithInstanceNetworkAndStatus(String instanceName, String networkName,
+         Instance.Status status) {
+      return new MockResponse().setBody(
+            stringFromResource("/aggregated_instance_list.json").replace("test-0", instanceName)
+                  .replace("default", networkName).replace("RUNNING", status.toString()));
+   }
+
+   private MockResponse diskResponseForInstance(String instanceName) {
+      return new MockResponse().setBody(
+            stringFromResource("/disk_get.json").replace("testimage1", instanceName + "-" + "TODO"));
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
index dcbd1bc..778dbd6 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
@@ -48,11 +48,11 @@ public class CreateNetworkIfNeededTest {
    public void testApply() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      ResourceFunctions resources = createMock(ResourceFunctions.class);
+      Resources resources = createMock(Resources.class);
 
       Network network = Network.create( //
             "abcd", // id
-            URI.create(BASE_URL + "/myproject/global/networks/this-network"), // selfLink
+            URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
             "this-network", // name
             null, // description
             "0.0.0.0/0", // rangeIPv4
@@ -61,7 +61,7 @@ public class CreateNetworkIfNeededTest {
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
-      Supplier<String> userProject = Suppliers.ofInstance("myproject");
+      Supplier<String> userProject = Suppliers.ofInstance("party");
 
       expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
 
@@ -86,11 +86,11 @@ public class CreateNetworkIfNeededTest {
    public void testApplyWithGateway() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      ResourceFunctions resources = createMock(ResourceFunctions.class);
+      Resources resources = createMock(Resources.class);
 
       Network network = Network.create( //
             "abcd", // id
-            URI.create(BASE_URL + "/myproject/global/networks/this-network"), // selfLink
+            URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
             "this-network", // name
             null, // description
             "0.0.0.0/0", // rangeIPv4
@@ -99,7 +99,7 @@ public class CreateNetworkIfNeededTest {
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
-      Supplier<String> userProject = Suppliers.ofInstance("myproject");
+      Supplier<String> userProject = Suppliers.ofInstance("party");
 
       expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
 
@@ -122,15 +122,15 @@ public class CreateNetworkIfNeededTest {
    }
 
    private AtomicOperationDone atomicOperationDone(final GoogleComputeEngineApi api,
-         final ResourceFunctions resources) {
+         final Resources resources) {
       return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
          @Override protected void configure() {
             bind(GoogleComputeEngineApi.class).toInstance(api);
-            bind(ResourceFunctions.class).toInstance(resources);
+            bind(Resources.class).toInstance(resources);
          }
 
          @Provides @UserProject Supplier<String> project() {
-            return Suppliers.ofInstance("myproject");
+            return Suppliers.ofInstance("party");
          }
       }).getInstance(AtomicOperationDone.class);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
index 068446f..5df13f0 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
@@ -45,11 +45,11 @@ import com.google.inject.Guice;
 
 @Test
 public class FindNetworkOrCreateTest {
-   private static final Supplier<String> USER_PROJECT = Suppliers.ofInstance("myproject");
+   private static final Supplier<String> USER_PROJECT = Suppliers.ofInstance("party");
    private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects";
    private static final Network NETWORK = Network.create( //
          "abcd", // id
-         URI.create(BASE_URL + "/myproject/global/networks/this-network"), // selfLink
+         URI.create(BASE_URL + "/party/global/networks/this-network"), // selfLink
          "this-network", // name
          null, // description
          "0.0.0.0/0", // rangeIPv4
@@ -87,7 +87,7 @@ public class FindNetworkOrCreateTest {
    public void testLoadNew() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      ResourceFunctions resources = createMock(ResourceFunctions.class);
+      Resources resources = createMock(Resources.class);
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
@@ -120,10 +120,10 @@ public class FindNetworkOrCreateTest {
       verify(api, nwApi, resources);
    }
 
-   private AtomicOperationDone atomicOperationDone(final ResourceFunctions resources) {
+   private AtomicOperationDone atomicOperationDone(final Resources resources) {
       return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
          @Override protected void configure() {
-            bind(ResourceFunctions.class).toInstance(resources);
+            bind(Resources.class).toInstance(resources);
          }
       }).getInstance(AtomicOperationDone.class);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
index 811abd3..b8aee36 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
@@ -55,10 +55,10 @@ public class FirewallToIpPermissionTest {
       String baseUrl = "https://www.googleapis.com/compute/v1/projects";
       return Firewall.create( //
             "abcd", // id
-            URI.create(baseUrl + "/myproject/global/firewalls/jclouds-test"), // selfLink
+            URI.create(baseUrl + "/jclouds/global/firewalls/jclouds-test"), // selfLink
             "jclouds-test", // name
             null, // description
-            URI.create(baseUrl + "/myproject/global/networks/jclouds-test"), // network
+            URI.create(baseUrl + "/jclouds/global/networks/jclouds-test"), // network
             ImmutableList.of("0.0.0.0/0"), // sourceRanges
             null, // sourceTags
             null, // targetTags

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
index d4df1e5..6abca24 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
@@ -32,7 +32,7 @@ public class GoogleComputeEngineImageToImageTest {
       Image image = image("arbitratyname");
       org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
       assertEquals(transformed.getName(), image.name());
-      assertEquals(transformed.getId(), image.name());
+      assertEquals(transformed.getId(), image.selfLink().toString());
       assertEquals(transformed.getProviderId(), image.id());
       assertSame(transformed.getOperatingSystem().getFamily(), OsFamily.LINUX);
    }
@@ -42,7 +42,7 @@ public class GoogleComputeEngineImageToImageTest {
       Image image = image("ubuntu-12-04-v123123");
       org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
       assertEquals(transformed.getName(), image.name());
-      assertEquals(transformed.getId(), image.name());
+      assertEquals(transformed.getId(), image.selfLink().toString());
       assertEquals(transformed.getProviderId(), image.id());
       assertSame(transformed.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
       assertEquals(transformed.getOperatingSystem().getVersion(), "12.04");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadataTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadataTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadataTest.java
deleted file mode 100644
index 2b69bdc..0000000
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadataTest.java
+++ /dev/null
@@ -1,237 +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.
- */
-package org.jclouds.googlecomputeengine.compute.functions;
-
-import static org.jclouds.compute.domain.Image.Status.AVAILABLE;
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.HardwareBuilder;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.ImageBuilder;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.domain.Processor;
-import org.jclouds.compute.domain.Volume.Type;
-import org.jclouds.compute.domain.VolumeBuilder;
-import org.jclouds.compute.functions.GroupNamingConvention;
-import org.jclouds.domain.Location;
-import org.jclouds.domain.LocationBuilder;
-import org.jclouds.domain.LocationScope;
-import org.jclouds.googlecomputeengine.compute.domain.InstanceInZone;
-import org.jclouds.googlecomputeengine.domain.Instance;
-import org.jclouds.googlecomputeengine.parse.ParseInstanceTest;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-
-@Test(groups = "unit", testName = "InstanceInZoneToNodeMetadataTest")
-public class InstanceInZoneToNodeMetadataTest {
-
-   /**
-    * GroupNamingConvention that always returns the same name provided in the constructor.
-    * The predicates returned always evaluate to true.
-    *
-    */
-   class FixedGroupNamingConvention implements GroupNamingConvention {
-      private final String name;
-
-      public FixedGroupNamingConvention(final String name) {
-         this.name = name;
-      }
-
-      @Override
-      public String sharedNameForGroup(final String group) {
-         return name;
-      }
-
-      @Override
-      public String uniqueNameForGroup(final String group) {
-         return name;
-      }
-
-      @Override
-      public String groupInUniqueNameOrNull(final String encoded) {
-         return name;
-      }
-
-      @Override
-      public String groupInSharedNameOrNull(final String encoded) {
-         return name;
-      }
-
-      @Override
-      public Predicate<String> containsGroup(final String group) {
-         return new Predicate<String>() {
-            @Override
-            public boolean apply(final String input) {
-               return true;
-            }
-         };
-      }
-
-      @Override
-      public Predicate<String> containsAnyGroup() {
-         return new Predicate<String>() {
-            @Override
-            public boolean apply(final String input) {
-               return true;
-            }
-         };
-      }
-
-      @Override
-      public String extractGroup(final String encoded) {
-         return name;
-      }
-   }
-
-   private Instance instance;
-
-   private Set<Hardware> hardwares;
-
-   private Set<Image> images;
-
-   private Set<Location> locations;
-
-   private InstanceInZoneToNodeMetadata groupGroupNodeParser;
-   private InstanceInZoneToNodeMetadata groupNullNodeParser;
-
-   @BeforeMethod
-   public final void setup() {
-      instance = new ParseInstanceTest().expected();
-
-      images = ImmutableSet.of(new ImageBuilder()
-         .id("1")
-         .uri(URI.create("https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140718"))
-         .providerId("1")
-         .name("mock image")
-         .status(AVAILABLE)
-         .operatingSystem(
-            OperatingSystem.builder().name("Ubuntu 14.04 x86_64").description("Ubuntu").family(OsFamily.UBUNTU)
-            .version("10.04").arch("x86_64").is64Bit(true).build()).build());
-
-      hardwares = ImmutableSet.of(new HardwareBuilder().id("my_id")
-         .uri(URI.create("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/machineTypes/"
-               + "n1-standard-1"))
-         .providerId("1")
-         .name("mock hardware").processor(new Processor(1.0, 1.0)).ram(2048)
-         .volume(new VolumeBuilder().size(20f).type(Type.LOCAL).build()).build());
-
-      locations = ImmutableSet.of(new LocationBuilder()
-         .id("id")
-         .description("https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a")
-         .scope(LocationScope.REGION)
-         .parent(
-               new LocationBuilder().id("0").description("mock parent location").scope(LocationScope.PROVIDER)
-               .build()).build());
-
-      groupGroupNodeParser = createNodeParser(hardwares, images, locations, "Group");
-      groupNullNodeParser = createNodeParser(hardwares, images, locations, null);
-   }
-
-   private InstanceInZoneToNodeMetadata createNodeParser(final Set<Hardware> hardware, final Set<Image> images,
-         final Set<Location> locations, final String groupName) {
-      Supplier<Map<URI, Location>> locationSupplier = new Supplier<Map<URI, Location>>() {
-         @Override
-         public Map<URI, Location> get() {
-            return Maps.uniqueIndex(locations, new Function<Location, URI>() {
-               @Override
-               public URI apply(final Location input) {
-                  return URI.create(input.getDescription());
-               }
-            });
-         }
-      };
-
-      Supplier<Map<URI, Hardware>> hardwareSupplier = new Supplier<Map<URI, Hardware>>() {
-         @Override
-         public Map<URI, Hardware> get() {
-            return Maps.uniqueIndex(hardware, new Function<Hardware, URI>() {
-               @Override
-               public URI apply(final Hardware input) {
-                  return input.getUri();
-               }
-            });
-         }
-      };
-
-      Supplier<Map<URI, Image>> imageSupplier = new Supplier<Map<URI, Image>>() {
-         @Override
-         public Map<URI, Image> get() {
-            return Maps.uniqueIndex(images, new Function<Image, URI>() {
-               @Override
-               public URI apply(final Image input) {
-                  return input.getUri();
-               }
-            });
-         }
-      };
-
-      GroupNamingConvention.Factory namingConventionFactory =
-         new GroupNamingConvention.Factory() {
-            @Override
-            public GroupNamingConvention createWithoutPrefix() {
-               return new FixedGroupNamingConvention(groupName);
-            }
-
-            @Override
-            public GroupNamingConvention create() {
-               return new FixedGroupNamingConvention(groupName);
-            }
-         };
-
-      return new InstanceInZoneToNodeMetadata(
-         ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
-            .put(Instance.Status.RUNNING, NodeMetadata.Status.PENDING).build(),
-            namingConventionFactory,
-            imageSupplier,
-            hardwareSupplier,
-            locationSupplier,
-            new FirewallTagNamingConvention.Factory(namingConventionFactory));
-   }
-
-   @Test
-   public final void testTagFilteringWorks() {
-      InstanceInZone instanceInZone = InstanceInZone.create(instance, "zoneId");
-      NodeMetadata nodeMetadata = groupGroupNodeParser.apply(instanceInZone);
-      assertEquals(nodeMetadata.getId(), "id/test-0");
-      assertEquals(nodeMetadata.getTags(), ImmutableSet.<String>of(
-            "aTag"  // "aTag" kept as a non firewall tag.
-            // "Group-port-42" filtered out as a firewall tag.
-      ));
-   }
-
-   @Test
-   public final void testInstanceWithGroupNull() {
-      InstanceInZone instanceInZone = InstanceInZone.create(instance, "zoneId");
-      NodeMetadata nodeMetadata = groupNullNodeParser.apply(instanceInZone);
-      assertEquals(nodeMetadata.getId(), "id/test-0");
-      assertEquals(nodeMetadata.getTags(), ImmutableSet.<String>of("aTag", "Group-port-42"));
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadataTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadataTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadataTest.java
new file mode 100644
index 0000000..6888b24
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadataTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import static com.google.common.collect.Maps.uniqueIndex;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume.Type;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.parse.ParseImageTest;
+import org.jclouds.googlecomputeengine.parse.ParseInstanceTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+@Test(groups = "unit", testName = "InstanceToNodeMetadataTest", singleThreaded = true) // BeforeMethod = singleThreaded
+public class InstanceToNodeMetadataTest {
+
+   /**
+    * GroupNamingConvention that always returns the same name provided in the constructor.
+    * The predicates returned always evaluate to true.
+    *
+    */
+   class FixedGroupNamingConvention implements GroupNamingConvention {
+      private final String name;
+
+      public FixedGroupNamingConvention(final String name) {
+         this.name = name;
+      }
+
+      @Override
+      public String sharedNameForGroup(final String group) {
+         return name;
+      }
+
+      @Override
+      public String uniqueNameForGroup(final String group) {
+         return name;
+      }
+
+      @Override
+      public String groupInUniqueNameOrNull(final String encoded) {
+         return name;
+      }
+
+      @Override
+      public String groupInSharedNameOrNull(final String encoded) {
+         return name;
+      }
+
+      @Override
+      public Predicate<String> containsGroup(final String group) {
+         return new Predicate<String>() {
+            @Override
+            public boolean apply(final String input) {
+               return true;
+            }
+         };
+      }
+
+      @Override
+      public Predicate<String> containsAnyGroup() {
+         return new Predicate<String>() {
+            @Override
+            public boolean apply(final String input) {
+               return true;
+            }
+         };
+      }
+
+      @Override
+      public String extractGroup(final String encoded) {
+         return name;
+      }
+   }
+
+   private Instance instance;
+   private Set<Hardware> hardwares;
+   private URI imageUrl = new ParseImageTest().expected().selfLink();
+   private Set<Location> locations;
+   private InstanceToNodeMetadata groupGroupNodeParser;
+   private InstanceToNodeMetadata groupNullNodeParser;
+
+   @BeforeMethod
+   public final void setup() {
+      instance = new ParseInstanceTest().expected();
+
+      hardwares = ImmutableSet.of(new HardwareBuilder().id("my_id")
+         .uri(URI.create("https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/machineTypes/"
+               + "n1-standard-1"))
+         .providerId("1")
+         .name("mock hardware").processor(new Processor(1.0, 1.0)).ram(2048)
+         .volume(new VolumeBuilder().size(20f).type(Type.LOCAL).build()).build());
+
+      locations = ImmutableSet.of(new LocationBuilder()
+         .id("id")
+         .description("https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a")
+         .scope(LocationScope.REGION)
+         .parent(
+               new LocationBuilder().id("0").description("mock parent location").scope(LocationScope.PROVIDER)
+               .build()).build());
+
+      groupGroupNodeParser = createNodeParser(hardwares, locations, "Group");
+      groupNullNodeParser = createNodeParser(hardwares, locations, null);
+   }
+
+   private InstanceToNodeMetadata createNodeParser(final Set<Hardware> hardware, final Set<Location> locations,
+         final String groupName) {
+      Supplier<Map<URI, Location>> locationSupplier = new Supplier<Map<URI, Location>>() {
+         @Override
+         public Map<URI, Location> get() {
+            return uniqueIndex(locations, new Function<Location, URI>() {
+               @Override
+               public URI apply(final Location input) {
+                  return URI.create(input.getDescription());
+               }
+            });
+         }
+      };
+
+      Supplier<Map<URI, Hardware>> hardwareSupplier = Suppliers
+            .<Map<URI, Hardware>>ofInstance(uniqueIndex(hardware, new Function<Hardware, URI>() {
+               @Override
+               public URI apply(final Hardware input) {
+                  return input.getUri();
+               }
+            }));
+
+      GroupNamingConvention.Factory namingConventionFactory =
+         new GroupNamingConvention.Factory() {
+            @Override
+            public GroupNamingConvention createWithoutPrefix() {
+               return new FixedGroupNamingConvention(groupName);
+            }
+
+            @Override
+            public GroupNamingConvention create() {
+               return new FixedGroupNamingConvention(groupName);
+            }
+         };
+
+      return new InstanceToNodeMetadata(
+         ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
+            .put(Instance.Status.RUNNING, NodeMetadata.Status.PENDING).build(),
+            namingConventionFactory,
+            ImmutableMap.of(instance.disks().get(0).source(), imageUrl),
+            hardwareSupplier,
+            locationSupplier,
+            new FirewallTagNamingConvention.Factory(namingConventionFactory));
+   }
+
+   @Test
+   public final void testTagFilteringWorks() {
+      NodeMetadata nodeMetadata = groupGroupNodeParser.apply(instance);
+      assertEquals(nodeMetadata.getId(), instance.selfLink().toString());
+      assertEquals(nodeMetadata.getTags(), ImmutableSet.of(
+            "aTag"  // "aTag" kept as a non firewall tag.
+            // "Group-port-42" filtered out as a firewall tag.
+      ));
+   }
+
+   @Test
+   public void imageUrl() {
+      NodeMetadata nodeMetadata = groupNullNodeParser.apply(instance);
+      assertEquals(nodeMetadata.getImageId(), imageUrl.toString());
+   }
+
+   @Test
+   public final void testInstanceWithGroupNull() {
+      NodeMetadata nodeMetadata = groupNullNodeParser.apply(instance);
+      assertEquals(nodeMetadata.getId(), instance.selfLink().toString());
+      assertEquals(nodeMetadata.getTags(), ImmutableSet.of("aTag", "Group-port-42"));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
index 933487f..4533a06 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
@@ -47,14 +47,14 @@ public class NetworkToSecurityGroupTest {
 
    @Test
    public void testApply() {
-      Supplier<String> projectSupplier = Suppliers.ofInstance("myproject");
+      Supplier<String> projectSupplier = Suppliers.ofInstance("party");
 
       FirewallToIpPermission fwToPerm = new FirewallToIpPermission();
 
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       FirewallApi fwApi = createMock(FirewallApi.class);
 
-      ListOptions options = filter("network eq .*/jclouds-test");
+      ListOptions options = filter("network eq .*/party-test");
       expect(api.getFirewallApi(projectSupplier.get()))
               .andReturn(fwApi);
       expect(fwApi.list(options)).andReturn(
@@ -64,8 +64,8 @@ public class NetworkToSecurityGroupTest {
 
       Network network = Network.create( //
             "abcd", // id
-            URI.create("https://www.googleapis.com/compute/v1/projects/myproject/global/networks/jclouds-test"),
-            "jclouds-test", // name
+            URI.create("https://www.googleapis.com/compute/v1/projects/party/global/networks/party-test"),
+            "party-test", // name
             "some description", // description
             "0.0.0.0/0", // rangeIPv4
             "1.2.3.4" // gatewayIPv4
@@ -75,8 +75,8 @@ public class NetworkToSecurityGroupTest {
 
       SecurityGroup group = netToSg.apply(network);
 
-      assertEquals(group.getId(), "jclouds-test");
-      assertEquals(group.getUri(), URI.create("https://www.googleapis.com/compute/v1/projects/myproject/global/networks/jclouds-test"));
+      assertEquals(group.getId(), "party-test");
+      assertEquals(group.getUri(), URI.create("https://www.googleapis.com/compute/v1/projects/party/global/networks/party-test"));
       assertEquals(group.getIpPermissions().size(), 3);
       assertTrue(Iterables.any(group.getIpPermissions(), Predicates.and(hasProtocol(IpProtocol.TCP),
               hasStartAndEndPort(1, 10))), "No permission found for TCP, ports 1-10");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiExpectTest.java
index ef18d2b..cec6fbc 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiExpectTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiExpectTest.java
@@ -24,7 +24,8 @@ import static org.testng.AssertJUnit.assertNull;
 
 import javax.ws.rs.core.MediaType;
 
-import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineExpectTest;
 import org.jclouds.googlecomputeengine.parse.ParseAddressListTest;
 import org.jclouds.googlecomputeengine.parse.ParseAddressTest;
 import org.jclouds.googlecomputeengine.parse.ParseRegionOperationTest;
@@ -33,13 +34,13 @@ import org.jclouds.http.HttpResponse;
 import org.testng.annotations.Test;
 
 @Test(groups = "unit", testName = "AddressApiExpectTest")
-public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
+public class AddressApiExpectTest extends BaseGoogleComputeEngineExpectTest<GoogleComputeEngineApi> {
 
    public void testGetAddressResponseIs2xx() throws Exception {
       HttpRequest get = HttpRequest
               .builder()
               .method("GET")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses/test-ip1")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses/test-ip1")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
@@ -47,7 +48,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
               .payload(payloadFromResource("/address_get.json")).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, operationResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, get, operationResponse).getAddressApi("party", "us-central1");
 
       assertEquals(api.get("test-ip1"), new ParseAddressTest().expected());
    }
@@ -56,14 +57,14 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest get = HttpRequest
               .builder()
               .method("GET")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses/test-ip1")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses/test-ip1")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
       HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, operationResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, get, operationResponse).getAddressApi("party", "us-central1");
 
       assertNull(api.get("test-ip1"));
    }
@@ -72,7 +73,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest insert = HttpRequest
               .builder()
               .method("POST")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN)
               .payload(payloadFromResourceWithContentType("/address_insert.json", MediaType.APPLICATION_JSON))
@@ -83,7 +84,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
               TOKEN_RESPONSE, insert,
-              insertAddressResponse).getAddressApi("myproject", "us-central1");
+              insertAddressResponse).getAddressApi("party", "us-central1");
 
       assertEquals(api.create("test-ip1"), new ParseRegionOperationTest().expected());
    }
@@ -92,7 +93,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest delete = HttpRequest
               .builder()
               .method("DELETE")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses/test-ip1")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses/test-ip1")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
@@ -100,7 +101,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
               .payload(payloadFromResource("/region_operation.json")).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, deleteResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, delete, deleteResponse).getAddressApi("party", "us-central1");
 
       assertEquals(api.delete("test-ip1"), new ParseRegionOperationTest().expected());
    }
@@ -109,14 +110,14 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest delete = HttpRequest
               .builder()
               .method("DELETE")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses/test-ip1")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses/test-ip1")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
       HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, deleteResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, delete, deleteResponse).getAddressApi("party", "us-central1");
 
       assertNull(api.delete("test-ip1"));
    }
@@ -125,7 +126,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest list = HttpRequest
               .builder()
               .method("GET")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
@@ -133,7 +134,7 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
               .payload(payloadFromResource("/address_list.json")).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, list, operationResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, list, operationResponse).getAddressApi("party", "us-central1");
 
       assertEquals(api.list().next().toString(), new ParseAddressListTest().expected().toString());
    }
@@ -142,14 +143,14 @@ public class AddressApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
       HttpRequest list = HttpRequest
               .builder()
               .method("GET")
-              .endpoint(BASE_URL + "/myproject/regions/us-central1/addresses")
+              .endpoint(BASE_URL + "/party/regions/us-central1/addresses")
               .addHeader("Accept", "application/json")
               .addHeader("Authorization", "Bearer " + TOKEN).build();
 
       HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
 
       AddressApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, list, operationResponse).getAddressApi("myproject", "us-central1");
+              TOKEN_RESPONSE, list, operationResponse).getAddressApi("party", "us-central1");
 
       assertFalse(api.list().hasNext());
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/6b5643c9/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java
new file mode 100644
index 0000000..eb148ca
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.features;
+
+import static org.jclouds.googlecomputeengine.options.ListOptions.Builder.maxResults;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "AggregatedListApiLiveTest")
+public class AggregatedListApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
+
+   private AggregatedListApi api() {
+      return api.aggregatedList(userProject.get());
+   }
+
+   public void machineTypes() {
+      Iterator<ListPage<MachineType>> pageIterator = api().machineTypes(maxResults(1));
+      assertTrue(pageIterator.hasNext());
+
+      List<MachineType> machineTypeAsList = pageIterator.next();
+
+      assertEquals(machineTypeAsList.size(), 9); // zone count!
+   }
+}