codexmobile-relay / scripts /relay-smoke-basic.mjs
Codex
deploy: CodexMobile Relay
90f0300
Raw
History Blame Contribute Delete
2.38 kB
import {
ApiError,
rateLimitLockFromError,
remainingLockSeconds
} from '../client/src/api.js';
import { buildLocalTargetUrl } from '../server/relay-protocol.js';
import {
nextReconnectDelay,
shouldResetReconnectDelay
} from './relay-mac-client-reconnect.mjs';
import { fail } from './relay-smoke-env.mjs';
export function runBasicRelayAssertions() {
expectInvalidForwardPathRejected();
verifyRateLimitRetryAfterHelpers();
verifyConnectorReconnectPolicy();
}
function expectInvalidForwardPathRejected() {
for (const path of ['//example.com/api/status', '/api/status\r\nx: y']) {
try {
buildLocalTargetUrl(path, 'http://127.0.0.1:3321');
fail('invalid forward path should be rejected', path);
} catch (error) {
if (error.status !== 400 || error.message !== 'relay_invalid_forward_path') {
fail('invalid forward path should fail with relay_invalid_forward_path', error);
}
}
}
}
function verifyRateLimitRetryAfterHelpers() {
const error = new ApiError('请求过快,请稍后再试。', {
status: 429,
code: 'relay_rate_limited',
retryAfter: 3
});
const lock = rateLimitLockFromError(error, 'send', 1000);
if (lock?.scope !== 'send' || lock.retryAfter !== 3 || lock.untilMs !== 4000) {
fail('rate limit helper should create a scoped retryAfter lock', lock);
}
if (remainingLockSeconds(lock, 1001) !== 3 || remainingLockSeconds(lock, 4000) !== 0) {
fail('rate limit helper should expose remaining lock seconds', lock);
}
const ignored = rateLimitLockFromError(new ApiError('offline', { status: 503, code: 'mac_offline' }), 'send', 1000);
if (ignored) {
fail('non-rate-limit errors should not create operation locks', ignored);
}
}
function verifyConnectorReconnectPolicy() {
let delay = nextReconnectDelay(60000, { active: true, idleHeartbeatMs: 300000 });
if (delay.delayMs !== 30000 || delay.nextDelayMs !== 30000) {
fail('active reconnect delay should cap at 30 seconds', delay);
}
delay = nextReconnectDelay(600000, { active: false, idleHeartbeatMs: 300000 });
if (delay.delayMs !== 300000 || delay.nextDelayMs !== 300000) {
fail('idle reconnect delay should cap at 5 minutes', delay);
}
if (shouldResetReconnectDelay(59999) || !shouldResetReconnectDelay(60000)) {
fail('stable online reconnect delay reset should require 60 seconds');
}
}