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]

Reply via email to