91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
import { join } from "node:path";
|
|
|
|
import { expect, it, vi } from "vitest";
|
|
|
|
import { buildNativeAotFixture } from "../../../scripts/lib/nativeaot-build.mjs";
|
|
|
|
const options = {
|
|
dotnet: "dotnet",
|
|
project: "fixture.csproj",
|
|
runtime: "win-x64",
|
|
output: "fixture-output",
|
|
};
|
|
|
|
it("restores the exact publish target before compiling without network restore", async () => {
|
|
const run = vi.fn<(command: string, args: string[]) => void>();
|
|
await buildNativeAotFixture(run, options);
|
|
expect(run).toHaveBeenCalledTimes(2);
|
|
const restore = run.mock.calls[0]?.[1] ?? [];
|
|
const publish = run.mock.calls[1]?.[1] ?? [];
|
|
expect(restore[0]).toBe("restore");
|
|
expect(publish[0]).toBe("publish");
|
|
expect(publish).toContain("--no-restore");
|
|
for (const argument of [
|
|
options.project,
|
|
options.runtime,
|
|
"-p:Configuration=Release",
|
|
`-p:BaseIntermediateOutputPath=${join(options.output, "obj")}/`,
|
|
]) {
|
|
expect(restore).toContain(argument);
|
|
expect(publish).toContain(argument);
|
|
}
|
|
});
|
|
|
|
it("retries without logging credential-bearing restore diagnostics", async () => {
|
|
const logged = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
const timeout = Object.assign(
|
|
new Error(
|
|
"dotnet restore ETIMEDOUT https://fixture-user:fixture-password@feed.invalid/v3/index.json",
|
|
),
|
|
{
|
|
code: "ETIMEDOUT",
|
|
},
|
|
);
|
|
const run = vi
|
|
.fn<(command: string, args: string[]) => void>()
|
|
.mockImplementationOnce(() => {
|
|
throw timeout;
|
|
});
|
|
try {
|
|
await buildNativeAotFixture(run, options);
|
|
expect(
|
|
logged.mock.calls.flat().every((value) => typeof value === "string"),
|
|
).toBe(true);
|
|
expect(logged.mock.calls.flat().join("\n")).not.toContain(
|
|
"fixture-password",
|
|
);
|
|
} finally {
|
|
logged.mockRestore();
|
|
}
|
|
expect(run.mock.calls.map((call) => call[1][0])).toEqual([
|
|
"restore",
|
|
"restore",
|
|
"publish",
|
|
]);
|
|
});
|
|
|
|
it("stops after two restore failures and preserves the final diagnostic", async () => {
|
|
const failure = new Error("NuGet source unavailable");
|
|
const run = vi.fn<(command: string, args: string[]) => void>(() => {
|
|
throw failure;
|
|
});
|
|
await expect(buildNativeAotFixture(run, options)).rejects.toMatchObject({
|
|
message: "NativeAOT dependency restore failed after two attempts",
|
|
cause: failure,
|
|
});
|
|
expect(run).toHaveBeenCalledTimes(2);
|
|
expect(run.mock.calls.every((call) => call[1][0] === "restore")).toBe(true);
|
|
});
|
|
|
|
it("does not retry compilation failures", async () => {
|
|
const failure = new Error("Native compiler rejected the fixture");
|
|
const run = vi
|
|
.fn<(command: string, args: string[]) => void>()
|
|
.mockImplementationOnce(() => {})
|
|
.mockImplementationOnce(() => {
|
|
throw failure;
|
|
});
|
|
await expect(buildNativeAotFixture(run, options)).rejects.toBe(failure);
|
|
expect(run).toHaveBeenCalledTimes(2);
|
|
});
|