This is an automated email from the ASF dual-hosted git repository.
gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 0ea76937e1e Quidem: Improved handling for subdirectories in
quidem.filter. (#18091)
0ea76937e1e is described below
commit 0ea76937e1e3fbf7ded102b4ec6270a83ebe6d45
Author: Gian Merlino <[email protected]>
AuthorDate: Fri Jun 6 15:59:19 2025 -0700
Quidem: Improved handling for subdirectories in quidem.filter. (#18091)
Reworks the handling of path traversal to apply filter patterns to
the entire relativized path, not just the filename.
This helps with nested test files like
`qaWin/basics_window_funcs.01.all.iq`.
Previously, `-Dquidem.filter=qaWin/basics_window*` would not match
that file, but `-Dquidem.filter=basics_window*` would. Now, the prior
matches and the former does not. This is in line with the behavior of
star (*) wildcards in shells, where they apply to individual path parts.
---
.../apache/druid/quidem/DruidQuidemTestBase.java | 58 ++++++++++++----------
1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/sql/src/test/java/org/apache/druid/quidem/DruidQuidemTestBase.java
b/sql/src/test/java/org/apache/druid/quidem/DruidQuidemTestBase.java
index 0cf15179920..6df17ce0c97 100644
--- a/sql/src/test/java/org/apache/druid/quidem/DruidQuidemTestBase.java
+++ b/sql/src/test/java/org/apache/druid/quidem/DruidQuidemTestBase.java
@@ -29,10 +29,6 @@ import net.hydromatic.quidem.Quidem.ConfigBuilder;
import org.apache.calcite.test.DiffTestCase;
import org.apache.calcite.util.Closer;
import org.apache.calcite.util.Util;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.OrFileFilter;
-import org.apache.commons.io.filefilter.TrueFileFilter;
-import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.druid.concurrent.Threads;
import org.apache.druid.error.DruidException;
import org.apache.druid.java.util.common.FileUtils;
@@ -48,8 +44,8 @@ import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
+import javax.annotation.Nullable;
import java.io.File;
-import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
@@ -57,11 +53,14 @@ import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.fail;
@@ -101,7 +100,8 @@ public abstract class DruidQuidemTestBase
private static final String PROPERTY_FILTER = "quidem.filter";
- private final FileFilter filter;
+ private final String filterStr;
+ private final List<Pattern> filterPatterns;
private DruidQuidemRunner druidQuidemRunner;
@@ -112,25 +112,29 @@ public abstract class DruidQuidemTestBase
public DruidQuidemTestBase(DruidQuidemRunner druidQuidemRunner)
{
- String filterStr = System.getProperty(PROPERTY_FILTER, null);
- filter = buildFileFilter(filterStr);
+ this.filterStr = System.getProperty(PROPERTY_FILTER, null);
+ this.filterPatterns = buildFilterPatterns(filterStr);
this.druidQuidemRunner = druidQuidemRunner;
}
- private IOFileFilter buildFileFilter(String filterStr)
+ private List<Pattern> buildFilterPatterns(@Nullable String filterStr)
{
if (null == filterStr) {
- return TrueFileFilter.INSTANCE;
+ return Collections.emptyList();
}
- List<IOFileFilter> fileFilters = new ArrayList<>();
- for (String filter : filterStr.split(",")) {
- if (!filter.endsWith("*") && !filter.endsWith(IQ_SUFFIX)) {
- filter = filter + IQ_SUFFIX;
+ final List<Pattern> filterPatterns = new ArrayList<>();
+ for (String filterGlob : filterStr.split(",")) {
+ if (!filterGlob.endsWith("*") && !filterGlob.endsWith(IQ_SUFFIX)) {
+ filterGlob = filterStr + IQ_SUFFIX;
}
- fileFilters.add(new WildcardFileFilter(filter));
+ filterPatterns.add(
+ Pattern.compile(
+ Arrays.stream(filterGlob.split("\\*", -1))
+ .map(Pattern::quote)
+ .collect(Collectors.joining("[^/]*"))));
}
- return new OrFileFilter(fileFilters);
+ return filterPatterns;
}
protected static class QuidemTestCaseConfiguration
@@ -221,7 +225,7 @@ public abstract class DruidQuidemTestBase
if (!commandLimitIgnoredFiles.contains(inFile.getName()) && nCommands >
80) {
throw DruidException.defensive(
"There are too many commands [%s] in file [%s] which would make
working with the test harder. "
- + "Please reduce the number of queries/commands/etc",
+ + "Please reduce the number of queries/commands/etc",
nCommands,
inFile
);
@@ -292,10 +296,10 @@ public abstract class DruidQuidemTestBase
connectionFactory.onSet("componentSupplier", componentSupplier);
}
ConfigBuilder configBuilder = Quidem.configBuilder()
- .withConnectionFactory(connectionFactory)
- .withPropertyHandler(connectionFactory)
- .withEnv(connectionFactory::envLookup)
- .withCommandHandler(commandHandler);
+
.withConnectionFactory(connectionFactory)
+
.withPropertyHandler(connectionFactory)
+
.withEnv(connectionFactory::envLookup)
+
.withCommandHandler(commandHandler);
Config config = configBuilder
.withReader(reader)
@@ -357,27 +361,29 @@ public abstract class DruidQuidemTestBase
}
for (File f : Files.fileTraverser().breadthFirst(testRoot)) {
- if (isTestIncluded(f)) {
+ if (isTestIncluded(testRoot, f)) {
Path relativePath = testRoot.toPath().relativize(f.toPath());
ret.add(relativePath.toString());
}
}
if (ret.isEmpty()) {
throw new IAE(
- "There are no test cases in directory [%s] or there are no matches
to filter [%s]",
+ "There are no test cases in directory[%s] or there are no matches to
filter[%s]",
testRoot,
- filter
+ filterStr
);
}
Collections.sort(ret);
return ret;
}
- private boolean isTestIncluded(File f)
+ private boolean isTestIncluded(File testRoot, File f)
{
+ String relativePath = testRoot.toPath().relativize(f.toPath()).toString();
return !f.isDirectory()
&& f.getName().endsWith(IQ_SUFFIX)
- && filter.accept(f);
+ && (filterPatterns.isEmpty() || filterPatterns.stream()
+ .anyMatch(pattern ->
pattern.matcher(relativePath).matches()));
}
protected abstract File getTestRoot();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]