blob: 945d5afd9a00e688d3c4f136e4e303a2f9bf6db7 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import assert from 'node:assert/strict';
import { spawnSync } from 'node:child_process';
import {
chmod,
mkdir,
mkdtemp,
readFile,
realpath,
rm,
symlink,
writeFile,
} from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { test } from 'node:test';
import { fileURLToPath } from 'node:url';
import { requireComputerUseLabRoot } from './lab-root.mjs';
test('Computer Use CLI advertises only the supported evidence commands', () => {
const result = spawnSync(
process.execPath,
[fileURLToPath(new URL('../computer-use.mjs', import.meta.url)), '--help'],
{ encoding: 'utf8' },
);
assert.equal(result.status, 0, result.stderr);
assert.equal(
result.stdout,
`Usage: node scripts/computer-use.mjs <command> [options]\n\nCommands:\n prepare\n real-ax\n real-model\n restart-soak\n provider-matrix\n`,
);
});
test('rejects missing and invalid Computer Use Lab roots', async () => {
const root = await mkdtemp(join(tmpdir(), 'maka-cu-lab-root-invalid-'));
try {
assert.throws(
() => requireComputerUseLabRoot({}),
new Error(
'MAKA_CU_AX_MODEL_LAB_ROOT is required: point it at a local checkout of the Codex CUA Lab fixture',
),
);
assert.throws(
() => requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: ' ' }),
/MAKA_CU_AX_MODEL_LAB_ROOT is required/,
);
assert.throws(
() => requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: 'relative/lab' }),
/MAKA_CU_AX_MODEL_LAB_ROOT must be an absolute path/,
);
assert.throws(
() => requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: join(root, 'missing') }),
/MAKA_CU_AX_MODEL_LAB_ROOT must point to an existing directory/,
);
assert.throws(
() => requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: root }),
/MAKA_CU_AX_MODEL_LAB_ROOT must contain an executable test-app\/launch\.sh/,
);
const nonExecutableRoot = join(root, 'non-executable');
const launcherPath = join(nonExecutableRoot, 'test-app', 'launch.sh');
await mkdir(join(nonExecutableRoot, 'test-app'), { recursive: true });
await writeFile(launcherPath, '#!/usr/bin/env bash\n');
await chmod(launcherPath, 0o644);
assert.throws(
() => requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: nonExecutableRoot }),
/MAKA_CU_AX_MODEL_LAB_ROOT must contain an executable test-app\/launch\.sh/,
);
} finally {
await rm(root, { recursive: true, force: true });
}
});
test('canonicalizes a valid Computer Use Lab root', async () => {
const root = await mkdtemp(join(tmpdir(), 'maka-cu-lab-root-valid-'));
try {
const fixtureRoot = join(root, 'fixture');
const linkedRoot = join(root, 'fixture-link');
const launcherPath = join(fixtureRoot, 'test-app', 'launch.sh');
await mkdir(join(fixtureRoot, 'test-app'), { recursive: true });
await writeFile(launcherPath, '#!/usr/bin/env bash\n');
await chmod(launcherPath, 0o755);
await symlink(fixtureRoot, linkedRoot);
assert.equal(
requireComputerUseLabRoot({ MAKA_CU_AX_MODEL_LAB_ROOT: linkedRoot }),
await realpath(fixtureRoot),
);
} finally {
await rm(root, { recursive: true, force: true });
}
});
test('Lab-backed entry points require the configured root', async () => {
const entryPoints = [
'process-restart-harness.mjs',
'process-restart-launcher.mjs',
'real-ax-harness.mjs',
'real-ax-launcher.mjs',
];
for (const entryPoint of entryPoints) {
const source = await readFile(new URL(entryPoint, import.meta.url), 'utf8');
assert.match(
source,
/const labRoot = requireComputerUseLabRoot\(\);/,
`${entryPoint} must require the configured Lab root`,
);
assert.doesNotMatch(
source,
/codex-computer-use-lab/i,
`${entryPoint} must not embed a contributor-specific Lab checkout`,
);
}
});