Skip to content

Commit 69ddb36

Browse files
author
Ewan Higgs
committed
HADOOP-16193. Add extra S3A MPU test to see what happens if a file is created during the MPU. Contributed by Steve Loughran
1 parent ee7c261 commit 69ddb36

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/contract/s3a/ITestS3AContractMultipartUploader.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,31 @@
1717
*/
1818
package org.apache.hadoop.fs.contract.s3a;
1919

20+
import java.io.ByteArrayInputStream;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import org.junit.Test;
2025
import org.slf4j.Logger;
2126
import org.slf4j.LoggerFactory;
2227

2328
import org.apache.hadoop.conf.Configuration;
29+
import org.apache.hadoop.fs.FileStatus;
30+
import org.apache.hadoop.fs.MultipartUploader;
31+
import org.apache.hadoop.fs.PartHandle;
2432
import org.apache.hadoop.fs.Path;
33+
import org.apache.hadoop.fs.UploadHandle;
2534
import org.apache.hadoop.fs.contract.AbstractFSContract;
2635
import org.apache.hadoop.fs.contract.AbstractContractMultipartUploaderTest;
2736
import org.apache.hadoop.fs.contract.ContractTestUtils;
2837
import org.apache.hadoop.fs.s3a.S3AFileSystem;
2938
import org.apache.hadoop.fs.s3a.WriteOperationHelper;
3039

40+
import static org.apache.hadoop.fs.contract.ContractTestUtils.dataset;
3141
import static org.apache.hadoop.fs.s3a.S3ATestConstants.*;
3242
import static org.apache.hadoop.fs.s3a.S3ATestUtils.*;
3343
import static org.apache.hadoop.fs.s3a.scale.AbstractSTestS3AHugeFiles.DEFAULT_HUGE_PARTITION_SIZE;
44+
import static org.apache.hadoop.test.LambdaTestUtils.eventually;
3445

3546
/**
3647
* Test MultipartUploader with S3A.
@@ -159,4 +170,47 @@ public void testDirectoryInTheWay() throws Exception {
159170
public void testMultipartUploadReverseOrder() throws Exception {
160171
ContractTestUtils.skip("skipped for speed");
161172
}
173+
174+
/**
175+
* This creates and then deletes a zero-byte file while an upload
176+
* is in progress, and verifies that the uploaded file is ultimately
177+
* visible.
178+
*/
179+
@Test
180+
public void testMultipartOverlapWithTransientFile() throws Throwable {
181+
// until there's a way to explicitly ask for a multipart uploader from a
182+
// specific FS, explicitly create one bonded to the raw FS.
183+
describe("testMultipartOverlapWithTransientFile");
184+
S3AFileSystem fs = getFileSystem();
185+
Path path = path("testMultipartOverlapWithTransientFile");
186+
fs.delete(path, true);
187+
MultipartUploader mpu = mpu(1);
188+
UploadHandle upload1 = mpu.initialize(path);
189+
byte[] dataset = dataset(1024, '0', 10);
190+
final Map<Integer, PartHandle> handles = new HashMap<>();
191+
LOG.info("Uploading multipart entry");
192+
PartHandle value = mpu.putPart(path, new ByteArrayInputStream(dataset), 1,
193+
upload1,
194+
dataset.length);
195+
// upload 1K
196+
handles.put(1, value);
197+
// confirm the path is absent
198+
ContractTestUtils.assertPathDoesNotExist(fs,
199+
"path being uploaded", path);
200+
// now create an empty file
201+
ContractTestUtils.touch(fs, path);
202+
final FileStatus touchStatus = fs.getFileStatus(path);
203+
LOG.info("0-byte file has been created: {}", touchStatus);
204+
fs.delete(path, false);
205+
// now complete the upload
206+
mpu.complete(path, handles, upload1);
207+
208+
// wait for the data to arrive
209+
eventually(timeToBecomeConsistentMillis(), 500, () -> {
210+
FileStatus mpuStatus = fs.getFileStatus(path);
211+
assertTrue("File is empty in " + mpuStatus, mpuStatus.getLen() > 0);
212+
return mpuStatus;
213+
});
214+
215+
}
162216
}

0 commit comments

Comments
 (0)