You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ni...@apache.org on 2014/03/18 03:59:58 UTC

[06/21] fixing https://issues.apache.org/jira/browse/STRATOS-520 - adding Openstack-nova module to dependencies

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApiLiveTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApiLiveTest.java
new file mode 100644
index 0000000..a7f14ad
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApiLiveTest.java
@@ -0,0 +1,274 @@
+/*
+ * 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.openstack.nova.v2_0.extensions;
+
+import static org.jclouds.util.Predicates2.retry;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.openstack.nova.v2_0.domain.Volume;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeSnapshot;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeSnapshotOptions;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+/**
+ * Tests behavior of VolumeApi
+ * 
+ * @author Adam Lowe
+ */
+@Test(groups = "live", testName = "VolumeApiLiveTest", singleThreaded = true)
+public class VolumeApiLiveTest extends BaseNovaApiLiveTest {
+
+   private Optional<? extends VolumeApi> volumeOption;
+   private String zone;
+
+   private Volume testVolume;
+   private VolumeSnapshot testSnapshot;
+
+   @BeforeClass(groups = {"integration", "live"})
+   @Override
+   public void setup() {
+      super.setup();
+      zone = Iterables.getLast(api.getConfiguredZones(), "nova");
+      volumeOption = api.getVolumeExtensionForZone(zone);
+   }
+
+   @AfterClass(groups = { "integration", "live" })
+   @Override
+   protected void tearDown() {
+      if (volumeOption.isPresent()) {
+         if (testSnapshot != null) {
+            final String snapshotId = testSnapshot.getId();
+            assertTrue(volumeOption.get().deleteSnapshot(snapshotId));
+            assertTrue(retry(new Predicate<VolumeApi>() {
+               public boolean apply(VolumeApi volumeApi) {
+                  return volumeOption.get().getSnapshot(snapshotId) == null;
+               }
+            }, 30 * 1000L).apply(volumeOption.get()));
+         }
+         if (testVolume != null) {
+            final String volumeId = testVolume.getId();
+            assertTrue(volumeOption.get().delete(volumeId));
+            assertTrue(retry(new Predicate<VolumeApi>() {
+               public boolean apply(VolumeApi volumeApi) {
+                  return volumeOption.get().get(volumeId) == null;
+               }
+            }, 180 * 1000L).apply(volumeOption.get()));
+         }
+      }
+      super.tearDown();
+   }
+
+   public void testCreateVolume() {
+      if (volumeOption.isPresent()) {
+         testVolume = volumeOption.get().create(
+               1,
+               CreateVolumeOptions.Builder.name("jclouds-test-volume").description("description of test volume")
+                     .availabilityZone(zone));
+         assertTrue(retry(new Predicate<VolumeApi>() {
+            public boolean apply(VolumeApi volumeApi) {
+               return volumeOption.get().get(testVolume.getId()).getStatus() == Volume.Status.AVAILABLE;
+            }
+         }, 180 * 1000L).apply(volumeOption.get()));
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolume")
+   public void testListVolumes() {
+      if (volumeOption.isPresent()) {
+         Set<? extends Volume> volumes = volumeOption.get().list().toSet();
+         assertNotNull(volumes);
+         boolean foundIt = false;
+         for (Volume vol : volumes) {
+            Volume details = volumeOption.get().get(vol.getId());
+            assertNotNull(details);
+            if (Objects.equal(details.getId(), testVolume.getId())) {
+               foundIt = true;
+            }
+         }
+         assertTrue(foundIt, "Failed to find the volume we created in list() response");
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolume")
+   public void testListVolumesInDetail() {
+      if (volumeOption.isPresent()) {
+         Set<? extends Volume> volumes = volumeOption.get().listInDetail().toSet();
+         assertNotNull(volumes);
+         boolean foundIt = false;
+         for (Volume vol : volumes) {
+            Volume details = volumeOption.get().get(vol.getId());
+            assertNotNull(details);
+            assertNotNull(details.getId());
+            assertNotNull(details.getCreated());
+            assertTrue(details.getSize() > -1);
+
+            assertEquals(details.getId(), vol.getId());
+            assertEquals(details.getSize(), vol.getSize());
+            assertEquals(details.getName(), vol.getName());
+            assertEquals(details.getDescription(), vol.getDescription());
+            assertEquals(details.getCreated(), vol.getCreated());
+            if (Objects.equal(details.getId(), testVolume.getId())) {
+               foundIt = true;
+            }
+         }
+         assertTrue(foundIt, "Failed to find the volume we previously created in listInDetail() response");
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolume")
+   public void testCreateSnapshot() {
+      if (volumeOption.isPresent()) {
+         testSnapshot = volumeOption.get().createSnapshot(
+                  testVolume.getId(),
+                  CreateVolumeSnapshotOptions.Builder.name("jclouds-live-test").description(
+                           "jclouds live test snapshot").force());
+         assertNotNull(testSnapshot);
+         assertNotNull(testSnapshot.getId());
+         final String snapshotId = testSnapshot.getId();
+         assertNotNull(testSnapshot.getStatus());
+         assertTrue(testSnapshot.getSize() > -1);
+         assertNotNull(testSnapshot.getCreated());
+
+         assertTrue(retry(new Predicate<VolumeApi>() {
+            public boolean apply(VolumeApi volumeApi) {
+               return volumeOption.get().getSnapshot(snapshotId).getStatus() == Volume.Status.AVAILABLE;
+            }
+         }, 30 * 1000L).apply(volumeOption.get()));
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testListSnapshots() {
+      if (volumeOption.isPresent()) {
+         Set<? extends VolumeSnapshot> snapshots = volumeOption.get().listSnapshots().toSet();
+         assertNotNull(snapshots);
+         boolean foundIt = false;
+         for (VolumeSnapshot snap : snapshots) {
+            VolumeSnapshot details = volumeOption.get().getSnapshot(snap.getId());
+            if (Objects.equal(snap.getVolumeId(), testVolume.getId())) {
+               foundIt = true;
+            }
+            assertNotNull(details);
+            assertEquals(details.getId(), snap.getId());
+            assertEquals(details.getVolumeId(), snap.getVolumeId());
+         }
+         assertTrue(foundIt, "Failed to find the snapshot we previously created in listSnapshots() response");
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testListSnapshotsInDetail() {
+      if (volumeOption.isPresent()) {
+         Set<? extends VolumeSnapshot> snapshots = volumeOption.get().listSnapshotsInDetail().toSet();
+         assertNotNull(snapshots);
+         boolean foundIt = false;
+         for (VolumeSnapshot snap : snapshots) {
+            VolumeSnapshot details = volumeOption.get().getSnapshot(snap.getId());
+            if (Objects.equal(snap.getVolumeId(), testVolume.getId())) {
+               foundIt = true;
+               assertSame(details, testSnapshot);
+            }
+            assertSame(details, snap);
+         }
+
+         assertTrue(foundIt, "Failed to find the snapshot we created in listSnapshotsInDetail() response");
+      }
+   }
+
+   private void assertSame(VolumeSnapshot a, VolumeSnapshot b) {
+      assertNotNull(a);
+      assertNotNull(b);
+      assertEquals(a.getId(), b.getId());
+      assertEquals(a.getDescription(), b.getDescription());
+      assertEquals(a.getName(), b.getName());
+      assertEquals(a.getVolumeId(), b.getVolumeId());
+   }
+
+   @Test(dependsOnMethods = "testCreateVolume")
+   public void testAttachments() {
+      if (volumeOption.isPresent()) {
+         String server_id = null;
+         try {
+            final String serverId = server_id = createServerInZone(zone).getId();
+
+            Set<? extends VolumeAttachment> attachments = volumeOption.get().listAttachmentsOnServer(serverId).toSet();
+            assertNotNull(attachments);
+            final int before = attachments.size();
+
+            VolumeAttachment testAttachment = volumeOption.get().attachVolumeToServerAsDevice(testVolume.getId(),
+                     serverId, "/dev/vdf");
+            assertNotNull(testAttachment.getId());
+            assertEquals(testAttachment.getVolumeId(), testVolume.getId());
+
+            assertTrue(retry(new Predicate<VolumeApi>() {
+               public boolean apply(VolumeApi volumeApi) {
+                  return volumeOption.get().listAttachmentsOnServer(serverId).size() > before;
+               }
+            }, 60 * 1000L).apply(volumeOption.get()));
+
+            attachments = volumeOption.get().listAttachmentsOnServer(serverId).toSet();
+            assertNotNull(attachments);
+            assertEquals(attachments.size(), before + 1);
+
+            assertEquals(volumeOption.get().get(testVolume.getId()).getStatus(), Volume.Status.IN_USE);
+
+            boolean foundIt = false;
+            for (VolumeAttachment att : attachments) {
+               VolumeAttachment details = volumeOption.get()
+                        .getAttachmentForVolumeOnServer(att.getVolumeId(), serverId);
+               assertNotNull(details);
+               assertNotNull(details.getId());
+               assertNotNull(details.getServerId());
+               assertNotNull(details.getVolumeId());
+               if (Objects.equal(details.getVolumeId(), testVolume.getId())) {
+                  foundIt = true;
+                  assertEquals(details.getDevice(), "/dev/vdf");
+                  assertEquals(details.getServerId(), serverId);
+               }
+            }
+
+            assertTrue(foundIt, "Failed to find the attachment we created in listAttachments() response");
+
+            volumeOption.get().detachVolumeFromServer(testVolume.getId(), serverId);
+            assertTrue(retry(new Predicate<VolumeApi>() {
+               public boolean apply(VolumeApi volumeApi) {
+                  return volumeOption.get().listAttachmentsOnServer(serverId).size() == before;
+               }
+            }, 60 * 1000L).apply(volumeOption.get()));
+
+         } finally {
+            if (server_id != null)
+               api.getServerApiForZone(zone).delete(server_id);
+         }
+
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiExpectTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiExpectTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiExpectTest.java
new file mode 100644
index 0000000..1b4857d
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiExpectTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.openstack.nova.v2_0.extensions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.date.DateService;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.nova.v2_0.domain.Volume;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
+import org.jclouds.rest.AuthorizationException;
+import org.jclouds.rest.ResourceNotFoundException;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+/**
+ * Tests VolumeAttachmentApi Guice wiring and parsing
+ *
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "VolumeAttachmentApiExpectTest")
+public class VolumeAttachmentApiExpectTest extends BaseNovaApiExpectTest {
+   private DateService dateService = new SimpleDateFormatDateService();
+
+   public void testListAttachments() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_list.json")).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      Set<? extends VolumeAttachment> attachments = api.listAttachmentsOnServer("instance-1").toSet();
+      assertEquals(attachments, ImmutableSet.of(testAttachment()));
+      // double-check individual fields
+      VolumeAttachment attachment = Iterables.getOnlyElement(attachments);
+      assertEquals(attachment.getDevice(), "/dev/vdc");
+      assertEquals(attachment.getServerId(), "b4785058-cb80-491b-baa3-e4ee6546450e");
+      assertEquals(attachment.getId(), "1");
+      assertEquals(attachment.getVolumeId(), "1");
+   }
+
+   @Test(expectedExceptions = AuthorizationException.class)
+   public void testListAttachmentsFail() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-2/os-volume_attachments");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(401).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      api.listAttachmentsOnServer("instance-2");
+   }
+   
+   public void testGetAttachment() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments/1");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeAttachment attachment = api.getAttachmentForVolumeOnServer("1", "instance-1");
+      assertEquals(attachment, testAttachment());
+   }
+
+   public void testGetAttachmentFail() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments/1");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+     assertNull(api.getAttachmentForVolumeOnServer("1", "instance-1"));
+   }
+
+   public void testAttachVolume() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("POST")
+                  .payload(payloadFromStringWithContentType("{\"volumeAttachment\":{\"volumeId\":\"1\",\"device\":\"/dev/vdc\"}}", MediaType.APPLICATION_JSON)).endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeAttachment result = api.attachVolumeToServerAsDevice("1", "instance-1", "/dev/vdc");
+      assertEquals(result, testAttachment());
+   }
+
+   @Test(expectedExceptions = ResourceNotFoundException.class)
+   public void testAttachVolumeFail() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("POST")
+                  .payload(payloadFromStringWithContentType("{\"volumeAttachment\":{\"volumeId\":\"1\",\"device\":\"/dev/vdc\"}}", MediaType.APPLICATION_JSON)).endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      api.attachVolumeToServerAsDevice("1", "instance-1","/dev/vdc");
+   }
+
+   public void testDetachVolume() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments/1");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.detachVolumeFromServer("1", "instance-1"));
+   }
+
+   public void testDetachVolumeFail() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/instance-1/os-volume_attachments/1");
+      VolumeAttachmentApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeAttachmentExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertFalse(api.detachVolumeFromServer("1", "instance-1"));
+   }
+   
+   protected Volume testVolume() {
+      return Volume.builder().status(Volume.Status.IN_USE).description("This is a test volume").zone("nova").name("test")
+            .attachments(ImmutableSet.of(testAttachment())).size(1).id("1").created(dateService.iso8601SecondsDateParse("2012-04-23 12:16:45")).build();
+   }
+
+   protected VolumeAttachment testAttachment() {
+      return VolumeAttachment.builder().device("/dev/vdc").serverId("b4785058-cb80-491b-baa3-e4ee6546450e").id("1").volumeId("1").build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiLiveTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiLiveTest.java
new file mode 100644
index 0000000..cc853d8
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApiLiveTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.openstack.nova.v2_0.extensions;
+
+import static org.jclouds.util.Predicates2.retry;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.openstack.nova.v2_0.domain.Volume;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+/**
+ * Tests behavior of Volume Attachment API
+ * 
+ * @author Everett Toews
+ */
+@Test(groups = "live", testName = "VolumeAttachmentApiLiveTest", singleThreaded = true)
+public class VolumeAttachmentApiLiveTest extends BaseNovaApiLiveTest {
+
+   private Optional<? extends VolumeApi> volumeApi;
+   private Optional<? extends VolumeAttachmentApi> volumeAttachmentApi;
+   
+   private String zone;
+   private Volume testVolume;
+
+   @BeforeClass(groups = {"integration", "live"})
+   @Override
+   public void setup() {
+      super.setup();
+      zone = Iterables.getLast(api.getConfiguredZones(), "nova");
+      volumeApi = api.getVolumeExtensionForZone(zone);
+      volumeAttachmentApi = api.getVolumeAttachmentExtensionForZone(zone);
+   }
+
+   @AfterClass(groups = { "integration", "live" })
+   @Override
+   protected void tearDown() {
+      if (volumeApi.isPresent()) {
+         if (testVolume != null) {
+            final String volumeId = testVolume.getId();
+            assertTrue(volumeApi.get().delete(volumeId));
+            assertTrue(retry(new Predicate<VolumeApi>() {
+               public boolean apply(VolumeApi volumeApi) {
+                  return volumeApi.get(volumeId) == null;
+               }
+            }, 180 * 1000L).apply(volumeApi.get()));
+         }
+      }
+
+      super.tearDown();
+   }
+
+   public void testCreateVolume() {
+      if (volumeApi.isPresent()) {
+         CreateVolumeOptions options = CreateVolumeOptions.Builder
+               .name("jclouds-test-volume")
+               .description("description of test volume")
+               .availabilityZone(zone);
+
+         testVolume = volumeApi.get().create(1, options);
+         assertTrue(retry(new Predicate<VolumeApi>() {
+            public boolean apply(VolumeApi volumeApi) {
+               return volumeApi.get(testVolume.getId()).getStatus() == Volume.Status.AVAILABLE;
+            }
+         }, 180 * 1000L).apply(volumeApi.get()));
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolume")
+   public void testAttachments() {
+      if (volumeApi.isPresent()) {
+         String server_id = null;
+         try {
+            final String serverId = server_id = createServerInZone(zone).getId();
+
+            Set<? extends VolumeAttachment> attachments = 
+                  volumeAttachmentApi.get().listAttachmentsOnServer(serverId).toSet();
+            assertNotNull(attachments);
+            final int before = attachments.size();
+
+            VolumeAttachment testAttachment = volumeAttachmentApi.get().attachVolumeToServerAsDevice(
+                  testVolume.getId(), serverId, "/dev/vdf");
+            assertNotNull(testAttachment.getId());
+            assertEquals(testAttachment.getVolumeId(), testVolume.getId());
+
+            assertTrue(retry(new Predicate<VolumeAttachmentApi>() {
+               public boolean apply(VolumeAttachmentApi volumeAttachmentApi) {
+                  return volumeAttachmentApi.listAttachmentsOnServer(serverId).size() > before;
+               }
+            }, 60 * 1000L).apply(volumeAttachmentApi.get()));
+
+            attachments = volumeAttachmentApi.get().listAttachmentsOnServer(serverId).toSet();
+            assertNotNull(attachments);
+            assertEquals(attachments.size(), before + 1);
+
+            assertEquals(volumeApi.get().get(testVolume.getId()).getStatus(), Volume.Status.IN_USE);
+
+            boolean foundIt = false;
+            for (VolumeAttachment att : attachments) {
+               VolumeAttachment details = volumeAttachmentApi.get()
+                        .getAttachmentForVolumeOnServer(att.getVolumeId(), serverId);
+               assertNotNull(details);
+               assertNotNull(details.getId());
+               assertNotNull(details.getServerId());
+               assertNotNull(details.getVolumeId());
+               if (Objects.equal(details.getVolumeId(), testVolume.getId())) {
+                  foundIt = true;
+                  assertEquals(details.getDevice(), "/dev/vdf");
+                  assertEquals(details.getServerId(), serverId);
+               }
+            }
+
+            assertTrue(foundIt, "Failed to find the attachment we created in listAttachments() response");
+
+            volumeAttachmentApi.get().detachVolumeFromServer(testVolume.getId(), serverId);
+            assertTrue(retry(new Predicate<VolumeAttachmentApi>() {
+               public boolean apply(VolumeAttachmentApi volumeAttachmentApi) {
+                  return volumeAttachmentApi.listAttachmentsOnServer(serverId).size() == before;
+               }
+            }, 60 * 1000L).apply(volumeAttachmentApi.get()));
+
+         } finally {
+            if (server_id != null)
+               api.getServerApiForZone(zone).delete(server_id);
+         }
+
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiExpectTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiExpectTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiExpectTest.java
new file mode 100644
index 0000000..36d8d0f
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiExpectTest.java
@@ -0,0 +1,259 @@
+/*
+ * 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.openstack.nova.v2_0.extensions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.date.DateService;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeType;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeTypeOptions;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests guice wiring and parsing of VolumeTypeApi
+ *
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "VolumeTypeApiExpectTest")
+public class VolumeTypeApiExpectTest extends BaseNovaApiExpectTest {
+   private DateService dateService = new SimpleDateFormatDateService();
+
+   public void testListVolumeTypes() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type_list.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      Set<? extends VolumeType> types = api.list().toSet();
+      assertEquals(types, ImmutableSet.of(testVolumeType()));
+   }
+
+   public void testGetVolumeType() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeType type = api.get("8");
+      assertEquals(type, testVolumeType());
+   }
+
+   public void testGetVolumeTypeFailNotFound() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertNull(api.get("8"));
+   }
+
+   public void testCreateVolumeType() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("POST")
+                  .payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\"}}", MediaType.APPLICATION_JSON))
+                  .build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeType type = api.create("jclouds-test-1");
+      assertEquals(type, testVolumeType());
+   }
+
+   public void testCreateVolumeTypeWithOptsNONE() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("POST")
+                  .payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\",\"extra_specs\":{}}}", MediaType.APPLICATION_JSON))
+                  .build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeType type = api.create("jclouds-test-1", CreateVolumeTypeOptions.NONE);
+      assertEquals(type, testVolumeType());
+   }
+
+   public void testCreateVolumeTypeWithOptsSet() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("POST")
+                  .payload(payloadFromStringWithContentType("{\"volume_type\":{\"name\":\"jclouds-test-1\",\"extra_specs\":{\"x\": \"y\"}}}", MediaType.APPLICATION_JSON))
+                  .build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      VolumeType type = api.create("jclouds-test-1", CreateVolumeTypeOptions.Builder.specs(ImmutableMap.of("x", "y")));
+      assertEquals(type, testVolumeType());
+   }
+
+   public void testDeleteVolumeType() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(200).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.delete("8"));
+   }
+
+   public void testDeleteVolumeTypeFailNotFound() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/8");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertFalse(api.delete("8"));
+   }
+
+   public void testGetAllExtraSpecs() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromResource("/volume_type_extra_specs.json")).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertEquals(api.getExtraSpecs("9"), ImmutableMap.of("test", "value1"));
+   }
+
+   public void testGetAllExtraSpecsFailNotFound() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.getExtraSpecs("9").isEmpty());
+   }
+
+   public void testSetAllExtraSpecs() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/9/extra_specs");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint)
+                  .method("POST")
+                  .payload(payloadFromStringWithContentType("{\"extra_specs\":{\"test1\":\"somevalue\"}}", MediaType.APPLICATION_JSON)).build(),
+            HttpResponse.builder().statusCode(200).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.updateExtraSpecs("9", ImmutableMap.of("test1", "somevalue")));
+   }
+
+   public void testSetExtraSpec() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint)
+                  .method("PUT")
+                  .payload(payloadFromStringWithContentType("{\"test1\":\"somevalue\"}", MediaType.APPLICATION_JSON)).build(),
+            HttpResponse.builder().statusCode(200).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.updateExtraSpec("5", "test1", "somevalue"));
+   }
+
+   public void testGetExtraSpec() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(200).payload(payloadFromStringWithContentType("{\"test1\":\"another value\"}", MediaType.APPLICATION_JSON)).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertEquals(api.getExtraSpec("5", "test1"), "another value");
+   }
+
+   public void testGetExtraSpecFailNotFound() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertNull(api.getExtraSpec("5", "test1"));
+   }
+
+   public void testDeleteExtraSpec() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(200).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertTrue(api.deleteExtraSpec("5", "test1"));
+   }
+
+   public void testDeleteExtraSpecFailNotFound() {
+      URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/os-volume-types/5/extra_specs/test1");
+      VolumeTypeApi api = requestsSendResponses(
+            keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
+            authenticatedGET().endpoint(endpoint).method("DELETE").build(),
+            HttpResponse.builder().statusCode(404).build()
+      ).getVolumeTypeExtensionForZone("az-1.region-a.geo-1").get();
+
+      assertFalse(api.deleteExtraSpec("5", "test1"));
+   }
+
+   public VolumeType testVolumeType() {
+      return VolumeType.builder().id("8").name("jclouds-test-1").created(dateService.iso8601SecondsDateParse("2012-05-10 12:33:06")).extraSpecs(ImmutableMap.of("test", "value1", "test1", "wibble")).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiLiveTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiLiveTest.java
new file mode 100644
index 0000000..02b0f50
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApiLiveTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.openstack.nova.v2_0.extensions;
+
+import static org.jclouds.util.Predicates2.retry;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.openstack.nova.v2_0.domain.VolumeType;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeTypeOptions;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+/**
+ * Tests behavior of VolumeTypeApi
+ *
+ * @author Adam Lowe
+ */
+@Test(groups = "live", testName = "VolumeTypeApiLiveTest", singleThreaded = true)
+public class VolumeTypeApiLiveTest extends BaseNovaApiLiveTest {
+
+   private Optional<? extends VolumeTypeApi> volumeTypeOption;
+   private String zone;
+
+   private VolumeType testVolumeType;
+
+   @BeforeGroups(groups = {"integration", "live"})
+   @Override
+   public void setup() {
+      super.setup();
+      zone = Iterables.getLast(api.getConfiguredZones(), "nova");
+      volumeTypeOption = api.getVolumeTypeExtensionForZone(zone);
+   }
+
+
+   @AfterClass(groups = { "integration", "live" })
+   @Override
+   protected void tearDown() {
+      if (volumeTypeOption.isPresent()) {
+         if (testVolumeType != null) {
+            final String id = testVolumeType.getId();
+            assertTrue(volumeTypeOption.get().delete(id));
+            assertTrue(retry(new Predicate<VolumeTypeApi>() {
+               public boolean apply(VolumeTypeApi volumeApi) {
+                  return volumeApi.get(id) == null;
+               }
+            }, 5 * 1000L).apply(volumeTypeOption.get()));
+         }
+      }
+      super.tearDown();
+   }
+
+   public void testCreateVolumeType() {
+      if (volumeTypeOption.isPresent()) {
+         testVolumeType = volumeTypeOption.get().create(
+               "jclouds-test-1", CreateVolumeTypeOptions.Builder.specs(ImmutableMap.of("test", "value1")));
+         assertTrue(retry(new Predicate<VolumeTypeApi>() {
+            public boolean apply(VolumeTypeApi volumeTypeApi) {
+               return volumeTypeApi.get(testVolumeType.getId()) != null;
+            }
+         }, 180 * 1000L).apply(volumeTypeOption.get()));
+
+         assertEquals(volumeTypeOption.get().get(testVolumeType.getId()).getName(), "jclouds-test-1");
+         assertEquals(volumeTypeOption.get().get(testVolumeType.getId()).getExtraSpecs(), ImmutableMap.of("test", "value1"));
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolumeType")
+   public void testListVolumeTypes() {
+      if (volumeTypeOption.isPresent()) {
+         Set<? extends VolumeType> volumeTypes = volumeTypeOption.get().list().toSet();
+         assertNotNull(volumeTypes);
+         boolean foundIt = false;
+         for (VolumeType vt : volumeTypes) {
+            VolumeType details = volumeTypeOption.get().get(vt.getId());
+            assertNotNull(details);
+            if (Objects.equal(details.getId(), testVolumeType.getId())) {
+               foundIt = true;
+            }
+         }
+         assertTrue(foundIt, "Failed to find the volume type we created in list() response");
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolumeType")
+   public void testExtraSpecs() {
+      if (volumeTypeOption.isPresent()) {
+         assertEquals(volumeTypeOption.get().getExtraSpecs(testVolumeType.getId()), ImmutableMap.of("test", "value1"));
+         assertEquals(volumeTypeOption.get().getExtraSpec(testVolumeType.getId(), "test"),  "value1");
+         assertTrue(volumeTypeOption.get().updateExtraSpecs(testVolumeType.getId(), ImmutableMap.of("test1", "wibble")));
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateVolumeType")
+   public void testUpdateIndividualSpec() {
+      if (volumeTypeOption.isPresent()) {
+         assertTrue(volumeTypeOption.get().updateExtraSpec(testVolumeType.getId(), "test1", "freddy"));
+         assertEquals(volumeTypeOption.get().getExtraSpec(testVolumeType.getId(), "test1"), "freddy");
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiExpectTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiExpectTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiExpectTest.java
new file mode 100644
index 0000000..4c91ec2
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiExpectTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.openstack.nova.v2_0.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
+import org.jclouds.openstack.nova.v2_0.parse.ParseExtensionListTest;
+import org.jclouds.openstack.nova.v2_0.parse.ParseExtensionTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests annotation parsing of {@code ExtensionAsyncApi}
+ * 
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "ExtensionApiExpectTest")
+public class ExtensionApiExpectTest extends BaseNovaApiExpectTest {
+
+   public void testListExtensionsWhenResponseIs2xx() throws Exception {
+      HttpRequest listExtensions = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/extensions")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(200)
+            .payload(payloadFromResource("/extension_list.json")).build();
+
+      NovaApi apiWhenExtensionsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, listExtensions, listExtensionsResponse);
+
+      assertEquals(apiWhenExtensionsExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1", "az-2.region-a.geo-1", "az-3.region-a.geo-1"));
+
+      assertEquals(apiWhenExtensionsExist.getExtensionApiForZone("az-1.region-a.geo-1").list().toString(),
+            new ParseExtensionListTest().expected().toString());
+   }
+
+   public void testListExtensionsWhenReponseIs404IsEmpty() throws Exception {
+      HttpRequest listExtensions = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/extensions")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse listExtensionsResponse = HttpResponse.builder().statusCode(404).build();
+
+      NovaApi apiWhenNoServersExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, listExtensions, listExtensionsResponse);
+
+      assertTrue(apiWhenNoServersExist.getExtensionApiForZone("az-1.region-a.geo-1").list().isEmpty());
+   }
+
+   // TODO: gson deserializer for Multimap
+   public void testGetExtensionByAliasWhenResponseIs2xx() throws Exception {
+
+      HttpRequest getExtension = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/extensions/RS-PIE")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(200)
+            .payload(payloadFromResource("/extension_details.json")).build();
+
+      NovaApi apiWhenExtensionsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, getExtension, getExtensionResponse);
+
+      assertEquals(apiWhenExtensionsExist.getExtensionApiForZone("az-1.region-a.geo-1").get("RS-PIE")
+            .toString(), new ParseExtensionTest().expected().toString());
+   }
+
+   public void testGetExtensionByAliasWhenResponseIs404() throws Exception {
+      HttpRequest getExtension = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/extensions/RS-PIE")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse getExtensionResponse = HttpResponse.builder().statusCode(404)
+            .payload(payloadFromResource("/extension_details.json")).build();
+
+      NovaApi apiWhenNoExtensionsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, getExtension, getExtensionResponse);
+
+      assertNull(apiWhenNoExtensionsExist.getExtensionApiForZone("az-1.region-a.geo-1").get("RS-PIE"));
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiLiveTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiLiveTest.java
new file mode 100644
index 0000000..b81a761
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/ExtensionApiLiveTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.openstack.nova.v2_0.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Set;
+
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
+import org.jclouds.openstack.v2_0.domain.Extension;
+import org.jclouds.openstack.v2_0.features.ExtensionApi;
+import org.testng.annotations.Test;
+
+/**
+ * Tests behavior of {@link ExtensionApi}
+ * 
+ * @author Adrian Cole
+ */
+@Test(groups = "live", testName = "ExtensionApiLiveTest")
+public class ExtensionApiLiveTest extends BaseNovaApiLiveTest {
+
+    /**
+     * Tests the listing of Extensions.
+     * 
+     * @throws Exception
+     */
+    @Test(description = "GET /v${apiVersion}/{tenantId}/extensions")
+    public void testListExtensions() throws Exception {
+       for (String zoneId : zones) {
+          ExtensionApi extensionApi = api.getExtensionApiForZone(zoneId);
+          Set<? extends Extension> response = extensionApi.list();
+          assertNotNull(response);
+          assertFalse(response.isEmpty());
+           for (Extension extension : response) {
+              assertNotNull(extension.getId());
+              assertNotNull(extension.getName());
+              assertNotNull(extension.getDescription());
+              assertNotNull(extension.getNamespace());
+              assertNotNull(extension.getUpdated());
+              assertNotNull(extension.getLinks());
+           }
+       }
+    }
+
+    /**
+     * Tests retrieval of Extensions using their alias.
+     * 
+     * @throws Exception
+     */
+    @Test(description = "GET /v${apiVersion}/{tenantId}/extensions/{alias}", dependsOnMethods = { "testListExtensions" })
+    public void testGetExtensionByAlias() throws Exception {
+       for (String zoneId : zones) {
+           ExtensionApi extensionApi = api.getExtensionApiForZone(zoneId);
+           Set<? extends Extension> response = extensionApi.list();
+           for (Extension extension : response) {
+              Extension details = extensionApi.get(extension.getId());
+              assertNotNull(details);
+              assertEquals(details.getId(), extension.getId());
+              assertEquals(details.getName(), extension.getName());
+              assertEquals(details.getDescription(), extension.getDescription());
+              assertEquals(details.getNamespace(), extension.getNamespace());
+              assertEquals(details.getUpdated(), extension.getUpdated());
+              assertEquals(details.getLinks(), extension.getLinks());
+           }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiExpectTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiExpectTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiExpectTest.java
new file mode 100644
index 0000000..22af220
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiExpectTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.openstack.nova.v2_0.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.Flavor;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest;
+import org.jclouds.openstack.nova.v2_0.parse.ParseCreateFlavorTest;
+import org.jclouds.openstack.nova.v2_0.parse.ParseFlavorListTest;
+import org.jclouds.openstack.nova.v2_0.parse.ParseFlavorTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests annotation parsing of {@code FlavorAsyncApi}
+ * 
+ * @author Jeremy Daggett, Ilja Bobkevic
+ */
+@Test(groups = "unit", testName = "FlavorApiExpectTest")
+public class FlavorApiExpectTest extends BaseNovaApiExpectTest {
+
+   public void testListFlavorsWhenResponseIs2xx() throws Exception {
+      HttpRequest listFlavors = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse listFlavorsResponse = HttpResponse.builder().statusCode(200)
+            .payload(payloadFromResource("/flavor_list.json")).build();
+
+      NovaApi apiWhenFlavorsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, listFlavors, listFlavorsResponse);
+
+      assertEquals(apiWhenFlavorsExist.getConfiguredZones(), ImmutableSet.of("az-1.region-a.geo-1", "az-2.region-a.geo-1", "az-3.region-a.geo-1"));
+
+      assertEquals(apiWhenFlavorsExist.getFlavorApiForZone("az-1.region-a.geo-1").list().concat().toString(),
+            new ParseFlavorListTest().expected().toString());
+   }
+
+   public void testListFlavorsWhenReponseIs404IsEmpty() throws Exception {
+      HttpRequest listFlavors = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse listFlavorsResponse = HttpResponse.builder().statusCode(404).build();
+
+      NovaApi apiWhenNoServersExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, listFlavors, listFlavorsResponse);
+
+      assertTrue(apiWhenNoServersExist.getFlavorApiForZone("az-1.region-a.geo-1").list().concat().isEmpty());
+   }
+
+   // TODO: gson deserializer for Multimap
+   public void testGetFlavorWhenResponseIs2xx() throws Exception {
+
+      HttpRequest getFlavor = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors/52415800-8b69-11e0-9b19-734f1195ff37")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse getFlavorResponse = HttpResponse.builder().statusCode(200)
+            .payload(payloadFromResource("/flavor_details.json")).build();
+
+      NovaApi apiWhenFlavorsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, getFlavor, getFlavorResponse);
+
+      assertEquals(
+            apiWhenFlavorsExist.getFlavorApiForZone("az-1.region-a.geo-1").get("52415800-8b69-11e0-9b19-734f1195ff37")
+                  .toString(), new ParseFlavorTest().expected().toString());
+   }
+
+   public void testGetFlavorWhenResponseIs404() throws Exception {
+      HttpRequest getFlavor = HttpRequest
+            .builder()
+            .method("GET")
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors/123")
+            .addHeader("Accept", "application/json")
+            .addHeader("X-Auth-Token", authToken).build();
+
+      HttpResponse getFlavorResponse = HttpResponse.builder().statusCode(404)
+            .payload(payloadFromResource("/flavor_details.json")).build();
+
+      NovaApi apiWhenNoFlavorsExist = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, getFlavor, getFlavorResponse);
+
+      assertNull(apiWhenNoFlavorsExist.getFlavorApiForZone("az-1.region-a.geo-1").get("123"));
+
+   }
+   
+   public void testCreateFlavor200() throws Exception {
+   	ParseCreateFlavorTest parser = new ParseCreateFlavorTest();
+      HttpRequest listFlavors = HttpRequest
+            .builder()
+            .method(HttpMethod.POST)
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors")
+            .addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
+            .addHeader("X-Auth-Token", authToken)
+            .payload(payloadFromResource(parser.resource())).build();
+      
+      HttpResponse listFlavorsResponse = HttpResponse.builder().statusCode(200)
+            .payload(payloadFromResource(parser.resource())).build();
+
+      NovaApi api = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+            responseWithKeystoneAccess, listFlavors, listFlavorsResponse);
+
+      assertEquals(
+            api.getFlavorApiForZone("az-1.region-a.geo-1").create(Flavor.builder()
+					.id("1cb47a44-9b84-4da4-bf81-c1976e8414ab")
+					.name("128 MB Server").ram(128).vcpus(1)
+					.disk(10).build())
+                  .toString(), parser.expected().toString());
+   }
+
+   public void testDeleteFlavor202() throws Exception {
+      String flavorId = "1cb47a44-9b84-4da4-bf81-c1976e8414ab";
+
+      HttpRequest updateMetadata = HttpRequest
+            .builder()
+            .method(HttpMethod.DELETE)
+            .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/flavors/" + flavorId)
+            .addHeader(HttpHeaders.ACCEPT, MediaType.WILDCARD)
+            .addHeader("X-Auth-Token", authToken)
+            .build();
+
+      HttpResponse updateMetadataResponse = HttpResponse.builder().statusCode(204).build();
+      
+      NovaApi api = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName,
+               responseWithKeystoneAccess, updateMetadata, updateMetadataResponse);
+
+      api.getFlavorApiForZone("az-1.region-a.geo-1").delete(flavorId);
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/d4243b7e/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiLiveTest.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiLiveTest.java
new file mode 100644
index 0000000..2af0d54
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/test/java/org/jclouds/openstack/nova/v2_0/features/FlavorApiLiveTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.openstack.nova.v2_0.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.openstack.nova.v2_0.domain.Flavor;
+import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
+import org.jclouds.openstack.v2_0.domain.Resource;
+import org.testng.annotations.Test;
+
+/**
+ * Tests behavior of {@link FlavorApi}
+ * 
+ * @author Jeremy Daggett
+ */
+@Test(groups = "live", testName = "FlavorApiLiveTest")
+public class FlavorApiLiveTest extends BaseNovaApiLiveTest {
+
+   /**
+    * Tests the listing of Flavors.
+    * 
+    * @throws Exception
+    */
+   @Test(description = "GET /v${apiVersion}/{tenantId}/flavors")
+   public void testListFlavors() throws Exception {
+      for (String zoneId : zones) {
+         FlavorApi flavorApi = api.getFlavorApiForZone(zoneId);
+         Set<? extends Resource> response = flavorApi.list().concat().toSet();
+         assertNotNull(response);
+         assertFalse(response.isEmpty());
+         for (Resource flavor : response) {
+            assertNotNull(flavor.getId());
+            assertNotNull(flavor.getName());
+            assertNotNull(flavor.getLinks());
+         }
+      }
+   }
+
+   /**
+    * Tests the listing of Flavors in detail.
+    * 
+    * @throws Exception
+    */
+   @Test(description = "GET /v${apiVersion}/{tenantId}/flavors/detail")
+   public void testListFlavorsInDetail() throws Exception {
+      for (String zoneId : zones) {
+         FlavorApi flavorApi = api.getFlavorApiForZone(zoneId);
+         Set<? extends Flavor> response = flavorApi.listInDetail().concat().toSet();
+         assertNotNull(response);
+         assertFalse(response.isEmpty());
+         for (Flavor flavor : response) {
+             assertNotNull(flavor.getId());
+             assertNotNull(flavor.getName());
+             assertNotNull(flavor.getLinks());
+             assertTrue(flavor.getRam() > 0);
+             assertTrue(flavor.getDisk() > 0);
+             assertTrue(flavor.getVcpus() > 0);
+         }
+      }
+   }
+
+   /**
+    * Tests getting Flavors by id.
+    * 
+    * @throws Exception
+    */
+   @Test(description = "GET /v${apiVersion}/{tenantId}/flavors/{id}", dependsOnMethods = { "testListFlavorsInDetail" })
+   public void testGetFlavorById() throws Exception {
+      for (String zoneId : zones) {
+         FlavorApi flavorApi = api.getFlavorApiForZone(zoneId);
+         Set<? extends Flavor> response = flavorApi.listInDetail().concat().toSet();
+         for (Flavor flavor : response) {
+            Flavor details = flavorApi.get(flavor.getId());
+            assertNotNull(details);
+            assertEquals(details.getId(), flavor.getId());
+            assertEquals(details.getName(), flavor.getName());
+            assertEquals(details.getLinks(), flavor.getLinks());
+            assertEquals(details.getRam(), flavor.getRam());
+            assertEquals(details.getDisk(), flavor.getDisk());
+            assertEquals(details.getVcpus(), flavor.getVcpus());
+         }
+      }
+   }
+
+}