Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @param succeededJobs succeeded jobs in the snapshot
* @param failedJobs failed jobs in the snapshot
* @param deadLetteredJobs dead-lettered jobs in the snapshot
* @param conversionSuccessRate succeeded jobs divided by total jobs
* @param conversionSuccessRate succeeded jobs divided by terminal succeeded/failed jobs
* @param p95TimeToPreviewMs p95 time to preview, when available
*/
public record KpiSnapshotRecord(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @param succeededJobs succeeded jobs in the exported snapshot
* @param failedJobs failed jobs in the exported snapshot
* @param deadLetteredJobs dead-lettered jobs in the exported snapshot
* @param conversionSuccessRate succeeded jobs divided by total jobs
* @param conversionSuccessRate succeeded jobs divided by terminal succeeded/failed jobs
* @param p95TimeToPreviewMs p95 time to preview, when available
*/
public record KpiSnapshotExportResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @param succeededJobs jobs with a ready preview artifact
* @param failedJobs jobs in failed state
* @param deadLetteredJobs failed jobs that exhausted retry handling
* @param conversionSuccessRate succeeded jobs divided by total jobs
* @param conversionSuccessRate succeeded jobs divided by terminal succeeded/failed jobs
* @param p95TimeToPreviewMs p95 processing time for succeeded jobs with timestamps
*/
public record KpiSnapshotResponse(
Expand Down Expand Up @@ -64,7 +64,8 @@ public static KpiSnapshotResponse from(List<ConversionJob> jobs) {
}

int total = jobs.size();
double successRate = total == 0 ? 0.0 : (double) succeeded / total;
int terminal = succeeded + failed;
double successRate = terminal == 0 ? 0.0 : (double) succeeded / terminal;
return new KpiSnapshotResponse(
total,
submitted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,44 @@ void fromSkipsPreviewTimingWhenSucceededJobsDoNotHaveCompleteTimestamps() {
assertNull(response.p95TimeToPreviewMs());
}

@Test
void conversionSuccessRateUsesOnlyTerminalOutcomes() {
KpiSnapshotResponse response = KpiSnapshotResponse.from(List.of(
job(ConversionJobStatus.SUCCEEDED),
job(ConversionJobStatus.SUCCEEDED),
job(ConversionJobStatus.FAILED),
job(ConversionJobStatus.SUBMITTED),
job(ConversionJobStatus.PROCESSING)
));

assertEquals(5, response.totalJobs());
assertEquals(1, response.submittedJobs());
assertEquals(1, response.processingJobs());
assertEquals(2, response.succeededJobs());
assertEquals(1, response.failedJobs());
assertEquals(2.0 / 3.0, response.conversionSuccessRate(), 1.0e-12);
}

@Test
void conversionSuccessRateIsZeroUntilOneJobReachesATerminalOutcome() {
KpiSnapshotResponse response = KpiSnapshotResponse.from(List.of(
job(ConversionJobStatus.SUBMITTED),
job(ConversionJobStatus.PROCESSING)
));

assertEquals(0.0, response.conversionSuccessRate());
}

private ConversionJob succeededJob(Instant startedAt, Instant completedAt) {
ConversionJob job = mock(ConversionJob.class);
when(job.getStatus()).thenReturn(ConversionJobStatus.SUCCEEDED);
ConversionJob job = job(ConversionJobStatus.SUCCEEDED);
when(job.getStartedAt()).thenReturn(startedAt);
when(job.getCompletedAt()).thenReturn(completedAt);
return job;
}

private ConversionJob job(ConversionJobStatus status) {
ConversionJob job = mock(ConversionJob.class);
when(job.getStatus()).thenReturn(status);
when(job.isDeadLettered()).thenReturn(false);
return job;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void kpiSnapshotSummarizesCurrentJobStates() {
.jsonPath("$.succeededJobs").isEqualTo(1)
.jsonPath("$.failedJobs").isEqualTo(1)
.jsonPath("$.deadLetteredJobs").isEqualTo(1)
.jsonPath("$.conversionSuccessRate").value(value -> assertEquals(0.25, (Double) value))
.jsonPath("$.conversionSuccessRate").value(value -> assertEquals(0.5, (Double) value))
.jsonPath("$.p95TimeToPreviewMs").value(value -> {
assertNotNull(value);
assertTrue(((Number) value).longValue() >= 0L);
Expand Down
Loading