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/16 16:53:35 UTC

jclouds-labs-google git commit: Extends coverage of AggregatedList API: address, disk, disk type, global operations.

Repository: jclouds-labs-google
Updated Branches:
  refs/heads/master 4e5581f8c -> 737495c6f


Extends coverage of AggregatedList API: address, disk, disk type, global operations.


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/commit/737495c6
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/tree/737495c6
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/diff/737495c6

Branch: refs/heads/master
Commit: 737495c6f99c225d6c02efb23817e0b1f96a4593
Parents: 4e5581f
Author: Katharina Probst <kp...@google.com>
Authored: Sat Nov 15 14:33:21 2014 -0800
Committer: Adrian Cole <ad...@apache.org>
Committed: Sun Nov 16 07:44:56 2014 -0800

----------------------------------------------------------------------
 .../googlecomputeengine/domain/Operation.java   |   2 +-
 .../features/AggregatedListApi.java             | 245 +++++++++++++++++--
 .../features/AggregatedListApiLiveTest.java     |  68 +++++
 .../features/AggregatedListApiMockTest.java     |  80 ++++++
 .../test/resources/aggregated_address_list.json | 131 ++++++++++
 .../aggregated_address_list_empty.json          | 115 +++++++++
 .../test/resources/aggregated_disk_list.json    | 118 +++++++++
 .../resources/aggregated_disk_list_empty.json   | 115 +++++++++
 .../resources/aggregated_disktype_list.json     | 127 ++++++++++
 .../aggregated_disktype_list_empty.json         | 115 +++++++++
 .../aggregated_global_operation_list.json       |  98 ++++++++
 .../aggregated_global_operation_list_empty.json | 115 +++++++++
 12 files changed, 1311 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
