Skip to content

Commit 12e6bff

Browse files
committed
source and test changes
1 parent 3874f72 commit 12e6bff

File tree

5 files changed

+53
-61
lines changed

5 files changed

+53
-61
lines changed

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FileContextCreateMkdirBaseTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static org.apache.hadoop.fs.FileContextTestHelper.*;
2828
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertIsDirectory;
2929
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertIsFile;
30+
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
3031

3132
import org.apache.hadoop.test.GenericTestUtils;
3233
import org.slf4j.event.Level;
@@ -131,7 +132,7 @@ public void testMkdirsRecursiveWithExistingDir() throws IOException {
131132
}
132133

133134
@Test
134-
public void testMkdirRecursiveWithExistingFile() throws IOException {
135+
public void testMkdirRecursiveWithExistingFile() throws Exception {
135136
Path f = getTestRootPath(fc, "NonExistant3/aDir");
136137
fc.mkdir(f, FileContext.DEFAULT_PERM, true);
137138
assertIsDirectory(fc.getFileStatus(f));
@@ -144,13 +145,12 @@ public void testMkdirRecursiveWithExistingFile() throws IOException {
144145

145146
// try creating another folder which conflicts with filePath
146147
Path dirPath = new Path(filePath, "bDir/cDir");
147-
try {
148-
fc.mkdir(dirPath, FileContext.DEFAULT_PERM, true);
149-
Assert.fail("Mkdir for " + dirPath
150-
+ MKDIR_FILE_PRESENT_ERROR);
151-
} catch(IOException e) {
152-
// failed as expected
153-
}
148+
intercept(
149+
IOException.class,
150+
null,
151+
"Mkdir for " + dirPath + MKDIR_FILE_PRESENT_ERROR,
152+
() -> fc.mkdir(dirPath, FileContext.DEFAULT_PERM, true)
153+
);
154154
}
155155

156156
@Test

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,8 +3769,7 @@ public boolean mkdirs(Path p, FsPermission permission) throws IOException,
37693769
createStoreContext(),
37703770
path,
37713771
createMkdirOperationCallbacks(),
3772-
isMagicCommitPath(path),
3773-
performanceCreation));
3772+
performanceCreation || isMagicCommitPath(path)));
37743773
}
37753774

37763775
/**
@@ -4209,7 +4208,6 @@ public boolean createEmptyDir(Path path, StoreContext storeContext)
42094208
storeContext,
42104209
path,
42114210
createMkdirOperationCallbacks(),
4212-
false,
42134211
performanceCreation));
42144212
}
42154213
}

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/MkdirOperation.java

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,22 @@ public class MkdirOperation extends ExecutingStoreOperation<Boolean> {
7070
private final boolean performanceCreation;
7171

7272
/**
73-
* Should checks for ancestors existing be skipped?
74-
* This flag is set when working with magic directories.
73+
* Initialize Mkdir Operation context for S3A.
74+
*
75+
* @param storeContext Store context.
76+
* @param dir Dir path of the directory.
77+
* @param callbacks MkdirCallbacks object used by the Mkdir operation.
78+
* @param performanceCreation If true, skip validation of the parent directory
79+
* structure.
7580
*/
76-
private final boolean isMagicPath;
77-
7881
public MkdirOperation(
7982
final StoreContext storeContext,
8083
final Path dir,
8184
final MkdirCallbacks callbacks,
82-
final boolean isMagicPath,
8385
final boolean performanceCreation) {
8486
super(storeContext);
8587
this.dir = dir;
8688
this.callbacks = callbacks;
87-
this.isMagicPath = isMagicPath;
8889
this.performanceCreation = performanceCreation;
8990
}
9091

@@ -106,14 +107,13 @@ public Boolean execute() throws IOException {
106107
}
107108

