Files
RustProxy/tools/checks/backend_protocol_0326_ui_test.mjs
T
2026-10-14 08:19:09 +02:00

55 lines
3.5 KiB
JavaScript

// Verifies real-status-to-badge mapping without guessing a configured Auto result.
import assert from 'node:assert/strict';
import fs from 'node:fs';
import vm from 'node:vm';
const source = fs.readFileSync('src/admin/web/vhosts/render.js', 'utf8');
const block = source.slice(source.indexOf('const VHOST_PROTOCOL_FRESH_MS = '), source.indexOf('function render() {'));
assert(block.includes('function renderUpstreamProtocolBadges(status)'));
const rustClient = fs.readFileSync('src/upstream/client.rs', 'utf8');
const rustPool = fs.readFileSync('src/balance/pool_view.rs', 'utf8');
assert(rustClient.includes('self.inner.observe_protocol(value.version())'));
assert(rustClient.includes('let response = client.request(request).await;'));
for (const name of ['upstream_protocol_observed','upstream_protocol_last_seen_ms','upstream_protocol_http1_total','upstream_protocol_http2_total']) {
assert(rustPool.includes(`"${name}"`), name);
}
const en = JSON.parse(fs.readFileSync('langs/en_US.json', 'utf8')).translations;
const pl = JSON.parse(fs.readFileSync('langs/pl_pl.json', 'utf8')).translations;
for(const key of ['vhBackendProtocolRecent','vhBackendProtocolUnobserved']) assert(en[key] && pl[key]);
const badge = (vhost, backend) => ({dataset:{upstreamProtocolVhost:vhost,upstreamProtocolBackend:backend},textContent:'',title:''});
const visible = [badge('api','auto-backend'),badge('api','h1-backend'),badge('other','auto-backend')];
const envelope = {config:{vhosts:[
{id:'api',backends:[{id:'auto-backend',protocol:'auto'},{id:'h1-backend',protocol:'http1'}]},
{id:'other',backends:[{id:'auto-backend',protocol:'auto'}]},
]}};
const ctx = {Date, Number, String, Map, envelope, document:{querySelectorAll:()=>visible},t:key=>en[key]};
vm.createContext(ctx);
vm.runInContext(block, ctx);
const recent = Date.now() - 2000;
let status = {backend_pools:[{id:'api',members:[
{id:'auto-backend',upstream_protocol_observed:'h2',upstream_protocol_last_seen_ms:recent,upstream_protocol_http1_total:5,upstream_protocol_http2_total:9},
{id:'h1-backend',upstream_protocol_observed:'h1',upstream_protocol_last_seen_ms:recent,upstream_protocol_http1_total:12},
]}]};
ctx.renderUpstreamProtocolBadges(status);
assert.equal(visible[0].textContent,'auto-backend · AUTO → H2');
assert.equal(visible[0].dataset.observed,'true');
assert(visible[0].title.includes('H1: 5; H2: 9'));
assert.equal(visible[1].textContent,'h1-backend · H1 → H1');
assert.equal(visible[2].textContent,'auto-backend · AUTO → ?');
assert.equal(visible[2].dataset.observed,'false');
// Old/stale response must not masquerade as a recent ALPN observation.
status.backend_pools[0].members[0].upstream_protocol_last_seen_ms = Date.now() - 3600000;
ctx.renderUpstreamProtocolBadges(status);
assert.equal(visible[0].textContent,'auto-backend · AUTO → ?');
assert.equal(visible[0].dataset.observed,'false');
assert(visible[0].title.startsWith(en.vhBackendProtocolUnobserved));
// Fresh data for a similarly named backend from another vhost must not leak.
ctx.renderUpstreamProtocolBadges({backend_pools:[{id:'other',members:[
{id:'auto-backend',upstream_protocol_observed:'h1',upstream_protocol_last_seen_ms:recent}
]}]});
assert.equal(visible[0].textContent,'auto-backend · AUTO → ?');
assert.equal(visible[2].textContent,'auto-backend · AUTO → H1');
ctx.renderUpstreamProtocolBadges({backend_pools:[]});
assert.equal(visible[2].textContent,'auto-backend · AUTO → ?');
console.log('PASS: observed Auto/H1/H2 badges, freshness, cross-vhost isolation and unknown data');