HADOOP-14946 S3Guard testPruneCommandCLI can fail. Contributed by Gabor Bota.
This commit is contained in:
parent
201440b987
commit
30284d020d
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.hadoop.util.StopWatch;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -61,6 +62,8 @@ public abstract class AbstractS3GuardToolTestBase extends AbstractS3ATestBase {
|
||||||
protected static final String S3A_THIS_BUCKET_DOES_NOT_EXIST
|
protected static final String S3A_THIS_BUCKET_DOES_NOT_EXIST
|
||||||
= "s3a://this-bucket-does-not-exist-00000000000";
|
= "s3a://this-bucket-does-not-exist-00000000000";
|
||||||
|
|
||||||
|
private static final int PRUNE_MAX_AGE_SECS = 2;
|
||||||
|
|
||||||
private MetadataStore ms;
|
private MetadataStore ms;
|
||||||
|
|
||||||
protected static void expectResult(int expected,
|
protected static void expectResult(int expected,
|
||||||
|
@ -186,24 +189,57 @@ public abstract class AbstractS3GuardToolTestBase extends AbstractS3ATestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to test prune() with sleep() without having flaky tests
|
||||||
|
* when things run slowly. Test is basically:
|
||||||
|
* 1. Set max path age to X seconds
|
||||||
|
* 2. Create some files (which writes entries to MetadataStore)
|
||||||
|
* 3. Sleep X+2 seconds (all files from above are now "stale")
|
||||||
|
* 4. Create some other files (these are "fresh").
|
||||||
|
* 5. Run prune on MetadataStore.
|
||||||
|
* 6. Assert that only files that were created before the sleep() were pruned.
|
||||||
|
*
|
||||||
|
* Problem is: #6 can fail if X seconds elapse between steps 4 and 5, since
|
||||||
|
* the newer files also become stale and get pruned. This is easy to
|
||||||
|
* reproduce by running all integration tests in parallel with a ton of
|
||||||
|
* threads, or anything else that slows down execution a lot.
|
||||||
|
*
|
||||||
|
* Solution: Keep track of time elapsed between #4 and #5, and if it
|
||||||
|
* exceeds X, just print a warn() message instead of failing.
|
||||||
|
*
|
||||||
|
* @param cmdConf configuration for command
|
||||||
|
* @param parent path
|
||||||
|
* @param args command args
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
private void testPruneCommand(Configuration cmdConf, Path parent,
|
private void testPruneCommand(Configuration cmdConf, Path parent,
|
||||||
String...args) throws Exception {
|
String...args) throws Exception {
|
||||||
Path keepParent = path("prune-cli-keep");
|
Path keepParent = path("prune-cli-keep");
|
||||||
|
StopWatch timer = new StopWatch();
|
||||||
try {
|
try {
|
||||||
getFileSystem().mkdirs(parent);
|
|
||||||
getFileSystem().mkdirs(keepParent);
|
|
||||||
|
|
||||||
S3GuardTool.Prune cmd = new S3GuardTool.Prune(cmdConf);
|
S3GuardTool.Prune cmd = new S3GuardTool.Prune(cmdConf);
|
||||||
cmd.setMetadataStore(ms);
|
cmd.setMetadataStore(ms);
|
||||||
|
|
||||||
|
getFileSystem().mkdirs(parent);
|
||||||
|
getFileSystem().mkdirs(keepParent);
|
||||||
createFile(new Path(parent, "stale"), true, true);
|
createFile(new Path(parent, "stale"), true, true);
|
||||||
createFile(new Path(keepParent, "stale-to-keep"), true, true);
|
createFile(new Path(keepParent, "stale-to-keep"), true, true);
|
||||||
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
|
|
||||||
|
Thread.sleep(TimeUnit.SECONDS.toMillis(PRUNE_MAX_AGE_SECS + 2));
|
||||||
|
|
||||||
|
timer.start();
|
||||||
createFile(new Path(parent, "fresh"), true, true);
|
createFile(new Path(parent, "fresh"), true, true);
|
||||||
|
|
||||||
assertMetastoreListingCount(parent, "Children count before pruning", 2);
|
assertMetastoreListingCount(parent, "Children count before pruning", 2);
|
||||||
exec(cmd, args);
|
exec(cmd, args);
|
||||||
assertMetastoreListingCount(parent, "Pruned children count", 1);
|
long msecElapsed = timer.now(TimeUnit.MILLISECONDS);
|
||||||
|
if (msecElapsed >= PRUNE_MAX_AGE_SECS * 1000) {
|
||||||
|
LOG.warn("Skipping an assertion: Test running too slowly ({} msec)",
|
||||||
|
msecElapsed);
|
||||||
|
} else {
|
||||||
|
assertMetastoreListingCount(parent, "Pruned children count remaining",
|
||||||
|
1);
|
||||||
|
}
|
||||||
assertMetastoreListingCount(keepParent,
|
assertMetastoreListingCount(keepParent,
|
||||||
"This child should have been kept (prefix restriction).", 1);
|
"This child should have been kept (prefix restriction).", 1);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -224,13 +260,14 @@ public abstract class AbstractS3GuardToolTestBase extends AbstractS3ATestBase {
|
||||||
public void testPruneCommandCLI() throws Exception {
|
public void testPruneCommandCLI() throws Exception {
|
||||||
Path testPath = path("testPruneCommandCLI");
|
Path testPath = path("testPruneCommandCLI");
|
||||||
testPruneCommand(getFileSystem().getConf(), testPath,
|
testPruneCommand(getFileSystem().getConf(), testPath,
|
||||||
"prune", "-seconds", "1", testPath.toString());
|
"prune", "-seconds", String.valueOf(PRUNE_MAX_AGE_SECS),
|
||||||
|
testPath.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPruneCommandConf() throws Exception {
|
public void testPruneCommandConf() throws Exception {
|
||||||
getConfiguration().setLong(Constants.S3GUARD_CLI_PRUNE_AGE,
|
getConfiguration().setLong(Constants.S3GUARD_CLI_PRUNE_AGE,
|
||||||
TimeUnit.SECONDS.toMillis(1));
|
TimeUnit.SECONDS.toMillis(PRUNE_MAX_AGE_SECS));
|
||||||
Path testPath = path("testPruneCommandConf");
|
Path testPath = path("testPruneCommandConf");
|
||||||
testPruneCommand(getConfiguration(), testPath,
|
testPruneCommand(getConfiguration(), testPath,
|
||||||
"prune", testPath.toString());
|
"prune", testPath.toString());
|
||||||
|
@ -286,7 +323,6 @@ public abstract class AbstractS3GuardToolTestBase extends AbstractS3ATestBase {
|
||||||
* Execute a command, returning the buffer if the command actually completes.
|
* Execute a command, returning the buffer if the command actually completes.
|
||||||
* If an exception is raised the output is logged instead.
|
* If an exception is raised the output is logged instead.
|
||||||
* @param cmd command
|
* @param cmd command
|
||||||
* @param buf buffer to use for tool output (not SLF4J output)
|
|
||||||
* @param args argument list
|
* @param args argument list
|
||||||
* @throws Exception on any failure
|
* @throws Exception on any failure
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue