production runtime and mock removal
This commit is contained in:
@@ -4,8 +4,7 @@ import {
|
||||
bailianStatus,
|
||||
buildBailianImagePayload,
|
||||
buildBailianVideoPayload,
|
||||
deriveBailianNativeBaseUrl,
|
||||
shouldMockBailian
|
||||
deriveBailianNativeBaseUrl
|
||||
} from "@/lib/bailian/client";
|
||||
|
||||
afterEach(() => {
|
||||
@@ -13,7 +12,6 @@ afterEach(() => {
|
||||
delete process.env.BAILIAN_VIDEO_MODEL;
|
||||
delete process.env.BAILIAN_API_KEY;
|
||||
delete process.env.DASHSCOPE_API_KEY;
|
||||
delete process.env.BAILIAN_MOCK;
|
||||
});
|
||||
|
||||
describe("Bailian client", () => {
|
||||
@@ -22,12 +20,6 @@ describe("Bailian client", () => {
|
||||
.toBe("https://workspace.cn-beijing.maas.aliyuncs.com");
|
||||
});
|
||||
|
||||
it("does not silently mock when the API key is missing", () => {
|
||||
expect(shouldMockBailian()).toBe(false);
|
||||
process.env.BAILIAN_MOCK = "true";
|
||||
expect(shouldMockBailian()).toBe(true);
|
||||
});
|
||||
|
||||
it("builds Wan 2.7 text-to-image and reference-image payloads", () => {
|
||||
const text = buildBailianImagePayload("image.generate", { prompt: "海边酒店", width: 2048, height: 2048 });
|
||||
expect(text).toMatchObject({ model: "wan2.7-image-pro", parameters: { size: "2048*2048", thinking_mode: true, watermark: false } });
|
||||
|
||||
@@ -9,7 +9,7 @@ describe("Go billing core compatibility fixture", () => {
|
||||
statuses: { insufficientBalance: 402, idempotencyConflict: 409 },
|
||||
idempotencyKeys: { charge: "job-charge:{jobId}", refund: "job-refund:{jobId}" },
|
||||
quote: { quantityRounding: "ceil", tiedWinner: "ambiguity_error", tierStandardFactors: "multiply", tierMarkupMultipliers: "maximum" },
|
||||
exemptions: { billingDisabled: true, mockProvider: true, platformSuperAdminQuota: true }
|
||||
exemptions: { billingDisabled: true, platformSuperAdminQuota: true }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,6 @@ describe("jobs v1 cross-language contract", () => {
|
||||
runtimeDir = await mkdtemp(join(tmpdir(), "zhinian-jobs-contract-"));
|
||||
process.env.ZHINIAN_RUNTIME_DIR = runtimeDir;
|
||||
process.env.ZHINIAN_DATA_BACKEND = "local";
|
||||
process.env.JIMENG_VISUAL_MOCK = "true";
|
||||
const request = new Request("http://local.test/api/v1/jobs", {
|
||||
headers: { "Idempotency-Key": "header-key" },
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { describe, expect, it } from "vitest";
|
||||
describe("Go provider adapter contract",()=>{it("freezes bounded adapters and safe errors",async()=>{const c=JSON.parse(await readFile(new URL("../contracts/providers/http-v1.json",import.meta.url),"utf8"));expect(Object.keys(c.providers)).toEqual(["volcengine-visual","evolink","bailian","seedance","mock"]);expect(c.errors).toEqual({generic:true,secretSafe:true});expect(c.liveCallsInTests).toBe(false);});});
|
||||
describe("Go provider adapter contract",()=>{it("freezes bounded adapters and safe errors",async()=>{const c=JSON.parse(await readFile(new URL("../contracts/providers/http-v1.json",import.meta.url),"utf8"));expect(Object.keys(c.providers)).toEqual(["volcengine-visual","evolink","bailian","seedance"]);expect(c.errors).toEqual({generic:true,secretSafe:true});expect(c.liveCallsInTests).toBe(false);});});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { mkdtemp, rm } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
authenticatePublicApiRequest,
|
||||
publicApiOwnerId,
|
||||
@@ -22,9 +22,8 @@ const envNames = [
|
||||
"ZHINIAN_RUNTIME_DIR",
|
||||
"ZHINIAN_DATA_BACKEND",
|
||||
"ZHINIAN_API_KEYS",
|
||||
"JIMENG_VISUAL_MOCK",
|
||||
"IMAGE_GENERATE_ENGINE",
|
||||
"EVOLINK_MOCK",
|
||||
"ZHINIAN_WORKER_POLL_INTERVAL_MS",
|
||||
"EVOLINK_API_KEY",
|
||||
"VOLCENGINE_ACCESS_KEY_ID",
|
||||
"VOLCENGINE_SECRET_ACCESS_KEY",
|
||||
@@ -42,23 +41,36 @@ describe("task management and public API helpers", () => {
|
||||
for (const name of envNames) previousEnv.set(name, process.env[name]);
|
||||
process.env.ZHINIAN_RUNTIME_DIR = runtimeDir;
|
||||
process.env.ZHINIAN_DATA_BACKEND = "local";
|
||||
process.env.ZHINIAN_WORKER_POLL_INTERVAL_MS = "1";
|
||||
process.env.ZHINIAN_API_KEYS = "agent-a:secret-a,agent-b:secret-b";
|
||||
process.env.JIMENG_VISUAL_MOCK = "true";
|
||||
process.env.VOLCENGINE_ACCESS_KEY_ID = "test-access";
|
||||
process.env.VOLCENGINE_SECRET_ACCESS_KEY = "test-secret";
|
||||
delete process.env.IMAGE_GENERATE_ENGINE;
|
||||
delete process.env.EVOLINK_MOCK;
|
||||
delete process.env.EVOLINK_API_KEY;
|
||||
delete process.env.VOLCENGINE_ACCESS_KEY_ID;
|
||||
delete process.env.VOLCENGINE_SECRET_ACCESS_KEY;
|
||||
delete process.env.ALI_OSS_ENDPOINT;
|
||||
delete process.env.ALI_OSS_BUCKET;
|
||||
delete process.env.ALI_OSS_ACCESS_KEY_ID;
|
||||
delete process.env.ALI_OSS_ACCESS_KEY_SECRET;
|
||||
delete process.env.ALI_OSS_PUBLIC_BASE_URL;
|
||||
vi.stubGlobal("fetch", vi.fn(async (input: RequestInfo | URL) => {
|
||||
const target = String(input);
|
||||
if (target.includes("CVSync2AsyncSubmitTask")) {
|
||||
return new Response(JSON.stringify({ code: 10000, data: { task_id: "visual-task-1" } }), { status: 200, headers: { "Content-Type": "application/json" } });
|
||||
}
|
||||
if (target.includes("CVSync2AsyncGetResult")) {
|
||||
return new Response(JSON.stringify({ code: 10000, data: { status: "done", image_urls: ["https://cdn.test/result.png"] } }), { status: 200, headers: { "Content-Type": "application/json" } });
|
||||
}
|
||||
if (target === "https://cdn.test/result.png") {
|
||||
return new Response(new Uint8Array([137, 80, 78, 71]), { status: 200, headers: { "Content-Type": "image/png" } });
|
||||
}
|
||||
throw new Error(`unexpected test fetch: ${target}`);
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
for (const name of envNames) restoreEnv(name, previousEnv.get(name));
|
||||
previousEnv.clear();
|
||||
vi.unstubAllGlobals();
|
||||
await rm(runtimeDir, { force: true, recursive: true });
|
||||
});
|
||||
|
||||
@@ -139,7 +151,6 @@ describe("task management and public API helpers", () => {
|
||||
|
||||
it("passes EvoLink quality through public image jobs", async () => {
|
||||
process.env.IMAGE_GENERATE_ENGINE = "evolink";
|
||||
process.env.EVOLINK_MOCK = "true";
|
||||
process.env.EVOLINK_API_KEY = "test-key";
|
||||
const result = await createPublicGenerationJob({
|
||||
client: { id: "agent-a", key: "secret-a" },
|
||||
@@ -151,7 +162,7 @@ describe("task management and public API helpers", () => {
|
||||
quality: "high"
|
||||
}
|
||||
});
|
||||
expect(result.job.provider).toBe("mock");
|
||||
expect(result.job.provider).toBe("evolink");
|
||||
expect(result.job.requestPayload.providerPayload).toMatchObject({
|
||||
model: "gpt-image-2",
|
||||
quality: "high"
|
||||
@@ -160,11 +171,11 @@ describe("task management and public API helpers", () => {
|
||||
|
||||
it("allows image jobs to override the default generation engine", async () => {
|
||||
process.env.IMAGE_GENERATE_ENGINE = "evolink";
|
||||
process.env.EVOLINK_MOCK = "true";
|
||||
process.env.EVOLINK_API_KEY = "test-key";
|
||||
|
||||
const jimengJob = await submitImageJob({
|
||||
ownerId: DEFAULT_OWNER_ID,
|
||||
externalClientId: "agent-test",
|
||||
capability: "image.generate",
|
||||
engine: "jimeng",
|
||||
prompt: "即梦模板",
|
||||
@@ -178,6 +189,7 @@ describe("task management and public API helpers", () => {
|
||||
|
||||
const image2Job = await submitImageJob({
|
||||
ownerId: DEFAULT_OWNER_ID,
|
||||
externalClientId: "agent-test",
|
||||
capability: "image.generate",
|
||||
engine: "evolink",
|
||||
prompt: "Image2 模板",
|
||||
@@ -194,7 +206,7 @@ describe("task management and public API helpers", () => {
|
||||
await Promise.all(Array.from({ length: 6 }, (_, index) => createGenerationJob({
|
||||
ownerId: DEFAULT_OWNER_ID,
|
||||
capability: "image.generate",
|
||||
provider: "mock",
|
||||
provider: "volcengine-visual",
|
||||
reqKey: "jimeng_seedream46_cvtob",
|
||||
status: "queued",
|
||||
prompt: `job ${index}`,
|
||||
@@ -214,7 +226,7 @@ describe("task management and public API helpers", () => {
|
||||
expect(await claimGenerationJobs({ workerId: "worker-c", limit: 1 })).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("processes a mock queued job to a terminal result through the worker tick", async () => {
|
||||
it("processes a real-provider queued job to a terminal result through the worker tick", async () => {
|
||||
const job = await createPublicGenerationJob({
|
||||
client: { id: "agent-a", key: "secret-a" },
|
||||
request: new Request("http://local.test/api/v1/jobs"),
|
||||
@@ -225,13 +237,22 @@ describe("task management and public API helpers", () => {
|
||||
}
|
||||
});
|
||||
expect(job.job.status).toBe("queued");
|
||||
const tick = await runWorkerTick({
|
||||
let tick = await runWorkerTick({
|
||||
workerId: "test-worker",
|
||||
origin: "http://local.test",
|
||||
limit: 1
|
||||
});
|
||||
expect(tick.claimed).toBe(1);
|
||||
const stored = await getGenerationJob(job.job.id);
|
||||
let stored = await getGenerationJob(job.job.id);
|
||||
for (let attempt = 0; attempt < 3 && stored?.status !== "succeeded"; attempt += 1) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
tick = await runWorkerTick({
|
||||
workerId: "test-worker",
|
||||
origin: "http://local.test",
|
||||
limit: 1
|
||||
});
|
||||
stored = await getGenerationJob(job.job.id);
|
||||
}
|
||||
expect(stored?.status).toBe("succeeded");
|
||||
expect(stored?.completedAt).toBeTruthy();
|
||||
expect(stored?.outputAssetIds.length).toBe(1);
|
||||
|
||||
Reference in New Issue
Block a user