Files
0pt/tests/analytics/arrow-fixture.test.ts

55 lines
2.2 KiB
TypeScript

/**
* The canonical BI-P005 fixture, in one place.
*
* Two jobs:
* 1. assert the encoder is DETERMINISTIC — the same columns must produce
* byte-identical output, or the "roundtrip" evidence would be comparing
* two different payloads run to run;
* 2. when ARROW_FIXTURE_DIR is set, write those exact bytes to disk so
* scripts/bi-p005-arrow-roundtrip.mjs hands pyarrow and DuckDB the bytes
* the SHIPPED module produces, not a copy of the encoder living in a
* script.
*/
import { describe, it, expect } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import { type ArrowColumn, encodeArrowStream } from '@/src/analytics/arrow/ipc';
/** The same three rows the ClickHouse side of the DoD produces. */
export const BI_P005_FIXTURE: ArrowColumn[] = [
{ name: 'tenant_id', type: 'utf8', values: ['t_alpha', 't_beta', 't_gamma'] },
{ name: 'n', type: 'int64', values: [1, 2, 3] },
{ name: 'v', type: 'float64', values: [1.5, 2.5, 3.25] },
{ name: 'flag', type: 'bool', values: [true, false, true] },
{
name: 'ts',
type: 'timestamp_ms',
values: [
new Date('2026-01-01T00:00:00.000Z'),
new Date('2026-06-15T08:09:10.123Z'),
new Date('2026-09-06T12:34:56.789Z'),
],
},
];
describe('BI-P005 canonical Arrow fixture', () => {
it('encodes deterministically', () => {
const a = encodeArrowStream(BI_P005_FIXTURE);
const b = encodeArrowStream(BI_P005_FIXTURE);
expect(Buffer.from(a).equals(Buffer.from(b))).toBe(true);
expect(a.length).toBeGreaterThan(0);
});
it('writes the fixture for the external roundtrip when asked', () => {
const dir = process.env.ARROW_FIXTURE_DIR;
if (!dir) return; // not an error: the normal test run has nowhere to put it
const bytes = encodeArrowStream(BI_P005_FIXTURE);
const out = path.join(dir, '02_0pt_encoded.arrow');
fs.writeFileSync(out, bytes);
expect(fs.statSync(out).size).toBe(bytes.length);
// Print the digest so the evidence file can be tied to these exact bytes.
console.log(`ARROW_FIXTURE_SHA256=${crypto.createHash('sha256').update(bytes).digest('hex')}`);
});
});