mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
test: correct the SYNC_WAIT_MS comment and guard six 202 branches (#656)
The comment added in #652 was wrong. It said SYNC_WAIT_MS=0 drives every tool through its 202 path; it does the opposite. BullMQ arms its timer under `if (ttl)`, so 0 is falsy, waitUntilFinished waits forever and every route answers 200, matching the repo-wide convention that 0 means unlimited. A small positive value such as 1 is what forces the async path. That error mattered: the local validation claimed for #652 exercised the synchronous path throughout and never reached settleAsyncFallback. Redone with SYNC_WAIT_MS=1, it surfaced six specs whose status gate accepts 202 but whose else branch then demands an error body a 202 never carries, a latent flake on a slow runner. Each now settles the job first. Under a forced 1ms window the 'expected undefined to be defined' failures drop from 55 to 0, and all 1183 tests still pass on the normal 30s window. Per-shard totals unchanged at 9903 tests, 9435 passed, 468 skipped. Specs asserting a bare 200 without listing 202 are deliberately untouched: they own the synchronous contract.
This commit is contained in:
@@ -60,6 +60,7 @@ describe("Multipage TIFF handling", () => {
|
|||||||
// Multipage TIFF should either succeed or return a clean error
|
// Multipage TIFF should either succeed or return a clean error
|
||||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||||
|
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
|
|
||||||
|
|||||||
@@ -507,6 +507,7 @@ describe("Image-to-PDF cross-format matrix", () => {
|
|||||||
|
|
||||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||||
|
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
expect(body.downloadUrl).toBeDefined();
|
expect(body.downloadUrl).toBeDefined();
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { fixtureDir } from "../../fixtures/index.js";
|
import { fixtureDir } from "../../fixtures/index.js";
|
||||||
|
import { settleAsyncFallback } from "../settle-job.js";
|
||||||
import { createMultipartPayload } from "../test-server.js";
|
import { createMultipartPayload } from "../test-server.js";
|
||||||
import {
|
import {
|
||||||
ACCEPTABLE_FALLBACK_CODES,
|
ACCEPTABLE_FALLBACK_CODES,
|
||||||
@@ -147,6 +148,7 @@ describe("Image enhancement across all 16 primary formats", () => {
|
|||||||
expect(res.statusCode).toBe(200);
|
expect(res.statusCode).toBe(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
expect(body.corrections).toBeDefined();
|
expect(body.corrections).toBeDefined();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { settleAsyncFallback } from "../settle-job.js";
|
||||||
import { createMultipartPayload } from "../test-server.js";
|
import { createMultipartPayload } from "../test-server.js";
|
||||||
import {
|
import {
|
||||||
ACCEPTABLE_FALLBACK_CODES,
|
ACCEPTABLE_FALLBACK_CODES,
|
||||||
@@ -327,6 +328,7 @@ describe("SVG through raster tools", () => {
|
|||||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||||
|
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
if (tool.id === "info") {
|
if (tool.id === "info") {
|
||||||
expect(body.width).toBeGreaterThan(0);
|
expect(body.width).toBeGreaterThan(0);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||||
import { fixtureDir, fixtures } from "../../fixtures/index.js";
|
import { fixtureDir, fixtures } from "../../fixtures/index.js";
|
||||||
|
import { settleAsyncFallback } from "../settle-job.js";
|
||||||
import {
|
import {
|
||||||
buildTestApp,
|
buildTestApp,
|
||||||
createMultipartPayload,
|
createMultipartPayload,
|
||||||
@@ -414,6 +415,7 @@ describe("Edit-metadata cross-format", () => {
|
|||||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
expect(body.downloadUrl).toBeDefined();
|
expect(body.downloadUrl).toBeDefined();
|
||||||
@@ -465,6 +467,7 @@ describe("Edit-metadata cross-format", () => {
|
|||||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||||
|
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
|
if (await settleAsyncFallback(res)) return;
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
// inspect returns metadata fields; at minimum it is an object
|
// inspect returns metadata fields; at minimum it is an object
|
||||||
expect(typeof body).toBe("object");
|
expect(typeof body).toBe("object");
|
||||||
|
|||||||
@@ -27,11 +27,17 @@ process.env.BULLMQ_PREFIX = `snapotter_test_${suffix}`;
|
|||||||
// test forks; 30s keeps tool routes synchronous (200) in tests while production
|
// test forks; 30s keeps tool routes synchronous (200) in tests while production
|
||||||
// stays at 8s.
|
// stays at 8s.
|
||||||
//
|
//
|
||||||
// An explicit SYNC_WAIT_MS is now honored verbatim rather than floored. The
|
// An explicit SYNC_WAIT_MS is honored verbatim rather than floored, so the
|
||||||
// constrained docker test image (macOS Docker VM, where Sharp and FFmpeg run
|
// constrained docker test image (macOS Docker VM, where Sharp and FFmpeg run
|
||||||
// ~2-3x slower) still widens the window, and forcing it *down* (SYNC_WAIT_MS=0)
|
// ~2-3x slower) can widen the window.
|
||||||
// drives every tool through its 202 path, which is the only way to exercise
|
//
|
||||||
// that branch on a machine fast enough to never hit it naturally.
|
// Careful with 0: per the repo-wide convention it means unlimited, not
|
||||||
|
// instant. BullMQ's waitUntilFinished only arms its timer under `if (ttl)`, so
|
||||||
|
// 0 waits forever and every route answers 200. To force the 202 path (the only
|
||||||
|
// way to exercise it on a machine fast enough never to hit it naturally), pass
|
||||||
|
// a small positive value such as SYNC_WAIT_MS=1. Note that most specs assert a
|
||||||
|
// bare 200 and will fail under it; only the ones that call
|
||||||
|
// settleAsyncFallback are written to survive.
|
||||||
const requestedSyncWait = process.env.SYNC_WAIT_MS?.trim();
|
const requestedSyncWait = process.env.SYNC_WAIT_MS?.trim();
|
||||||
const hasExplicitSyncWait =
|
const hasExplicitSyncWait =
|
||||||
Boolean(requestedSyncWait) && Number.isFinite(Number(requestedSyncWait));
|
Boolean(requestedSyncWait) && Number.isFinite(Number(requestedSyncWait));
|
||||||
|
|||||||
Reference in New Issue
Block a user