108109
// get the file status of the path.
109-
// this is done even for a magic path, to avoid always issuing PUT
110-
// requests. Doing that without a check wouild seem to be an
111-
// optimization, but it is not because
112-
// 1. PUT is slower than HEAD
113-
// 2. Write capacity is less than read capacity on a shard
114-
// 3. It adds needless entries in versioned buckets, slowing
115-
// down subsequent operations.
116-
FileStatus fileStatus = getPathStatusExpectingDir(dir);
110+
// this is not done for magic path i.e. performanceCreation mode.
111+
// For performanceCreation mode, we would probe for HEAD only.
112+
// For non-performance or regular mode, the probe for both HEAD and LIST would
113+
// be done.
114+
S3AFileStatus fileStatus = performanceCreation
115+
? probePathStatusOrNull(dir, StatusProbeEnum.HEAD_ONLY)
116+
: getPathStatusExpectingDir(dir);
117117
if (fileStatus != null) {
118118
if (fileStatus.isDirectory()) {
119119
return true;
@@ -123,15 +123,6 @@ public Boolean execute() throws IOException {
123123
}
124124
// file status was null
125125

126-
// is the path magic?
127-
// If so, we declare success without looking any further
128-
if (isMagicPath) {
129-
// Create the marker file immediately,
130-
// and don't delete markers
131-
callbacks.createFakeDirectory(dir, true);
132-
return true;
133-
}
134-
135126
// if performance creation mode is set, no need to check
136127
// whether the closest ancestor is dir.
137128
if (!performanceCreation) {
@@ -143,7 +134,8 @@ public Boolean execute() throws IOException {
143134

144135
// Create the marker file, delete the parent entries
145136
// if the filesystem isn't configured to retain them
146-
callbacks.createFakeDirectory(dir, false);
137+
callbacks.createFakeDirectory(dir,
138+
performanceCreation);
147139
return true;
148140
}
149141

@@ -220,7 +212,7 @@ private S3AFileStatus getPathStatusExpectingDir(final Path path)
220212
throws IOException {
221213
S3AFileStatus status = probePathStatusOrNull(path,
222214
StatusProbeEnum.DIRECTORIES);
223-
if (status == null && !isMagicPath) {
215+
if (status == null && !performanceCreation) {
224216
status = probePathStatusOrNull(path,
225217
StatusProbeEnum.FILE);
226218
}

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

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
package org.apache.hadoop.fs.contract.s3a;
2020

21-
import org.assertj.core.api.Assertions;
21+
import java.io.IOException;
22+
import java.io.UncheckedIOException;
23+
2224
import org.junit.Test;
2325

2426
import org.apache.hadoop.conf.Configuration;
@@ -27,6 +29,7 @@
2729

2830
import static org.apache.hadoop.fs.s3a.Constants.FS_S3A_CREATE_PERFORMANCE;
2931
import static org.apache.hadoop.fs.s3a.S3ATestUtils.removeBaseAndBucketOverrides;
32+
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
3033

3134
/**
3235
* Test mkdir operations on S3A with create performance mode.
@@ -51,18 +54,21 @@ protected AbstractFSContract createContract(Configuration conf) {
5154

5255
@Test
5356
public void testMkdirOverParentFile() throws Throwable {
57+
intercept(
58+
UncheckedIOException.class,
59+
MKDIRS_NOT_FAILED_OVER_FILE,
60+
"Dir creation should not have failed. "
61+
+ "Creation performance mode is expected "
62+
+ "to create dir without checking file "
63+
+ "status of parent dir.",
64+
this::callTestMkdirOverParentFile);
65+
}
66+
67+
private void callTestMkdirOverParentFile() {
5468
try {
5569
super.testMkdirOverParentFile();
56-
throw new RuntimeException(
57-
"Dir creation should not have failed. "
58-
+ "Creation performance mode is expected "
59-
+ "to create dir without checking file "
60-
+ "status of parent dir.");
61-
} catch (AssertionError e) {
62-
Assertions
63-
.assertThat(e)
64-
.describedAs("assertion error from testMkdirOverParentFile")
65-
.hasMessageStartingWith(MKDIRS_NOT_FAILED_OVER_FILE);
70+
} catch (Throwable e) {
71+
throw new UncheckedIOException(new IOException(e));
6672
}
6773
}
6874

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/fileContext/ITestS3AFileContextCreateMkdirCreatePerf.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import static org.apache.hadoop.fs.s3a.Constants.FS_S3A_CREATE_PERFORMANCE;
2727
import static org.apache.hadoop.fs.s3a.S3ATestUtils.removeBaseAndBucketOverrides;
28+
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
2829

2930
/**
3031
* Extends FileContextCreateMkdirBaseTest for a S3a FileContext with
@@ -53,20 +54,15 @@ public void tearDown() throws Exception {
5354
}
5455

5556
@Test
56-
public void testMkdirRecursiveWithExistingFile() throws IOException {
57-
try {
58-
super.testMkdirRecursiveWithExistingFile();
59-
throw new RuntimeException(
60-
"Dir creation should not have failed. "
61-
+ "Creation performance mode is expected "
62-
+ "to create dir without checking file "
63-
+ "status of parent dir.");
64-
} catch (AssertionError e) {
65-
Assertions
66-
.assertThat(e)
67-
.describedAs("assertion error from testMkdirRecursiveWithExistingFile")
68-
.hasMessageContaining(MKDIR_FILE_PRESENT_ERROR);
69-
}
57+
public void testMkdirRecursiveWithExistingFile() throws Exception {
58+
intercept(
59+
AssertionError.class,
60+
MKDIR_FILE_PRESENT_ERROR,
61+
"Dir creation should not have failed. "
62+
+ "Creation performance mode is expected "
63+
+ "to create dir without checking file "
64+
+ "status of parent dir.",
65+
super::testMkdirRecursiveWithExistingFile);
7066
}
7167

7268
}

0 commit comments

Comments
 (0)