This is an automated email from the ASF dual-hosted git repository.

rohangarg 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 d6a12c4389b Add ability to enable ResultCache in tests (#15465)
d6a12c4389b is described below

commit d6a12c4389b66189ecc3ccd9eedb82c10483df92
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Mon Jan 22 15:02:59 2024 +0100

    Add ability to enable ResultCache in tests (#15465)
---
 .../apache/druid/benchmark/query/SqlBenchmark.java |   2 +-
 .../benchmark/query/SqlExpressionBenchmark.java    |   2 +-
 .../benchmark/query/SqlNestedDataBenchmark.java    |   4 +-
 .../benchmark/query/SqlVsNativeBenchmark.java      |   2 +-
 .../CompressedBigDecimalSqlAggregatorTestBase.java |   2 +-
 .../sql/TDigestSketchSqlAggregatorTest.java        |   2 +-
 .../hll/sql/HllSketchSqlAggregatorTest.java        |  38 ++++++-
 .../sql/DoublesSketchSqlAggregatorTest.java        |   2 +-
 .../theta/sql/ThetaSketchSqlAggregatorTest.java    |   2 +-
 .../sql/ArrayOfDoublesSketchSqlAggregatorTest.java |   2 +-
 .../bloom/sql/BloomFilterSqlAggregatorTest.java    |   2 +-
 ...dBucketsHistogramQuantileSqlAggregatorTest.java |   2 +-
 .../histogram/sql/QuantileSqlAggregatorTest.java   |   2 +-
 .../druid/msq/test/CalciteArraysQueryMSQTest.java  |  21 +---
 .../msq/test/CalciteSelectJoinQueryMSQTest.java    |  21 +---
 .../druid/msq/test/CalciteSelectQueryMSQTest.java  |  18 +--
 .../druid/msq/test/CalciteUnionQueryMSQTest.java   |  20 +---
 .../variance/sql/VarianceSqlAggregatorTest.java    |   2 +-
 .../druid/client/CachingClusteredClient.java       |   6 +-
 .../apache/druid/guice/DruidInjectorBuilder.java   |   4 +-
 .../initialization/ServerInjectorBuilder.java      |   2 +-
 .../initialization/ServiceInjectorBuilder.java     |   7 --
 .../druid/server/ClientQuerySegmentWalkerTest.java |   6 +-
 .../java/org/apache/druid/server/EtagProvider.java |  68 ++++++++++++
 .../org/apache/druid/server/QueryStackTests.java   |  76 +++++++------
 .../server/SpecificSegmentsQuerySegmentWalker.java |  62 +++++++----
 .../server/TestClusterQuerySegmentWalker.java      |  12 +-
 .../sql/calcite/util/CacheTestHelperModule.java    | 121 +++++++++++++++++++++
 .../druid/sql/calcite/BaseCalciteQueryTest.java    |  21 ++--
 .../druid/sql/calcite/CalciteArraysQueryTest.java  |   3 +-
 .../sql/calcite/CalciteNestedDataQueryTest.java    |   2 +-
 .../druid/sql/calcite/SqlTestFrameworkConfig.java  |  51 +++++++--
 .../calcite/SqlVectorizedExpressionSanityTest.java |   2 +-
 .../schema/BrokerSegmentMetadataCacheCommon.java   |   2 +-
 .../BrokerSegmentMetadataCacheConcurrencyTest.java |   2 +-
 .../calcite/schema/DruidSchemaNoDataInitTest.java  |   2 +-
 .../druid/sql/calcite/schema/SystemSchemaTest.java |   2 +-
 .../calcite/util/CalciteTestInjectorBuilder.java   |  63 -----------
 .../druid/sql/calcite/util/CalciteTests.java       |   9 +-
 .../druid/sql/calcite/util/SqlTestFramework.java   |  20 +++-
 .../druid/sql/calcite/util/TestDataBuilder.java    |   3 +-
 41 files changed, 445 insertions(+), 247 deletions(-)

diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
index fbdc6bff7fa..489a4c6e58e 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlBenchmark.java
@@ -522,7 +522,7 @@ public class SqlBenchmark
   )
   {
     final QueryRunnerFactoryConglomerate conglomerate = 
QueryStackTests.createQueryRunnerFactoryConglomerate(closer);
-    final SpecificSegmentsQuerySegmentWalker walker = new 
SpecificSegmentsQuerySegmentWalker(conglomerate);
+    final SpecificSegmentsQuerySegmentWalker walker = 
SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate);
     final PlannerConfig plannerConfig = new PlannerConfig();
 
     for (final Map.Entry<DataSegment, QueryableIndex> segmentEntry : 
segmentMap.entrySet()) {
diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
index d24ce997b9e..f21f6de6a69 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java
@@ -324,7 +324,7 @@ public class SqlExpressionBenchmark
         PROCESSING_CONFIG
     );
 
-    final SpecificSegmentsQuerySegmentWalker walker = new 
SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    final SpecificSegmentsQuerySegmentWalker walker = 
SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate).add(
         dataSegment,
         index
     );
diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlNestedDataBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlNestedDataBenchmark.java
index 4c49f918094..3922ee0e377 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlNestedDataBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlNestedDataBenchmark.java
@@ -112,7 +112,7 @@ public class SqlNestedDataBenchmark
     {
       return 1;
     }
-    
+
     @Override
     public String getFormatString()
     {
@@ -326,7 +326,7 @@ public class SqlNestedDataBenchmark
         PROCESSING_CONFIG
     );
 
-    final SpecificSegmentsQuerySegmentWalker walker = new 
SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    final SpecificSegmentsQuerySegmentWalker walker = 
SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate).add(
         dataSegment,
         index
     );
diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
index e4f8b5570bf..bffc03469e8 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlVsNativeBenchmark.java
@@ -117,7 +117,7 @@ public class SqlVsNativeBenchmark
     final QueryRunnerFactoryConglomerate conglomerate = 
QueryStackTests.createQueryRunnerFactoryConglomerate(closer);
     final PlannerConfig plannerConfig = new PlannerConfig();
 
-    this.walker = closer.register(new 
SpecificSegmentsQuerySegmentWalker(conglomerate).add(dataSegment, index));
+    this.walker = 
closer.register(SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate).add(dataSegment,
 index));
     final DruidSchemaCatalog rootSchema =
         CalciteTests.createMockRootSchema(conglomerate, walker, plannerConfig, 
AuthTestUtils.TEST_AUTHORIZER_MAPPER);
     engine = CalciteTests.createMockSqlEngine(walker, conglomerate);
diff --git 
a/extensions-contrib/compressed-bigdecimal/src/test/java/org/apache/druid/compressedbigdecimal/CompressedBigDecimalSqlAggregatorTestBase.java
 
b/extensions-contrib/compressed-bigdecimal/src/test/java/org/apache/druid/compressedbigdecimal/CompressedBigDecimalSqlAggregatorTestBase.java
index cda55e314e0..2acc0d88e8d 100644
--- 
a/extensions-contrib/compressed-bigdecimal/src/test/java/org/apache/druid/compressedbigdecimal/CompressedBigDecimalSqlAggregatorTestBase.java
+++ 
b/extensions-contrib/compressed-bigdecimal/src/test/java/org/apache/druid/compressedbigdecimal/CompressedBigDecimalSqlAggregatorTestBase.java
@@ -98,7 +98,7 @@ public abstract class 
CompressedBigDecimalSqlAggregatorTestBase extends BaseCalc
                     .rows(ROWS1)
                     .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-contrib/tdigestsketch/src/test/java/org/apache/druid/query/aggregation/tdigestsketch/sql/TDigestSketchSqlAggregatorTest.java
 
