You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by an...@apache.org on 2014/10/09 00:17:13 UTC
[2/6] Import openstack-swift from labs.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
new file mode 100644
index 0000000..84d08fe
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_CONTAINER_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_OBJECT_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_REMOVE_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_TEMPORARY_URL_KEY;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.Account;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+@Test(groups = "unit", testName = "AccountApiMockTest")
+public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
+
+ /** upper-cases first char, and lower-cases rest!! **/
+ public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(accountResponse()
+ // note silly casing
+ .addHeader(ACCOUNT_METADATA_PREFIX + "Apiname", "swift")
+ .addHeader(ACCOUNT_METADATA_PREFIX + "Apiversion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ Account account = api.getAccountApi("DFW").get();
+ assertEquals(account.getContainerCount(), 3l);
+ assertEquals(account.getObjectCount(), 42l);
+ assertEquals(account.getBytesUsed(), 323479l);
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(account.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
+ }
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void updateMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(accountResponse()
+ .addHeader(ACCOUNT_METADATA_PREFIX + "ApiName", "swift")
+ .addHeader(ACCOUNT_METADATA_PREFIX + "ApiVersion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getAccountApi("DFW").updateMetadata(metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+
+ RecordedRequest replaceRequest = server.takeRequest();
+ assertRequest(replaceRequest, "POST", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replaceRequest.getHeader(ACCOUNT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void updateTemporaryUrlKey() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(accountResponse()));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getAccountApi("DFW").updateTemporaryUrlKey("foobar"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+
+ RecordedRequest replaceRequest = server.takeRequest();
+ assertRequest(replaceRequest, "POST", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9");
+ assertEquals(replaceRequest.getHeader(ACCOUNT_TEMPORARY_URL_KEY), "foobar");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void deleteMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(accountResponse()));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getAccountApi("DFW").deleteMetadata(metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9 HTTP/1.1");
+ for (String key : metadata.keySet()) {
+ assertEquals(deleteRequest.getHeader(ACCOUNT_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
+
+ public static MockResponse accountResponse() {
+ return new MockResponse()
+ .addHeader(ACCOUNT_CONTAINER_COUNT, "3")
+ .addHeader(ACCOUNT_OBJECT_COUNT, "42")
+ .addHeader(ACCOUNT_BYTES_USED, "323479");
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
new file mode 100644
index 0000000..6901ac9
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+
+import org.jboss.shrinkwrap.api.GenericArchive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.exporter.TarGzExporter;
+import org.jclouds.io.ByteStreams2;
+import org.jclouds.io.Payload;
+import org.jclouds.io.payloads.ByteSourcePayload;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
+import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;
+import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteSource;
+
+@Test(groups = "live", testName = "BulkApiLiveTest")
+public class BulkApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
+
+ private static final int OBJECT_COUNT = 10;
+ private String containerName = getClass().getSimpleName();
+ List<String> paths = Lists.newArrayList();
+ byte[] tarGz;
+
+ public void testNotPresentWhenDeleting() throws Exception {
+ for (String regionId : regions) {
+ BulkDeleteResponse deleteResponse = api.getBulkApi(regionId).bulkDelete(
+ ImmutableList.of(UUID.randomUUID().toString()));
+ assertEquals(deleteResponse.getDeleted(), 0);
+ assertEquals(deleteResponse.getNotFound(), 1);
+ assertTrue(deleteResponse.getErrors().isEmpty());
+ }
+ }
+
+ public void testExtractArchive() throws Exception {
+ for (String regionId : regions) {
+ Payload payload = new ByteSourcePayload(ByteSource.wrap(tarGz));
+
+ ExtractArchiveResponse extractResponse = api.getBulkApi(regionId)
+ .extractArchive(containerName, payload, "tar.gz");
+ assertEquals(extractResponse.getCreated(), OBJECT_COUNT);
+ assertTrue(extractResponse.getErrors().isEmpty());
+ assertEquals(api.getContainerApi(regionId).get(containerName).getObjectCount(), OBJECT_COUNT);
+
+ // repeat the command
+ extractResponse = api.getBulkApi(regionId).extractArchive(containerName, payload, "tar.gz");
+ assertEquals(extractResponse.getCreated(), OBJECT_COUNT);
+ assertTrue(extractResponse.getErrors().isEmpty());
+ }
+ }
+
+ @Test(dependsOnMethods = "testExtractArchive")
+ public void testBulkDelete() throws Exception {
+ for (String regionId : regions) {
+ BulkDeleteResponse deleteResponse = api.getBulkApi(regionId).bulkDelete(paths);
+ assertEquals(deleteResponse.getDeleted(), OBJECT_COUNT);
+ assertEquals(deleteResponse.getNotFound(), 0);
+ assertTrue(deleteResponse.getErrors().isEmpty());
+ assertEquals(api.getContainerApi(regionId).get(containerName).getObjectCount(), 0);
+ }
+ }
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setup() {
+ super.setup();
+ for (String regionId : regions) {
+ boolean created = api.getContainerApi(regionId).create(containerName);
+ if (!created) {
+ deleteAllObjectsInContainer(regionId, containerName);
+ }
+ }
+ GenericArchive files = ShrinkWrap.create(GenericArchive.class, "files.tar.gz");
+ StringAsset content = new StringAsset("foo");
+ for (int i = 0; i < OBJECT_COUNT; i++) {
+ paths.add(containerName + "/file" + i);
+ files.add(content, "/file" + i);
+ }
+
+ try {
+ tarGz = ByteStreams2.toByteArrayAndClose(files.as(TarGzExporter.class).exportAsInputStream());
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ @Override
+ @AfterClass(groups = "live")
+ public void tearDown() {
+ for (String regionId : regions) {
+ deleteAllObjectsInContainer(regionId, containerName);
+ api.getContainerApi(regionId).deleteIfEmpty(containerName);
+ }
+ super.tearDown();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
new file mode 100644
index 0000000..3136b52
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.jboss.shrinkwrap.api.GenericArchive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.exporter.TarGzExporter;
+import org.jclouds.io.ByteStreams2;
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.io.ByteSource;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+@Test(groups = "unit", testName = "BulkApiMockTest")
+public class BulkApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
+
+ public void testExtractArchive() throws Exception {
+ GenericArchive files = ShrinkWrap.create(GenericArchive.class, "files.tar.gz");
+ StringAsset content = new StringAsset("foo");
+ for (int i = 0; i < 10; i++) {
+ files.add(content, "/file" + i);
+ }
+
+ byte[] tarGz = ByteStreams2.toByteArrayAndClose(files.as(TarGzExporter.class).exportAsInputStream());
+
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201).setBody("{\"Number Files Created\": 10, \"Errors\": []}")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ Payload payload = Payloads.newByteSourcePayload(ByteSource.wrap(tarGz));
+ ExtractArchiveResponse response = api.getBulkApi("DFW").extractArchive("myContainer", payload, "tar.gz");
+
+ assertEquals(response.getCreated(), 10);
+ assertTrue(response.getErrors().isEmpty());
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ RecordedRequest extractRequest = server.takeRequest();
+ assertRequest(extractRequest, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer?extract-archive=tar.gz");
+ assertEquals(extractRequest.getBody(), tarGz);
+ } finally {
+ server.shutdown();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
new file mode 100644
index 0000000..bf2ba98
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.swift.v1.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.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.swift.v1.options.UpdateContainerOptions;
+import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ * Provides live tests for the {@link ContainerApi}.
+ */
+@Test(groups = "live", testName = "ContainerApiLiveTest")
+public class ContainerApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
+
+ private String name = getClass().getSimpleName();
+
+ public void testCreateWithOptions() throws Exception {
+ for (String regionId : regions) {
+ ImmutableMultimap<String, String> headers =
+ ImmutableMultimap.of(SwiftHeaders.STATIC_WEB_INDEX, "__index.html",
+ SwiftHeaders.STATIC_WEB_ERROR, "__error.html");
+ CreateContainerOptions opts = new CreateContainerOptions().headers(headers);
+
+ assertNotNull(api.getContainerApi(regionId).create(name, opts));
+
+ Container container = api.getContainerApi(regionId).get(name);
+ assertNotNull(container);
+ assertEquals(container.getName(), name);
+ assertEquals(container.getMetadata().size(), 2);
+ assertEquals(container.getMetadata().get("web-index"), "__index.html");
+ assertEquals(container.getMetadata().get("web-error"), "__error.html");
+
+ assertTrue(api.getContainerApi(regionId).deleteIfEmpty(name));
+ }
+ }
+
+ public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+ final String nameWithSpaces = "container # ! special";
+
+ for (String regionId : regions) {
+ assertTrue(api.getContainerApi(regionId).create(nameWithSpaces));
+ Container container = api.getContainerApi(regionId).get(nameWithSpaces);
+ assertNotNull(container);
+ assertEquals(container.getName(), nameWithSpaces);
+
+ assertTrue(api.getContainerApi(regionId).deleteIfEmpty(nameWithSpaces));
+ }
+ }
+
+ public void testList() throws Exception {
+ for (String regionId : regions) {
+ ContainerApi containerApi = api.getContainerApi(regionId);
+ FluentIterable<Container> response = containerApi.list();
+ assertNotNull(response);
+ for (Container container : response) {
+ assertNotNull(container.getName());
+ assertTrue(container.getObjectCount() >= 0);
+ assertTrue(container.getBytesUsed() >= 0);
+ }
+ }
+ }
+
+ public void testListWithOptions() throws Exception {
+ String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
+ for (String regionId : regions) {
+ ListContainerOptions options = ListContainerOptions.Builder.marker(lexicographicallyBeforeName);
+ Container container = api.getContainerApi(regionId).list(options).get(0);
+ assertEquals(container.getName(), name);
+ assertTrue(container.getObjectCount() == 0);
+ assertTrue(container.getBytesUsed() == 0);
+ }
+ }
+
+ public void testUpdate() throws Exception {
+ for (String regionId : regions) {
+ ImmutableMultimap<String, String> headers =
+ ImmutableMultimap.of(SwiftHeaders.STATIC_WEB_INDEX, "__index.html",
+ SwiftHeaders.STATIC_WEB_ERROR, "__error.html");
+ UpdateContainerOptions opts = new UpdateContainerOptions().headers(headers);
+
+ assertNotNull(api.getContainerApi(regionId).create(name));
+
+ Container container = api.getContainerApi(regionId).get(name);
+ assertNotNull(container);
+ assertEquals(container.getName(), name);
+ assertTrue(container.getMetadata().isEmpty());
+
+ assertNotNull(api.getContainerApi(regionId).update(name, opts));
+
+ Container updatedContainer = api.getContainerApi(regionId).get(name);
+ assertNotNull(updatedContainer);
+ assertEquals(updatedContainer.getName(), name);
+ assertEquals(updatedContainer.getMetadata().size(), 2);
+ assertEquals(updatedContainer.getMetadata().get("web-index"), "__index.html");
+ assertEquals(updatedContainer.getMetadata().get("web-error"), "__error.html");
+
+ assertTrue(api.getContainerApi(regionId).deleteIfEmpty(name));
+ }
+ }
+
+ public void testGet() throws Exception {
+ for (String regionId : regions) {
+ Container container = api.getContainerApi(regionId).get(name);
+ assertEquals(container.getName(), name);
+ assertTrue(container.getObjectCount() == 0);
+ assertTrue(container.getBytesUsed() == 0);
+ }
+ }
+
+ public void testUpdateMetadata() throws Exception {
+ Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
+
+ for (String regionId : regions) {
+ ContainerApi containerApi = api.getContainerApi(regionId);
+ assertTrue(containerApi.updateMetadata(name, meta));
+ containerHasMetadata(containerApi, name, meta);
+ }
+ }
+
+ public void testDeleteMetadata() throws Exception {
+ Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
+
+ for (String regionId : regions) {
+ ContainerApi containerApi = api.getContainerApi(regionId);
+ // update
+ assertTrue(containerApi.updateMetadata(name, meta));
+ containerHasMetadata(containerApi, name, meta);
+ // delete
+ assertTrue(containerApi.deleteMetadata(name, meta));
+ Container container = containerApi.get(name);
+ for (Entry<String, String> entry : meta.entrySet()) {
+ // note keys are returned in lower-case!
+ assertFalse(container.getMetadata().containsKey(entry.getKey().toLowerCase()));
+ }
+ }
+ }
+
+ static void containerHasMetadata(ContainerApi containerApi, String name, Map<String, String> meta) {
+ Container container = containerApi.get(name);
+ for (Entry<String, String> entry : meta.entrySet()) {
+ // note keys are returned in lower-case!
+ assertEquals(container.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue(),
+ container + " didn't have metadata: " + entry);
+ }
+ }
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setup() {
+ super.setup();
+ for (String regionId : regions) {
+ api.getContainerApi(regionId).create(name);
+ }
+ }
+
+ @Override
+ @AfterClass(groups = "live")
+ public void tearDown() {
+ for (String regionId : regions) {
+ api.getContainerApi(regionId).deleteIfEmpty(name);
+ }
+ super.tearDown();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
new file mode 100644
index 0000000..6b3ef66
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
@@ -0,0 +1,363 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_OBJECT_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_REMOVE_METADATA_PREFIX;
+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.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.blobstore.ContainerNotFoundException;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+@Test(groups = "unit", testName = "ContainerApiMockTest")
+public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
+
+ public void testList() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/container_list.json"))));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ ImmutableList<Container> containers = api.getContainerApi("DFW").list().toList();
+ assertEquals(containers, ImmutableList.of(
+ Container.builder()
+ .name("test_container_1")
+ .objectCount(2)
+ .bytesUsed(78).build(),
+ Container.builder()
+ .name("test_container_2")
+ .objectCount(1)
+ .bytesUsed(17).build()));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testListWithOptions() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/container_list.json"))));
+
+ ListContainerOptions options = ListContainerOptions.Builder.marker("test");
+ assertNotNull(options);
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ ImmutableList<Container> containers = api.getContainerApi("DFW").list(options).toList();
+ assertEquals(containers, ImmutableList.of(
+ Container.builder()
+ .name("test_container_1")
+ .objectCount(2)
+ .bytesUsed(78).build(),
+ Container.builder()
+ .name("test_container_2")
+ .objectCount(1)
+ .bytesUsed(17).build()));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9?marker=test");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testContainerExists() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+ server.enqueue(addCommonHeaders(containerResponse()
+ .addHeader(CONTAINER_METADATA_PREFIX + "ApiName", "swift")
+ .addHeader(CONTAINER_METADATA_PREFIX + "ApiVersion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").create("myContainer", anybodyRead().metadata(metadata)));
+
+ Container container = api.getContainerApi("DFW").get("myContainer");
+ assertEquals(container.getName(), "myContainer");
+ assertEquals(container.getObjectCount(), 42l);
+ assertEquals(container.getBytesUsed(), 323479l);
+ for (Entry<String, String> entry : container.getMetadata().entrySet()) {
+ assertEquals(container.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
+ }
+ assertEquals(server.getRequestCount(), 3);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ @Test(expectedExceptions = ContainerNotFoundException.class)
+ public void testContainerDoesNotExist() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").create("myContainer", anybodyRead().metadata(metadata)));
+
+ // the head call will throw the ContainerNotFoundException
+ api.getContainerApi("DFW").get("myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreate() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").create("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreateWithOptions() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").create("myContainer", anybodyRead().metadata(metadata)));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+
+ RecordedRequest createRequest = server.takeRequest();
+ assertRequest(createRequest, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+
+ assertEquals(createRequest.getHeader(CONTAINER_READ), CONTAINER_ACL_ANYBODY_READ);
+
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(createRequest.getHeader(CONTAINER_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").create("container # ! special"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container%20%23%20%21%20special");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testAlreadyCreated() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(202)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertFalse(api.getContainerApi("DFW").create("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ /** upper-cases first char, and lower-cases rest!! **/
+ public void testGetKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse()
+ // note silly casing
+ .addHeader(CONTAINER_METADATA_PREFIX + "Apiname", "swift")
+ .addHeader(CONTAINER_METADATA_PREFIX + "Apiversion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ Container container = api.getContainerApi("DFW").get("myContainer");
+ assertEquals(container.getName(), "myContainer");
+ assertEquals(container.getObjectCount(), 42l);
+ assertEquals(container.getBytesUsed(), 323479l);
+ for (Entry<String, String> entry : container.getMetadata().entrySet()) {
+ assertEquals(container.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
+ }
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testUpdateMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse()
+ .addHeader(CONTAINER_METADATA_PREFIX + "ApiName", "swift")
+ .addHeader(CONTAINER_METADATA_PREFIX + "ApiVersion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").updateMetadata("myContainer", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest replaceRequest = server.takeRequest();
+ assertEquals(replaceRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replaceRequest.getHeader(CONTAINER_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testDeleteMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse()));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").deleteMetadata("myContainer", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ for (String key : metadata.keySet()) {
+ assertEquals(deleteRequest.getHeader(CONTAINER_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testDeleteIfEmpty() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").deleteIfEmpty("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testAlreadyDeleted() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getContainerApi("DFW").deleteIfEmpty("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testDeleteWhenNotEmpty() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(409)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertFalse(api.getContainerApi("DFW").deleteIfEmpty("myContainer"));
+
+ } finally {
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ server.shutdown();
+ }
+ }
+
+ private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
+
+ static MockResponse containerResponse() {
+ return new MockResponse()
+ .addHeader(CONTAINER_OBJECT_COUNT, "42")
+ .addHeader(CONTAINER_BYTES_USED, "323479");
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
new file mode 100644
index 0000000..09e34b5
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CreatePublicContainerLiveTest")
+public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
+
+ private String name = getClass().getSimpleName();
+
+ public void testAnybodyReadUpdatesMetadata() throws Exception {
+ for (String regionId : api.getConfiguredRegions()) {
+ api.getContainerApi(regionId).create(name, anybodyRead());
+ assertTrue(api.getContainerApi(regionId).get(name).getAnybodyRead().get());
+ }
+ }
+
+ @Override
+ @AfterClass(groups = "live")
+ public void tearDown() {
+ for (String regionId : api.getConfiguredRegions()) {
+ api.getContainerApi(regionId).deleteIfEmpty(name);
+ }
+ super.tearDown();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
new file mode 100644
index 0000000..5a472ff
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
@@ -0,0 +1,286 @@
+/*
+ * 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.swift.v1.features;
+
+import static org.jclouds.http.options.GetOptions.Builder.tail;
+import static org.jclouds.io.Payloads.newByteSourcePayload;
+import static org.jclouds.openstack.swift.v1.options.ListContainerOptions.Builder.marker;
+import static org.jclouds.util.Strings2.toStringAndClose;
+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 static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.http.options.GetOptions;
+import org.jclouds.io.Payload;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.ByteSource;
+
+/**
+ * Provides live tests for the {@link ObjectApi}.
+ */
+@Test(groups = "live", testName = "ObjectApiLiveTest", singleThreaded = true)
+public class ObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
+
+ private String name = getClass().getSimpleName();
+ private String containerName = getClass().getSimpleName() + "Container";
+ static final Payload PAYLOAD = newByteSourcePayload(ByteSource.wrap("swifty".getBytes()));
+
+ public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+ final String containerName = "container # ! special";
+ final String objectName = "object # ! special";
+
+ for (String regionId : regions) {
+ assertNotNull(api.getContainerApi(regionId).create(containerName));
+ assertNotNull(api.getObjectApi(regionId, containerName).put(objectName, PAYLOAD));
+
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(objectName);
+ assertEquals(object.getName(), objectName);
+ checkObject(object);
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
+
+ api.getObjectApi(regionId, containerName).delete(objectName);
+ api.getContainerApi(regionId).deleteIfEmpty(containerName);
+ }
+ }
+
+ public void testPutWithExpiration() throws Exception {
+ String objectName = "test-expiration";
+
+ long expireMillis = new Date().getTime() + 1000 * 60 * 60 * 24;
+ Date expireAt = new Date(expireMillis);
+
+ Payload payload = newByteSourcePayload(ByteSource.wrap("swifty".getBytes()));
+ payload.getContentMetadata().setExpires(expireAt);
+
+ for (String regionId : regions) {
+ String etag = api.getObjectApi(regionId, containerName).put(objectName, payload);
+ assertNotNull(etag);
+
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(objectName);
+ assertEquals(object.getName(), objectName);
+ checkObject(object);
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
+
+ api.getObjectApi(regionId, containerName).delete(objectName);
+ }
+ }
+ public void testCopyObject() throws Exception {
+ for (String regionId : regions) {
+ // source
+ String sourceContainer = "src" + containerName;
+ String sourceObjectName = "original.txt";
+ String badSource = "badSource";
+
+ // destination
+ String destinationContainer = "dest" + containerName;
+ String destinationObject = "copy.txt";
+ String destinationPath = "/" + destinationContainer + "/" + destinationObject;
+
+ ContainerApi containerApi = api.getContainerApi(regionId);
+
+ // create source and destination dirs
+ containerApi.create(sourceContainer);
+ containerApi.create(destinationContainer);
+
+ // get the api for this region and container
+ ObjectApi srcApi = api.getObjectApi(regionId, sourceContainer);
+ ObjectApi destApi = api.getObjectApi(regionId, destinationContainer);
+
+ // Create source object
+ assertNotNull(srcApi.put(sourceObjectName, PAYLOAD));
+ SwiftObject sourceObject = srcApi.get(sourceObjectName);
+ checkObject(sourceObject);
+
+ // Create the destination object
+ assertNotNull(destApi.put(destinationObject, PAYLOAD));
+ SwiftObject object = destApi.get(destinationObject);
+ checkObject(object);
+
+ // check the copy operation
+ assertTrue(destApi.copy(destinationObject, sourceContainer, sourceObjectName));
+ assertNotNull(destApi.get(destinationObject));
+
+ // now get a real SwiftObject
+ SwiftObject destSwiftObject = destApi.get(destinationObject);
+ assertEquals(toStringAndClose(destSwiftObject.getPayload().openStream()), "swifty");
+
+ // test exception thrown on bad source name
+ try {
+ destApi.copy(destinationObject, badSource, sourceObjectName);
+ fail("Expected CopyObjectException");
+ } catch (CopyObjectException e) {
+ assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObjectName);
+ assertEquals(e.getDestinationPath(), destinationPath);
+ }
+
+ deleteAllObjectsInContainer(regionId, sourceContainer);
+ containerApi.deleteIfEmpty(sourceContainer);
+
+ deleteAllObjectsInContainer(regionId, destinationContainer);
+ containerApi.deleteIfEmpty(destinationContainer);
+ }
+ }
+
+ public void testList() throws Exception {
+ for (String regionId : regions) {
+ ObjectApi objectApi = api.getObjectApi(regionId, containerName);
+ ObjectList response = objectApi.list();
+ assertEquals(response.getContainer(), api.getContainerApi(regionId).get(containerName));
+ for (SwiftObject object : response) {
+ checkObject(object);
+ }
+ }
+ }
+
+ public void testListWithOptions() throws Exception {
+ for (String regionId : regions) {
+ ObjectApi objectApi = api.getObjectApi(regionId, containerName);
+ ObjectList response = objectApi.list(ListContainerOptions.NONE);
+ assertEquals(response.getContainer(), api.getContainerApi(regionId).get(containerName));
+ for (SwiftObject object : response) {
+ checkObject(object);
+ }
+ }
+ }
+
+ public void testMetadata() throws Exception {
+ for (String regionId : regions) {
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(name);
+ assertEquals(object.getName(), name);
+ checkObject(object);
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
+ }
+ }
+
+ public void testUpdateMetadata() throws Exception {
+ for (String regionId : regions) {
+ ObjectApi objectApi = api.getObjectApi(regionId, containerName);
+
+ Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
+ assertTrue(objectApi.updateMetadata(name, meta));
+
+ SwiftObject object = objectApi.get(name);
+ for (Entry<String, String> entry : meta.entrySet()) {
+ // note keys are returned in lower-case!
+ assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue(),
+ object + " didn't have metadata: " + entry);
+ }
+ }
+ }
+
+ public void testGet() throws Exception {
+ for (String regionId : regions) {
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(name, GetOptions.NONE);
+ assertEquals(object.getName(), name);
+ checkObject(object);
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
+ }
+ }
+
+ public void testPrivateByDefault() throws Exception {
+ for (String regionId : regions) {
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(name);
+ try {
+ object.getUri().toURL().openStream();
+ fail("shouldn't be able to access " + object);
+ } catch (IOException expected) {
+ }
+ }
+ }
+
+ public void testGetOptions() throws Exception {
+ for (String regionId : regions) {
+ SwiftObject object = api.getObjectApi(regionId, containerName).get(name, tail(1));
+ assertEquals(object.getName(), name);
+ checkObject(object);
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "y");
+ }
+ }
+
+ public void testListOptions() throws Exception {
+ String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
+ for (String regionId : regions) {
+ SwiftObject object = api.getObjectApi(regionId, containerName)
+ .list(marker(lexicographicallyBeforeName)).get(0);
+ assertEquals(object.getName(), name);
+ checkObject(object);
+ }
+ }
+
+ public void testDeleteMetadata() throws Exception {
+ for (String regionId : regions) {
+ ObjectApi objectApi = api.getObjectApi(regionId, containerName);
+
+ Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
+
+ assertTrue(objectApi.updateMetadata(name, meta));
+ assertFalse(objectApi.get(name).getMetadata().isEmpty());
+
+ assertTrue(objectApi.deleteMetadata(name, meta));
+ assertTrue(objectApi.get(name).getMetadata().isEmpty());
+ }
+ }
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setup() {
+ super.setup();
+ for (String regionId : regions) {
+ api.getContainerApi(regionId).create(containerName);
+ api.getObjectApi(regionId, containerName).put(name, PAYLOAD);
+ }
+ }
+
+ @Override
+ @AfterClass(groups = "live")
+ public void tearDown() {
+ for (String regionId : regions) {
+ deleteAllObjectsInContainer(regionId, containerName);
+ api.getObjectApi(regionId, containerName).delete(name);
+ api.getContainerApi(regionId).deleteIfEmpty(containerName);
+ }
+
+ super.tearDown();
+ }
+
+ static void checkObject(SwiftObject object) {
+ assertNotNull(object.getName());
+ assertNotNull(object.getUri());
+ assertNotNull(object.getETag());
+ assertTrue(object.getLastModified().getTime() <= System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
+ assertNotNull(object.getPayload().getContentMetadata().getContentLength());
+ assertNotNull(object.getPayload().getContentMetadata().getContentType());
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/8505539a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
new file mode 100644
index 0000000..8c0e4d1
--- /dev/null
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
@@ -0,0 +1,515 @@
+/*
+ * 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.swift.v1.features;
+
+import static com.google.common.base.Charsets.US_ASCII;
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.net.HttpHeaders.EXPIRES;
+import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
+import static org.jclouds.Constants.PROPERTY_RETRY_DELAY_START;
+import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
+import static org.jclouds.http.options.GetOptions.Builder.tail;
+import static org.jclouds.io.Payloads.newByteSourcePayload;
+import static org.jclouds.openstack.swift.v1.features.ContainerApiMockTest.containerResponse;
+import static org.jclouds.openstack.swift.v1.options.ListContainerOptions.Builder.marker;
+import static org.jclouds.openstack.swift.v1.options.PutOptions.Builder.metadata;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_REMOVE_METADATA_PREFIX;
+import static org.jclouds.util.Strings2.toStringAndClose;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.http.HttpResponseException;
+import org.jclouds.io.Payload;
+import org.jclouds.io.payloads.ByteSourcePayload;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.ByteSource;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+/**
+ * Provides mock tests for the {@link ObjectApi}.
+ */
+@Test(groups = "unit", testName = "ObjectApiMockTest")
+public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
+ SimpleDateFormatDateService dates = new SimpleDateFormatDateService();
+
+ static final Payload PAYLOAD = newByteSourcePayload(ByteSource.wrap("swifty".getBytes()));
+
+ protected ImmutableList<SwiftObject> parsedObjectsForUrl(String baseUri) {
+ baseUri += "v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer";
+ return ImmutableList.of(
+ SwiftObject.builder()
+ .name("test_obj_1")
+ .uri(URI.create(baseUri + "/test_obj_1"))
+ .etag("4281c348eaf83e70ddce0e07221c3d28")
+ .payload(payload(14, "application/octet-stream", new Date(1406243553)))
+ .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(),
+ SwiftObject.builder()
+ .name("test_obj_2")
+ .uri(URI.create(baseUri + "/test_obj_2"))
+ .etag("b039efe731ad111bc1b0ef221c3849d0")
+ .payload(payload(64l, "application/octet-stream", null))
+ .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(),
+ SwiftObject.builder()
+ .name("test obj 3")
+ .uri(URI.create(baseUri + "/test%20obj%203"))
+ .etag("0b2e80bd0744d9ebb20484149a57c82e")
+ .payload(payload(14, "application/octet-stream", new Date()))
+ .lastModified(dates.iso8601DateParse("2014-05-20T05:26:32.612278")).build());
+ }
+
+ public void testList() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse()
+ .addHeader(CONTAINER_READ, CONTAINER_ACL_ANYBODY_READ)
+ .setBody(stringFromResource("/object_list.json"))));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ ObjectList objects = api.getObjectApi("DFW", "myContainer").list();
+ assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
+ assertEquals(objects.getContainer().getName(), "myContainer");
+ assertTrue(objects.getContainer().getAnybodyRead().get());
+
+ // Check MD5 is parsed from the ETag header.
+ SwiftObject object1 = objects.get(1);
+ assertEquals(base16().lowerCase().decode(object1.getETag()),
+ object1.getPayload().getContentMetadata().getContentMD5AsHashCode().asBytes());
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testListWithOptions() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse()
+ .addHeader(CONTAINER_READ, CONTAINER_ACL_ANYBODY_READ)
+ .setBody(stringFromResource("/object_list.json"))));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ ObjectList objects = api.getObjectApi("DFW", "myContainer").list(new ListContainerOptions());
+ assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
+ assertEquals(objects.getContainer().getName(), "myContainer");
+ assertTrue(objects.getContainer().getAnybodyRead().get());
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testListOptions() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(containerResponse().setBody(stringFromResource("/object_list.json"))));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ ObjectList objects = api.getObjectApi("DFW", "myContainer").list(marker("test"));
+ assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer?marker=test");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreate() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse()
+ .setResponseCode(201)
+ .addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b"))
+ .addHeader("Expires", "1406243553"));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertEquals(
+ api.getObjectApi("DFW", "myContainer").put("myObject", PAYLOAD,
+ metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ RecordedRequest replace = server.takeRequest();
+ assertRequest(replace, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+
+ assertEquals(new String(replace.getBody()), "swifty");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replace.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201).addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
+
+ final String containerName = "container # ! special";
+ final String objectName = "object # ! special";
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertEquals(
+ api.getObjectApi("DFW", containerName).put(objectName, PAYLOAD,
+ metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ RecordedRequest replace = server.takeRequest();
+ assertRequest(replace, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container%20%23%20%21%20special/object%20%23%20%21%20special");
+
+ assertEquals(new String(replace.getBody()), "swifty");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCreateWith408Retry() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(408))); // 1
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(408))); // 2
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(408))); // 3
+
+ // Finally success
+ server.enqueue(addCommonHeaders(new MockResponse()
+ .setResponseCode(201)
+ .addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
+
+ try {
+ Properties overrides = new Properties();
+ overrides.setProperty(PROPERTY_MAX_RETRIES, 5 + "");
+
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift", overrides);
+ assertEquals(
+ api.getObjectApi("DFW", "myContainer").put("myObject", PAYLOAD,
+ metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+
+ assertEquals(server.getRequestCount(), 5);
+ assertAuthentication(server);
+ RecordedRequest replace = server.takeRequest();
+ // This should take a while.
+ assertRequest(replace, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+
+ assertEquals(new String(replace.getBody()), "swifty");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replace.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ /** upper-cases first char, and lower-cases rest!! **/
+ public void testGetWithoutKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(objectResponse()
+ // note silly casing
+ .addHeader(OBJECT_METADATA_PREFIX + "Apiname", "swift")
+ .addHeader(OBJECT_METADATA_PREFIX + "Apiversion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ SwiftObject object = api.getObjectApi("DFW", "myContainer").getWithoutBody("myObject");
+ assertEquals(object.getName(), "myObject");
+ assertEquals(object.getETag(), "8a964ee2a5e88be344f36c22562a6486");
+
+ // Check MD5 is parsed from the ETag header.
+ assertEquals(base16().lowerCase().decode(object.getETag()),
+ object.getPayload().getContentMetadata().getContentMD5AsHashCode().asBytes());
+
+ assertEquals(object.getLastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
+ for (Entry<String, String> entry : object.getMetadata().entrySet()) {
+ assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
+ }
+ assertEquals(object.getPayload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
+ assertEquals(toStringAndClose(object.getPayload().openStream()), "");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertAuthentication(server);
+ assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testGet() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(objectResponse()
+ // note silly casing
+ .addHeader(OBJECT_METADATA_PREFIX + "Apiname", "swift")
+ .addHeader(OBJECT_METADATA_PREFIX + "Apiversion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ SwiftObject object = api.getObjectApi("DFW", "myContainer").get("myObject", tail(1));
+ assertEquals(object.getName(), "myObject");
+ assertEquals(object.getETag(), "8a964ee2a5e88be344f36c22562a6486");
+ assertEquals(object.getLastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
+ for (Entry<String, String> entry : object.getMetadata().entrySet()) {
+ assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
+ }
+
+ Payload payload = object.getPayload();
+ assertEquals(payload.getContentMetadata().getContentLength(), Long.valueOf(4));
+ assertEquals(payload.getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
+ assertEquals(payload.getContentMetadata().getExpires(), dates.rfc822DateParse("Wed, 23 Jul 2014 14:00:00 GMT"));
+
+ assertEquals(toStringAndClose(payload.openStream()), "ABCD");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest get = server.takeRequest();
+ assertEquals(get.getRequestLine(),
+ "GET /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ @Test(expectedExceptions = HttpResponseException.class, timeOut = 20000)
+ public void testCreateWithTimeout() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ // Typically we would enqueue a response for the put. However, in this case, test the timeout by not providing one.
+
+ try {
+ Properties overrides = new Properties();
+
+ overrides.setProperty(PROPERTY_SO_TIMEOUT, 5000 + ""); // This time-outs the connection
+ overrides.setProperty(PROPERTY_MAX_RETRIES, 0 + ""); // 0 retries == 1 try. Semantics.
+ overrides.setProperty(PROPERTY_RETRY_DELAY_START, 0 + ""); // exponential backoff already working for this call. This is the delay BETWEEN attempts.
+
+ final SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift", overrides);
+
+ api.getObjectApi("DFW", "myContainer").put("myObject", new ByteSourcePayload(ByteSource.wrap("swifty".getBytes())), metadata(metadata));
+
+ fail("testReplaceTimeout test should have failed with an HttpResponseException.");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testUpdateMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(objectResponse()
+ .addHeader(OBJECT_METADATA_PREFIX + "ApiName", "swift")
+ .addHeader(OBJECT_METADATA_PREFIX + "ApiVersion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getObjectApi("DFW", "myContainer").updateMetadata("myObject", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest replaceRequest = server.takeRequest();
+ assertEquals(replaceRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replaceRequest.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testUpdateMetadataContentType() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(objectResponse()
+ .addHeader(OBJECT_METADATA_PREFIX + "ApiName", "swift")
+ .addHeader(OBJECT_METADATA_PREFIX + "ApiVersion", "v1.1")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getObjectApi("DFW", "myContainer").updateMetadata("myObject", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest replaceRequest = server.takeRequest();
+ assertEquals(replaceRequest.getHeaders("Content-Type").get(0), "", "updateMetadata should send an empty content-type header, but sent "
+ + replaceRequest.getHeaders("Content-Type").get(0).toString());
+
+ assertEquals(replaceRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ for (Entry<String, String> entry : metadata.entrySet()) {
+ assertEquals(replaceRequest.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testDeleteMetadata() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(objectResponse()));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getObjectApi("DFW", "myContainer").deleteMetadata("myObject", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ for (String key : metadata.keySet()) {
+ assertEquals(deleteRequest.getHeader(OBJECT_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testDelete() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ api.getObjectApi("DFW", "myContainer").delete("myObject");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testAlreadyDeleted() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ api.getObjectApi("DFW", "myContainer").delete("myObject");
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void testCopyObject() throws Exception {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)
+ .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bar/foo.txt")));
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ assertTrue(api.getObjectApi("DFW", "foo")
+ .copy("bar.txt", "bar", "foo.txt"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+
+ RecordedRequest copyRequest = server.takeRequest();
+ assertEquals(copyRequest.getRequestLine(),
+ "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/foo/bar.txt HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ @Test(expectedExceptions = CopyObjectException.class)
+ public void testCopyObjectFail() throws InterruptedException, IOException {
+ MockWebServer server = mockOpenStackServer();
+ server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+ server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)
+ .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bogus/foo.txt")));
+
+ try {
+ SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+ // the following line will throw the CopyObjectException
+ api.getObjectApi("DFW", "foo").copy("bar.txt", "bogus", "foo.txt");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
+
+ static MockResponse objectResponse() {
+ return new MockResponse()
+ .addHeader("Last-Modified", "Fri, 12 Jun 2010 13:40:18 GMT")
+ .addHeader("ETag", "8a964ee2a5e88be344f36c22562a6486")
+ // TODO: MWS doesn't allow you to return content length w/o content
+ // on HEAD!
+ .setBody("ABCD".getBytes(US_ASCII))
+ .addHeader("Content-Length", "4")
+ .addHeader("Content-Type", "text/plain; charset=UTF-8")
+ .addHeader(EXPIRES, "Wed, 23 Jul 2014 14:00:00 GMT");
+ }
+
+ static Payload payload(long bytes, String contentType, Date expires) {
+ Payload payload = newByteSourcePayload(ByteSource.empty());
+ payload.getContentMetadata().setContentLength(bytes);
+ payload.getContentMetadata().setContentType(contentType);
+ payload.getContentMetadata().setExpires(expires);
+ return payload;
+ }
+}