@oneuptime/common 14.0.2 → 14.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/AlertFeed.ts +2 -0
- package/Models/DatabaseModels/IncidentAlert.ts +540 -0
- package/Models/DatabaseModels/IncidentFeed.ts +2 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Project.ts +60 -0
- package/Models/DatabaseModels/RumApplication.ts +52 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/IncidentAlertService.ts +1811 -0
- package/Server/Services/IncidentService.ts +210 -10
- package/Server/Services/IncidentStateTimelineService.ts +24 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
- package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
- package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
- package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
- package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
- package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
- package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
- package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
- package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
- package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
- package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
- package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
- package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
- package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
- package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
- package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
- package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
- package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
- package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
- package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
- package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
- package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
- package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
- package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
- package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
- package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
- package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
- package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
- package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
- package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
- package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
- package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
- package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
- package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
- package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
- package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
- package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
- package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
- package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
- package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
- package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
- package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
- package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
- package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
- package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
- package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
- package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
- package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
- package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
- package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
- package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
- package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
- package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
- package/Tests/Types/Rum/WebVitals.test.ts +173 -0
- package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
- package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
- package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
- package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
- package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
- package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
- package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
- package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
- package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
- package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
- package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
- package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
- package/Types/Incident/IncidentAlertLink.ts +38 -0
- package/Types/Permission.ts +48 -0
- package/Types/Rum/SessionReplay.ts +25 -6
- package/Types/Rum/WebVitals.ts +52 -0
- package/UI/Components/Detail/FieldLabel.tsx +8 -0
- package/UI/Components/InfoCard/InfoCard.tsx +47 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +95 -17
- package/UI/Components/ModelTable/Column.ts +5 -0
- package/UI/Components/Table/TableHeader.tsx +47 -2
- package/UI/Components/Table/Types/Column.ts +7 -0
- package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
- package/UI/Utils/PermissionGate.ts +11 -2
- package/Utils/Incident/IncidentFromAlerts.ts +516 -0
- package/Utils/Rum/SessionTraceState.ts +212 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
- package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +62 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
- package/build/dist/Server/Services/IncidentService.js +164 -12
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
- package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/WebVitals.js +25 -0
- package/build/dist/Types/Rum/WebVitals.js.map +1 -1
- package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
- package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +66 -14
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +18 -2
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
- package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
- package/build/dist/UI/Utils/PermissionGate.js +4 -2
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
- package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
- package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { CEPH_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/CephMetricDescriptions";
|
|
5
|
+
import {
|
|
6
|
+
CLOUD_INSTANCE_METRIC_DESCRIPTIONS,
|
|
7
|
+
CLOUD_METRIC_DESCRIPTIONS,
|
|
8
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/CloudMetricDescriptions";
|
|
9
|
+
import { CONTAINER_HOST_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/ContainerHostMetricDescriptions";
|
|
10
|
+
import {
|
|
11
|
+
DOCKER_SWARM_INSIGHTS_CHART_DESCRIPTIONS,
|
|
12
|
+
DOCKER_SWARM_METRIC_DESCRIPTIONS,
|
|
13
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/DockerSwarmMetricDescriptions";
|
|
14
|
+
import { HOST_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/HostMetricDescriptions";
|
|
15
|
+
import { KUBERNETES_CLUSTER_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/KubernetesClusterMetricDescriptions";
|
|
16
|
+
import { PROXMOX_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/ProxmoxMetricDescriptions";
|
|
17
|
+
import { VMWARE_METRIC_DESCRIPTIONS } from "../../../../App/FeatureSet/Dashboard/src/Components/MetricDescriptions/VMwareMetricDescriptions";
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* The same idea, explained the same way on every resource page.
|
|
21
|
+
*
|
|
22
|
+
* MetricDescriptionsCatalog.test.ts holds each text to the shape rules; the
|
|
23
|
+
* per-resource tests hold each text to its own page's code. This file reads
|
|
24
|
+
* every family side by side, so a customer who meets "p95", "the last 5
|
|
25
|
+
* minutes of the selected range" or "100% is one core" on one page reads
|
|
26
|
+
* the same words - and the same caveats - on the next.
|
|
27
|
+
*
|
|
28
|
+
* Only wording is pinned here. Whether a sentence is TRUE for its page is
|
|
29
|
+
* the job of that family's own test, which reads the page's code.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const DESCRIPTIONS_DIR: string = path.join(
|
|
33
|
+
__dirname,
|
|
34
|
+
"..",
|
|
35
|
+
"..",
|
|
36
|
+
"..",
|
|
37
|
+
"..",
|
|
38
|
+
"App",
|
|
39
|
+
"FeatureSet",
|
|
40
|
+
"Dashboard",
|
|
41
|
+
"src",
|
|
42
|
+
"Components",
|
|
43
|
+
"MetricDescriptions",
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
type Entry = { where: string; text: string };
|
|
47
|
+
|
|
48
|
+
function loadEveryText(): Array<Entry> {
|
|
49
|
+
const entries: Array<Entry> = [];
|
|
50
|
+
|
|
51
|
+
for (const file of fs.readdirSync(DESCRIPTIONS_DIR).sort()) {
|
|
52
|
+
if (!file.endsWith(".ts") || file.endsWith(".d.ts")) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
57
|
+
const module: Record<string, unknown> = require(
|
|
58
|
+
path.join(DESCRIPTIONS_DIR, file),
|
|
59
|
+
) as Record<string, unknown>;
|
|
60
|
+
|
|
61
|
+
for (const [exportName, value] of Object.entries(module)) {
|
|
62
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const [key, text] of Object.entries(
|
|
67
|
+
value as Record<string, unknown>,
|
|
68
|
+
)) {
|
|
69
|
+
if (typeof text === "string") {
|
|
70
|
+
entries.push({ where: `${exportName}.${key}`, text });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return entries;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const EVERY_TEXT: Array<Entry> = loadEveryText();
|
|
80
|
+
|
|
81
|
+
function offenders(check: (text: string) => boolean): Array<string> {
|
|
82
|
+
return EVERY_TEXT.filter((entry: Entry): boolean => {
|
|
83
|
+
return check(entry.text);
|
|
84
|
+
}).map((entry: Entry): string => {
|
|
85
|
+
return entry.where;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const SLOT_OR_BUCKET: RegExp = /\b(time slots?|slots?|buckets?)\b/i;
|
|
90
|
+
const LAST_FIVE_MINUTES_OF_RANGE: RegExp =
|
|
91
|
+
/last 5 minutes of the (selected )?range/;
|
|
92
|
+
const OFTEN_WHOLE_RANGE: RegExp = /often the whole range(?! on ranges over)/;
|
|
93
|
+
const P95_TOKEN: RegExp = /\bp95\b/;
|
|
94
|
+
const PERCENTILE_TOKEN: RegExp = /\bp(\d{2})\b/g;
|
|
95
|
+
const RECLAIM: RegExp = /reclaim/i;
|
|
96
|
+
const ALLOCATABLE_EXPLAINED: RegExp =
|
|
97
|
+
/hand out to pods|left for pods|pods can use/;
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
* The fleet-wide overview tiles that average only the last 5 minutes fall
|
|
101
|
+
* back to the whole range when no interval STARTS in that window - usual
|
|
102
|
+
* past 12 hours, whose intervals are 15 minutes or wider. The one text
|
|
103
|
+
* exempt here names a 5-minute figure used only while the page loads.
|
|
104
|
+
*/
|
|
105
|
+
const LOADING_ONLY_FIVE_MINUTE_FALLBACK: Array<string> = [
|
|
106
|
+
"VMWARE_METRIC_DESCRIPTIONS.overviewDatastores",
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
describe("metric descriptions read the same across resource types", () => {
|
|
110
|
+
test("the catalog found every family", () => {
|
|
111
|
+
expect(EVERY_TEXT.length).toBeGreaterThan(400);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("an interval is called an interval, never a time slot or a bucket", () => {
|
|
115
|
+
expect(
|
|
116
|
+
offenders((text: string): boolean => {
|
|
117
|
+
return SLOT_OR_BUCKET.test(text);
|
|
118
|
+
}),
|
|
119
|
+
).toEqual([]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("every 5-minute tile says it is usually the whole range past 12 hours", () => {
|
|
123
|
+
const missing: Array<string> = EVERY_TEXT.filter(
|
|
124
|
+
(entry: Entry): boolean => {
|
|
125
|
+
return (
|
|
126
|
+
LAST_FIVE_MINUTES_OF_RANGE.test(entry.text) &&
|
|
127
|
+
!entry.text.includes("12 hours") &&
|
|
128
|
+
!LOADING_ONLY_FIVE_MINUTE_FALLBACK.includes(entry.where)
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
).map((entry: Entry): string => {
|
|
132
|
+
return entry.where;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(missing).toEqual([]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("the whole-range fallback names its threshold wherever it says 'often'", () => {
|
|
139
|
+
expect(
|
|
140
|
+
offenders((text: string): boolean => {
|
|
141
|
+
return OFTEN_WHOLE_RANGE.test(text);
|
|
142
|
+
}),
|
|
143
|
+
).toEqual([]);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("the fallback wording is shared by the Kubernetes, Proxmox, VMware and container host tiles", () => {
|
|
147
|
+
const canonical: string =
|
|
148
|
+
"(often the whole range on ranges over 12 hours or without recent data)";
|
|
149
|
+
|
|
150
|
+
for (const text of [
|
|
151
|
+
KUBERNETES_CLUSTER_METRIC_DESCRIPTIONS.cpu,
|
|
152
|
+
KUBERNETES_CLUSTER_METRIC_DESCRIPTIONS.memory,
|
|
153
|
+
PROXMOX_METRIC_DESCRIPTIONS.clusterMemory,
|
|
154
|
+
VMWARE_METRIC_DESCRIPTIONS.overviewHostCpu,
|
|
155
|
+
VMWARE_METRIC_DESCRIPTIONS.overviewHostMemory,
|
|
156
|
+
VMWARE_METRIC_DESCRIPTIONS.overviewVmCpuReady,
|
|
157
|
+
CONTAINER_HOST_METRIC_DESCRIPTIONS.avgCpu,
|
|
158
|
+
CONTAINER_HOST_METRIC_DESCRIPTIONS.peakMemory,
|
|
159
|
+
]) {
|
|
160
|
+
expect(text).toContain(canonical);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The Host tiles say the same with "usually", pinned by their own test.
|
|
164
|
+
expect(HOST_METRIC_DESCRIPTIONS.cpu).toContain("12 hours");
|
|
165
|
+
expect(HOST_METRIC_DESCRIPTIONS.cpu).toContain("no recent data");
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("every percentile is introduced the same way: 'pNN means the NNth percentile'", () => {
|
|
169
|
+
const unexplained: Array<string> = [];
|
|
170
|
+
|
|
171
|
+
for (const entry of EVERY_TEXT) {
|
|
172
|
+
for (const match of entry.text.matchAll(PERCENTILE_TOKEN)) {
|
|
173
|
+
const rank: string = match[1]!;
|
|
174
|
+
|
|
175
|
+
if (!entry.text.includes(`p${rank} means the ${rank}th percentile`)) {
|
|
176
|
+
unexplained.push(`${entry.where}: p${rank}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
expect(unexplained).toEqual([]);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("every tile that averages per-interval p95s says each interval counts the same", () => {
|
|
185
|
+
expect(
|
|
186
|
+
offenders((text: string): boolean => {
|
|
187
|
+
return (
|
|
188
|
+
P95_TOKEN.test(text) &&
|
|
189
|
+
text.includes("then averaged over the selected range") &&
|
|
190
|
+
!text.includes("so quiet and busy intervals count equally")
|
|
191
|
+
);
|
|
192
|
+
}),
|
|
193
|
+
).toEqual([]);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("an agent that disconnects after 15 minutes of silence, checked every 5, says 15 to 20", () => {
|
|
197
|
+
for (const text of [
|
|
198
|
+
KUBERNETES_CLUSTER_METRIC_DESCRIPTIONS.agentStatus,
|
|
199
|
+
PROXMOX_METRIC_DESCRIPTIONS.agentStatus,
|
|
200
|
+
VMWARE_METRIC_DESCRIPTIONS.overviewAgentStatus,
|
|
201
|
+
]) {
|
|
202
|
+
expect(text).toContain("15 to 20 minutes after data stops arriving");
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test("docker_stats container memory leaves out the same cache on the host and Swarm pages", () => {
|
|
207
|
+
for (const text of [
|
|
208
|
+
CONTAINER_HOST_METRIC_DESCRIPTIONS.containerMemory,
|
|
209
|
+
DOCKER_SWARM_METRIC_DESCRIPTIONS.taskMemory,
|
|
210
|
+
DOCKER_SWARM_METRIC_DESCRIPTIONS.taskMemoryColumn,
|
|
211
|
+
DOCKER_SWARM_INSIGHTS_CHART_DESCRIPTIONS.taskMemory,
|
|
212
|
+
]) {
|
|
213
|
+
expect(text.toLowerCase()).toContain(
|
|
214
|
+
"file cache the system has not used recently",
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Only inactive cache is subtracted, so nothing claims all of it is.
|
|
219
|
+
expect(
|
|
220
|
+
offenders((text: string): boolean => {
|
|
221
|
+
return RECLAIM.test(text);
|
|
222
|
+
}),
|
|
223
|
+
).toEqual([]);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("docker_stats CPU states its scale in the same words on every page", () => {
|
|
227
|
+
for (const text of [
|
|
228
|
+
CONTAINER_HOST_METRIC_DESCRIPTIONS.avgCpu,
|
|
229
|
+
CONTAINER_HOST_METRIC_DESCRIPTIONS.containerCpu,
|
|
230
|
+
DOCKER_SWARM_INSIGHTS_CHART_DESCRIPTIONS.clusterCpu,
|
|
231
|
+
DOCKER_SWARM_INSIGHTS_CHART_DESCRIPTIONS.topTasksCpu,
|
|
232
|
+
]) {
|
|
233
|
+
expect(text).toContain("100% is one full CPU core");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (const text of [
|
|
237
|
+
CLOUD_METRIC_DESCRIPTIONS.cpu,
|
|
238
|
+
CLOUD_INSTANCE_METRIC_DESCRIPTIONS.cpu,
|
|
239
|
+
]) {
|
|
240
|
+
expect(text).toContain(
|
|
241
|
+
"100% is one full CPU core or all the CPU the task was given",
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
test("no text weighs data against a picker", () => {
|
|
247
|
+
expect(
|
|
248
|
+
offenders((text: string): boolean => {
|
|
249
|
+
return text.includes("not the time range picker");
|
|
250
|
+
}),
|
|
251
|
+
).toEqual([]);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("every Kubernetes text that divides by allocatable says what allocatable is", () => {
|
|
255
|
+
expect(
|
|
256
|
+
offenders((text: string): boolean => {
|
|
257
|
+
return (
|
|
258
|
+
text.includes("allocatable") && !ALLOCATABLE_EXPLAINED.test(text)
|
|
259
|
+
);
|
|
260
|
+
}),
|
|
261
|
+
).toEqual([]);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test("Ceph titles that abbreviate say what the letters stand for", () => {
|
|
265
|
+
expect(CEPH_METRIC_DESCRIPTIONS.clientIops).toContain(
|
|
266
|
+
"operations per second (IOPS)",
|
|
267
|
+
);
|
|
268
|
+
expect(CEPH_METRIC_DESCRIPTIONS.pgStates).toContain(
|
|
269
|
+
"Placement groups (the chunks Ceph splits each pool into)",
|
|
270
|
+
);
|
|
271
|
+
expect(CEPH_METRIC_DESCRIPTIONS.osdStates).toContain(
|
|
272
|
+
"Every OSD (a daemon that stores data, usually one per disk)",
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
});
|