Files
memind/services/orchestrator/executor-admission-policy.test.mjs
T

68 lines
2.0 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createExecutorAdmissionPolicy } from './executor-admission-policy.mjs';
import {
createExecutorGateway,
createInMemoryExecutorJobStore,
createPhase5ExecutorAdapterRegistry,
} from './executor-gateway.mjs';
function request(overrides = {}) {
return {
jobId: 'job-1',
idempotencyKey: 'idem-1',
executor: 'goosed',
task: {
instruction: 'do it',
workspaceRef: { kind: 'workspace-alias', id: 'canary' },
},
subject: { tenantId: 'tenant-1', userId: 'user-1' },
authorization: { executionAllowed: true },
policy: { sideEffectsAllowed: true },
...overrides,
};
}
test('admission policy enforces allowlists, workspace kinds and durable-store quotas', async () => {
const store = createInMemoryExecutorJobStore();
const policy = createExecutorAdmissionPolicy({
store,
config: {
tenantAllowlist: ['tenant-1'],
userAllowlist: ['user-1'],
maxUserActive: 1,
},
});
assert.equal((await policy.evaluate(request())).allowed, true);
assert.equal(
(await policy.evaluate(request({
subject: { tenantId: 'tenant-2', userId: 'user-1' },
}))).reason,
'executor_tenant_not_allowed',
);
assert.equal(
(await policy.evaluate(request({
task: {
instruction: 'do it',
workspaceRef: { kind: 'absolute-path', id: '/tmp/repo' },
},
}))).reason,
'executor_workspace_kind_not_allowed',
);
const gateway = createExecutorGateway({
store,
registry: createPhase5ExecutorAdapterRegistry({ enabledExecutors: ['goosed'] }),
executionEnabled: true,
admissionPolicy: policy,
});
const first = await gateway.createJob(request());
assert.equal(first.job.status, 'queued');
const second = await gateway.createJob(request({
jobId: 'job-2',
idempotencyKey: 'idem-2',
}));
assert.equal(second.job.status, 'blocked');
assert.equal(second.job.reason, 'executor_user_concurrency_limited');
});