@Test
  public void monitorQueryExecutionCancelsLongRunningQueriesAndSetsExceptionAndThrowsException() {

    QueryMonitor queryMonitor = new QueryMonitor(
        new ScheduledThreadPoolExecutor(1),
        cache,
        EXPIRE_QUICK_MILLIS);

    final Answer<Void> processSetQueryCanceledException = invocation -> {
      final Object[] args = invocation.getArguments();
      if (args[0] instanceof CacheRuntimeException) {
        cacheRuntimeException = (CacheRuntimeException) args[0];
      } else {
        throw new AssertionError(
            "setQueryCanceledException() received argument that wasn't a CacheRuntimeException.");
      }
      return null;
    };

    doAnswer(processSetQueryCanceledException).when(executionContext)
        .setQueryCanceledException(any(CacheRuntimeException.class));

    startQueryThread(queryMonitor, executionContext);

    GeodeAwaitility.await().until(() -> cacheRuntimeException != null);

    assertThat(cacheRuntimeException)
        .hasMessageContaining("canceled after exceeding max execution time");

    assertThat(queryExecutionCanceledException).isNotNull();
  }
Test QueryMonitor, integrated with its ScheduledThreadPoolExecutor.

Mock DefaultQuery.
geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/QueryMonitorIntegrationTest.java