b/extensions-contrib/tdigestsketch/src/test/java/org/apache/druid/query/aggregation/tdigestsketch/sql/TDigestSketchSqlAggregatorTest.java
index b55cce2fafc..de515814d23 100644
--- 
a/extensions-contrib/tdigestsketch/src/test/java/org/apache/druid/query/aggregation/tdigestsketch/sql/TDigestSketchSqlAggregatorTest.java
+++ 
b/extensions-contrib/tdigestsketch/src/test/java/org/apache/druid/query/aggregation/tdigestsketch/sql/TDigestSketchSqlAggregatorTest.java
@@ -97,7 +97,7 @@ public class TDigestSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
                     .rows(TestDataBuilder.ROWS1)
                     .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
index 4d5e2ce354a..22204a5f9a4 100644
--- 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
+++ 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/sql/HllSketchSqlAggregatorTest.java
@@ -74,8 +74,10 @@ import 
org.apache.druid.segment.virtual.ExpressionVirtualColumn;
 import 
org.apache.druid.segment.writeout.OffHeapMemorySegmentWriteOutMediumFactory;
 import org.apache.druid.server.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.sql.calcite.BaseCalciteQueryTest;
+import org.apache.druid.sql.calcite.SqlTestFrameworkConfig;
 import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
+import org.apache.druid.sql.calcite.util.CacheTestHelperModule.ResultCacheMode;
 import org.apache.druid.sql.calcite.util.CalciteTests;
 import org.apache.druid.sql.calcite.util.TestDataBuilder;
 import org.apache.druid.sql.guice.SqlModule;
@@ -232,6 +234,7 @@ public class HllSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
       )
   );
 
+
   @Override
   public void gatherProperties(Properties properties)
   {
@@ -279,7 +282,7 @@ public class HllSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
         .rows(TestDataBuilder.ROWS1_WITH_NUMERIC_DIMS)
         .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
@@ -1181,6 +1184,39 @@ public class HllSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
         .run();
   }
 
+  @SqlTestFrameworkConfig(resultCache = ResultCacheMode.ENABLED)
+  @Test
+  public void testResultCacheWithWindowing()
+  {
+    cannotVectorize();
+    skipVectorize();
+    for (int i = 0; i < 2; i++) {
+      testBuilder()
+          .queryContext(ImmutableMap.of(PlannerContext.CTX_ENABLE_WINDOW_FNS, 
true))
+          .sql(
+              "SELECT "
+                  + " TIME_FLOOR(__time, 'P1D') as dayLvl,\n"
+                  + "  dim1,\n"
+                  + "  HLL_SKETCH_ESTIMATE(DS_HLL(hllsketch_dim1,18,'HLL_4'), 
true),\n"
+                  + "  
HLL_SKETCH_ESTIMATE(DS_HLL(DS_HLL(hllsketch_dim1,18,'HLL_4'),18,'HLL_4') OVER 
(PARTITION BY dim1), true),"
+                  + "  1\n"
+                  + "FROM\n"
+                  + "  (select * from  druid.foo ) ttt\n"
+                  + "  WHERE  __time >= '1903-08-02' AND __time <= 
'2033-08-07'\n"
+                  + "  and dim1 not like '%ikipedia' and l1 > -4\n"
+                  + "  group by 1,2"
+          )
+          .expectedResults(
+              ImmutableList.of(
+                  new Object[] {946684800000L, "", 0.0D, 0.0D, 1},
+                  new Object[] {946771200000L, "10.1", 1.0D, 1.0D, 1},
+                  new Object[] {946857600000L, "2", 1.0D, 1.0D, 1}
+              )
+          )
+          .run();
+    }
+  }
+
   /**
    * This is an extremely subtle test, so we explain with a comment.  The `m1` 
column in the input data looks like
    * `["1.0", "2.0", "3.0", "4.0", "5.0", "6.0"]` while the `d1` column looks 
like
diff --git 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
index bd7910408f2..c71890c036c 100644
--- 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
+++ 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/sql/DoublesSketchSqlAggregatorTest.java
@@ -109,7 +109,7 @@ public class DoublesSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
                     .rows(TestDataBuilder.ROWS1)
                     .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchSqlAggregatorTest.java
 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchSqlAggregatorTest.java
index 5836c23e4d3..2650e15a04b 100644
--- 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchSqlAggregatorTest.java
+++ 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaSketchSqlAggregatorTest.java
@@ -138,7 +138,7 @@ public class ThetaSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
                                              .rows(TestDataBuilder.ROWS1)
                                              .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(DATA_SOURCE)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/tuple/sql/ArrayOfDoublesSketchSqlAggregatorTest.java
 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/tuple/sql/ArrayOfDoublesSketchSqlAggregatorTest.java
index 7fab051f47c..134c2c76e4f 100644
--- 
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/tuple/sql/ArrayOfDoublesSketchSqlAggregatorTest.java
+++ 
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/tuple/sql/ArrayOfDoublesSketchSqlAggregatorTest.java
@@ -139,7 +139,7 @@ public class ArrayOfDoublesSketchSqlAggregatorTest extends 
BaseCalciteQueryTest
                                              .rows(ROWS)
                                              .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(DATA_SOURCE)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/druid-bloom-filter/src/test/java/org/apache/druid/query/aggregation/bloom/sql/BloomFilterSqlAggregatorTest.java
 
b/extensions-core/druid-bloom-filter/src/test/java/org/apache/druid/query/aggregation/bloom/sql/BloomFilterSqlAggregatorTest.java
index 699acac8f9a..8dcab824abf 100644
--- 
a/extensions-core/druid-bloom-filter/src/test/java/org/apache/druid/query/aggregation/bloom/sql/BloomFilterSqlAggregatorTest.java
+++ 
b/extensions-core/druid-bloom-filter/src/test/java/org/apache/druid/query/aggregation/bloom/sql/BloomFilterSqlAggregatorTest.java
@@ -96,7 +96,7 @@ public class BloomFilterSqlAggregatorTest extends 
BaseCalciteQueryTest
                     .rows(TestDataBuilder.ROWS1_WITH_NUMERIC_DIMS)
                     .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(DATA_SOURCE)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/FixedBucketsHistogramQuantileSqlAggregatorTest.java
 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/FixedBucketsHistogramQuantileSqlAggregatorTest.java
index 67db321a358..75a29ab4f2f 100644
--- 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/FixedBucketsHistogramQuantileSqlAggregatorTest.java
+++ 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/FixedBucketsHistogramQuantileSqlAggregatorTest.java
@@ -103,7 +103,7 @@ public class FixedBucketsHistogramQuantileSqlAggregatorTest 
extends BaseCalciteQ
                                              .rows(TestDataBuilder.ROWS1)
                                              .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java
 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java
index 13902a2cd83..3ee18f886f0 100644
--- 
a/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java
+++ 
b/extensions-core/histogram/src/test/java/org/apache/druid/query/aggregation/histogram/sql/QuantileSqlAggregatorTest.java
@@ -102,7 +102,7 @@ public class QuantileSqlAggregatorTest extends 
BaseCalciteQueryTest
                                              .rows(TestDataBuilder.ROWS1)
                                              .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE1)
                    .interval(index.getDataInterval())
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteArraysQueryMSQTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteArraysQueryMSQTest.java
index 92f8d6f4e79..619cd6d2d1c 100644
--- 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteArraysQueryMSQTest.java
+++ 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteArraysQueryMSQTest.java
@@ -31,36 +31,21 @@ import org.apache.druid.server.QueryLifecycleFactory;
 import org.apache.druid.sql.calcite.CalciteArraysQueryTest;
 import org.apache.druid.sql.calcite.QueryTestBuilder;
 import org.apache.druid.sql.calcite.run.SqlEngine;
-import org.junit.After;
-import org.junit.Before;
 
 /**
  * Runs {@link CalciteArraysQueryTest} but with MSQ engine
  */
 public class CalciteArraysQueryMSQTest extends CalciteArraysQueryTest
 {
-  private TestGroupByBuffers groupByBuffers;
-
-  @Before
-  public void setup2()
-  {
-    groupByBuffers = TestGroupByBuffers.createDefault();
-  }
-
-  @After
-  public void teardown2()
-  {
-    groupByBuffers.close();
-  }
-
   @Override
   public void configureGuice(DruidInjectorBuilder builder)
   {
     super.configureGuice(builder);
-    builder.addModules(CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
groupByBuffers).toArray(new Module[0]));
+    builder.addModules(
+        CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
TestGroupByBuffers.createDefault()).toArray(new Module[0])
+    );
   }
 
