Skip to content

Commit 153eee0

Browse files
committed
test: de-flake jobProgressPublisherEmitsExecutingEvents
The progress publisher is a hot SubmissionPublisher with no replay, and the subscriber can only attach after backtest() returns the handle. With the sub-millisecond test poll interval, the STARTED to COMPLETED loop could emit both EXECUTING events and close the publisher before the subscriber attached, so the assertion occasionally saw no EXECUTING event. Hold the first execution poll until the subscriber is attached via a latch counted down in onSubscribe, making the observation deterministic. Test-only change; no production behavior is affected.
1 parent 9bb8fd7 commit 153eee0

1 file changed

Lines changed: 13 additions & 4 deletions

File tree

src/test/java/com/qtsurfer/api/sdk/workflows/DomainObjectsTest.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,19 @@ void jobProgressPublisherEmitsExecutingEvents() throws Exception {
117117
.thenReturn(new JobState().status(JobState.StatusEnum.COMPLETED).size(1).completed(1));
118118
when(backtestingApi.executeBacktesting(anyString(), eq(DataSourceType.TICKER), any(ExecuteBacktestingRequest.class)))
119119
.thenReturn(new AcceptedJob().jobId("exec-2"));
120+
// The progress publisher is hot (SubmissionPublisher, no replay) and the
121+
// subscriber can only attach after backtest() returns the handle, by which
122+
// point the sub-millisecond poll loop may already have emitted the EXECUTING
123+
// events and closed. Hold the first EXECUTING poll until the subscriber is
124+
// attached so the event is observed deterministically.
125+
CountDownLatch subscribed = new CountDownLatch(1);
120126
when(backtestingApi.getExecutionResult(anyString(), eq(DataSourceType.TICKER), eq("exec-2")))
121-
.thenReturn(new BacktestJobResult()
122-
.state(new JobState().status(JobState.StatusEnum.STARTED).size(100).completed(25))
123-
.results(new ResultMap()))
127+
.thenAnswer(inv -> {
128+
assertTrue(subscribed.await(5, TimeUnit.SECONDS), "subscriber attached before first EXECUTING poll");
129+
return new BacktestJobResult()
130+
.state(new JobState().status(JobState.StatusEnum.STARTED).size(100).completed(25))
131+
.results(new ResultMap());
132+
})
124133
.thenReturn(new BacktestJobResult()
125134
.state(new JobState().status(JobState.StatusEnum.COMPLETED).size(100).completed(100))
126135
.results(new ResultMap().strategyId("strategy-abc")));
@@ -132,7 +141,7 @@ void jobProgressPublisherEmitsExecutingEvents() throws Exception {
132141
CountDownLatch complete = new CountDownLatch(1);
133142
job.progress().subscribe(new Flow.Subscriber<>() {
134143
Flow.Subscription sub;
135-
@Override public void onSubscribe(Flow.Subscription s) { sub = s; s.request(Long.MAX_VALUE); }
144+
@Override public void onSubscribe(Flow.Subscription s) { sub = s; s.request(Long.MAX_VALUE); subscribed.countDown(); }
136145
@Override public void onNext(BacktestProgress p) { seen.add(p); }
137146
@Override public void onError(Throwable t) { complete.countDown(); }
138147
@Override public void onComplete() { complete.countDown(); }

0 commit comments

Comments
 (0)