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/25 19:54:16 UTC

jclouds-labs-google git commit: Added Image.deprecate, ImageApiMockTest completed, removed ImageApiExpectTest

Repository: jclouds-labs-google
Updated Branches:
  refs/heads/master 81b4351b3 -> 0260afd4e


Added Image.deprecate, ImageApiMockTest completed, removed ImageApiExpectTest


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/0260afd4
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/tree/0260afd4
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/diff/0260afd4

Branch: refs/heads/master
Commit: 0260afd4e6564a6b51ab9178418a0f5f3284a68b
Parents: 81b4351
Author: Daniel Broudy <br...@google.com>
Authored: Mon Nov 10 18:35:58 2014 -0800
Committer: Adrian Cole <ac...@twitter.com>
Committed: Tue Nov 25 10:54:00 2014 -0800

----------------------------------------------------------------------
 .../GoogleComputeEngineImageToImage.java        |  11 +-
 .../googlecomputeengine/domain/Deprecated.java  |  11 +-
 .../googlecomputeengine/features/ImageApi.java  |  16 ++
 .../options/DeprecateOptions.java               |  11 +-
 .../GoogleComputeEngineImageToImageTest.java    |  42 ++++-
 .../features/ImageApiExpectTest.java            | 184 -------------------
 .../features/ImageApiLiveTest.java              |  30 +++
 .../features/ImageApiMockTest.java              | 135 ++++++++++++++
 .../BaseGoogleComputeEngineApiMockTest.java     |   4 +
 .../parse/ParseImageListTest.java               |   9 +-
 .../parse/ParseImageTest.java                   |  12 +-
 .../parse/ParseOperationTest.java               |  13 +-
 .../src/test/resources/image_deprecate.json     |   7 +
 13 files changed, 275 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
index 24fab18..1700e3d 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
@@ -27,6 +27,7 @@ import java.util.List;
 import org.jclouds.compute.domain.ImageBuilder;
 import org.jclouds.compute.domain.OperatingSystem;
 import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
 import org.jclouds.googlecomputeengine.domain.Image;
 
 import com.google.common.base.Function;
@@ -44,6 +45,13 @@ public final class GoogleComputeEngineImageToImage implements Function<Image, or
               .status(Status.AVAILABLE)
               .uri(image.selfLink());
 
+      if (image.deprecated() != null) {
+         builder.userMetadata(ImmutableMap.of("deprecatedState", image.deprecated().state().name()));
+         if (image.deprecated().state() == State.DELETED){
+            builder.status(Status.DELETED);
+         }
+      }
+
       List<String> splits = Lists.newArrayList(image.name().split("-"));
       OperatingSystem.Builder osBuilder = defaultOperatingSystem(image);
       if (splits == null || splits.size() == 0 || splits.size() < 3) {
@@ -58,9 +66,6 @@ public final class GoogleComputeEngineImageToImage implements Function<Image, or
       String version = on(".").join(limit(skip(splits, 1), splits.size() - 2));
       osBuilder.version(version);
 
-      if (image.deprecated() != null) {
-         builder.userMetadata(ImmutableMap.of("deprecatedState", image.deprecated().state()));
-      }
       builder.version(getLast(splits));
       return builder.operatingSystem(osBuilder.build()).build();
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Deprecated.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Deprecated.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Deprecated.java
index 1af5d6b..77077df 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Deprecated.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Deprecated.java
@@ -26,8 +26,15 @@ import com.google.auto.value.AutoValue;
 /** Deprecation information for an image or kernel */
 @AutoValue
 public abstract class Deprecated {
+
+   public enum State{
+      DELETED,
+      DEPRECATED,
+      OBSELETE;
+   }
+
    /** The deprecation state of this image. */
-   @Nullable public abstract String state();
+   @Nullable public abstract State state();
 
    /** A fully-qualified URL of the suggested replacement for the deprecated image. */
    @Nullable public abstract URI replacement();
@@ -48,7 +55,7 @@ public abstract class Deprecated {
    @Nullable public abstract String deleted();
 
    @SerializedNames({ "state", "replacement", "deprecated", "obsolete", "deleted" })
-   public static Deprecated create(String state, URI replacement, String deprecated, String obsolete, String deleted) {
+   public static Deprecated create(State state, URI replacement, String deprecated, String obsolete, String deleted) {
       return new AutoValue_Deprecated(state, replacement, deprecated, obsolete, deleted);
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
index 4123236..e7c24e6 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
@@ -40,9 +40,11 @@ import org.jclouds.googlecomputeengine.domain.Image;
 import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.googlecomputeengine.internal.BaseArg0ToIteratorOfListPage;
 import org.jclouds.googlecomputeengine.internal.BaseToIteratorOfListPage;
+import org.jclouds.googlecomputeengine.options.DeprecateOptions;
 import org.jclouds.googlecomputeengine.options.ListOptions;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Endpoint;
 import org.jclouds.rest.annotations.EndpointParam;
 import org.jclouds.rest.annotations.Fallback;
@@ -102,6 +104,20 @@ public interface ImageApi {
    Operation createFromDisk(@PayloadParam("name") String image, @PayloadParam("sourceDisk") String sourceDisk);
 
    /**
+    * Sets the deprecation status of an image. If no message body is given, clears the deprecation status instead.
+    *
+    * @param image  The Image resource to deprecate.
+    * @param deprecated the deprecation status to return
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.
+    */
+   @Named("Images:deprecate")
+   @POST
+   @Endpoint(CurrentProject.class)
+   @Path("/global/images/{image}/deprecate")
+   Operation deprecate(@PathParam("image") String image, @BinderParam(BindToJsonPayload.class) DeprecateOptions deprecated);
+
+   /**
     * Retrieves the list of image 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.

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/options/DeprecateOptions.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/options/DeprecateOptions.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/options/DeprecateOptions.java
index 382bf71..ce19ded 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/options/DeprecateOptions.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/options/DeprecateOptions.java
@@ -18,6 +18,7 @@ package org.jclouds.googlecomputeengine.options;
 
 import java.net.URI;
 import java.util.Date;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
 
 /**
  * Options to set the deprecation status of a resource. Currently only for images.
@@ -26,12 +27,6 @@ import java.util.Date;
  */
 public class DeprecateOptions {
 
-   public enum State {
-      DEPRECATED,
-      OBSOLETE,
-      DELETED
-   }
-
    private State state;
    private URI replacement;
    private Date deprecated;
@@ -92,7 +87,7 @@ public class DeprecateOptions {
    }
 
    /**
-    * @see org.jclouds.googlecomputeengine.options.DeprecateOptions#getReplacement()
+    * @see DeprecateOptions#getReplacement()
     */
    public DeprecateOptions replacement(URI replacement) {
       this.replacement = replacement;
@@ -116,7 +111,7 @@ public class DeprecateOptions {
    }
 
    /**
-    * @see org.jclouds.googlecomputeengine.options.DeprecateOptions#getDeleted()
+    * @see DeprecateOptions#getDeleted()
     */
    public DeprecateOptions deleted(Date deleted) {
       this.deleted = deleted;

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/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 6abca24..9414b98 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
@@ -21,7 +21,10 @@ import static org.testng.Assert.assertSame;
 
 import java.net.URI;
 
+import org.jclouds.compute.domain.Image.Status;
 import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.googlecomputeengine.domain.Deprecated;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
 import org.jclouds.googlecomputeengine.domain.Image;
 import org.testng.annotations.Test;
 
@@ -29,7 +32,7 @@ import org.testng.annotations.Test;
 public class GoogleComputeEngineImageToImageTest {
    public void testArbitraryImageName() {
       GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
-      Image image = image("arbitratyname");
+      Image image = image("arbitratyname", null);
       org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
       assertEquals(transformed.getName(), image.name());
       assertEquals(transformed.getId(), image.selfLink().toString());
@@ -39,7 +42,7 @@ public class GoogleComputeEngineImageToImageTest {
 
    public void testWellFormedImageName() {
       GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
-      Image image = image("ubuntu-12-04-v123123");
+      Image image = image("ubuntu-12-04-v123123", null);
       org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
       assertEquals(transformed.getName(), image.name());
       assertEquals(transformed.getId(), image.selfLink().toString());
@@ -48,7 +51,38 @@ public class GoogleComputeEngineImageToImageTest {
       assertEquals(transformed.getOperatingSystem().getVersion(), "12.04");
    }
 
-   private static Image image(String name) {
+   public void testDeleted(){
+      GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
+      Deprecated deprecated =  Deprecated.create(
+         State.DELETED, // state
+         URI.create("http://baseurl/projects/centos-cloud/global/images/centos-6-2-v20120326test"), // replacement
+         "2014-07-16T22:16:13.468Z", // deprecated
+         "2015-07-16T22:16:13.468Z", // obsolete
+         "2016-07-16T22:16:13.468Z"); // deleted
+      Image image = image("test-deprecated", deprecated);
+      org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
+      assertEquals(transformed.getName(), image.name());
+      assertEquals(transformed.getId(), image.selfLink().toString());
+      assertEquals(transformed.getProviderId(), image.id());
+      assertSame(transformed.getOperatingSystem().getFamily(), OsFamily.LINUX);
+      assertEquals(transformed.getUserMetadata().get("deprecatedState"), image.deprecated().state().name());
+      assertEquals(transformed.getStatus(), Status.DELETED);
+   }
+
+   public void testDeprecated(){
+      GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
+      Deprecated deprecated =  Deprecated.create(
+         State.DEPRECATED, // state
+         URI.create("http://baseurl/projects/centos-cloud/global/images/centos-6-2-v20120326test"), // replacement
+         "2014-07-16T22:16:13.468Z", // deprecated
+         "2015-07-16T22:16:13.468Z", // obsolete
+         "2016-07-16T22:16:13.468Z"); // deleted
+      Image image = image("test-deprecated", deprecated);
+      org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
+      assertEquals(transformed.getStatus(), Status.AVAILABLE);
+   }
+
+   private static Image image(String name, Deprecated deprecated) {
       return Image.create( //
             "1234", // id
             URI.create("http://test.com/1234"), // selfLink
@@ -56,7 +90,7 @@ public class GoogleComputeEngineImageToImageTest {
             "", // description
             "RAW", // sourceType
             Image.RawDisk.create(URI.create("foo"), "TAR", null), // rawDisk
-            null // deprecated
+            deprecated // deprecated
       );
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
deleted file mode 100644
index 7091d91..0000000
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
+++ /dev/null
@@ -1,184 +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.features;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.AssertJUnit.assertNull;
-
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineExpectTest;
-import org.jclouds.googlecomputeengine.parse.ParseImageListTest;
-import org.jclouds.googlecomputeengine.parse.ParseImageTest;
-import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.testng.annotations.Test;
-
-@Test(groups = "unit", testName = "ImageApiExpectTest")
-public class ImageApiExpectTest extends BaseGoogleComputeEngineExpectTest<GoogleComputeEngineApi> {
-   HttpRequest get = HttpRequest
-         .builder()
-         .method("GET")
-         .endpoint(BASE_URL + "/party/global/images/centos-6-2-v20120326")
-         .addHeader("Accept", "application/json")
-         .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-   public void get() throws Exception {
-      HttpResponse response = HttpResponse.builder().statusCode(200)
-              .payload(payloadFromResource("/image_get.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, response).images();
-
-      assertEquals(imageApi.get(get.getEndpoint()), new ParseImageTest().expected());
-   }
-
-   public void getResponseIs4xx() throws Exception {
-      HttpResponse response = HttpResponse.builder().statusCode(404).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, response).images();
-
-      assertNull(imageApi.get(get.getEndpoint()));
-   }
-
-   public void getByName() throws Exception {
-      HttpResponse response = HttpResponse.builder().statusCode(200)
-            .payload(payloadFromResource("/image_get.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-            TOKEN_RESPONSE, get, response).images();
-
-      assertEquals(imageApi.get("centos-6-2-v20120326"), new ParseImageTest().expected());
-   }
-
-   public void getByNameResponseIs4xx() throws Exception {
-      HttpResponse response = HttpResponse.builder().statusCode(404).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-            TOKEN_RESPONSE, get, response).images();
-
-      assertNull(imageApi.get("centos-6-2-v20120326"));
-   }
-
-   public void testDeleteImageResponseIs2xx() {
-      HttpRequest delete = HttpRequest
-              .builder()
-              .method("DELETE")
-              .endpoint(BASE_URL + "/party/global/images/centos-6-2-v20120326")
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
-              .payload(payloadFromResource("/operation.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, deleteResponse).images();
-
-      assertEquals(imageApi.delete("centos-6-2-v20120326"), new ParseOperationTest().expected());
-   }
-
-   public void testDeleteImageResponseIs4xx() {
-      HttpRequest delete = HttpRequest
-              .builder()
-              .method("DELETE")
-              .endpoint(BASE_URL + "/party/global/images/centos-6-2-v20120326")
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, deleteResponse).images();
-
-      assertNull(imageApi.delete("centos-6-2-v20120326"));
-   }
-
-   public static final HttpRequest LIST_PROJECT_IMAGES_REQUEST = HttpRequest
-         .builder()
-         .method("GET")
-         .endpoint(BASE_URL + "/party/global/images")
-         .addHeader("Accept", "application/json")
-         .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-   public static final HttpResponse LIST_PROJECT_IMAGES_RESPONSE = HttpResponse.builder().statusCode(200)
-         .payload(staticPayloadFromResource("/image_list.json")).build();
-
-   public void list() {
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE).images();
-
-      assertEquals(imageApi.list().next(), new ParseImageListTest().expected());
-   }
-
-   public void listEmpty() {
-      HttpResponse response = HttpResponse.builder().statusCode(200)
-            .payload(payloadFromResource("/list_empty.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, LIST_PROJECT_IMAGES_REQUEST, response).images();
-
-      assertFalse(imageApi.list().hasNext());
-   }
-
-   public static final HttpRequest LIST_CENTOS_IMAGES_REQUEST = HttpRequest
-         .builder()
-         .method("GET")
-         .endpoint(BASE_URL + "/centos-cloud/global/images")
-         .addHeader("Accept", "application/json")
-         .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-   public void listInProject() {
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-            TOKEN_RESPONSE, LIST_CENTOS_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE).images();
-
-      assertEquals(imageApi.listInProject("centos-cloud").next(), new ParseImageListTest().expected());
-   }
-
-   public void listInProjectEmpty() {
-      HttpResponse response = HttpResponse.builder().statusCode(200)
-            .payload(payloadFromResource("/list_empty.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-            TOKEN_RESPONSE, LIST_CENTOS_IMAGES_REQUEST, response).images();
-
-      assertFalse(imageApi.listInProject("centos-cloud").hasNext());
-   }
-
-   public void testCreateImageFromPdResponseIs2xx(){
-      HttpRequest createImage = HttpRequest
-            .builder()
-            .method("POST")
-            .endpoint(BASE_URL + "/party/global/images")
-            .addHeader("Accept", "application/json")
-            .addHeader("Authorization", "Bearer " + TOKEN)
-            .payload(payloadFromResource("/image_insert_from_pd.json"))
-            .build();
-
-      HttpResponse createImageResponse = HttpResponse.builder().statusCode(200)
-                                  .payload(payloadFromResource("/operation.json")).build();
-
-      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-            TOKEN_RESPONSE, createImage, createImageResponse).images();
-
-      assertEquals(imageApi.createFromDisk("my-image", BASE_URL + "/party/zones/us-central1-a/disks/mydisk"),
-            new ParseOperationTest().expected());
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
index 5699edb..4d1afc7 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
@@ -18,15 +18,19 @@ 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.assertNull;
 
 import java.net.URI;
 import java.util.Iterator;
 import java.util.List;
 
+import org.jclouds.date.internal.SimpleDateFormatDateService;
 import org.jclouds.googlecloud.domain.ListPage;
 import org.jclouds.googlecomputeengine.domain.Disk;
 import org.jclouds.googlecomputeengine.domain.Image;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
 import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
+import org.jclouds.googlecomputeengine.options.DeprecateOptions;
 import org.testng.annotations.Test;
 
 public class ImageApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
@@ -81,6 +85,32 @@ public class ImageApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
    }
 
    @Test(groups = "live", dependsOnMethods = "testGetCreatedImage")
+   public void testDeprecateImage(){
+      Image image = api().get(IMAGE_NAME);
+      assertNull(image.deprecated());
+      String deprecated = "2015-07-16T22:16:13.468Z";
+      String obsolete = "2016-10-16T22:16:13.468Z";
+      String deleted = "2017-01-16T22:16:13.468Z";
+
+      URI replacement = URI.create("https://www.googleapis.com/compute/v1/projects/centos-cloud/global/images/centos-6-2-v20120326test");
+
+      DeprecateOptions deprecateOptions = new DeprecateOptions().state(State.DEPRECATED)
+            .replacement(replacement)
+            .deprecated(new SimpleDateFormatDateService().iso8601DateParse(deprecated))
+            .obsolete(new SimpleDateFormatDateService().iso8601DateParse(obsolete))
+            .deleted(new SimpleDateFormatDateService().iso8601DateParse(deleted));
+
+      assertOperationDoneSuccessfully(api().deprecate(IMAGE_NAME, deprecateOptions));
+
+      image = api().get(IMAGE_NAME);
+      assertEquals(image.deprecated().state(), State.DEPRECATED);
+      assertEquals(image.deprecated().replacement(), replacement);
+      assertEquals(image.deprecated().deprecated(), deprecated);
+      assertEquals(image.deprecated().obsolete(), obsolete);
+      assertEquals(image.deprecated().deleted(), deleted);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "testDeprecateImage", alwaysRun = true)
    public void testCleanup(){
       assertOperationDoneSuccessfully(api().delete(IMAGE_NAME));
       assertOperationDoneSuccessfully(diskApi().delete(DISK_NAME));

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiMockTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiMockTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiMockTest.java
new file mode 100644
index 0000000..7fd62c5
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiMockTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+
+import java.net.URI;
+
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
+import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiMockTest;
+import org.jclouds.googlecomputeengine.options.DeprecateOptions;
+import org.jclouds.googlecomputeengine.parse.ParseImageListTest;
+import org.jclouds.googlecomputeengine.parse.ParseImageTest;
+import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ImageApiMockTest", singleThreaded = true)
+public class ImageApiMockTest extends BaseGoogleComputeEngineApiMockTest {
+
+   public void get() throws Exception {
+      server.enqueue(jsonResponse("/image_get.json"));
+
+      assertEquals(imageApi().get(URI.create(url("/projects/party/global/images/centos-6-2-v20120326"))),
+            new ParseImageTest().expected(url("/projects")));
+      assertSent(server, "GET", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void get_4xx() throws Exception {
+      server.enqueue(response404());
+
+      assertNull(imageApi().get(URI.create(url("/projects/party/global/images/centos-6-2-v20120326"))));
+      assertSent(server, "GET", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void getByName() throws Exception {
+      server.enqueue(jsonResponse("/image_get.json"));
+
+      assertEquals(imageApi().get("centos-6-2-v20120326"), new ParseImageTest().expected(url("/projects")));
+      assertSent(server, "GET", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void getByName_4xx() throws Exception {
+      server.enqueue(response404());
+
+      assertNull(imageApi().get("centos-6-2-v20120326"));
+      assertSent(server, "GET", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void deleteImage_2xx()  throws Exception {
+      server.enqueue(jsonResponse("/operation.json"));
+
+      assertEquals(imageApi().delete("centos-6-2-v20120326"),
+            new ParseOperationTest().expected(url("/projects")));
+      assertSent(server, "DELETE", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void deleteImage_4xx() throws Exception {
+      server.enqueue(response404());
+
+      assertNull(imageApi().delete("centos-6-2-v20120326"));
+      assertSent(server, "DELETE", "/projects/party/global/images/centos-6-2-v20120326");
+   }
+
+   public void list() throws InterruptedException {
+      server.enqueue(jsonResponse("/image_list.json"));
+
+      assertEquals(imageApi().list().next(), new ParseImageListTest().expected(url("/projects")));
+      assertSent(server, "GET", "/projects/party/global/images");
+   }
+
+   public void list_empty() throws InterruptedException {
+      server.enqueue(jsonResponse("/list_empty.json"));
+
+      assertFalse(imageApi().list().hasNext());
+      assertSent(server, "GET", "/projects/party/global/images");
+   }
+
+   public void listInProject() throws InterruptedException {
+      server.enqueue(jsonResponse("/image_list.json"));
+
+      assertEquals(imageApi().listInProject("centos-cloud").next(), new ParseImageListTest().expected(url("/projects")));
+      assertSent(server, "GET", "/projects/centos-cloud/global/images");
+   }
+
+   public void listInProject_empty() throws InterruptedException {
+      server.enqueue(jsonResponse("/list_empty.json"));
+
+      assertFalse(imageApi().listInProject("centos-cloud").hasNext());
+      assertSent(server, "GET", "/projects/centos-cloud/global/images");
+   }
+
+   public void createImageFromPd_2xx() throws InterruptedException{
+      server.enqueue(jsonResponse("/operation.json"));
+
+      assertEquals(imageApi().createFromDisk("my-image", url("/projects/party/zones/us-central1-a/disks/mydisk")),
+            new ParseOperationTest().expected(url("/projects")));
+      assertSent(server, "POST", "/projects/party/global/images", stringFromResource("/image_insert_from_pd.json"));
+   }
+
+   public void deprecateImage_2xx() throws InterruptedException{
+      String imageName = "test-image";
+      server.enqueue(jsonResponse("/operation.json"));
+
+      DeprecateOptions options = new DeprecateOptions().state(State.DEPRECATED)
+            .replacement(URI.create(url("/projects/centos-cloud/global/images/centos-6-2-v20120326test")))
+            .deprecated(new SimpleDateFormatDateService().iso8601DateParse("2014-07-16T22:16:13.468Z"))
+            .obsolete(new SimpleDateFormatDateService().iso8601DateParse("2014-10-16T22:16:13.468Z"))
+            .deleted(new SimpleDateFormatDateService().iso8601DateParse("2015-01-16T22:16:13.468Z"));
+
+      assertEquals(imageApi().deprecate(imageName, options),
+            new ParseOperationTest().expected(url("/projects")));
+      assertSent(server, "POST", "/projects/party/global/images/" + imageName + "/deprecate", stringFromResource("/image_deprecate.json"));
+   }
+
+   ImageApi imageApi(){
+      return api().images();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiMockTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiMockTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiMockTest.java
index d0c8dee..1b06ad2 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiMockTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiMockTest.java
@@ -104,6 +104,10 @@ public class BaseGoogleComputeEngineApiMockTest {
       return new MockResponse().addHeader("Content-Type", "application/json").setBody(stringFromResource(resource));
    }
 
+   protected MockResponse response404(){
+      return new MockResponse().setStatus("HTTP/1.1 404 Not Found");
+   }
+
    protected String stringFromResource(String resourceName) {
       try {
          return toStringAndClose(getClass().getResourceAsStream(resourceName))

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageListTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageListTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageListTest.java
index c128875..16c66e5 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageListTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageListTest.java
@@ -37,8 +37,13 @@ public class ParseImageListTest extends BaseGoogleComputeEngineParseTest<ListPag
 
    @Override @Consumes(MediaType.APPLICATION_JSON)
    public ListPage<Image> expected() {
-      return ForwardingListPage.create( //
-            ImmutableList.of(new ParseImageTest().expected()), // items
+      return expected(BASE_URL);
+      }
+
+   @Consumes(MediaType.APPLICATION_JSON)
+   public ListPage<Image> expected(String baseUrl) {
+       return ForwardingListPage.create( //
+            ImmutableList.of(new ParseImageTest().expected(baseUrl)), // items
             null // nextPageToken
       );
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageTest.java
index 27bb940..7a14a37 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseImageTest.java
@@ -24,6 +24,7 @@ import java.net.URI;
 import javax.ws.rs.Consumes;
 
 import org.jclouds.googlecomputeengine.domain.Deprecated;
+import org.jclouds.googlecomputeengine.domain.Deprecated.State;
 import org.jclouds.googlecomputeengine.domain.Image;
 import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
 import org.testng.annotations.Test;
@@ -38,16 +39,21 @@ public class ParseImageTest extends BaseGoogleComputeEngineParseTest<Image> {
 
    @Override @Consumes(APPLICATION_JSON)
    public Image expected() {
+      return expected(BASE_URL);
+   }
+
+   @Consumes(APPLICATION_JSON)
+   public Image expected(String baseUrl) {
       return Image.create( //
             "12941197498378735318", // id
-            URI.create(BASE_URL + "/centos-cloud/global/images/centos-6-2-v20120326"), // selfLink
+            URI.create(baseUrl + "/centos-cloud/global/images/centos-6-2-v20120326"), // selfLink
             "centos-6-2-v20120326", // name
             "DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000", // description
             "RAW", // sourceType
             RawDisk.create(URI.create(""), "TAR", null), // rawDisk
             Deprecated.create( // deprecated
-                  "DEPRECATED", // state
-                  URI.create(BASE_URL + "/centos-cloud/global/images/centos-6-v20130104"), // replacement
+                  State.DEPRECATED, // state
+                  URI.create(baseUrl + "/centos-cloud/global/images/centos-6-v20130104"), // replacement
                   null, // deprecated
                   null, // obsolete
                   null // deleted

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseOperationTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseOperationTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseOperationTest.java
index 9023dd9..a4e9055 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseOperationTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseOperationTest.java
@@ -36,12 +36,17 @@ public class ParseOperationTest extends BaseGoogleComputeEngineParseTest<Operati
 
    @Override @Consumes(APPLICATION_JSON)
    public Operation expected() {
+      return expected(BASE_URL);
+   }
+
+   @Consumes(APPLICATION_JSON)
+   public Operation expected(String baseUrl) {
       return Operation.create( //
             "13053095055850848306", // id
-            URI.create(BASE_URL + "/party/zones/us-central1-a/operations/operation-1354084865060"),
+            URI.create(baseUrl + "/party/zones/us-central1-a/operations/operation-1354084865060"),
             "operation-1354084865060", // name
             null, // description
-            URI.create(BASE_URL + "/party/zones/us-central1-a/instances/test-1"), // targetLink
+            URI.create(baseUrl + "/party/zones/us-central1-a/instances/test-1"), // targetLink
             "13053094017547040099", // targetId
             null, // clientOperationId
             Operation.Status.DONE, // status
@@ -55,8 +60,8 @@ public class ParseOperationTest extends BaseGoogleComputeEngineParseTest<Operati
             null, // httpErrorMessage
             "insert", // operationType
             null, // errors
-            URI.create(BASE_URL + "/party/regions/us-central1"), // region
-            URI.create(BASE_URL + "/party/zones/us-central1-a") // zone
+            URI.create(baseUrl + "/party/regions/us-central1"), // region
+            URI.create(baseUrl + "/party/zones/us-central1-a") // zone
       );
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/0260afd4/google-compute-engine/src/test/resources/image_deprecate.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/image_deprecate.json b/google-compute-engine/src/test/resources/image_deprecate.json
new file mode 100644
index 0000000..c40cc03
--- /dev/null
+++ b/google-compute-engine/src/test/resources/image_deprecate.json
@@ -0,0 +1,7 @@
+{
+  "state": "DEPRECATED",
+  "replacement": "https://www.googleapis.com/compute/v1/projects/centos-cloud/global/images/centos-6-2-v20120326test",
+  "deprecated": "2014-07-16T22:16:13.468Z",
+  "obsolete": "2014-10-16T22:16:13.468Z",
+  "deleted": "2015-01-16T22:16:13.468Z"
+}
\ No newline at end of file