index 4cabead..59bda21 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
@@ -81,7 +81,7 @@ public abstract class Operation {
    @Nullable public abstract String statusMessage();
 
    /** User who requested the operation, for example {@code user@example.com}. */
-   public abstract String user();
+   @Nullable public abstract String user();
 
    /**
     * A progress indicator that ranges from 0 to 100. This should not be used to guess at when the

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java
index eb6522f..47c7f1f 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java
@@ -29,8 +29,12 @@ import javax.ws.rs.QueryParam;
 
 import org.jclouds.googlecloud.domain.ListPage;
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.Address;
+import org.jclouds.googlecomputeengine.domain.Disk;
+import org.jclouds.googlecomputeengine.domain.DiskType;
 import org.jclouds.googlecomputeengine.domain.Instance;
 import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.googlecomputeengine.internal.BaseToIteratorOfListPage;
 import org.jclouds.googlecomputeengine.options.ListOptions;
 import org.jclouds.javax.annotation.Nullable;
@@ -41,19 +45,21 @@ import org.jclouds.rest.annotations.Transform;
 
 import com.google.common.base.Function;
 
-@SkipEncoding({'/', '='})
+@SkipEncoding({ '/', '=' })
 @RequestFilters(OAuthAuthenticationFilter.class)
 @Path("/aggregated")
 @Consumes(APPLICATION_JSON)
 public interface AggregatedListApi {
 
    /**
-    * Retrieves the list of machine type resources available to the specified project.
-    * By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
-    * been set.
+    * Retrieves the list of machine type resources available to the specified
+    * project. By default the list as a maximum size of 100, if no options are
+    * provided or ListOptions#getMaxResults() has not been set.
     *
-    * @param pageToken   marks the beginning of the next list page
-    * @param listOptions listing options
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
     * @return a page of the list
     */
    @Named("MachineTypes:aggregatedList")
@@ -78,13 +84,16 @@ public interface AggregatedListApi {
    static final class MachineTypePages extends BaseToIteratorOfListPage<MachineType, MachineTypePages> {
       private final GoogleComputeEngineApi api;
 
-      @Inject MachineTypePages(GoogleComputeEngineApi api) {
+      @Inject
+      MachineTypePages(GoogleComputeEngineApi api) {
          this.api = api;
       }
 
-      @Override protected Function<String, ListPage<MachineType>> fetchNextPage(final ListOptions options) {
+      @Override
+      protected Function<String, ListPage<MachineType>> fetchNextPage(final ListOptions options) {
          return new Function<String, ListPage<MachineType>>() {
-            @Override public ListPage<MachineType> apply(String pageToken) {
+            @Override
+            public ListPage<MachineType> apply(String pageToken) {
                return api.aggregatedList().pageOfMachineTypes(pageToken, options);
             }
          };
@@ -92,12 +101,14 @@ public interface AggregatedListApi {
    }
 
    /**
-    * Retrieves the list of instance resources available to the specified project.
-    * By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
-    * been set.
+    * Retrieves the list of instance resources available to the specified
+    * project. By default the list as a maximum size of 100, if no options are
+    * provided or ListOptions#getMaxResults() has not been set.
     *
-    * @param pageToken   marks the beginning of the next list page
-    * @param listOptions listing options
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
     * @return a page of the list
     */
    @Named("Instances:aggregatedList")
@@ -122,16 +133,216 @@ public interface AggregatedListApi {
    static final class InstancePages extends BaseToIteratorOfListPage<Instance, InstancePages> {
       private final GoogleComputeEngineApi api;
 
-      @Inject InstancePages(GoogleComputeEngineApi api) {
+      @Inject
+      InstancePages(GoogleComputeEngineApi api) {
          this.api = api;
       }
 
-      @Override protected Function<String, ListPage<Instance>> fetchNextPage(final ListOptions options) {
+      @Override
+      protected Function<String, ListPage<Instance>> fetchNextPage(final ListOptions options) {
          return new Function<String, ListPage<Instance>>() {
-            @Override public ListPage<Instance> apply(String pageToken) {
+            @Override
+            public ListPage<Instance> apply(String pageToken) {
                return api.aggregatedList().pageOfInstances(pageToken, options);
             }
          };
       }
    }
+
+   /**
+    * Retrieves the list of address resources available to the specified
+    * project. By default the list as a maximum size of 100, if no options are
+    * provided or ListOptions#getMaxResults() has not been set.
+    *
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
+    * @return a page of the list
+    */
+   @Named("Addresses:aggregatedList")
+   @GET
+   @Path("/addresses")
+   ListPage<Address> pageOfAddresses(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions);
+
+   /** @see #pageOfAddresses(String, ListOptions) */
+   @Named("Addresses:aggregatedList")
+   @GET
+   @Path("/addresses")
+   @Transform(AddressPages.class)
+   Iterator<ListPage<Address>> addresses();
+
+   /** @see #pageOfAddresses(String, ListOptions) */
+   @Named("Addresses:aggregatedList")
+   @GET
+   @Path("/addresses")
+   @Transform(AddressPages.class)
+   Iterator<ListPage<Address>> addresses(ListOptions options);
+
+   static final class AddressPages extends BaseToIteratorOfListPage<Address, AddressPages> {
+      private final GoogleComputeEngineApi api;
+
+      @Inject
+      AddressPages(GoogleComputeEngineApi api) {
+         this.api = api;
+      }
+
+      @Override
+      protected Function<String, ListPage<Address>> fetchNextPage(final ListOptions options) {
+         return new Function<String, ListPage<Address>>() {
+            @Override
+            public ListPage<Address> apply(String pageToken) {
+               return api.aggregatedList().pageOfAddresses(pageToken, options);
+            }
+         };
+      }
+   }
+
+   /**
+    * Retrieves the list of disk resources available to the specified project.
+    * By default the list as a maximum size of 100, if no options are provided
+    * or ListOptions#getMaxResults() has not been set.
+    *
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
+    * @return a page of the list
+    */
+   @Named("Disks:aggregatedList")
+   @GET
+   @Path("/disks")
+   ListPage<Disk> pageOfDisks(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions);
+
+   /** @see #pageOfDisks(String, ListOptions) */
+   @Named("Disks:aggregatedList")
+   @GET
+   @Path("/disks")
+   @Transform(DiskPages.class)
+   Iterator<ListPage<Disk>> disks();
+
+   /** @see #pageOfDisks(String, ListOptions) */
+   @Named("Disks:aggregatedList")
+   @GET
+   @Path("/disks")
+   @Transform(DiskPages.class)
+   Iterator<ListPage<Disk>> disks(ListOptions options);
+
+   static final class DiskPages extends BaseToIteratorOfListPage<Disk, DiskPages> {
+      private final GoogleComputeEngineApi api;
+
+      @Inject
+      DiskPages(GoogleComputeEngineApi api) {
+         this.api = api;
+      }
+
+      @Override
+      protected Function<String, ListPage<Disk>> fetchNextPage(final ListOptions options) {
+         return new Function<String, ListPage<Disk>>() {
+            @Override
+            public ListPage<Disk> apply(String pageToken) {
+               return api.aggregatedList().pageOfDisks(pageToken, options);
+            }
+         };
+      }
+   }
+
+   /**
+    * Retrieves the list of disk type resources available to the specified
+    * project. By default the list as a maximum size of 100, if no options are
+    * provided or ListOptions#getMaxResults() has not been set.
+    *
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
+    * @return a page of the list
+    */
+   @Named("DiskTypes:aggregatedList")
+   @GET
+   @Path("/diskTypes")
+   ListPage<DiskType> pageOfDiskTypes(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions);
+
+   /** @see #pageOfDiskTypes(String, ListOptions) */
+   @Named("DiskTypes:aggregatedList")
+   @GET
+   @Path("/diskTypes")
+   @Transform(DiskTypePages.class)
+   Iterator<ListPage<DiskType>> diskTypes();
+
+   /** @see #pageOfDiskTypes(String, ListOptions) */
+   @Named("DiskTypes:aggregatedList")
+   @GET
+   @Path("/diskTypes")
+   @Transform(DiskTypePages.class)
+   Iterator<ListPage<DiskType>> diskTypes(ListOptions options);
+
+   static final class DiskTypePages extends BaseToIteratorOfListPage<DiskType, DiskTypePages> {
+      private final GoogleComputeEngineApi api;
+
+      @Inject
+      DiskTypePages(GoogleComputeEngineApi api) {
+         this.api = api;
+      }
+
+      @Override
+      protected Function<String, ListPage<DiskType>> fetchNextPage(final ListOptions options) {
+         return new Function<String, ListPage<DiskType>>() {
+            @Override
+            public ListPage<DiskType> apply(String pageToken) {
+               return api.aggregatedList().pageOfDiskTypes(pageToken, options);
+            }
+         };
+      }
+   }
+
+   /**
+    * Retrieves the list of global operations resources available to the
+    * specified project. By default the list as a maximum size of 100, if no
+    * options are provided or ListOptions#getMaxResults() has not been set.
+    *
+    * @param pageToken
+    *           marks the beginning of the next list page
+    * @param listOptions
+    *           listing options
+    * @return a page of the list
+    */
+   @Named("GlobalOperations:aggregatedList")
+   @GET
+   @Path("/operations")
+   ListPage<Operation> pageOfGlobalOperations(@Nullable @QueryParam("pageToken") String pageToken,
+         ListOptions listOptions);
+
+   /** @see #pageOfGlobalOperations(String, ListOptions) */
+   @Named("GlobalOperations:aggregatedList")
+   @GET
+   @Path("/operations")
+   @Transform(OperationPages.class)
+   Iterator<ListPage<Operation>> globalOperations();
+
+   /** @see #pageOfGlobalOperations(String, ListOptions) */
+   @Named("GlobalOperations:aggregatedList")
+   @GET
+   @Path("/operations")
+   @Transform(OperationPages.class)
+   Iterator<ListPage<Operation>> globalOperations(ListOptions options);
+
+   static final class OperationPages extends BaseToIteratorOfListPage<Operation, OperationPages> {
+      private final GoogleComputeEngineApi api;
+
+      @Inject
+      OperationPages(GoogleComputeEngineApi api) {
+         this.api = api;
+      }
+
+      @Override
+      protected Function<String, ListPage<Operation>> fetchNextPage(final ListOptions options) {
+         return new Function<String, ListPage<Operation>>() {
+            @Override
+            public ListPage<Operation> apply(String pageToken) {
+               return api.aggregatedList().pageOfGlobalOperations(pageToken, options);
+            }
+         };
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/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
index 436fea0..349a9ac 100644
--- 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
@@ -24,13 +24,21 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.jclouds.googlecloud.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.Address;
+import org.jclouds.googlecomputeengine.domain.Disk;
+import org.jclouds.googlecomputeengine.domain.DiskType;
 import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
+import org.testng.SkipException;
 import org.testng.annotations.Test;
 
 @Test(groups = "live", testName = "AggregatedListApiLiveTest")
 public class AggregatedListApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
+   public static final String DISK_NAME = "aggregated-list-api-live-test-disk";
+   public static final int sizeGb = 1;
+
    private AggregatedListApi api() {
       return api.aggregatedList();
    }
@@ -43,4 +51,64 @@ public class AggregatedListApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
 
       assertEquals(machineTypeAsList.size(), 9); // zone count!
    }
+
+   public void addresses() {
+      Iterator<ListPage<Address>> pageIterator = api().addresses(maxResults(1));
+      // make sure that in spite of having only one result per page we get at
+      // least two results
+      int count = 0;
+      for (; count < 2 && pageIterator.hasNext();) {
+         ListPage<Address> result = pageIterator.next();
+         if (!result.isEmpty()) {
+            count++;
+         }
+      }
+      if (count < 2) {
+         throw new SkipException("Not enough addresses");
+      }
+      assertEquals(count, 2);
+   }
+
+   public void disks() {
+      Iterator<ListPage<Disk>> pageIterator = api().disks(maxResults(1));
+      // make sure that in spite of having only one result per page we get at
+      // least two results
+      int count = 0;
+      for (; count < 2 && pageIterator.hasNext();) {
+         ListPage<Disk> result = pageIterator.next();
+         if (!result.isEmpty()) {
+            count++;
+         }
+      }
+      if (count < 2) {
+         throw new SkipException("Not enough disks");
+      }
+      assertEquals(count, 2);
+   }
+
+   public void diskTypes() {
+      Iterator<ListPage<DiskType>> pageIterator = api().diskTypes(maxResults(1));
+      assertTrue(pageIterator.hasNext());
+
+      List<DiskType> diskTypeAsList = pageIterator.next();
+
+      assertEquals(diskTypeAsList.size(), 1);
+   }
+
+   public void globalOperations() {
+      Iterator<ListPage<Operation>> pageIterator = api().globalOperations(maxResults(1));
+      // make sure that in spite of having only one result per page we get at
+      // least two results
+      int count = 0;
+      for (; count < 2 && pageIterator.hasNext();) {
+         ListPage<Operation> result = pageIterator.next();
+         if (!result.isEmpty()) {
+            count++;
+         }
+      }
+      if (count < 2) {
+         throw new SkipException("Not enough global operations");
+      }
+      assertEquals(count, 2);
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java
index 8a1be6b..f6f1c3a 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java
@@ -64,4 +64,84 @@ public class AggregatedListApiMockTest extends BaseGoogleComputeEngineApiMockTes
 
       assertSent(server, "GET", "/projects/party/aggregated/instances");
    }
+
+   public void addresses() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_address_list.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertTrue(aggregatedList.addresses().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/addresses");
+   }
+
+   public void addressesResponseIs4xx() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_address_list_empty.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertFalse(aggregatedList.addresses().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/addresses");
+   }
+
+   public void disks() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_disk_list.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertTrue(aggregatedList.disks().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/disks");
+   }
+
+   public void disksResponseIs4xx() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_disk_list_empty.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertFalse(aggregatedList.disks().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/disks");
+   }
+
+   public void diskTypes() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_disktype_list.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertTrue(aggregatedList.diskTypes().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/diskTypes");
+   }
+
+   public void diskTypesResponseIs4xx() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_disktype_list_empty.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertFalse(aggregatedList.diskTypes().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/diskTypes");
+   }
+
+   public void globalOperations() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_global_operation_list.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertTrue(aggregatedList.globalOperations().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/operations");
+   }
+
+   public void globalOperationsResponseIs4xx() throws Exception {
+      server.enqueue(jsonResponse("/aggregated_global_operation_list_empty.json"));
+
+      AggregatedListApi aggregatedList = api().aggregatedList();
+
+      assertFalse(aggregatedList.globalOperations().hasNext());
+
+      assertSent(server, "GET", "/projects/party/aggregated/operations");
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_address_list.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_address_list.json b/google-compute-engine/src/test/resources/aggregated_address_list.json
new file mode 100644
index 0000000..d461879
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_address_list.json
@@ -0,0 +1,131 @@
+{
+ "kind": "compute#addressAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/addresses",
+ "id": "projects/party/aggregated/addresses",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "addresses": [
+    {
+
+        "kind": "compute#address",
+        "id": "4439373783165447583",
+        "creationTimestamp": "2013-07-26T13:57:20.204-07:00",
+        "status": "RESERVED",
+        "region": "https://www.googleapis.com/compute/v1/projects/party/regions/us-central1",
+        "name": "test-ip1",
+        "description": "",
+        "address": "173.255.115.190",
+        "selfLink": "https://www.googleapis.com/compute/v1/projects/party/regions/us-central1/addresses/test-ip1"
+    },
+    {
+
+        "kind": "compute#address",
+        "id": "4881363978908129158",
+        "creationTimestamp": "2013-07-26T14:08:21.552-07:00",
+        "status": "RESERVED",
+        "region": "https://www.googleapis.com/compute/v1/projects/party/regions/us-central1",
+        "name": "test-ip2",
+        "description": "",
+        "address": "173.255.118.115",
+        "selfLink": "https://www.googleapis.com/compute/v1/projects/party/regions/us-central1/addresses/test-ip2"
+    }
+   ]
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_address_list_empty.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_address_list_empty.json b/google-compute-engine/src/test/resources/aggregated_address_list_empty.json
new file mode 100644
index 0000000..22f407d
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_address_list_empty.json
@@ -0,0 +1,115 @@
+{
+ "kind": "compute#addressAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/addresses",
+ "id": "projects/party/aggregated/addresses",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-a"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_disk_list.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_disk_list.json b/google-compute-engine/src/test/resources/aggregated_disk_list.json
new file mode 100644
index 0000000..599e23d
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_disk_list.json
@@ -0,0 +1,118 @@
+{
+ "kind": "compute#diskAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/disks",
+ "id": "projects/party/aggregated/disks",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "disks": [
+    {
+	     "kind": "compute#disk",
+	     "id": "13050421646334304115",
+	     "creationTimestamp": "2012-11-25T01:38:48.306",
+	     "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/disks/testimage1",
+	     "name": "testimage1",
+	     "sizeGb": "1",
+	     "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a",
+	     "status": "READY",
+	     "type": "https://www.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a/diskTypes/pd-standard"
+	}
+   ]
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_disk_list_empty.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_disk_list_empty.json b/google-compute-engine/src/test/resources/aggregated_disk_list_empty.json
new file mode 100644
index 0000000..d74d3e0
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_disk_list_empty.json
@@ -0,0 +1,115 @@
+{
+ "kind": "compute#diskAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/disks",
+ "id": "projects/party/aggregated/disks",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-a"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_disktype_list.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_disktype_list.json b/google-compute-engine/src/test/resources/aggregated_disktype_list.json
new file mode 100644
index 0000000..12a9e33
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_disktype_list.json
@@ -0,0 +1,127 @@
+{
+ "kind": "compute#diskTypeAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/diskTypes",
+ "id": "projects/party/aggregated/diskTypes",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "diskTypes": [
+	  {
+	   "kind": "compute#diskType",
+	   "creationTimestamp": "2014-06-02T11:07:28.530-07:00",
+	   "name": "pd-standard",
+	   "description": "Standard Persistent Disk",
+	   "validDiskSize": "10GB-10TB",
+	   "zone": "https://content.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a",
+	   "selfLink": "https://content.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a/diskTypes/pd-standard",
+	   "defaultDiskSizeGb": "500"
+	  },
+	  {
+	   "kind": "compute#diskType",
+	   "creationTimestamp": "2014-06-02T11:07:28.529-07:00",
+	   "name": "pd-ssd",
+	   "description": "SSD Persistent Disk",
+	   "validDiskSize": "10GB-1TB",
+	   "zone": "https://content.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a",
+	   "selfLink": "https://content.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a/diskTypes/pd-ssd",
+	   "defaultDiskSizeGb": "100"
+	  }
+   ]
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_disktype_list_empty.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_disktype_list_empty.json b/google-compute-engine/src/test/resources/aggregated_disktype_list_empty.json
new file mode 100644
index 0000000..cd5e22c
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_disktype_list_empty.json
@@ -0,0 +1,115 @@
+{
+ "kind": "compute#diskTypeAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/diskTypes",
+ "id": "projects/party/aggregated/diskTypes",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-a"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_global_operation_list.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_global_operation_list.json b/google-compute-engine/src/test/resources/aggregated_global_operation_list.json
new file mode 100644
index 0000000..93f86c3
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_global_operation_list.json
@@ -0,0 +1,98 @@
+{
+ "kind": "compute#operationAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/operations",
+ "id": "projects/party/aggregated/operations",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "operations": [
+      {
+         "kind": "compute#operation",
+         "id": "13053095055850848306",
+         "selfLink": "https://www.googleapis.com/compute/v1/projects/party/global/operations/operation-1354084865060",
+         "name": "operation-1354084865060",
+         "targetLink": "https://www.googleapis.com/compute/v1/projects/party/global/firewalls/jclouds-test-delete",
+         "targetId": "13053094017547040099",
+         "status": "DONE",
+         "user": "user@developer.gserviceaccount.com",
+         "progress": 100,
+         "insertTime": "2012-11-28T06:41:05.060",
+         "startTime": "2012-11-28T06:41:05.142",
+         "endTime": "2012-11-28T06:41:06.142",
+         "operationType": "insert"
+      }
+    ]
+  }
+ }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/737495c6/google-compute-engine/src/test/resources/aggregated_global_operation_list_empty.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/aggregated_global_operation_list_empty.json b/google-compute-engine/src/test/resources/aggregated_global_operation_list_empty.json
new file mode 100644
index 0000000..09d0414
--- /dev/null
+++ b/google-compute-engine/src/test/resources/aggregated_global_operation_list_empty.json
@@ -0,0 +1,115 @@
+{
+ "kind": "compute#operationAggregatedList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/operations",
+ "id": "projects/party/aggregated/operations",
+ "items": {
+  "zones/asia-east1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-a"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-b"
+     }
+    ]
+   }
+  },
+  "zones/asia-east1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/asia-east1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/asia-east1-c"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-a"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-b"
+     }
+    ]
+   }
+  },
+  "zones/europe-west1-c": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/europe-west1-c' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/europe-west1-c"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-a": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-a' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-a"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-b": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-b' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-b"
+     }
+    ]
+   }
+  },
+  "zones/us-central1-f": {
+   "warning": {
+    "code": "NO_RESULTS_ON_PAGE",
+    "message": "There are no results for scope 'zones/us-central1-f' on this page.",
+    "data": [
+     {
+      "key": "scope",
+      "value": "zones/us-central1-f"
+     }
+    ]
+   }
+  }
+ }
+}
\ No newline at end of file