



















@@ -923,6 +923,47 @@ function isLatestGenAiModelCallSpan(span: CapturedSpan): boolean {
923923);
924924}
925925926+async function delay(ms: number): Promise<void> {
927+await new Promise((resolve) => setTimeout(resolve, ms));
928+}
929+930+function hasRequiredSmokeSignals(receiver: ReturnType<typeof startLocalOtlpReceiver>): boolean {
931+const spanNames = new Set(receiver.capturedSpans.map((span) => span.name));
932+const metricNames = new Set(receiver.capturedMetrics.map((metric) => metric.name));
933+return (
934+REQUIRED_SPAN_NAMES.every((name) => spanNames.has(name)) &&
935+receiver.capturedSpans.some(isLatestGenAiModelCallSpan) &&
936+REQUIRED_METRIC_NAMES.every((name) => metricNames.has(name)) &&
937+receiver.capturedLogRecords.length > 0 &&
938+["traces", "metrics", "logs"].every((signal) =>
939+receiver.capturedRequests.some((request) => request.signal === signal)
940+)
941+);
942+}
943+944+async function waitForExpectedTelemetry(
945+ receiver: ReturnType<typeof startLocalOtlpReceiver>,
946+ timeoutMs: number,
947+): Promise<void> {
948+const deadline = Date.now() + timeoutMs;
949+while (Date.now() < deadline) {
950+if (hasRequiredSmokeSignals(receiver)) {
951+return;
952+}
953+await delay(250);
954+}
955+}
956+957+function formatBoundedList(values: readonly string[], maxItems: number): string {
958+if (values.length === 0) {
959+return "(none)";
960+}
961+ const visible = values.slice(0, maxItems);
962+ const suffix =
963+ values.length > visible.length ? `, ... (${values.length - visible.length} more)` : "";
964+return `${visible.join(", ")}${suffix}`;
965+}
966+926967function assertSmoke(params: {
927968childExitCode: number;
928969disallowedBodyNeedles: string[];
@@ -1075,7 +1116,11 @@ async function main() {
10751116child.stdout?.on("data", (chunk) => process.stdout.write(chunk));
10761117child.stderr?.on("data", (chunk) => process.stderr.write(chunk));
10771118childExitCode = await waitForChild(child);
1078-await new Promise((resolve) => setTimeout(resolve, 3000));
1119+if (childExitCode === 0) {
1120+await waitForExpectedTelemetry(receiver, 15_000);
1121+} else {
1122+await delay(3000);
1123+}
10791124} finally {
10801125try {
10811126await collector?.close();
@@ -1136,6 +1181,20 @@ async function main() {
11361181for (const failure of assertion.failures) {
11371182process.stderr.write(`qa-otel-smoke: ${failure}\n`);
11381183}
1184+process.stderr.write(
1185+`qa-otel-smoke: captured request counts traces=${assertion.signalRequestCounts.traces} ` +
1186+`metrics=${assertion.signalRequestCounts.metrics} logs=${assertion.signalRequestCounts.logs}\n`,
1187+);
1188+process.stderr.write(
1189+`qa-otel-smoke: captured decoded counts spans=${receiver.capturedSpans.length} ` +
1190+`metrics=${receiver.capturedMetrics.length} logs=${receiver.capturedLogRecords.length}\n`,
1191+);
1192+process.stderr.write(
1193+`qa-otel-smoke: captured span names: ${formatBoundedList(assertion.spanNames, 40)}\n`,
1194+);
1195+process.stderr.write(
1196+`qa-otel-smoke: captured metric names: ${formatBoundedList(assertion.metricNames, 40)}\n`,
1197+);
11391198for (const [signal, contexts] of Object.entries(assertion.leakContexts)) {
11401199for (const context of contexts ?? []) {
11411200process.stderr.write(`qa-otel-smoke: ${signal} leak context: ${context}\n`);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。