Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
/** Utilities for unit-testing S3 endpoints. */
public final class EndpointTestUtils {

/** Get key content. */
public static Response get(
ObjectEndpoint subject,
String bucket,
String key
) throws IOException, OS3Exception {
return subject.get(bucket, key, 0, null, 0, null, null);
}

/** Get key tags. */
public static Response getTagging(
ObjectEndpoint subject,
Expand All @@ -43,6 +52,18 @@ public static Response getTagging(
return subject.get(bucket, key, 0, null, 0, null, "");
}

/** List parts of MPU. */
public static Response listParts(
ObjectEndpoint subject,
String bucket,
String key,
String uploadID,
int maxParts,
int nextPart
) throws IOException, OS3Exception {
return subject.get(bucket, key, 0, uploadID, maxParts, String.valueOf(nextPart), null);
}

/** Put without content. */
public static Response putDir(
ObjectEndpoint subject,
Expand Down Expand Up @@ -98,6 +119,15 @@ public static Response put(
}
}

/** Delete key. */
public static Response delete(
ObjectEndpoint subject,
String bucket,
String key
) throws IOException, OS3Exception {
return subject.delete(bucket, key, null, null);
}

/** Delete key tags. */
public static Response deleteTagging(
ObjectEndpoint subject,
Expand Down Expand Up @@ -168,10 +198,25 @@ public static void completeMultipartUpload(
}
}

/** Abort multipart upload. */
public static Response abortMultipartUpload(
ObjectEndpoint subject,
String bucket,
String key,
String uploadID
) throws IOException, OS3Exception {
return subject.delete(bucket, key, uploadID, null);
}

/** Verify response is success for {@code request}. */
public static <E extends Exception> void assertSucceeds(CheckedSupplier<Response, E> request) throws E {
assertStatus(HttpStatus.SC_OK, request);
}

/** Verify response status for {@code request}. */
public static <E extends Exception> void assertStatus(int status, CheckedSupplier<Response, E> request) throws E {
try (Response response = request.get()) {
assertEquals(HttpStatus.SC_OK, response.getStatus());
assertEquals(status, response.getStatus());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@

package org.apache.hadoop.ozone.s3.endpoint;

import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.abortMultipartUpload;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertErrorResponse;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertStatus;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.initiateMultipartUpload;
import static org.apache.hadoop.ozone.s3.util.S3Consts.STORAGE_CLASS_HEADER;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.client.OzoneClient;
import org.apache.hadoop.ozone.client.OzoneClientStub;
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
import org.apache.http.HttpStatus;
import org.junit.jupiter.api.Test;

/**
Expand All @@ -54,22 +55,12 @@ public void testAbortMultipartUpload() throws Exception {
.setClient(client)
.build();


String uploadID = initiateMultipartUpload(rest, bucket, key);

// Abort multipart upload
Response response = rest.delete(bucket, key, uploadID, null);

assertEquals(204, response.getStatus());
assertStatus(HttpStatus.SC_NO_CONTENT, () -> abortMultipartUpload(rest, bucket, key, uploadID));

// test with unknown upload Id.
try {
rest.delete(bucket, key, "random", null);
} catch (OS3Exception ex) {
assertEquals(S3ErrorTable.NO_SUCH_UPLOAD.getCode(), ex.getCode());
assertEquals(S3ErrorTable.NO_SUCH_UPLOAD.getErrorMessage(),
ex.getErrorMessage());
}

assertErrorResponse(S3ErrorTable.NO_SUCH_UPLOAD, () -> abortMultipartUpload(rest, bucket, key, "random"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.hadoop.ozone.s3.endpoint;

import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertErrorResponse;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.initiateMultipartUpload;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.uploadPart;
import static org.apache.hadoop.ozone.s3.util.S3Consts.STORAGE_CLASS_HEADER;
Expand All @@ -27,6 +28,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.IOException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import org.apache.hadoop.ozone.OzoneConsts;
Expand Down Expand Up @@ -71,45 +73,36 @@ public void setUp() throws Exception {

@Test
public void testListParts() throws Exception {
Response response = rest.get(OzoneConsts.S3_BUCKET, OzoneConsts.KEY, 0,
uploadID, 3, "0", null);

ListPartsResponse listPartsResponse =
(ListPartsResponse) response.getEntity();
ListPartsResponse listPartsResponse = listParts(3, 0);

assertFalse(listPartsResponse.getTruncated());
assertEquals(3, listPartsResponse.getPartList().size());

}

@Test
public void testListPartsContinuation() throws Exception {
Response response = rest.get(OzoneConsts.S3_BUCKET, OzoneConsts.KEY, 0,
uploadID, 2, "0", null);
ListPartsResponse listPartsResponse =
(ListPartsResponse) response.getEntity();
ListPartsResponse listPartsResponse = listParts(2, 0);

assertTrue(listPartsResponse.getTruncated());
assertEquals(2, listPartsResponse.getPartList().size());

// Continue
response = rest.get(OzoneConsts.S3_BUCKET, OzoneConsts.KEY, 0, uploadID, 2,
Integer.toString(listPartsResponse.getNextPartNumberMarker()), null);
listPartsResponse = (ListPartsResponse) response.getEntity();
listPartsResponse = listParts(2, listPartsResponse.getNextPartNumberMarker());

assertFalse(listPartsResponse.getTruncated());
assertEquals(1, listPartsResponse.getPartList().size());

}

@Test
public void testListPartsWithUnknownUploadID() throws Exception {
try {
rest.get(OzoneConsts.S3_BUCKET, OzoneConsts.KEY, 0,
uploadID, 2, "0", null);
} catch (OS3Exception ex) {
assertEquals(S3ErrorTable.NO_SUCH_UPLOAD.getErrorMessage(),
ex.getErrorMessage());
public void testListPartsWithUnknownUploadID() {
assertErrorResponse(S3ErrorTable.NO_SUCH_UPLOAD,
() -> EndpointTestUtils.listParts(rest, OzoneConsts.S3_BUCKET, "no-such-key", "no-such-upload", 2, 0));
}

private ListPartsResponse listParts(int maxParts, int nextPart) throws IOException, OS3Exception {
try (Response response = EndpointTestUtils.listParts(rest, OzoneConsts.S3_BUCKET, OzoneConsts.KEY,
uploadID, maxParts, nextPart)) {
return (ListPartsResponse) response.getEntity();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@

package org.apache.hadoop.ozone.s3.endpoint;

import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertStatus;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.delete;
import static org.junit.jupiter.api.Assertions.assertFalse;

import java.io.IOException;
import org.apache.hadoop.ozone.client.OzoneBucket;
import org.apache.hadoop.ozone.client.OzoneClient;
import org.apache.hadoop.ozone.client.OzoneClientStub;
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
import org.apache.http.HttpStatus;
import org.junit.jupiter.api.Test;

/**
Expand All @@ -32,7 +35,7 @@
public class TestObjectDelete {

@Test
public void delete() throws IOException, OS3Exception {
void testDelete() throws IOException, OS3Exception {
//GIVEN
OzoneClient client = new OzoneClientStub();
client.getObjectStore().createS3Bucket("b1");
Expand All @@ -47,7 +50,7 @@ public void delete() throws IOException, OS3Exception {
.build();

//WHEN
rest.delete("b1", "key1", null, null);
assertStatus(HttpStatus.SC_NO_CONTENT, () -> delete(rest, "b1", "key1"));

//THEN
assertFalse(bucket.listKeys("").hasNext(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
package org.apache.hadoop.ozone.s3.endpoint;

import static org.apache.hadoop.ozone.s3.S3GatewayConfigKeys.OZONE_S3G_FSO_DIRECTORY_CREATION_ENABLED;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertErrorResponse;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.assertSucceeds;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.get;
import static org.apache.hadoop.ozone.s3.endpoint.EndpointTestUtils.put;
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.NO_SUCH_KEY;
import static org.apache.hadoop.ozone.s3.util.S3Consts.RANGE_HEADER;
Expand All @@ -27,7 +29,6 @@
import static org.apache.hadoop.ozone.s3.util.S3Consts.X_AMZ_CONTENT_SHA256;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -96,9 +97,9 @@ public void init() throws OS3Exception, IOException {
}

@Test
public void get() throws IOException, OS3Exception {
public void testGet() throws IOException, OS3Exception {
//WHEN
Response response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
Response response = get(rest, BUCKET_NAME, KEY_NAME);

//THEN
OzoneClientTestUtils.assertKeyContent(bucket, KEY_NAME, CONTENT);
Expand All @@ -114,7 +115,7 @@ public void get() throws IOException, OS3Exception {
@Test
public void getKeyWithTag() throws IOException, OS3Exception {
//WHEN
Response response = rest.get(BUCKET_NAME, KEY_WITH_TAG, 0, null, 0, null, null);
Response response = get(rest, BUCKET_NAME, KEY_WITH_TAG);

//THEN
OzoneClientTestUtils.assertKeyContent(bucket, KEY_WITH_TAG, CONTENT);
Expand All @@ -130,7 +131,7 @@ public void getKeyWithTag() throws IOException, OS3Exception {
public void inheritRequestHeader() throws IOException, OS3Exception {
setDefaultHeader();

Response response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
Response response = get(rest, BUCKET_NAME, KEY_NAME);

assertEquals(CONTENT_TYPE1,
response.getHeaderString("Content-Type"));
Expand Down Expand Up @@ -160,7 +161,7 @@ public void overrideResponseHeader() throws IOException, OS3Exception {
CONTENT_DISPOSITION2);
queryParameter.putSingle("response-content-encoding", CONTENT_ENCODING2);

Response response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
Response response = get(rest, BUCKET_NAME, KEY_NAME);

assertEquals(CONTENT_TYPE2,
response.getHeaderString("Content-Type"));
Expand All @@ -181,13 +182,13 @@ public void getRangeHeader() throws IOException, OS3Exception {
Response response;
when(headers.getHeaderString(RANGE_HEADER)).thenReturn("bytes=0-0");

response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
response = get(rest, BUCKET_NAME, KEY_NAME);
assertEquals("1", response.getHeaderString("Content-Length"));
assertEquals(String.format("bytes 0-0/%s", CONTENT.length()),
response.getHeaderString("Content-Range"));

when(headers.getHeaderString(RANGE_HEADER)).thenReturn("bytes=0-");
response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
response = get(rest, BUCKET_NAME, KEY_NAME);
assertEquals(String.valueOf(CONTENT.length()),
response.getHeaderString("Content-Length"));
assertEquals(
Expand All @@ -200,15 +201,15 @@ public void getRangeHeader() throws IOException, OS3Exception {
@Test
public void getStatusCode() throws IOException, OS3Exception {
Response response;
response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
response = get(rest, BUCKET_NAME, KEY_NAME);
assertEquals(response.getStatus(),
Response.Status.OK.getStatusCode());

// https://www.rfc-editor.org/rfc/rfc7233#section-4.1
// The 206 (Partial Content) status code indicates that the server is
// successfully fulfilling a range request for the target resource
when(headers.getHeaderString(RANGE_HEADER)).thenReturn("bytes=0-1");
response = rest.get(BUCKET_NAME, KEY_NAME, 0, null, 0, null, null);
response = get(rest, BUCKET_NAME, KEY_NAME);
assertEquals(response.getStatus(),
Response.Status.PARTIAL_CONTENT.getStatusCode());
assertNull(response.getHeaderString(TAG_COUNT_HEADER));
Expand All @@ -232,19 +233,12 @@ private void setDefaultHeader() {
@Test
public void testGetWhenKeyIsDirectoryAndDoesNotEndWithASlash()
throws IOException {
// GIVEN
final String keyPath = "keyDir";
OzoneConfiguration config = new OzoneConfiguration();
config.set(OZONE_S3G_FSO_DIRECTORY_CREATION_ENABLED, "true");
rest.setOzoneConfiguration(config);
bucket.createDirectory(keyPath);

// WHEN
final OS3Exception ex = assertThrows(OS3Exception.class,
() -> rest.get(BUCKET_NAME, keyPath, 0, null, 0, null, null));

// THEN
assertEquals(NO_SUCH_KEY.getCode(), ex.getCode());
bucket.deleteKey(keyPath);
assertErrorResponse(NO_SUCH_KEY, () -> get(rest, BUCKET_NAME, keyPath));
}
}
Loading