Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import { afterEach, describe, expect, it } from 'vitest';
|
|
import {
|
|
createLogger,
|
|
currentRequestId,
|
|
getLogLevel,
|
|
nextRequestId,
|
|
renderTraceBytes,
|
|
runWithoutRequestContext,
|
|
runWithRequestId,
|
|
runWithTraceRequest,
|
|
setLogLevel,
|
|
} from '../src/logger';
|
|
|
|
const originalLevel = getLogLevel();
|
|
|
|
afterEach(() => {
|
|
setLogLevel(originalLevel);
|
|
});
|
|
|
|
describe('TRACE diagnostics contract', () => {
|
|
it('renders every byte as continuous lowercase hexadecimal', () => {
|
|
expect(renderTraceBytes(new Uint8Array())).toBe('');
|
|
expect(renderTraceBytes(new Uint8Array([0x00, 0x01, 0x0f, 0x10, 0xff]))).toBe('00010f10ff');
|
|
});
|
|
|
|
it('renders only the addressed Uint8Array view', () => {
|
|
const backing = new Uint8Array([0xaa, 0x00, 0x0f, 0xff, 0xbb]);
|
|
|
|
expect(renderTraceBytes(backing.subarray(1, 4))).toBe('000fff');
|
|
expect(renderTraceBytes(Buffer.from(backing.buffer).subarray(2, 4))).toBe('0fff');
|
|
});
|
|
|
|
it('does not render bytes while TRACE is disabled', () => {
|
|
setLogLevel('info');
|
|
let rendered = false;
|
|
|
|
createLogger('Trace.Contract').trace(() => {
|
|
rendered = true;
|
|
return ['body=%s', renderTraceBytes(new Uint8Array([0xff]))];
|
|
});
|
|
|
|
expect(rendered).toBe(false);
|
|
});
|
|
|
|
it('creates distinct request contexts that survive asynchronous work', async () => {
|
|
setLogLevel('info');
|
|
const beforeDisabled = nextRequestId();
|
|
expect(runWithTraceRequest(() => currentRequestId())).toBeUndefined();
|
|
const afterDisabled = nextRequestId();
|
|
expect(afterDisabled).toBe(beforeDisabled + 1);
|
|
|
|
setLogLevel('trace');
|
|
const observeContext = () =>
|
|
runWithTraceRequest(async () => {
|
|
const before = currentRequestId();
|
|
await Promise.resolve();
|
|
const after = currentRequestId();
|
|
expect(after).toBe(before);
|
|
return after;
|
|
});
|
|
|
|
const first = await observeContext();
|
|
expect(currentRequestId()).toBeUndefined();
|
|
const second = await observeContext();
|
|
expect(currentRequestId()).toBeUndefined();
|
|
|
|
expect(first).toEqual(expect.any(Number));
|
|
expect(first).toBeGreaterThan(0);
|
|
expect(second).toEqual(expect.any(Number));
|
|
expect(second).toBeGreaterThan(0);
|
|
expect(second).not.toBe(first);
|
|
});
|
|
|
|
it('allocates once for nested TRACE contexts and reuses the request id', () => {
|
|
setLogLevel('trace');
|
|
const before = nextRequestId();
|
|
|
|
const observed = runWithTraceRequest(() => {
|
|
const outer = currentRequestId();
|
|
const inner = runWithTraceRequest(() => currentRequestId());
|
|
return { outer, inner };
|
|
});
|
|
|
|
const after = nextRequestId();
|
|
expect(observed.outer).toEqual(expect.any(Number));
|
|
expect(observed.inner).toBe(observed.outer);
|
|
expect(observed.outer).toBe(before + 1);
|
|
expect(after).toBe(before + 2);
|
|
expect(currentRequestId()).toBeUndefined();
|
|
});
|
|
|
|
it('detaches long-lived resources from the current request context', async () => {
|
|
await runWithRequestId(4243, async () => {
|
|
expect(currentRequestId()).toBe(4243);
|
|
const detached = await runWithoutRequestContext(async () => {
|
|
expect(currentRequestId()).toBeUndefined();
|
|
await Promise.resolve();
|
|
return currentRequestId();
|
|
});
|
|
expect(detached).toBeUndefined();
|
|
expect(currentRequestId()).toBe(4243);
|
|
});
|
|
expect(currentRequestId()).toBeUndefined();
|
|
});
|
|
|
|
it('reuses an existing request context even while TRACE is disabled', async () => {
|
|
setLogLevel('info');
|
|
|
|
await runWithRequestId(4242, async () => {
|
|
const observed = await runWithTraceRequest(async () => {
|
|
await Promise.resolve();
|
|
return currentRequestId();
|
|
});
|
|
expect(observed).toBe(4242);
|
|
});
|
|
});
|
|
});
|