Preserve RRD preview frames and clarify onboard K1 status

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 15:27:13 +03:00
parent 67398fef10
commit 92b60de945
19 changed files with 516 additions and 94 deletions
@@ -35,11 +35,28 @@ test('active acquisition exposes STOP and Rerun without another START',()=>{
const active={...device,control:{...device.control,can_start:false,can_stop:true},snapshot:{...device.snapshot,acquisition:'streaming'}};
const markup=render(active);
assert.match(markup,/Остановить устройство/);
assert.match(markup,/sensor-live-layout/);
assert.match(markup,/k1-preview-spatial/);
assert.match(markup,/>Статус</);
assert.match(markup,/>Rerun</);
assert.doesNotMatch(markup,/Восстановить просмотр|nodedc-activity-indicator/);
assert.doesNotMatch(markup,/Инициировать запуск|Обновить просмотр/);
assert.equal(presentation.k1ManualState(active,false).canStart,false);
assert.equal(presentation.k1ManualState(active,false).showStop,true);
});
test('calibration loader stays inside the primary action',()=>{
const starting={...device,control:{...device.control,can_start:false},snapshot:{...device.snapshot,acquisition:'starting'}};
const markup=render(starting);
assert.match(markup,/<button[^>]*aria-busy="true"[\s\S]*?nodedc-activity-indicator[\s\S]*?Запускаем устройство<\/button>/);
assert.equal((markup.match(/nodedc-activity-indicator"/g)||[]).length,1);
assert.doesNotMatch(markup,/Остановить устройство|k1-preview-spatial/);
});
test('completed STOP remains visible while the control connection is checked again',()=>{
const stopped={...device,online:false,verified:false,control:{...device.control,phase:'completed',can_start:false,network_applied:true}};
const markup=render(stopped);
assert.match(markup,/Устройство остановлено/);
assert.match(markup,/Проверить состояние K1/);
assert.doesNotMatch(markup,/Инициировать запуск|нет управления/);
});
test('enrollment handoff opens only the verified current session',()=>{
const inventory={fresh:true,items:[device],operations:[]};
assert.equal(enrolledDevice(inventory,'exact-session'),device);
@@ -0,0 +1,43 @@
import assert from 'node:assert/strict';
import {before,after,test} from 'node:test';
import {execFileSync} from 'node:child_process';
import {createServer} from 'vite';
let server,previewFrames,assertRrd;
before(async()=>{
server=await createServer({appType:'custom',logLevel:'silent',server:{middlewareMode:true}});
({previewFrames,assertRrd}=await server.ssrLoadModule('@xgrids-k1/frontend/sensors/previewFrames.ts'));
});
after(async()=>{await server?.close();});
const array=bytes=>Uint8Array.from(bytes).buffer;
const header=size=>{const value=new Uint8Array(8);value.set([77,67,70,49]);new DataView(value.buffer).setUint32(4,size);return value.buffer;};
test('native RRD crosses many RTC fragments and reaches decoder once, byte-for-byte',()=>{
const payload=execFileSync('../../.venv/bin/python',['-c',`import rerun as rr, numpy as np, sys
r=rr.RecordingStream('synthetic-r10-js'); b=r.binary_stream()
r.log('points',rr.Points3D(np.random.default_rng(42).random((5000,3))))
sys.stdout.buffer.write(b.read())`]);
assert.ok(payload.length>16384);
const calls=[];
const receiver=previewFrames(value=>{assertRrd(value);calls.push(value);});
for(let record=0;record<2;record++){
receiver.push(header(payload.length));
for(let offset=0;offset<payload.length;offset+=16384){
receiver.push(array(payload.subarray(offset,offset+16384)));
if(offset+16384<payload.length)assert.equal(calls.length,record);
}
assert.deepEqual(Buffer.from(calls[record]),payload);
}
assert.equal(calls.length,2);
receiver.close();
});
test('partial, oversized, unframed and invalid records never enter the decoder',()=>{
let calls=0;
const receiver=previewFrames(value=>{assertRrd(value);calls++;});
assert.throws(()=>receiver.push(array([1,2,3])));
assert.throws(()=>receiver.push(header(8*1024*1024+1)));
assert.throws(()=>receiver.push(header(0)));
receiver.push(header(20));receiver.push(array([1,2]));receiver.close();
assert.equal(calls,0);
receiver.push(header(12));assert.throws(()=>receiver.push(array(new Uint8Array(13))));receiver.close();
receiver.push(header(12));assert.throws(()=>receiver.push(array(new Uint8Array(12))));
assert.equal(calls,0);
});