test: consolidate sudo fallback edge-case scenarios

This commit is contained in:
Peter Steinberger
2026-02-22 17:44:58 +00:00
parent 03285465ff
commit 5b078c8305

View File

@@ -70,15 +70,16 @@ async function writeSkillWithInstaller(
return writeSkillWithInstallers(workspaceDir, name, [{ id: "deps", kind, ...extra }]);
}
function mockBinaryAvailability(availableBinaries: string[]) {
const available = new Set(availableBinaries);
function mockAvailableBinaries(binaries: string[]) {
const available = new Set(binaries);
hasBinaryMock.mockImplementation((bin: string) => available.has(bin));
}
function getAptGetCalls() {
return runCommandWithTimeoutMock.mock.calls.filter(
function assertNoAptGetFallbackCalls() {
const aptCalls = runCommandWithTimeoutMock.mock.calls.filter(
(call) => Array.isArray(call[0]) && (call[0] as string[]).includes("apt-get"),
);
expect(aptCalls).toHaveLength(0);
}
describe("skills-install fallback edge cases", () => {
@@ -109,41 +110,55 @@ describe("skills-install fallback edge cases", () => {
await fs.rm(workspaceDir, { recursive: true, force: true }).catch(() => undefined);
});
it("apt-get available but sudo missing/unusable returns helpful error for go install", async () => {
// go not available, brew not available, apt-get + sudo are available, sudo check fails
mockBinaryAvailability(["apt-get", "sudo"]);
it("handles sudo probe failures for go install without apt fallback", async () => {
for (const testCase of [
{
label: "sudo returns password required",
setup: () =>
runCommandWithTimeoutMock.mockResolvedValueOnce({
code: 1,
stdout: "",
stderr: "sudo: a password is required",
}),
assert: (result: { message: string; stderr: string }) => {
expect(result.message).toContain("sudo");
expect(result.message).toContain("https://go.dev/doc/install");
},
},
{
label: "sudo probe throws executable-not-found",
setup: () =>
runCommandWithTimeoutMock.mockRejectedValueOnce(
new Error('Executable not found in $PATH: "sudo"'),
),
assert: (result: { message: string; stderr: string }) => {
expect(result.message).toContain("sudo is not usable");
expect(result.stderr).toContain("Executable not found");
},
},
]) {
runCommandWithTimeoutMock.mockClear();
mockAvailableBinaries(["apt-get", "sudo"]);
testCase.setup();
// sudo -n true fails (no passwordless sudo)
runCommandWithTimeoutMock.mockResolvedValueOnce({
code: 1,
stdout: "",
stderr: "sudo: a password is required",
});
const result = await installSkill({
workspaceDir,
skillName: "go-tool-single",
installId: "deps",
});
const result = await installSkill({
workspaceDir,
skillName: "go-tool-single",
installId: "deps",
});
expect(result.ok).toBe(false);
expect(result.message).toContain("sudo");
expect(result.message).toContain("https://go.dev/doc/install");
// Verify sudo -n true was called
expect(runCommandWithTimeoutMock).toHaveBeenCalledWith(
["sudo", "-n", "true"],
expect.objectContaining({ timeoutMs: 5_000 }),
);
// Verify apt-get install was NOT called
const aptCalls = getAptGetCalls();
expect(aptCalls).toHaveLength(0);
expect(result.ok, testCase.label).toBe(false);
testCase.assert(result);
expect(runCommandWithTimeoutMock, testCase.label).toHaveBeenCalledWith(
["sudo", "-n", "true"],
expect.objectContaining({ timeoutMs: 5_000 }),
);
assertNoAptGetFallbackCalls();
}
});
it("status-selected go installer fails gracefully when apt fallback needs sudo", async () => {
// no go/brew, but apt and sudo are present
mockBinaryAvailability(["apt-get", "sudo"]);
mockAvailableBinaries(["apt-get", "sudo"]);
runCommandWithTimeoutMock.mockResolvedValueOnce({
code: 1,
@@ -165,32 +180,8 @@ describe("skills-install fallback edge cases", () => {
expect(result.message).toContain("sudo is not usable");
});
it("handles sudo probe spawn failures without throwing", async () => {
// go not available, brew not available, apt-get + sudo appear available
mockBinaryAvailability(["apt-get", "sudo"]);
runCommandWithTimeoutMock.mockRejectedValueOnce(
new Error('Executable not found in $PATH: "sudo"'),
);
const result = await installSkill({
workspaceDir,
skillName: "go-tool-single",
installId: "deps",
});
expect(result.ok).toBe(false);
expect(result.message).toContain("sudo is not usable");
expect(result.stderr).toContain("Executable not found");
// Verify apt-get install was NOT called
const aptCalls = getAptGetCalls();
expect(aptCalls).toHaveLength(0);
});
it("uv not installed and no brew returns helpful error without curl auto-install", async () => {
// uv not available, brew not available, curl IS available
mockBinaryAvailability(["curl"]);
mockAvailableBinaries(["curl"]);
const result = await installSkill({
workspaceDir,