• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

temporalio / sdk-java / #351

04 Aug 2026 11:58PM UTC coverage: 67.781% (-0.5%) from 68.245%
#351

push

github

web-flow
Add dev server downloader & runner to testing package (#2982)

7311 of 12876 branches covered (56.78%)

Branch coverage included in aggregate %.

331 of 703 new or added lines in 12 files covered. (47.08%)

28 existing lines in 13 files now uncovered.

30207 of 42476 relevant lines covered (71.12%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.78
/temporal-testing/src/main/java/io/temporal/testing/internal/SDKTestWorkflowRule.java
1
package io.temporal.testing.internal;
2

3
import static io.temporal.client.WorkflowClient.QUERY_TYPE_STACK_TRACE;
4
import static org.junit.Assert.fail;
5

6
import com.google.common.base.Charsets;
7
import com.google.common.base.Throwables;
8
import com.google.common.io.CharSink;
9
import com.google.common.io.Files;
10
import com.uber.m3.tally.Scope;
11
import io.temporal.api.enums.v1.EventType;
12
import io.temporal.api.enums.v1.IndexedValueType;
13
import io.temporal.api.history.v1.History;
14
import io.temporal.api.history.v1.HistoryEvent;
15
import io.temporal.api.nexus.v1.Endpoint;
16
import io.temporal.client.ActivityClient;
17
import io.temporal.client.ActivityClientOptions;
18
import io.temporal.client.NexusClient;
19
import io.temporal.client.NexusClientOptions;
20
import io.temporal.client.WorkflowClient;
21
import io.temporal.client.WorkflowClientOptions;
22
import io.temporal.client.WorkflowQueryException;
23
import io.temporal.client.WorkflowStub;
24
import io.temporal.common.SearchAttributeKey;
25
import io.temporal.common.WorkerDeploymentVersion;
26
import io.temporal.common.WorkflowExecutionHistory;
27
import io.temporal.common.interceptors.WorkerInterceptor;
28
import io.temporal.internal.common.env.DebugModeUtils;
29
import io.temporal.internal.worker.WorkflowExecutorCache;
30
import io.temporal.serviceclient.WorkflowServiceStubs;
31
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
32
import io.temporal.testing.TestWorkflowEnvironment;
33
import io.temporal.testing.TestWorkflowRule;
34
import io.temporal.worker.*;
35
import io.temporal.workflow.Functions;
36
import java.io.File;
37
import java.io.IOException;
38
import java.lang.reflect.InvocationTargetException;
39
import java.lang.reflect.Method;
40
import java.time.Duration;
41
import java.util.ArrayList;
42
import java.util.List;
43
import java.util.UUID;
44
import java.util.concurrent.*;
45
import javax.annotation.Nonnull;
46
import javax.annotation.Nullable;
47
import org.junit.Test;
48
import org.junit.rules.TestRule;
49
import org.junit.rules.Timeout;
50
import org.junit.runner.Description;
51
import org.junit.runners.model.Statement;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

55
/**
56
 * Intended to be used only in the Java SDK test code. This Rule duplicates {@link TestWorkflowRule}
57
 * and provides additional convenience methods for SDK development
58
 */
59
public class SDKTestWorkflowRule implements TestRule {
60
  private static final Logger log = LoggerFactory.getLogger(SDKTestWorkflowRule.class);
1✔
61

62
  private static final long DEFAULT_TEST_TIMEOUT_SECONDS = 10;
63

64
  private static final long BUSY_WAIT_SLEEP_MS = 100;
65

66
  public static final String NAMESPACE = "UnitTest";
67
  public static final String UUID_REGEXP =
68
      "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
69
  // Enable to regenerate JsonFiles used for replay testing.
70
  public static final boolean REGENERATE_JSON_FILES = false;
71
  // Only enable when USE_EXTERNAL_SERVICE is true
72
  public static final boolean useExternalService =
73
      ExternalServiceTestConfigurator.isUseExternalService();
1✔
74
  public static final boolean USE_VIRTUAL_THREADS =
75
      ExternalServiceTestConfigurator.isUseVirtualThreads();
1✔
76
  private static final List<ScheduledFuture<?>> delayedCallbacks = new ArrayList<>();
1✔
77
  private static final ScheduledExecutorService scheduledExecutor =
1✔
78
      new ScheduledThreadPoolExecutor(1);
79

80
  @Nullable private final Timeout globalTimeout;
81

82
  private final TestWorkflowRule testWorkflowRule;
83

84
  private SDKTestWorkflowRule(SDKTestWorkflowRule.Builder builder) {
1✔
85
    globalTimeout =
1✔
86
        !DebugModeUtils.isTemporalDebugModeOn()
1!
87
            ? Timeout.seconds(
1✔
88
                builder.testTimeoutSeconds == 0
1✔
89
                    ? DEFAULT_TEST_TIMEOUT_SECONDS
1✔
90
                    : builder.testTimeoutSeconds)
1✔
91
            : null;
1✔
92

93
    testWorkflowRule =
1✔
94
        ExternalServiceTestConfigurator.configure(builder.testWorkflowRuleBuilder).build();
1✔
95
  }
1✔
96

97
  public static Builder newBuilder() {
98
    return new Builder();
1✔
99
  }
100

101
  public static class Builder {
102
    private long testTimeoutSeconds;
103

104
    private boolean workerFactoryOptionsAreSet = false;
1✔
105
    private boolean workerOptionsAreSet = false;
1✔
106
    private final TestWorkflowRule.Builder testWorkflowRuleBuilder;
107

108
    public Builder() {
1✔
109
      testWorkflowRuleBuilder = TestWorkflowRule.newBuilder();
1✔
110
    }
1✔
111

112
    public Builder setWorkflowServiceStubsOptions(
113
        WorkflowServiceStubsOptions workflowServiceStubsOptions) {
114
      testWorkflowRuleBuilder.setWorkflowServiceStubsOptions(workflowServiceStubsOptions);
1✔
115
      return this;
1✔
116
    }
117

118
    public Builder setWorkflowClientOptions(WorkflowClientOptions workflowClientOptions) {
119
      testWorkflowRuleBuilder.setWorkflowClientOptions(workflowClientOptions);
1✔
120
      return this;
1✔
121
    }
122

123
    public Builder setActivityClientOptions(ActivityClientOptions activityClientOptions) {
124
      testWorkflowRuleBuilder.setActivityClientOptions(activityClientOptions);
×
125
      return this;
×
126
    }
127

128
    public Builder setWorkerOptions(WorkerOptions options) {
129
      testWorkflowRuleBuilder.setWorkerOptions(
1✔
130
          WorkerOptions.newBuilder(options).setUsingVirtualThreads(USE_VIRTUAL_THREADS).build());
1✔
131
      workerOptionsAreSet = true;
1✔
132
      return this;
1✔
133
    }
134

135
    public Builder setWorkerFactoryOptions(WorkerFactoryOptions options) {
136
      options =
137
          (options.getWorkerInterceptors() == null)
1✔
138
              ? WorkerFactoryOptions.newBuilder(options)
1✔
139
                  .setWorkerInterceptors(
1✔
140
                      new TracingWorkerInterceptor(new TracingWorkerInterceptor.FilteredTrace()))
141
                  .build()
1✔
142
              : options;
1✔
143
      testWorkflowRuleBuilder.setWorkerFactoryOptions(options);
1✔
144
      workerFactoryOptionsAreSet = true;
1✔
145
      return this;
1✔
146
    }
147

148
    public Builder setNamespace(String namespace) {
149
      testWorkflowRuleBuilder.setNamespace(namespace);
×
150
      return this;
×
151
    }
152

153
    public Builder setWorkflowTypes(Class<?>... workflowTypes) {
154
      testWorkflowRuleBuilder.setWorkflowTypes(workflowTypes);
1✔
155
      return this;
1✔
156
    }
157

158
    public Builder setNexusServiceImplementation(Object... nexusServiceImplementations) {
159
      testWorkflowRuleBuilder.setNexusServiceImplementation(nexusServiceImplementations);
1✔
160
      return this;
1✔
161
    }
162

163
    public Builder setWorkflowTypes(
164
        WorkflowImplementationOptions implementationOptions, Class<?>... workflowTypes) {
165
      testWorkflowRuleBuilder.setWorkflowTypes(implementationOptions, workflowTypes);
1✔
166
      return this;
1✔
167
    }
168

169
    public Builder setActivityImplementations(Object... activityImplementations) {
170
      testWorkflowRuleBuilder.setActivityImplementations(activityImplementations);
1✔
171
      return this;
1✔
172
    }
173

174
    public Builder setUseExternalService(boolean useExternalService) {
UNCOV
175
      testWorkflowRuleBuilder.setUseExternalService(useExternalService);
×
UNCOV
176
      return this;
×
177
    }
178

179
    public Builder setTarget(String target) {
180
      testWorkflowRuleBuilder.setTarget(target);
×
181
      return this;
×
182
    }
183

184
    /** Global test timeout. Default is 10 seconds. */
185
    public Builder setTestTimeoutSeconds(long testTimeoutSeconds) {
186
      this.testTimeoutSeconds = testTimeoutSeconds;
1✔
187
      return this;
1✔
188
    }
189

190
    public Builder setInitialTimeMillis(long initialTimeMillis) {
191
      testWorkflowRuleBuilder.setInitialTimeMillis(initialTimeMillis);
1✔
192
      return this;
1✔
193
    }
194

195
    public Builder setDoNotStart(boolean doNotStart) {
196
      testWorkflowRuleBuilder.setDoNotStart(doNotStart);
1✔
197
      return this;
1✔
198
    }
199

200
    public Builder setUseTimeskipping(boolean useTimeskipping) {
201
      testWorkflowRuleBuilder.setUseTimeskipping(useTimeskipping);
1✔
202
      return this;
1✔
203
    }
204

205
    public Builder registerSearchAttribute(String name, IndexedValueType type) {
206
      testWorkflowRuleBuilder.registerSearchAttribute(name, type);
1✔
207
      return this;
1✔
208
    }
209

210
    public Builder registerSearchAttribute(SearchAttributeKey<?> key) {
211
      testWorkflowRuleBuilder.registerSearchAttribute(key);
1✔
212
      return this;
1✔
213
    }
214

215
    public Builder setMetricsScope(Scope scope) {
216
      testWorkflowRuleBuilder.setMetricsScope(scope);
1✔
217
      return this;
1✔
218
    }
219

220
    public SDKTestWorkflowRule build() {
221
      if (!workerFactoryOptionsAreSet) {
1✔
222
        testWorkflowRuleBuilder.setWorkerFactoryOptions(
1✔
223
            WorkerFactoryOptions.newBuilder()
1✔
224
                .setUsingVirtualWorkflowThreads(USE_VIRTUAL_THREADS)
1✔
225
                .setWorkerInterceptors(
1✔
226
                    new TracingWorkerInterceptor(new TracingWorkerInterceptor.FilteredTrace()))
227
                .build());
1✔
228
      }
229
      if (!workerOptionsAreSet) {
1✔
230
        testWorkflowRuleBuilder.setWorkerOptions(
1✔
231
            WorkerOptions.newBuilder().setUsingVirtualThreads(USE_VIRTUAL_THREADS).build());
1✔
232
      }
233
      return new SDKTestWorkflowRule(this);
1✔
234
    }
235
  }
236

237
  public Statement apply(@Nonnull Statement base, Description description) {
238
    Statement testWorkflowStatement =
1✔
239
        new Statement() {
1✔
240
          @Override
241
          public void evaluate() throws Throwable {
242
            base.evaluate();
1✔
243
            shutdown();
1✔
244
          }
1✔
245
        };
246

247
    Test annotation = description.getAnnotation(Test.class);
1✔
248
    boolean timeoutIsOverriddenOnTestAnnotation = annotation != null && annotation.timeout() > 0;
1✔
249
    if (globalTimeout != null && !timeoutIsOverriddenOnTestAnnotation) {
1!
250
      testWorkflowStatement = globalTimeout.apply(testWorkflowStatement, description);
1✔
251
    }
252

253
    return testWorkflowRule.apply(testWorkflowStatement, description);
1✔
254
  }
255

256
  public <T extends WorkerInterceptor> T getInterceptor(Class<T> type) {
257
    return testWorkflowRule.getInterceptor(type);
1✔
258
  }
259

260
  public String getTaskQueue() {
261
    return testWorkflowRule.getTaskQueue();
1✔
262
  }
263

264
  public String getDeploymentName() {
265
    return "deployment-" + testWorkflowRule.getUniquePostfix();
1✔
266
  }
267

268
  public Endpoint getNexusEndpoint() {
269
    return testWorkflowRule.getNexusEndpoint();
1✔
270
  }
271

272
  /**
273
   * Returns a {@link NexusClient} bound to this rule's namespace and service stubs. Use for tests
274
   * that exercise the standalone Nexus client surface.
275
   */
276
  public NexusClient getNexusClient() {
277
    return NexusClient.newInstance(
×
278
        getWorkflowServiceStubs(),
×
279
        NexusClientOptions.newBuilder()
×
280
            .setNamespace(getWorkflowClient().getOptions().getNamespace())
×
281
            .build());
×
282
  }
283

284
  public Worker getWorker() {
285
    return testWorkflowRule.getWorker();
1✔
286
  }
287

288
  /** Start a new worker, re-using existing options and modifying them with the provided modifier */
289
  public Worker newWorker(Functions.Proc1<WorkerOptions.Builder> optionsModifier) {
290
    WorkerOptions.Builder optionsBuilder =
1✔
291
        WorkerOptions.newBuilder(testWorkflowRule.getWorkerOptions());
1✔
292
    optionsModifier.apply(optionsBuilder);
1✔
293
    WorkerOptions workerOptions = optionsBuilder.build();
1✔
294
    WorkerFactory wf = WorkerFactory.newInstance(getWorkflowClient(), getWorkerFactoryOptions());
1✔
295
    return wf.newWorker(getTaskQueue(), workerOptions);
1✔
296
  }
297

298
  /** Start a new worker, changing only the build ID */
299
  public Worker newWorkerWithBuildID(String buildId) {
300
    return newWorker(
1✔
301
        (opts) ->
302
            opts.setDeploymentOptions(
1✔
303
                WorkerDeploymentOptions.newBuilder()
1✔
304
                    .setVersion(new WorkerDeploymentVersion(getDeploymentName(), buildId))
1✔
305
                    .setUseVersioning(true)
1✔
306
                    .build()));
1✔
307
  }
308

309
  public WorkerFactoryOptions getWorkerFactoryOptions() {
310
    return testWorkflowRule.getWorkerFactoryOptions();
1✔
311
  }
312

313
  public WorkflowExecutionHistory getExecutionHistory(String workflowId) {
314
    return testWorkflowRule.getWorkflowClient().fetchHistory(workflowId);
1✔
315
  }
316

317
  public WorkflowExecutionHistory getExecutionHistory(String workflowId, String runId) {
318
    return testWorkflowRule.getWorkflowClient().fetchHistory(workflowId, runId);
1✔
319
  }
320

321
  /** Returns list of all events of the given EventType found in the history. */
322
  public List<HistoryEvent> getHistoryEvents(String workflowId, EventType eventType) {
323
    List<HistoryEvent> result = new ArrayList<>();
1✔
324
    History history = getExecutionHistory(workflowId).getHistory();
1✔
325
    for (HistoryEvent event : history.getEventsList()) {
1✔
326
      if (eventType == event.getEventType()) {
1✔
327
        result.add(event);
1✔
328
      }
329
    }
1✔
330
    return result;
1✔
331
  }
332

333
  /** Returns the first event of the given EventType found in the history. */
334
  public HistoryEvent getHistoryEvent(String workflowId, EventType eventType) {
335
    History history = getExecutionHistory(workflowId).getHistory();
1✔
336
    for (HistoryEvent event : history.getEventsList()) {
1!
337
      if (eventType == event.getEventType()) {
1✔
338
        return event;
1✔
339
      }
340
    }
1✔
341
    throw new IllegalArgumentException("No event of " + eventType + " found in the history");
×
342
  }
343

344
  /** Asserts that an event of the given EventType is found in the history. */
345
  public void assertHistoryEvent(String workflowId, EventType eventType) {
346
    assertHistoryEvent(workflowId, null, eventType);
1✔
347
  }
1✔
348

349
  public void assertHistoryEvent(String workflowId, String runId, EventType eventType) {
350
    History history = getExecutionHistory(workflowId, runId).getHistory();
1✔
351
    for (HistoryEvent event : history.getEventsList()) {
1!
352
      if (eventType == event.getEventType()) {
1✔
353
        return;
1✔
354
      }
355
    }
1✔
356
    fail("No event of " + eventType + " found in the history");
×
357
  }
×
358

359
  /** Asserts that an event of the given EventType is not found in the history. */
360
  public void assertNoHistoryEvent(String workflowId, EventType eventType) {
361
    assertNoHistoryEvent(workflowId, null, eventType);
1✔
362
  }
1✔
363

364
  /** Asserts that an event of the given EventType is not found in the history. */
365
  public void assertNoHistoryEvent(String workflowId, String runId, EventType eventType) {
366
    History history = getExecutionHistory(workflowId, runId).getHistory();
1✔
367
    assertNoHistoryEvent(history, eventType);
1✔
368
  }
1✔
369

370
  /** Asserts that an event of the given EventType is not found in the history. */
371
  public static void assertNoHistoryEvent(History history, EventType eventType) {
372
    for (HistoryEvent event : history.getEventsList()) {
1✔
373
      if (eventType == event.getEventType()) {
1!
374
        fail("Event of " + eventType + " found in the history");
×
375
      }
376
    }
1✔
377
  }
1✔
378

379
  /** Waits till the end of the workflow task if there is a workflow task in progress */
380
  public void waitForTheEndOfWFT(String workflowId) {
381
    WorkflowExecutionHistory initialHistory = getExecutionHistory(workflowId);
1✔
382

383
    HistoryEvent lastEvent = initialHistory.getLastEvent();
1✔
384
    if (isWFTInProgress(lastEvent)) {
1✔
385
      // wait for completion of a workflow task in progress
386
      long startEventId = lastEvent.getEventId();
1✔
387
      while (true) {
388
        List<HistoryEvent> historyEvents =
1✔
389
            getExecutionHistory(workflowId).getHistory().getEventsList();
1✔
390
        if (historyEvents.stream()
1✔
391
            .filter(e -> e.getEventId() > startEventId)
1✔
392
            .anyMatch(e -> !isWFTInProgress(e))) {
1!
393
          return;
1✔
394
        }
395
        busyWaitSleep();
1✔
396
      }
1✔
397
    }
398
  }
1✔
399

400
  public WorkflowClient getWorkflowClient() {
401
    return testWorkflowRule.getWorkflowClient();
1✔
402
  }
403

404
  public ActivityClient getActivityClient() {
405
    return testWorkflowRule.getActivityClient();
×
406
  }
407

408
  public WorkflowServiceStubs getWorkflowServiceStubs() {
409
    return testWorkflowRule.getWorkflowServiceStubs();
1✔
410
  }
411

412
  public boolean isUseExternalService() {
413
    return useExternalService;
1✔
414
  }
415

416
  public TestWorkflowEnvironment getTestEnvironment() {
417
    return testWorkflowRule.getTestEnvironment();
1✔
418
  }
419

420
  public <T> T newWorkflowStub(Class<T> workflow) {
421
    return testWorkflowRule.newWorkflowStub(workflow);
1✔
422
  }
423

424
  public <T> T newWorkflowStubTimeoutOptions(Class<T> workflow) {
425
    return getWorkflowClient()
1✔
426
        .newWorkflowStub(workflow, SDKTestOptions.newWorkflowOptionsWithTimeouts(getTaskQueue()));
1✔
427
  }
428

429
  public <T> T newWorkflowStubTimeoutOptions(Class<T> workflow, String workflowIdPrefix) {
430
    String workflowId = workflowIdPrefix + "-" + UUID.randomUUID();
1✔
431
    return getWorkflowClient()
1✔
432
        .newWorkflowStub(
1✔
433
            workflow,
434
            SDKTestOptions.newWorkflowOptionsWithTimeouts(getTaskQueue()).toBuilder()
1✔
435
                .setWorkflowId(workflowId)
1✔
436
                .build());
1✔
437
  }
438

439
  public <T> T newWorkflowStub200sTimeoutOptions(Class<T> workflow) {
440
    return getWorkflowClient()
1✔
441
        .newWorkflowStub(
1✔
442
            workflow, SDKTestOptions.newWorkflowOptionsForTaskQueue200sTimeout(getTaskQueue()));
1✔
443
  }
444

445
  public WorkflowStub newUntypedWorkflowStub(String workflow) {
446
    return testWorkflowRule.newUntypedWorkflowStub(workflow);
1✔
447
  }
448

449
  public WorkflowStub newUntypedWorkflowStubTimeoutOptions(String workflow) {
450
    return getWorkflowClient()
1✔
451
        .newUntypedWorkflowStub(
1✔
452
            workflow, SDKTestOptions.newWorkflowOptionsWithTimeouts(getTaskQueue()));
1✔
453
  }
454

455
  /** Used to ensure that workflow first workflow task is executed. */
456
  public static void waitForOKQuery(Object anyStub) {
457
    WorkflowStub untypedStub;
458
    if (anyStub instanceof WorkflowStub) {
1✔
459
      untypedStub = (WorkflowStub) anyStub;
1✔
460
    } else {
461
      untypedStub = WorkflowStub.fromTyped(anyStub);
1✔
462
    }
463
    while (true) {
464
      try {
465
        String stackTrace = untypedStub.query(QUERY_TYPE_STACK_TRACE, String.class);
1✔
466
        if (!stackTrace.isEmpty()) {
1!
467
          break;
1✔
468
        }
469
        busyWaitSleep();
×
470
      } catch (WorkflowQueryException e) {
×
471
        // Ignore
472
      }
×
473
    }
474
  }
1✔
475

476
  public <R> void addWorkflowImplementationFactory(
477
      Class<R> factoryImpl, Functions.Func<R> factoryFunc) {
478
    this.getTestEnvironment()
1✔
479
        .getWorkerFactory()
1✔
480
        .getWorker(this.getTaskQueue())
1✔
481
        .registerWorkflowImplementationFactory(factoryImpl, factoryFunc);
1✔
482
  }
1✔
483

484
  @SuppressWarnings("deprecation")
485
  public void regenerateHistoryForReplay(String workflowId, String fileName) {
486
    if (REGENERATE_JSON_FILES) {
487
      String json = getExecutionHistory(workflowId).toJson(true);
488
      String projectPath = System.getProperty("user.dir");
489
      String resourceFile = projectPath + "/src/test/resources/" + fileName + ".json";
490
      File file = new File(resourceFile);
491
      CharSink sink = Files.asCharSink(file, Charsets.UTF_8);
492
      try {
493
        sink.write(json);
494
      } catch (IOException e) {
495
        Throwables.propagateIfPossible(e, RuntimeException.class);
496
      }
497
      log.info("Regenerated history file: " + resourceFile);
498
    }
499
  }
1✔
500

501
  // TODO: Refactor testEnv to support testing through real service to avoid these switches.
502
  public void registerDelayedCallback(Duration delay, Runnable r) {
503
    if (useExternalService) {
1!
504
      ScheduledFuture<?> result =
×
505
          scheduledExecutor.schedule(r, delay.toMillis(), TimeUnit.MILLISECONDS);
×
506
      delayedCallbacks.add(result);
×
507
    } else {
×
508
      testWorkflowRule.getTestEnvironment().registerDelayedCallback(delay, r);
1✔
509
    }
510
  }
1✔
511

512
  protected void shutdown() throws Throwable {
513
    getTestEnvironment().shutdown();
1✔
514

515
    TracingWorkerInterceptor tracer = getInterceptor(TracingWorkerInterceptor.class);
1✔
516
    if (tracer != null) {
1✔
517
      tracer.assertExpected();
1✔
518
    }
519

520
    for (ScheduledFuture<?> result : delayedCallbacks) {
1!
521
      if (result.isDone() && !result.isCancelled()) {
×
522
        try {
523
          result.get();
×
524
        } catch (InterruptedException e) {
×
525
          Thread.currentThread().interrupt();
×
526
        } catch (ExecutionException e) {
×
527
          throw e.getCause();
×
528
        }
×
529
      }
530
    }
×
531
  }
1✔
532

533
  public void sleep(Duration d) {
534
    if (useExternalService) {
1!
535
      try {
536
        Thread.sleep(d.toMillis());
×
537
      } catch (InterruptedException e) {
×
538
        Thread.currentThread().interrupt();
×
539
        throw new RuntimeException("Interrupted", e);
×
540
      }
×
541
    } else {
542
      testWorkflowRule.getTestEnvironment().sleep(d);
1✔
543
    }
544
  }
1✔
545

546
  /** Causes eviction of all workflows in the worker cache */
547
  // TODO replace the horrible reflection implementation with a normal protected access by hiding
548
  //  WorkerFactory under an interface.
549
  public void invalidateWorkflowCache() {
550
    WorkerFactory workerFactory = testWorkflowRule.getTestEnvironment().getWorkerFactory();
1✔
551
    try {
552
      Method getCache = WorkerFactory.class.getDeclaredMethod("getCache");
1✔
553
      getCache.setAccessible(true);
1✔
554
      WorkflowExecutorCache cache = (WorkflowExecutorCache) getCache.invoke(workerFactory);
1✔
555
      cache.invalidateAll();
1✔
556
      while (cache.size() > 0) {
1!
557
        busyWaitSleep();
×
558
      }
559
    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
×
560
      throw new RuntimeException(e);
×
561
    }
1✔
562
  }
1✔
563

564
  private static boolean isWFTInProgress(HistoryEvent event) {
565
    EventType eventType = event.getEventType();
1✔
566
    switch (eventType) {
1✔
567
      case EVENT_TYPE_WORKFLOW_TASK_STARTED:
568
      case EVENT_TYPE_WORKFLOW_TASK_SCHEDULED:
569
        return true;
1✔
570
      default:
571
        return false;
1✔
572
    }
573
  }
574

575
  private static void busyWaitSleep() {
576
    try {
577
      Thread.sleep(BUSY_WAIT_SLEEP_MS);
1✔
578
    } catch (InterruptedException e) {
×
579
      Thread.currentThread().interrupt();
×
580
      throw new RuntimeException(e);
×
581
    }
1✔
582
  }
1✔
583
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc