Adds three new SD-WAN checks (wanAppRtpMos/Loss/Jitter) that measure
REAL voice-traffic quality on actual RTP frames via Prisma DPI, not
synthetic link probes. Graded against the WORST 5-minute window so
transient degradation the 24h link-probe averages smooth away
actually surfaces.
Voice-app selection is tenant-configurable via PRISMA_APP_ID_VOICE +
PRISMA_APP_NAME_VOICE (Webex_Calling_RTP recommended for Webex
Calling shops — the Webex-specific DPI signature excludes non-Webex
UDP noise). Legacy PRISMA_APP_ID_RTP_BASE still honored with a
one-time deprecation warning.
Widens the default WAN look-back from 24h to 7 days: per-app metrics
only get datapoints when calls actually happen, so sporadic Webex
Calling stores (3-4 calls/day) need a wider window for worst-window
statistics to be meaningful. Interval picker snaps 7d to 1hour
buckets (168 pts) to keep payloads bounded while preserving
worst-hour granularity. Hard-capped at 7d — beyond that Prisma
downsamples to 1-day buckets and the signal collapses.
Also:
- Client-side concurrency limiter (PRISMA_MAX_INFLIGHT, default 3)
to prevent 429 cascades when /voicediag fans out 10+ parallel
metric fetches
- "View in Prisma UI" deep links in both /phonestatus WAN follow-up
and /voicediag details, threading through a new
integrations/paloalto/urls.js builder
- humanizeMetricUnit maps raw API unit strings ("percentage",
"milliseconds") to display symbols ("%", "ms") to fix
"11.83percentage" leaking to the UI
- getAppAudio envelope distinguishes not-configured / fetch-failed /
no-traffic states so misleading "set env var" messages don't fire
when the real problem is a 429
Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
3.1 KiB
JavaScript
83 lines
3.1 KiB
JavaScript
// tests/paloalto.urls.test.js
|
|
//
|
|
// Pure unit tests for integrations/paloalto/urls.js — no HTTP, no
|
|
// mocks. The builders here feed deep-link markdown into user-facing
|
|
// output, so any silent format change would show up as broken links
|
|
// in production. The tests spell out both the exact URL shape and
|
|
// the boundary conditions (null ids, base-URL env override).
|
|
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
getPrismaUiBaseUrl,
|
|
buildAppDetailsUrl,
|
|
} from '../integrations/paloalto/urls.js';
|
|
|
|
function withEnv(kvs, fn) {
|
|
const prev = {};
|
|
for (const k of Object.keys(kvs)) prev[k] = process.env[k];
|
|
try {
|
|
for (const [k, v] of Object.entries(kvs)) {
|
|
if (v === undefined) delete process.env[k];
|
|
else process.env[k] = v;
|
|
}
|
|
return fn();
|
|
} finally {
|
|
for (const [k, v] of Object.entries(prev)) {
|
|
if (v === undefined) delete process.env[k];
|
|
else process.env[k] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
test('getPrismaUiBaseUrl: defaults to the production SCM hostname', () => {
|
|
withEnv({ PRISMA_UI_BASE_URL: undefined }, () => {
|
|
assert.equal(getPrismaUiBaseUrl(), 'https://stratacloudmanager.paloaltonetworks.com');
|
|
});
|
|
});
|
|
|
|
test('getPrismaUiBaseUrl: PRISMA_UI_BASE_URL override is honored', () => {
|
|
withEnv({ PRISMA_UI_BASE_URL: 'https://scm.partner.example.com' }, () => {
|
|
assert.equal(getPrismaUiBaseUrl(), 'https://scm.partner.example.com');
|
|
});
|
|
});
|
|
|
|
test('getPrismaUiBaseUrl: trailing slashes are stripped so `${base}/x` concats cleanly', () => {
|
|
// A trailing slash would produce "//insights/…" which some routers
|
|
// treat as a different route from "/insights/…". Normalize.
|
|
withEnv({ PRISMA_UI_BASE_URL: 'https://scm.example.com///' }, () => {
|
|
assert.equal(getPrismaUiBaseUrl(), 'https://scm.example.com');
|
|
});
|
|
});
|
|
|
|
test('getPrismaUiBaseUrl: empty / whitespace env falls back to default', () => {
|
|
withEnv({ PRISMA_UI_BASE_URL: ' ' }, () => {
|
|
assert.equal(getPrismaUiBaseUrl(), 'https://stratacloudmanager.paloaltonetworks.com');
|
|
});
|
|
});
|
|
|
|
test('buildAppDetailsUrl: builds the exact SCM Application Path Details URL', () => {
|
|
// Ground truth from the user (CG00127 + rtp-base app).
|
|
withEnv({ PRISMA_UI_BASE_URL: undefined }, () => {
|
|
const url = buildAppDetailsUrl('16190109915660160', '15932000365560116');
|
|
assert.equal(
|
|
url,
|
|
'https://stratacloudmanager.paloaltonetworks.com/insights/operational/sdwan-applications/15932000365560116/site/16190109915660160/details',
|
|
);
|
|
});
|
|
});
|
|
|
|
test('buildAppDetailsUrl: null / missing ids → null (renderers no-op on falsy)', () => {
|
|
assert.equal(buildAppDetailsUrl(null, '15932000365560116'), null);
|
|
assert.equal(buildAppDetailsUrl('16190109915660160', null), null);
|
|
assert.equal(buildAppDetailsUrl(null, null), null);
|
|
assert.equal(buildAppDetailsUrl('', ''), null);
|
|
});
|
|
|
|
test('buildAppDetailsUrl: numeric ids coerced to strings in the URL (Prisma ids are int-like)', () => {
|
|
withEnv({ PRISMA_UI_BASE_URL: 'https://scm.example.com' }, () => {
|
|
const url = buildAppDetailsUrl(16190109915660160n, 15932000365560116n);
|
|
assert.match(url, /15932000365560116\/site\/16190109915660160\/details$/);
|
|
});
|
|
});
|