-
   @Override
   public SqlEngine createEngine(
       QueryLifecycleFactory qlf,
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectJoinQueryMSQTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectJoinQueryMSQTest.java
index 644d0d05451..a357b5a48fe 100644
--- 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectJoinQueryMSQTest.java
+++ 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectJoinQueryMSQTest.java
@@ -36,8 +36,6 @@ import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.run.EngineFeature;
 import org.apache.druid.sql.calcite.run.QueryMaker;
 import org.apache.druid.sql.calcite.run.SqlEngine;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
 
@@ -45,7 +43,7 @@ import org.junit.runner.RunWith;
  * Runs {@link CalciteJoinQueryTest} but with MSQ engine.
  */
 @RunWith(Enclosed.class)
-public class CalciteSelectJoinQueryMSQTest
+public abstract class CalciteSelectJoinQueryMSQTest
 {
   /**
    * Run all tests with {@link JoinAlgorithm#BROADCAST}.
@@ -89,7 +87,6 @@ public class CalciteSelectJoinQueryMSQTest
   {
     private final JoinAlgorithm joinAlgorithm;
 
-    private TestGroupByBuffers groupByBuffers;
 
     protected Base(final JoinAlgorithm joinAlgorithm)
     {
@@ -97,23 +94,13 @@ public class CalciteSelectJoinQueryMSQTest
       this.joinAlgorithm = joinAlgorithm;
     }
 
-    @Before
-    public void setup2()
-    {
-      groupByBuffers = TestGroupByBuffers.createDefault();
-    }
-
-    @After
-    public void teardown2()
-    {
-      groupByBuffers.close();
-    }
-
     @Override
     public void configureGuice(DruidInjectorBuilder builder)
     {
       super.configureGuice(builder);
-      builder.addModules(CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
groupByBuffers).toArray(new Module[0]));
+      builder.addModules(
+          CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
TestGroupByBuffers.createDefault()).toArray(new Module[0])
+      );
     }
 
     @Override
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectQueryMSQTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectQueryMSQTest.java
index fccce2e8402..da98254e4de 100644
--- 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectQueryMSQTest.java
+++ 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteSelectQueryMSQTest.java
@@ -33,9 +33,7 @@ import org.apache.druid.server.QueryLifecycleFactory;
 import org.apache.druid.sql.calcite.CalciteQueryTest;
 import org.apache.druid.sql.calcite.QueryTestBuilder;
 import org.apache.druid.sql.calcite.run.SqlEngine;
-import org.junit.After;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -44,25 +42,11 @@ import org.junit.Test;
  */
 public class CalciteSelectQueryMSQTest extends CalciteQueryTest
 {
-  private TestGroupByBuffers groupByBuffers;
-
-  @Before
-  public void setup2()
-  {
-    groupByBuffers = TestGroupByBuffers.createDefault();
-  }
-
-  @After
-  public void teardown2()
-  {
-    groupByBuffers.close();
-  }
-
   @Override
   public void configureGuice(DruidInjectorBuilder builder)
   {
     super.configureGuice(builder);
-    builder.addModules(CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
groupByBuffers).toArray(new Module[0]));
+    builder.addModules(CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
TestGroupByBuffers.createDefault()).toArray(new Module[0]));
   }
 
 
diff --git 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteUnionQueryMSQTest.java
 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteUnionQueryMSQTest.java
index 01379e2a93f..acea7d675d4 100644
--- 
a/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteUnionQueryMSQTest.java
+++ 
b/extensions-core/multi-stage-query/src/test/java/org/apache/druid/msq/test/CalciteUnionQueryMSQTest.java
@@ -43,8 +43,6 @@ import org.apache.druid.sql.calcite.QueryTestBuilder;
 import org.apache.druid.sql.calcite.filtration.Filtration;
 import org.apache.druid.sql.calcite.run.SqlEngine;
 import org.apache.druid.sql.calcite.util.CalciteTests;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -53,25 +51,13 @@ import org.junit.Test;
  */
 public class CalciteUnionQueryMSQTest extends CalciteUnionQueryTest
 {
-  private TestGroupByBuffers groupByBuffers;
-
-  @Before
-  public void setup2()
-  {
-    groupByBuffers = TestGroupByBuffers.createDefault();
-  }
-
-  @After
-  public void teardown2()
-  {
-    groupByBuffers.close();
-  }
-
   @Override
   public void configureGuice(DruidInjectorBuilder builder)
   {
     super.configureGuice(builder);
-    builder.addModules(CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
groupByBuffers).toArray(new Module[0]));
+    builder.addModules(
+        CalciteMSQTestsHelper.fetchModules(temporaryFolder, 
TestGroupByBuffers.createDefault()).toArray(new Module[0])
+    );
   }
 
 
diff --git 
a/extensions-core/stats/src/test/java/org/apache/druid/query/aggregation/variance/sql/VarianceSqlAggregatorTest.java
 
b/extensions-core/stats/src/test/java/org/apache/druid/query/aggregation/variance/sql/VarianceSqlAggregatorTest.java
index 0c57b2ad061..879d6e093a7 100644
--- 
a/extensions-core/stats/src/test/java/org/apache/druid/query/aggregation/variance/sql/VarianceSqlAggregatorTest.java
+++ 
b/extensions-core/stats/src/test/java/org/apache/druid/query/aggregation/variance/sql/VarianceSqlAggregatorTest.java
@@ -112,7 +112,7 @@ public class VarianceSqlAggregatorTest extends 
BaseCalciteQueryTest
                     .rows(TestDataBuilder.ROWS1_WITH_NUMERIC_DIMS)
                     .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(conglomerate).add(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(injector, 
conglomerate).add(
         DataSegment.builder()
                    .dataSource(CalciteTests.DATASOURCE3)
                    .interval(index.getDataInterval())
diff --git 
a/server/src/main/java/org/apache/druid/client/CachingClusteredClient.java 
b/server/src/main/java/org/apache/druid/client/CachingClusteredClient.java
index 76fe97fa185..7bcb4c2ce03 100644
--- a/server/src/main/java/org/apache/druid/client/CachingClusteredClient.java
+++ b/server/src/main/java/org/apache/druid/client/CachingClusteredClient.java
@@ -347,9 +347,9 @@ public class CachingClusteredClient implements 
QuerySegmentWalker
       final Set<SegmentServerSelector> segmentServers = 
computeSegmentsToQuery(timeline, specificSegments);
       @Nullable
       final byte[] queryCacheKey = 
cacheKeyManager.computeSegmentLevelQueryCacheKey();
-      if (query.getContext().get(QueryResource.HEADER_IF_NONE_MATCH) != null) {
-        @Nullable
-        final String prevEtag = (String) 
query.getContext().get(QueryResource.HEADER_IF_NONE_MATCH);
+      @Nullable
+      final String prevEtag = (String) 
query.getContext().get(QueryResource.HEADER_IF_NONE_MATCH);
+      if (prevEtag != null) {
         @Nullable
         final String currentEtag = 
cacheKeyManager.computeResultLevelCachingEtag(segmentServers, queryCacheKey);
         if (null != currentEtag) {
diff --git 
a/server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java 
b/server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java
index 5ddce3729c6..964acc31641 100644
--- a/server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java
+++ b/server/src/main/java/org/apache/druid/guice/DruidInjectorBuilder.java
@@ -117,7 +117,7 @@ public class DruidInjectorBuilder
     return this;
   }
 
-  public DruidInjectorBuilder addAll(List<? extends Object> inputs)
+  public DruidInjectorBuilder addAll(Iterable<? extends Object> inputs)
   {
     for (Object o : inputs) {
       addInput(o);
@@ -159,7 +159,7 @@ public class DruidInjectorBuilder
 
   public DruidInjectorBuilder addClass(Class<?> input)
   {
-    if (!acceptModule((Class<?>) input)) {
+    if (!acceptModule(input)) {
       return this;
     }
     if (DruidModule.class.isAssignableFrom(input)) {
diff --git 
a/server/src/main/java/org/apache/druid/initialization/ServerInjectorBuilder.java
 
b/server/src/main/java/org/apache/druid/initialization/ServerInjectorBuilder.java
index f9b421ec5e8..fd441b958bf 100644
--- 
a/server/src/main/java/org/apache/druid/initialization/ServerInjectorBuilder.java
+++ 
b/server/src/main/java/org/apache/druid/initialization/ServerInjectorBuilder.java
@@ -106,7 +106,7 @@ public class ServerInjectorBuilder
     CoreInjectorBuilder coreBuilder = new CoreInjectorBuilder(childInjector, 
nodeRoles).forServer();
 
     // Override with the per-service modules.
-    ServiceInjectorBuilder serviceBuilder = new 
ServiceInjectorBuilder(coreBuilder).addAll(
+    ServiceInjectorBuilder serviceBuilder = (ServiceInjectorBuilder) new 
ServiceInjectorBuilder(coreBuilder).addAll(
         Iterables.concat(
             // bind nodeRoles for the new injector as well
             ImmutableList.of(registerNodeRoleModule),
diff --git 
a/server/src/main/java/org/apache/druid/initialization/ServiceInjectorBuilder.java
 
b/server/src/main/java/org/apache/druid/initialization/ServiceInjectorBuilder.java
index 0b21f1031b4..cf9f2ea4dcd 100644
--- 
a/server/src/main/java/org/apache/druid/initialization/ServiceInjectorBuilder.java
+++ 
b/server/src/main/java/org/apache/druid/initialization/ServiceInjectorBuilder.java
@@ -53,11 +53,4 @@ public class ServiceInjectorBuilder extends 
DruidInjectorBuilder
     return Guice.createInjector(merge());
   }
 
-  public ServiceInjectorBuilder addAll(Iterable<? extends Module> modules)
-  {
-    for (Module module : modules) {
-      add(module);
-    }
-    return this;
-  }
 }
diff --git 
a/server/src/test/java/org/apache/druid/server/ClientQuerySegmentWalkerTest.java
 
b/server/src/test/java/org/apache/druid/server/ClientQuerySegmentWalkerTest.java
index ce39f0efdcd..9295c79f1af 100644
--- 
a/server/src/test/java/org/apache/druid/server/ClientQuerySegmentWalkerTest.java
+++ 
b/server/src/test/java/org/apache/druid/server/ClientQuerySegmentWalkerTest.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.inject.Injector;
 import org.apache.druid.client.DirectDruidClient;
 import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.java.util.common.Intervals;
@@ -1480,7 +1481,9 @@ public class ClientQuerySegmentWalkerTest
       }
     }
 
+    Injector injector = QueryStackTests.injector();
     walker = QueryStackTests.createClientQuerySegmentWalker(
+        injector,
         new CapturingWalker(
             QueryStackTests.createClusterQuerySegmentWalker(
                 ImmutableMap.<String, VersionedIntervalTimeline<String, 
ReferenceCountingSegment>>builder()
@@ -1492,7 +1495,8 @@ public class ClientQuerySegmentWalkerTest
                     .put(ARRAY_UNKNOWN, makeTimeline(ARRAY_UNKNOWN, 
ARRAY_INLINE_UNKNOWN))
                     .build(),
                 conglomerate,
-                schedulerForTest
+                schedulerForTest,
+                injector
             ),
             ClusterOrLocal.CLUSTER
         ),
diff --git a/server/src/test/java/org/apache/druid/server/EtagProvider.java 
b/server/src/test/java/org/apache/druid/server/EtagProvider.java
new file mode 100644
index 00000000000..3d8e5b841de
--- /dev/null
+++ b/server/src/test/java/org/apache/druid/server/EtagProvider.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.server;
+
+import com.google.inject.Key;
+import org.apache.druid.error.DruidException;
+import org.apache.druid.query.Query;
+import org.apache.druid.query.TableDataSource;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+public interface EtagProvider
+{
+  Key<EtagProvider> KEY = Key.get(EtagProvider.class);
+
+  String getEtagFor(Query<?> query);
+
+  class EmptyEtagProvider implements EtagProvider
+  {
+    @Override
+    public String getEtagFor(Query<?> query)
+    {
+      return null;
+    }
+  }
+
+  class ProvideEtagBasedOnDatasource implements EtagProvider
+  {
+    @Override
+    public String getEtagFor(Query<?> query)
+    {
+      if (!query.getDataSource().isCacheable(true)) {
+        return null;
+      }
+      if (!(query.getDataSource() instanceof TableDataSource)) {
+        throw DruidException.defensive("only TableDataSource handled right 
now");
+      }
+      try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+        TableDataSource tableDataSource = (TableDataSource) 
query.getDataSource();
+        baos.write(query.getDataSource().getCacheKey());
+        baos.write(tableDataSource.getName().getBytes(StandardCharsets.UTF_8));
+        return "ETP-" + new String(baos.toByteArray(), StandardCharsets.UTF_8);
+      }
+      catch (IOException e) {
+        throw DruidException.defensive().build(e, "Unexpected IOException");
+      }
+    }
+  }
+}
diff --git a/server/src/test/java/org/apache/druid/server/QueryStackTests.java 
b/server/src/test/java/org/apache/druid/server/QueryStackTests.java
index 2301a9ace39..925996d661b 100644
--- a/server/src/test/java/org/apache/druid/server/QueryStackTests.java
+++ b/server/src/test/java/org/apache/druid/server/QueryStackTests.java
@@ -19,9 +19,17 @@
 
 package org.apache.druid.server;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.inject.Injector;
+import org.apache.druid.client.cache.Cache;
 import org.apache.druid.client.cache.CacheConfig;
+import org.apache.druid.guice.DruidInjectorBuilder;
+import org.apache.druid.guice.ExpressionModule;
+import org.apache.druid.guice.SegmentWranglerModule;
+import org.apache.druid.guice.StartupInjectorBuilder;
+import org.apache.druid.initialization.CoreInjectorBuilder;
 import org.apache.druid.java.util.common.io.Closer;
 import org.apache.druid.java.util.emitter.service.ServiceEmitter;
 import org.apache.druid.query.BrokerParallelMergeConfig;
@@ -41,6 +49,7 @@ import org.apache.druid.query.QueryToolChest;
 import org.apache.druid.query.QueryToolChestWarehouse;
 import org.apache.druid.query.RetryQueryRunnerConfig;
 import org.apache.druid.query.TestBufferPool;
+import org.apache.druid.query.expression.LookupEnabledTestExprMacroTable;
 import org.apache.druid.query.groupby.GroupByQuery;
 import org.apache.druid.query.groupby.GroupByQueryConfig;
 import org.apache.druid.query.groupby.GroupByQueryRunnerFactory;
@@ -70,7 +79,6 @@ import org.apache.druid.query.topn.TopNQueryQueryToolChest;
 import org.apache.druid.query.topn.TopNQueryRunnerFactory;
 import org.apache.druid.segment.ReferenceCountingSegment;
 import org.apache.druid.segment.SegmentWrangler;
-import org.apache.druid.segment.TestHelper;
 import org.apache.druid.segment.join.FrameBasedInlineJoinableFactory;
 import org.apache.druid.segment.join.InlineJoinableFactory;
 import org.apache.druid.segment.join.JoinableFactory;
@@ -82,11 +90,15 @@ import org.apache.druid.server.metrics.NoopServiceEmitter;
 import org.apache.druid.server.metrics.SubqueryCountStatsProvider;
 import org.apache.druid.server.scheduling.ManualQueryPrioritizationStrategy;
 import org.apache.druid.server.scheduling.NoQueryLaningStrategy;
+import org.apache.druid.sql.calcite.util.CacheTestHelperModule;
+import org.apache.druid.sql.calcite.util.CacheTestHelperModule.ResultCacheMode;
 import org.apache.druid.timeline.VersionedIntervalTimeline;
 import org.apache.druid.utils.JvmUtils;
 import org.junit.Assert;
 
 import javax.annotation.Nullable;
+
+import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Supplier;
@@ -114,6 +126,7 @@ public class QueryStackTests
   }
 
   public static ClientQuerySegmentWalker createClientQuerySegmentWalker(
+      final Injector injector,
       final QuerySegmentWalker clusterWalker,
       final QuerySegmentWalker localWalker,
       final QueryRunnerFactoryConglomerate conglomerate,
@@ -135,35 +148,10 @@ public class QueryStackTests
         },
         joinableFactory,
         new RetryQueryRunnerConfig(),
-        TestHelper.makeJsonMapper(),
+        injector.getInstance(ObjectMapper.class),
         serverConfig,
-        null /* Cache */,
-        new CacheConfig()
-        {
-          @Override
-          public boolean isPopulateCache()
-          {
-            return false;
-          }
-
-          @Override
-          public boolean isUseCache()
-          {
-            return false;
-          }
-
-          @Override
-          public boolean isPopulateResultLevelCache()
-          {
-            return false;
-          }
-
-          @Override
-          public boolean isUseResultLevelCache()
-          {
-            return false;
-          }
-        },
+        injector.getInstance(Cache.class),
+        injector.getInstance(CacheConfig.class),
         new SubqueryGuardrailHelper(null, 
JvmUtils.getRuntimeInfo().getMaxHeapSizeBytes(), 1),
         new SubqueryCountStatsProvider()
     );
@@ -172,10 +160,11 @@ public class QueryStackTests
   public static TestClusterQuerySegmentWalker createClusterQuerySegmentWalker(
       Map<String, VersionedIntervalTimeline<String, ReferenceCountingSegment>> 
timelines,
       QueryRunnerFactoryConglomerate conglomerate,
-      @Nullable QueryScheduler scheduler
+      @Nullable QueryScheduler scheduler,
+      Injector injector
   )
   {
-    return new TestClusterQuerySegmentWalker(timelines, conglomerate, 
scheduler);
+    return new TestClusterQuerySegmentWalker(timelines, conglomerate, 
scheduler, injector.getInstance(EtagProvider.KEY));
   }
 
   public static LocalQuerySegmentWalker createLocalQuerySegmentWalker(
@@ -385,4 +374,29 @@ public class QueryStackTests
 
     return new MapJoinableFactory(setBuilder.build(), mapBuilder.build());
   }
+
+  public static DruidInjectorBuilder injectorBuilder()
+  {
+    Injector startupInjector = new StartupInjectorBuilder()
+        .build();
+
+    DruidInjectorBuilder injectorBuilder = new 
CoreInjectorBuilder(startupInjector)
+        .ignoreLoadScopes()
+        .addModule(new ExpressionModule())
+        .addModule(new SegmentWranglerModule())
+        .addModule(new CacheTestHelperModule(ResultCacheMode.DISABLED));
+
+    return injectorBuilder;
+  }
+
+  public static Injector injector()
+  {
+
+    final LookupExtractorFactoryContainerProvider lookupProvider;
+    lookupProvider = 
LookupEnabledTestExprMacroTable.createTestLookupProvider(Collections.emptyMap());
+
+    return injectorBuilder()
+        .addModule(binder -> 
binder.bind(LookupExtractorFactoryContainerProvider.class).toInstance(lookupProvider))
+        .build();
+  }
 }
diff --git 
a/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java
 
b/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java
index c111cc9f7f4..ad6bb45f0fb 100644
--- 
a/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java
+++ 
b/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java
@@ -22,6 +22,7 @@ package org.apache.druid.server;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Ordering;
 import com.google.common.io.Closeables;
+import com.google.inject.Injector;
 import org.apache.druid.query.DataSource;
 import org.apache.druid.query.FrameBasedInlineDataSource;
 import org.apache.druid.query.InlineDataSource;
@@ -68,7 +69,7 @@ import java.util.Set;
 public class SpecificSegmentsQuerySegmentWalker implements QuerySegmentWalker, 
Closeable
 {
   private final QuerySegmentWalker walker;
-  private final Map<String, VersionedIntervalTimeline<String, 
ReferenceCountingSegment>> timelines = new HashMap<>();
+  private final Map<String, VersionedIntervalTimeline<String, 
ReferenceCountingSegment>> timelines;
   private final List<Closeable> closeables = new ArrayList<>();
   private final List<DataSegment> segments = new ArrayList<>();
   private static final LookupExtractorFactoryContainerProvider 
LOOKUP_EXTRACTOR_FACTORY_CONTAINER_PROVIDER =
@@ -87,33 +88,45 @@ public class SpecificSegmentsQuerySegmentWalker implements 
QuerySegmentWalker, C
         }
       };
 
+  public static SpecificSegmentsQuerySegmentWalker createWalker(
+      final QueryRunnerFactoryConglomerate conglomerate)
+  {
+    return createWalker(QueryStackTests.injector(), conglomerate);
+  }
+
   /**
    * Create an instance using the provided query runner factory conglomerate 
and lookup provider.
    * If a JoinableFactory is provided, it will be used instead of the default. 
If a scheduler is included,
    * the runner will schedule queries according to the scheduling config.
    */
-  public SpecificSegmentsQuerySegmentWalker(
+  public static SpecificSegmentsQuerySegmentWalker createWalker(
+      final Injector injector,
       final QueryRunnerFactoryConglomerate conglomerate,
       final SegmentWrangler segmentWrangler,
       final JoinableFactoryWrapper joinableFactoryWrapper,
-      final QueryScheduler scheduler
-  )
+      final QueryScheduler scheduler)
   {
-    this.walker = QueryStackTests.createClientQuerySegmentWalker(
-        QueryStackTests.createClusterQuerySegmentWalker(
-            timelines,
-            conglomerate,
-            scheduler
-        ),
-        QueryStackTests.createLocalQuerySegmentWalker(
+    Map<String, VersionedIntervalTimeline<String, ReferenceCountingSegment>> 
timelines = new HashMap<>();
+    return new SpecificSegmentsQuerySegmentWalker(
+        timelines,
+        QueryStackTests.createClientQuerySegmentWalker(
+            injector,
+            QueryStackTests.createClusterQuerySegmentWalker(
+                timelines,
+                conglomerate,
+                scheduler,
+                injector
+            ),
+            QueryStackTests.createLocalQuerySegmentWalker(
+                conglomerate,
+                segmentWrangler,
+                joinableFactoryWrapper,
+                scheduler
+            ),
             conglomerate,
-            segmentWrangler,
-            joinableFactoryWrapper,
-            scheduler
-        ),
-        conglomerate,
-        joinableFactoryWrapper.getJoinableFactory(),
-        new ServerConfig()
+            joinableFactoryWrapper.getJoinableFactory(),
+            new ServerConfig()
+        )
     );
   }
 
@@ -121,9 +134,10 @@ public class SpecificSegmentsQuerySegmentWalker implements 
QuerySegmentWalker, C
    * Create an instance without any lookups and with a default {@link 
JoinableFactory} that handles only inline
    * datasources.
    */
-  public SpecificSegmentsQuerySegmentWalker(final 
QueryRunnerFactoryConglomerate conglomerate)
+  public static SpecificSegmentsQuerySegmentWalker createWalker(final Injector 
injector, final QueryRunnerFactoryConglomerate conglomerate)
   {
-    this(
+    return createWalker(
+        injector,
         conglomerate,
         new MapSegmentWrangler(
             ImmutableMap.<Class<? extends DataSource>, 
SegmentWrangler>builder()
@@ -140,6 +154,14 @@ public class SpecificSegmentsQuerySegmentWalker implements 
QuerySegmentWalker, C
     );
   }
 
+  public SpecificSegmentsQuerySegmentWalker(
+      Map<String, VersionedIntervalTimeline<String, ReferenceCountingSegment>> 
timelines,
+      QuerySegmentWalker walker)
+  {
+    this.timelines = timelines;
+    this.walker = walker;
+  }
+
   public SpecificSegmentsQuerySegmentWalker add(final DataSegment descriptor, 
final Segment segment)
   {
     final ReferenceCountingSegment referenceCountingSegment =
diff --git 
a/server/src/test/java/org/apache/druid/server/TestClusterQuerySegmentWalker.java
 
b/server/src/test/java/org/apache/druid/server/TestClusterQuerySegmentWalker.java
index 5fbfabbfcd7..7c4133404ec 100644
--- 
a/server/src/test/java/org/apache/druid/server/TestClusterQuerySegmentWalker.java
+++ 
b/server/src/test/java/org/apache/druid/server/TestClusterQuerySegmentWalker.java
@@ -41,6 +41,7 @@ import org.apache.druid.query.QueryToolChest;
 import org.apache.druid.query.ReferenceCountingSegmentQueryRunner;
 import org.apache.druid.query.SegmentDescriptor;
 import org.apache.druid.query.TableDataSource;
+import org.apache.druid.query.context.ResponseContext.Keys;
 import org.apache.druid.query.planning.DataSourceAnalysis;
 import org.apache.druid.query.spec.SpecificSegmentQueryRunner;
 import org.apache.druid.query.spec.SpecificSegmentSpec;
@@ -74,18 +75,22 @@ public class TestClusterQuerySegmentWalker implements 
QuerySegmentWalker
   private final QueryRunnerFactoryConglomerate conglomerate;
   @Nullable
   private final QueryScheduler scheduler;
+  private final EtagProvider etagProvider;
 
   TestClusterQuerySegmentWalker(
       Map<String, VersionedIntervalTimeline<String, ReferenceCountingSegment>> 
timelines,
       QueryRunnerFactoryConglomerate conglomerate,
-      @Nullable QueryScheduler scheduler
+      @Nullable QueryScheduler scheduler,
+      EtagProvider etagProvider
   )
   {
     this.timelines = timelines;
     this.conglomerate = conglomerate;
     this.scheduler = scheduler;
+    this.etagProvider = etagProvider;
   }
 
+
   @Override
   public <T> QueryRunner<T> getQueryRunnerForIntervals(final Query<T> query, 
final Iterable<Interval> intervals)
   {
@@ -159,6 +164,11 @@ public class TestClusterQuerySegmentWalker implements 
QuerySegmentWalker
     // to actually serve the queries
     return (theQuery, responseContext) -> {
       responseContext.initializeRemainingResponses();
+
+      String etag = etagProvider.getEtagFor(theQuery.getQuery());
+      if (etag != null) {
+        responseContext.put(Keys.ETAG, etag);
+      }
       responseContext.addRemainingResponse(
           theQuery.getQuery().getMostSpecificId(), 0);
       if (scheduler != null) {
diff --git 
a/server/src/test/java/org/apache/druid/sql/calcite/util/CacheTestHelperModule.java
 
b/server/src/test/java/org/apache/druid/sql/calcite/util/CacheTestHelperModule.java
new file mode 100644
index 00000000000..4c34fa6b294
--- /dev/null
+++ 
b/server/src/test/java/org/apache/druid/sql/calcite/util/CacheTestHelperModule.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.util;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Module;
+import com.google.inject.Provides;
+import org.apache.druid.client.cache.Cache;
+import org.apache.druid.client.cache.CacheConfig;
+import org.apache.druid.client.cache.MapCache;
+import org.apache.druid.server.EtagProvider;
+
+public class CacheTestHelperModule extends AbstractModule
+{
+
+  public enum ResultCacheMode
+  {
+    DISABLED,
+    ENABLED;
+
+    public Module makeModule()
+    {
+      return new CacheTestHelperModule(this);
+    }
+
+    public boolean isPopulateResultLevelCache()
+    {
+      return this != DISABLED;
+    }
+
+    public boolean isUseResultLevelCache()
+    {
+      return this != DISABLED;
+    }
+  }
+
+  protected final Cache cache;
+  private CacheConfig cacheConfig;
+  private EtagProvider etagProvider;
+
+  static class TestCacheConfig extends CacheConfig
+  {
+    private ResultCacheMode resultLevelCache;
+
+    public TestCacheConfig(ResultCacheMode resultCacheMode)
+    {
+      this.resultLevelCache = resultCacheMode;
+    }
+
+    @Override
+    public boolean isPopulateResultLevelCache()
+    {
+      return resultLevelCache.isPopulateResultLevelCache();
+    }
+
+    @Override
+    public boolean isUseResultLevelCache()
+    {
+      return resultLevelCache.isUseResultLevelCache();
+    }
+
+  }
+
+  public CacheTestHelperModule(ResultCacheMode resultCacheMode)
+  {
+    cacheConfig = new TestCacheConfig(resultCacheMode);
+
+    switch (resultCacheMode) {
+      case ENABLED:
+        etagProvider = new EtagProvider.ProvideEtagBasedOnDatasource();
+        cache = MapCache.create(1_000_000L);
+        break;
+      case DISABLED:
+        etagProvider = new EtagProvider.EmptyEtagProvider();
+        cache = null;
+        break;
+      default:
+        throw new RuntimeException();
+    }
+  }
+
+  @Provides
+  EtagProvider etagProvider()
+  {
+    return etagProvider;
+  }
+
+  @Provides
+  CacheConfig getCacheConfig()
+  {
+    return cacheConfig;
+  }
+
+  @Provides
+  Cache getCache()
+  {
+    return cache;
+  }
+
+  @Override
+  public void configure()
+  {
+  }
+}
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
index eb2528a6d1c..d089ea5acc4 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/BaseCalciteQueryTest.java
@@ -114,7 +114,6 @@ import org.joda.time.DateTimeZone;
 import org.joda.time.Interval;
 import org.joda.time.chrono.ISOChronology;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -299,7 +298,7 @@ public class BaseCalciteQueryTest extends CalciteTestBase
 
   public QueryLogHook queryLogHook;
 
-  public QueryComponentSupplier baseComponentSupplier;
+  private QueryComponentSupplier baseComponentSupplier;
   public PlannerComponentSupplier basePlannerComponentSupplier = new 
StandardPlannerComponentSupplier();
 
   public BaseCalciteQueryTest()
@@ -633,7 +632,7 @@ public class BaseCalciteQueryTest extends CalciteTestBase
   @ClassRule
   public static SqlTestFrameworkConfig.ClassRule queryFrameworkClassRule = new 
SqlTestFrameworkConfig.ClassRule();
 
-  @Rule
+  @Rule(order = 3)
   public SqlTestFrameworkConfig.MethodRule queryFrameworkRule = 
queryFrameworkClassRule.methodRule(this);
 
   public SqlTestFramework queryFramework()
@@ -641,14 +640,6 @@ public class BaseCalciteQueryTest extends CalciteTestBase
     return queryFrameworkRule.get();
   }
 
-  @Before
-  public void before() throws Exception
-  {
-    baseComponentSupplier = new StandardComponentSupplier(
-        temporaryFolder.newFolder()
-    );
-  }
-
   @Override
   public SpecificSegmentsQuerySegmentWalker createQuerySegmentWalker(
       final QueryRunnerFactoryConglomerate conglomerate,
@@ -676,6 +667,14 @@ public class BaseCalciteQueryTest extends CalciteTestBase
   @Override
   public void gatherProperties(Properties properties)
   {
+    try {
+      baseComponentSupplier = new StandardComponentSupplier(
+          temporaryFolder.newFolder()
+      );
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
     baseComponentSupplier.gatherProperties(properties);
   }
 
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
index e4f609ef9ff..61b484b6a8b 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
@@ -202,7 +202,8 @@ public class CalciteArraysQueryTest extends 
BaseCalciteQueryTest
                     .inputTmpDir(temporaryFolder.newFolder())
                     .buildMMappedIndex();
 
-    SpecificSegmentsQuerySegmentWalker walker = new 
SpecificSegmentsQuerySegmentWalker(
+    SpecificSegmentsQuerySegmentWalker walker = 
SpecificSegmentsQuerySegmentWalker.createWalker(
+        injector,
         conglomerate,
         new MapSegmentWrangler(
             ImmutableMap.<Class<? extends DataSource>, 
SegmentWrangler>builder()
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
index a40dfbf79f9..6c177e76e7b 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java
@@ -321,7 +321,7 @@ public class CalciteNestedDataQueryTest extends 
BaseCalciteQueryTest
                     .buildMMappedIndex();
 
 
-    SpecificSegmentsQuerySegmentWalker walker = new 
SpecificSegmentsQuerySegmentWalker(conglomerate);
+    SpecificSegmentsQuerySegmentWalker walker = 
SpecificSegmentsQuerySegmentWalker.createWalker(injector, conglomerate);
     walker.add(
         DataSegment.builder()
                    .dataSource(DATA_SOURCE)
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/SqlTestFrameworkConfig.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/SqlTestFrameworkConfig.java
index e9c5d773fef..d1f53541fb9 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/SqlTestFrameworkConfig.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/SqlTestFrameworkConfig.java
@@ -20,10 +20,10 @@
 package org.apache.druid.sql.calcite;
 
 import org.apache.druid.query.topn.TopNQueryConfig;
+import org.apache.druid.sql.calcite.util.CacheTestHelperModule.ResultCacheMode;
 import org.apache.druid.sql.calcite.util.SqlTestFramework;
 import 
org.apache.druid.sql.calcite.util.SqlTestFramework.QueryComponentSupplier;
 import org.junit.rules.ExternalResource;
-import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
@@ -37,8 +37,8 @@ import java.util.Map;
 /**
  * Annotation to specify desired framework settings.
  *
- * This class provides junit rule facilities to build the framework 
accordingly to the annotation.
- * These rules also cache the previously created frameworks.
+ * This class provides junit rule facilities to build the framework accordingly
+ * to the annotation. These rules also cache the previously created frameworks.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
@@ -48,13 +48,15 @@ public @interface SqlTestFrameworkConfig
 
   int minTopNThreshold() default TopNQueryConfig.DEFAULT_MIN_TOPN_THRESHOLD;
 
+  ResultCacheMode resultCache() default ResultCacheMode.DISABLED;
+
   /**
    * @see {@link SqlTestFrameworkConfig}
    */
   class ClassRule extends ExternalResource
   {
 
-    Map<SqlTestFrameworkConfig, SqlTestFramework> frameworkMap = new 
HashMap<SqlTestFrameworkConfig, SqlTestFramework>();
+    Map<SqlTestFrameworkConfig, ConfigurationInstance> configMap = new 
HashMap<>();
 
     public MethodRule methodRule(BaseCalciteQueryTest testHost)
     {
@@ -64,17 +66,17 @@ public @interface SqlTestFrameworkConfig
     @Override
     protected void after()
     {
-      for (SqlTestFramework f : frameworkMap.values()) {
+      for (ConfigurationInstance f : configMap.values()) {
         f.close();
       }
-      frameworkMap.clear();
+      configMap.clear();
     }
   }
 
   /**
    * @see {@link SqlTestFrameworkConfig}
    */
-  class MethodRule implements TestRule
+  class MethodRule extends ExternalResource
   {
     private SqlTestFrameworkConfig config;
     private ClassRule classRule;
@@ -90,9 +92,10 @@ public @interface SqlTestFrameworkConfig
     public SqlTestFrameworkConfig defaultConfig()
     {
       try {
-        return getClass()
+        SqlTestFrameworkConfig annotation = MethodRule.class
             .getMethod("defaultConfig")
             .getAnnotation(SqlTestFrameworkConfig.class);
+        return annotation;
       }
       catch (NoSuchMethodException | SecurityException e) {
         throw new RuntimeException(e);
@@ -111,16 +114,40 @@ public @interface SqlTestFrameworkConfig
 
     public SqlTestFramework get()
     {
-      return classRule.frameworkMap.computeIfAbsent(config, 
this::createFramework);
+      return getConfigurationInstance().framework;
+    }
+
+    private ConfigurationInstance getConfigurationInstance()
+    {
+      return classRule.configMap.computeIfAbsent(config, 
this::buildConfiguration);
     }
 
-    private SqlTestFramework createFramework(SqlTestFrameworkConfig config)
+    ConfigurationInstance buildConfiguration(SqlTestFrameworkConfig config)
+    {
+      return new ConfigurationInstance(config, testHost);
+    }
+
+  }
+
+  class ConfigurationInstance
+  {
+
+    public SqlTestFramework framework;
+
+    ConfigurationInstance(SqlTestFrameworkConfig config, 
QueryComponentSupplier testHost)
     {
       SqlTestFramework.Builder builder = new SqlTestFramework.Builder(testHost)
           .catalogResolver(testHost.createCatalogResolver())
           .minTopNThreshold(config.minTopNThreshold())
-          .mergeBufferCount(config.numMergeBuffers());
-      return builder.build();
+          .mergeBufferCount(config.numMergeBuffers())
+          .withOverrideModule(config.resultCache().makeModule());
+      framework = builder.build();
+    }
+
+    public void close()
+    {
+      framework.close();
     }
   }
+
 }
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
index fc9c63cc667..6c87c321a42 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/SqlVectorizedExpressionSanityTest.java
@@ -130,7 +130,7 @@ public class SqlVectorizedExpressionSanityTest extends 
InitializedNullHandlingTe
     );
     CONGLOMERATE = 
QueryStackTests.createQueryRunnerFactoryConglomerate(CLOSER);
 
-    WALKER = new SpecificSegmentsQuerySegmentWalker(CONGLOMERATE).add(
+    WALKER = SpecificSegmentsQuerySegmentWalker.createWalker(CONGLOMERATE).add(
         dataSegment,
         INDEX
     );
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheCommon.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheCommon.java
index e8c9baf98c0..cea8e905e49 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheCommon.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheCommon.java
@@ -86,7 +86,7 @@ public class BrokerSegmentMetadataCacheCommon extends 
SegmentMetadataCacheCommon
       }
     };
 
-    walker = new SpecificSegmentsQuerySegmentWalker(conglomerate)
+    walker = SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate)
         .add(segment1, index1)
         .add(segment2, index2)
         .add(segment3, index2)
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheConcurrencyTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheConcurrencyTest.java
index 56ebcf5b99b..e74d029f626 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheConcurrencyTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/BrokerSegmentMetadataCacheConcurrencyTest.java
@@ -101,7 +101,7 @@ public class BrokerSegmentMetadataCacheConcurrencyTest 
extends BrokerSegmentMeta
   {
     super.setUp();
     tmpDir = temporaryFolder.newFolder();
-    walker = new SpecificSegmentsQuerySegmentWalker(conglomerate);
+    walker = SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate);
     inventoryView = new TestServerInventoryView();
     serverView = newBrokerServerView(inventoryView);
     inventoryView.init();
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidSchemaNoDataInitTest.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidSchemaNoDataInitTest.java
index 08f16ae9307..a1ad4201c6d 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidSchemaNoDataInitTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/DruidSchemaNoDataInitTest.java
@@ -52,7 +52,7 @@ public class DruidSchemaNoDataInitTest extends CalciteTestBase
       final QueryRunnerFactoryConglomerate conglomerate = 
QueryStackTests.createQueryRunnerFactoryConglomerate(closer);
       final BrokerSegmentMetadataCache cache = new BrokerSegmentMetadataCache(
           CalciteTests.createMockQueryLifecycleFactory(
-              new SpecificSegmentsQuerySegmentWalker(conglomerate),
+              SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate),
               conglomerate
           ),
           new TestTimelineServerView(Collections.emptyList()),
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/SystemSchemaTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/SystemSchemaTest.java
index e0a3bb5b266..40772374537 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/schema/SystemSchemaTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/schema/SystemSchemaTest.java
@@ -247,7 +247,7 @@ public class SystemSchemaTest extends CalciteTestBase
                                               .rows(ROWS3)
                                               .buildMMappedIndex();
 
-    walker = new SpecificSegmentsQuerySegmentWalker(conglomerate)
+    walker = SpecificSegmentsQuerySegmentWalker.createWalker(conglomerate)
         .add(segment1, index1)
         .add(segment2, index2)
         .add(segment3, index3);
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTestInjectorBuilder.java
 
b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTestInjectorBuilder.java
deleted file mode 100644
index 75744263f14..00000000000
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTestInjectorBuilder.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.druid.sql.calcite.util;
-
-import com.google.inject.Injector;
-import org.apache.druid.guice.ExpressionModule;
-import org.apache.druid.guice.SegmentWranglerModule;
-import org.apache.druid.guice.StartupInjectorBuilder;
-import org.apache.druid.initialization.CoreInjectorBuilder;
-import org.apache.druid.sql.calcite.aggregation.SqlAggregationModule;
-import 
org.apache.druid.sql.calcite.util.testoperator.CalciteTestOperatorModule;
-
-/**
- * Create the injector used for {@link CalciteTests#INJECTOR}, but in a way
- * that is extensible.
- */
-public class CalciteTestInjectorBuilder extends CoreInjectorBuilder
-{
-  public CalciteTestInjectorBuilder()
-  {
-    super(new StartupInjectorBuilder()
-              .withEmptyProperties()
-              .build());
-    add(
-        new ExpressionModule(),
-        new SegmentWranglerModule(),
-        new LookylooModule(),
-        new SqlAggregationModule(),
-        new CalciteTestOperatorModule()
-    );
-  }
-
-  @Override
-  public Injector build()
-  {
-    try {
-      return super.build();
-    }
-    catch (Exception e) {
-      // Catches failures when used as a static initializer.
-      e.printStackTrace();
-      System.exit(1);
-      throw e;
-    }
-  }
-}
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
index a9ca48e90a9..0bb5130c148 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java
@@ -59,6 +59,7 @@ import org.apache.druid.segment.join.JoinableFactoryWrapper;
 import org.apache.druid.server.DruidNode;
 import org.apache.druid.server.QueryLifecycleFactory;
 import org.apache.druid.server.QueryScheduler;
+import org.apache.druid.server.QueryStackTests;
 import org.apache.druid.server.SpecificSegmentsQuerySegmentWalker;
 import org.apache.druid.server.coordination.DruidServerMetadata;
 import org.apache.druid.server.security.Access;
@@ -73,6 +74,7 @@ import org.apache.druid.server.security.Escalator;
 import org.apache.druid.server.security.NoopEscalator;
 import org.apache.druid.server.security.ResourceType;
 import org.apache.druid.sql.SqlStatementFactory;
+import org.apache.druid.sql.calcite.aggregation.SqlAggregationModule;
 import org.apache.druid.sql.calcite.planner.DruidOperatorTable;
 import org.apache.druid.sql.calcite.planner.PlannerConfig;
 import org.apache.druid.sql.calcite.planner.PlannerFactory;
@@ -83,6 +85,7 @@ import org.apache.druid.sql.calcite.schema.DruidSchema;
 import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
 import org.apache.druid.sql.calcite.schema.MetadataSegmentView;
 import org.apache.druid.sql.calcite.schema.SystemSchema;
+import 
org.apache.druid.sql.calcite.util.testoperator.CalciteTestOperatorModule;
 import org.apache.druid.timeline.DataSegment;
 import org.joda.time.Duration;
 
@@ -232,7 +235,11 @@ public class CalciteTests
       null
   );
 
-  public static final Injector INJECTOR = new 
CalciteTestInjectorBuilder().build();
+  public static final Injector INJECTOR = QueryStackTests.injectorBuilder()
+      .addModule(new LookylooModule())
+      .addModule(new SqlAggregationModule())
+      .addModule(new CalciteTestOperatorModule())
+      .build();
 
   private CalciteTests()
   {
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/SqlTestFramework.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/util/SqlTestFramework.java
index fa7055d3e58..8ec1f30fafc 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/util/SqlTestFramework.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/SqlTestFramework.java
@@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Binder;
 import com.google.inject.Injector;
+import com.google.inject.Module;
 import com.google.inject.Provides;
 import org.apache.druid.guice.DruidInjectorBuilder;
 import org.apache.druid.guice.ExpressionModule;
@@ -32,6 +33,7 @@ import org.apache.druid.guice.SegmentWranglerModule;
 import org.apache.druid.guice.StartupInjectorBuilder;
 import org.apache.druid.initialization.CoreInjectorBuilder;
 import org.apache.druid.initialization.DruidModule;
+import org.apache.druid.initialization.ServiceInjectorBuilder;
 import org.apache.druid.java.util.common.RE;
 import org.apache.druid.java.util.common.io.Closer;
 import org.apache.druid.math.expr.ExprMacroTable;
@@ -67,6 +69,8 @@ import org.apache.druid.timeline.DataSegment;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 import java.util.Set;
 
@@ -367,6 +371,7 @@ public class SqlTestFramework
     private int minTopNThreshold = TopNQueryConfig.DEFAULT_MIN_TOPN_THRESHOLD;
     private int mergeBufferCount;
     private CatalogResolver catalogResolver = CatalogResolver.NULL_RESOLVER;
+    private List<Module> overrideModules = new ArrayList<>();
 
     public Builder(QueryComponentSupplier componentSupplier)
     {
@@ -391,6 +396,12 @@ public class SqlTestFramework
       return this;
     }
 
+    public Builder withOverrideModule(Module m)
+    {
+      this.overrideModules.add(m);
+      return this;
+    }
+
     public SqlTestFramework build()
     {
       return new SqlTestFramework(this);
@@ -559,7 +570,7 @@ public class SqlTestFramework
     Injector startupInjector = new StartupInjectorBuilder()
         .withProperties(properties)
         .build();
-    DruidInjectorBuilder injectorBuilder = new 
CoreInjectorBuilder(startupInjector)
+    CoreInjectorBuilder injectorBuilder = (CoreInjectorBuilder) new 
CoreInjectorBuilder(startupInjector)
         // Ignore load scopes. This is a unit test, not a Druid node. If a
         // test pulls in a module, then pull in that module, even though we are
         // not the Druid node to which the module is scoped.
@@ -569,8 +580,13 @@ public class SqlTestFramework
         .addModule(new SqlAggregationModule())
         .addModule(new ExpressionModule())
         .addModule(new TestSetupModule(builder));
+
     builder.componentSupplier.configureGuice(injectorBuilder);
-    this.injector = injectorBuilder.build();
+
+    ServiceInjectorBuilder serviceInjector = new 
ServiceInjectorBuilder(injectorBuilder);
+    serviceInjector.addAll(builder.overrideModules);
+
+    this.injector = serviceInjector.build();
     this.engine = 
builder.componentSupplier.createEngine(queryLifecycleFactory(), 
queryJsonMapper(), injector);
     componentSupplier.configureJsonMapper(queryJsonMapper());
     componentSupplier.finalizeTestFramework(this);
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java
index 53480e2532d..86831768148 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java
@@ -832,7 +832,8 @@ public class TestDataBuilder
         .rows(USER_VISIT_ROWS)
         .buildMMappedIndex();
 
-    return new SpecificSegmentsQuerySegmentWalker(
+    return SpecificSegmentsQuerySegmentWalker.createWalker(
+        injector,
         conglomerate,
         injector.getInstance(SegmentWrangler.class),
         joinableFactoryWrapper,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to