@oneuptime/common 12.0.12 → 12.0.13
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/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +17 -6
- package/Server/Services/LogAggregationService.ts +34 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +300 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +332 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +17 -1
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.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/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +15 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +2 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Which monitor step a result is evaluated against.
|
|
3
|
+
*
|
|
4
|
+
* A monitor can have several steps and EACH step carries its own criteria. A
|
|
5
|
+
* probe result names the step it actually ran in `monitorStepId`, so that step
|
|
6
|
+
* — not whichever step happens to sit first in the array — decides which
|
|
7
|
+
* criteria may match. Five outputs hang off that choice:
|
|
8
|
+
*
|
|
9
|
+
* - `criteriaMetId`, matched against the ingested step's criteria only;
|
|
10
|
+
* - `ingestedMonitorStepId`, echoed back to the probe;
|
|
11
|
+
* - `nextMonitorStepId`, which walks the chain from the ingested step;
|
|
12
|
+
* - the step handed to MonitorCriteriaEvaluator.processMonitorStep;
|
|
13
|
+
* - the step handed to checkProbeAgreement, which keys every other probe's
|
|
14
|
+
* lastMonitoringLog by step id — the wrong id compares this result against
|
|
15
|
+
* other probes' state for a different step.
|
|
16
|
+
*
|
|
17
|
+
* MonitorResource used to run the `.find()` for the ingested step and DISCARD
|
|
18
|
+
* its result, leaving `monitorStep` pinned to `monitorStepsInstanceArray[0]`.
|
|
19
|
+
* Single-step monitors (the overwhelming majority, including every SSL
|
|
20
|
+
* monitor) could not notice; multi-step monitors silently evaluated every
|
|
21
|
+
* step's results against step 0's criteria.
|
|
22
|
+
*
|
|
23
|
+
* A `monitorStepId` that matches NO step is stale — the step was deleted after
|
|
24
|
+
* the probe was scheduled — and still falls back to step 0 rather than
|
|
25
|
+
* dropping the result. That fallback is pinned here too, because it is the one
|
|
26
|
+
* case where "use step 0" is deliberate rather than a bug.
|
|
27
|
+
*
|
|
28
|
+
* Everything heavy is mocked BEFORE importing MonitorResource: the criteria
|
|
29
|
+
* evaluator (pulls native isolated-vm via VMAPI/VMRunner), the monitor and
|
|
30
|
+
* probe services (Postgres), the per-monitor semaphore (Redis), the metric and
|
|
31
|
+
* log utils (ClickHouse) and the logger. checkProbeAgreement is spied on so
|
|
32
|
+
* this suite pins only the step it is HANDED — its internals are covered by
|
|
33
|
+
* MonitorResourceProbeAgreementReuse.test.ts. Pure in-memory model instances.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
jest.mock("../../../../Server/Utils/Monitor/MonitorCriteriaEvaluator", () => {
|
|
37
|
+
return {
|
|
38
|
+
__esModule: true,
|
|
39
|
+
default: {
|
|
40
|
+
processMonitorStep: jest.fn(),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
jest.mock("../../../../Server/Services/MonitorService", () => {
|
|
46
|
+
return {
|
|
47
|
+
__esModule: true,
|
|
48
|
+
default: {
|
|
49
|
+
findOneById: jest.fn(),
|
|
50
|
+
updateColumnsByIdWithoutHooks: jest.fn(),
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
jest.mock("../../../../Server/Services/MonitorProbeService", () => {
|
|
56
|
+
return {
|
|
57
|
+
__esModule: true,
|
|
58
|
+
default: {
|
|
59
|
+
findBy: jest.fn(),
|
|
60
|
+
updateColumnsByIdWithoutHooks: jest.fn(),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
jest.mock("../../../../Server/Infrastructure/Semaphore", () => {
|
|
66
|
+
return {
|
|
67
|
+
__esModule: true,
|
|
68
|
+
default: {
|
|
69
|
+
lock: jest.fn(),
|
|
70
|
+
release: jest.fn(),
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
jest.mock("../../../../Server/Utils/Monitor/MonitorMetricUtil", () => {
|
|
76
|
+
return {
|
|
77
|
+
__esModule: true,
|
|
78
|
+
default: {
|
|
79
|
+
saveMonitorMetrics: jest.fn(),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
jest.mock("../../../../Server/Utils/Monitor/MonitorLogUtil", () => {
|
|
85
|
+
return {
|
|
86
|
+
__esModule: true,
|
|
87
|
+
default: {
|
|
88
|
+
saveMonitorLog: jest.fn(),
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
jest.mock("../../../../Server/Utils/Logger", () => {
|
|
94
|
+
return {
|
|
95
|
+
__esModule: true,
|
|
96
|
+
default: {
|
|
97
|
+
debug: jest.fn(),
|
|
98
|
+
info: jest.fn(),
|
|
99
|
+
warn: jest.fn(),
|
|
100
|
+
error: jest.fn(),
|
|
101
|
+
trace: jest.fn(),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
import MonitorResourceUtil from "../../../../Server/Utils/Monitor/MonitorResource";
|
|
107
|
+
import MonitorCriteriaEvaluator from "../../../../Server/Utils/Monitor/MonitorCriteriaEvaluator";
|
|
108
|
+
import MonitorService from "../../../../Server/Services/MonitorService";
|
|
109
|
+
import MonitorProbeService from "../../../../Server/Services/MonitorProbeService";
|
|
110
|
+
import Semaphore from "../../../../Server/Infrastructure/Semaphore";
|
|
111
|
+
import DataToProcess from "../../../../Server/Utils/Monitor/DataToProcess";
|
|
112
|
+
import Monitor from "../../../../Models/DatabaseModels/Monitor";
|
|
113
|
+
import MonitorProbe from "../../../../Models/DatabaseModels/MonitorProbe";
|
|
114
|
+
import MonitorCriteria from "../../../../Types/Monitor/MonitorCriteria";
|
|
115
|
+
import MonitorCriteriaInstance from "../../../../Types/Monitor/MonitorCriteriaInstance";
|
|
116
|
+
import MonitorStep from "../../../../Types/Monitor/MonitorStep";
|
|
117
|
+
import MonitorSteps from "../../../../Types/Monitor/MonitorSteps";
|
|
118
|
+
import MonitorType from "../../../../Types/Monitor/MonitorType";
|
|
119
|
+
import ServerMonitorResponse from "../../../../Types/Monitor/ServerMonitor/ServerMonitorResponse";
|
|
120
|
+
import ObjectID from "../../../../Types/ObjectID";
|
|
121
|
+
import OneUptimeDate from "../../../../Types/Date";
|
|
122
|
+
import ProbeApiIngestResponse from "../../../../Types/Probe/ProbeApiIngestResponse";
|
|
123
|
+
import ProbeMonitorResponse from "../../../../Types/Probe/ProbeMonitorResponse";
|
|
124
|
+
import { describe, expect, test, beforeEach, afterEach } from "@jest/globals";
|
|
125
|
+
|
|
126
|
+
const processMonitorStepMock: jest.Mock =
|
|
127
|
+
MonitorCriteriaEvaluator.processMonitorStep as unknown as jest.Mock;
|
|
128
|
+
|
|
129
|
+
const findOneByIdMock: jest.Mock =
|
|
130
|
+
MonitorService.findOneById as unknown as jest.Mock;
|
|
131
|
+
|
|
132
|
+
const findByMock: jest.Mock =
|
|
133
|
+
MonitorProbeService.findBy as unknown as jest.Mock;
|
|
134
|
+
|
|
135
|
+
const lockMock: jest.Mock = Semaphore.lock as unknown as jest.Mock;
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* One criteria per step, so the criteria id that comes back on the response
|
|
139
|
+
* names the step it was read off — exactly the coupling the discarded lookup
|
|
140
|
+
* broke.
|
|
141
|
+
*/
|
|
142
|
+
type MakeStep = (criteriaName: string) => MonitorStep;
|
|
143
|
+
|
|
144
|
+
const makeStep: MakeStep = (criteriaName: string): MonitorStep => {
|
|
145
|
+
const criteriaInstance: MonitorCriteriaInstance =
|
|
146
|
+
new MonitorCriteriaInstance();
|
|
147
|
+
criteriaInstance.data!.name = criteriaName;
|
|
148
|
+
|
|
149
|
+
const monitorCriteria: MonitorCriteria = new MonitorCriteria();
|
|
150
|
+
monitorCriteria.data = {
|
|
151
|
+
monitorCriteriaInstanceArray: [criteriaInstance],
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const step: MonitorStep = new MonitorStep();
|
|
155
|
+
step.data!.monitorCriteria = monitorCriteria;
|
|
156
|
+
|
|
157
|
+
return step;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
type CriteriaIdOfStep = (step: MonitorStep) => string;
|
|
161
|
+
|
|
162
|
+
const criteriaIdOfStep: CriteriaIdOfStep = (step: MonitorStep): string => {
|
|
163
|
+
return step.data!.monitorCriteria.data!.monitorCriteriaInstanceArray[0]!.data!
|
|
164
|
+
.id;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
type MakeMonitor = (input: {
|
|
168
|
+
monitorType: MonitorType;
|
|
169
|
+
steps: Array<MonitorStep>;
|
|
170
|
+
}) => Monitor;
|
|
171
|
+
|
|
172
|
+
const makeMonitor: MakeMonitor = (input: {
|
|
173
|
+
monitorType: MonitorType;
|
|
174
|
+
steps: Array<MonitorStep>;
|
|
175
|
+
}): Monitor => {
|
|
176
|
+
const monitorSteps: MonitorSteps = new MonitorSteps();
|
|
177
|
+
monitorSteps.data = {
|
|
178
|
+
monitorStepsInstanceArray: input.steps,
|
|
179
|
+
/*
|
|
180
|
+
* Left undefined on purpose: a set default status sends the
|
|
181
|
+
* no-criteria-met path into MonitorStatusTimelineService, which this
|
|
182
|
+
* suite has no reason to reach.
|
|
183
|
+
*/
|
|
184
|
+
defaultMonitorStatusId: undefined,
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const monitor: Monitor = new Monitor();
|
|
188
|
+
monitor.id = ObjectID.generate();
|
|
189
|
+
monitor.projectId = ObjectID.generate();
|
|
190
|
+
monitor.monitorType = input.monitorType;
|
|
191
|
+
monitor.monitorSteps = monitorSteps;
|
|
192
|
+
|
|
193
|
+
return monitor;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
type MakeProbeResult = (input: {
|
|
197
|
+
monitor: Monitor;
|
|
198
|
+
probeId: ObjectID;
|
|
199
|
+
monitorStepId: ObjectID;
|
|
200
|
+
}) => DataToProcess;
|
|
201
|
+
|
|
202
|
+
const makeProbeResult: MakeProbeResult = (input: {
|
|
203
|
+
monitor: Monitor;
|
|
204
|
+
probeId: ObjectID;
|
|
205
|
+
monitorStepId: ObjectID;
|
|
206
|
+
}): DataToProcess => {
|
|
207
|
+
return {
|
|
208
|
+
projectId: input.monitor.projectId!,
|
|
209
|
+
monitorId: input.monitor.id!,
|
|
210
|
+
probeId: input.probeId,
|
|
211
|
+
monitorStepId: input.monitorStepId,
|
|
212
|
+
isOnline: true,
|
|
213
|
+
failureCause: "",
|
|
214
|
+
} as ProbeMonitorResponse;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
type StepPassedToEvaluator = () => MonitorStep;
|
|
218
|
+
|
|
219
|
+
const stepPassedToEvaluator: StepPassedToEvaluator = (): MonitorStep => {
|
|
220
|
+
return processMonitorStepMock.mock.calls[0]![0].monitorStep;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
describe("MonitorResourceUtil.monitorResource ingested monitor step selection", () => {
|
|
224
|
+
let checkProbeAgreementSpy: jest.SpyInstance;
|
|
225
|
+
|
|
226
|
+
beforeEach(() => {
|
|
227
|
+
jest.clearAllMocks();
|
|
228
|
+
|
|
229
|
+
lockMock.mockResolvedValue({});
|
|
230
|
+
|
|
231
|
+
/*
|
|
232
|
+
* Stands in for the real evaluator in the one respect this suite is
|
|
233
|
+
* about: the criteria it can match are exactly the ones hanging off the
|
|
234
|
+
* step it was handed. rootCause stays null so the criteria-met branch
|
|
235
|
+
* (incidents, alerts, status timeline) never runs.
|
|
236
|
+
*/
|
|
237
|
+
processMonitorStepMock.mockImplementation(
|
|
238
|
+
(input: {
|
|
239
|
+
monitorStep: MonitorStep;
|
|
240
|
+
probeApiIngestResponse: ProbeApiIngestResponse;
|
|
241
|
+
}): Promise<ProbeApiIngestResponse> => {
|
|
242
|
+
return Promise.resolve({
|
|
243
|
+
...input.probeApiIngestResponse,
|
|
244
|
+
criteriaMetId: criteriaIdOfStep(input.monitorStep),
|
|
245
|
+
rootCause: null,
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* Agreement itself is covered elsewhere; here it only has to pass the
|
|
252
|
+
* evaluated criteria through so the response still reports it, while
|
|
253
|
+
* recording the step it was given.
|
|
254
|
+
*/
|
|
255
|
+
checkProbeAgreementSpy = jest
|
|
256
|
+
.spyOn(MonitorResourceUtil as any, "checkProbeAgreement")
|
|
257
|
+
.mockImplementation((input: any) => {
|
|
258
|
+
return Promise.resolve({
|
|
259
|
+
hasAgreement: true,
|
|
260
|
+
agreementCount: 1,
|
|
261
|
+
requiredCount: 1,
|
|
262
|
+
totalActiveProbes: 1,
|
|
263
|
+
agreedCriteriaId: input.currentCriteriaMetId,
|
|
264
|
+
agreedRootCause: input.currentRootCause,
|
|
265
|
+
agreedProbeNames: [],
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
afterEach(() => {
|
|
271
|
+
jest.restoreAllMocks();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
describe("probe result naming a step (multi-step monitor)", () => {
|
|
275
|
+
let stepOne: MonitorStep;
|
|
276
|
+
let stepTwo: MonitorStep;
|
|
277
|
+
let stepThree: MonitorStep;
|
|
278
|
+
let monitor: Monitor;
|
|
279
|
+
let probeId: ObjectID;
|
|
280
|
+
|
|
281
|
+
beforeEach(() => {
|
|
282
|
+
stepOne = makeStep("Step one criteria");
|
|
283
|
+
stepTwo = makeStep("Step two criteria");
|
|
284
|
+
stepThree = makeStep("Step three criteria");
|
|
285
|
+
|
|
286
|
+
monitor = makeMonitor({
|
|
287
|
+
monitorType: MonitorType.Website,
|
|
288
|
+
steps: [stepOne, stepTwo, stepThree],
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
probeId = ObjectID.generate();
|
|
292
|
+
|
|
293
|
+
const monitorProbe: MonitorProbe = new MonitorProbe();
|
|
294
|
+
monitorProbe.id = ObjectID.generate();
|
|
295
|
+
monitorProbe.probeId = probeId;
|
|
296
|
+
monitorProbe.isEnabled = true;
|
|
297
|
+
|
|
298
|
+
findOneByIdMock.mockResolvedValue(monitor);
|
|
299
|
+
findByMock.mockResolvedValue([monitorProbe]);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("evaluates the named step's criteria, not step 0's", async () => {
|
|
303
|
+
const response: ProbeApiIngestResponse =
|
|
304
|
+
await MonitorResourceUtil.monitorResource(
|
|
305
|
+
makeProbeResult({
|
|
306
|
+
monitor: monitor,
|
|
307
|
+
probeId: probeId,
|
|
308
|
+
monitorStepId: stepTwo.id,
|
|
309
|
+
}),
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
expect(stepPassedToEvaluator().id.toString()).toBe(stepTwo.id.toString());
|
|
313
|
+
expect(response.criteriaMetId).toBe(criteriaIdOfStep(stepTwo));
|
|
314
|
+
expect(response.criteriaMetId).not.toBe(criteriaIdOfStep(stepOne));
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("reports the named step as the ingested step", async () => {
|
|
318
|
+
const response: ProbeApiIngestResponse =
|
|
319
|
+
await MonitorResourceUtil.monitorResource(
|
|
320
|
+
makeProbeResult({
|
|
321
|
+
monitor: monitor,
|
|
322
|
+
probeId: probeId,
|
|
323
|
+
monitorStepId: stepTwo.id,
|
|
324
|
+
}),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
expect(response.ingestedMonitorStepId?.toString()).toBe(
|
|
328
|
+
stepTwo.id.toString(),
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
test("walks the step chain on from the named step", async () => {
|
|
333
|
+
const response: ProbeApiIngestResponse =
|
|
334
|
+
await MonitorResourceUtil.monitorResource(
|
|
335
|
+
makeProbeResult({
|
|
336
|
+
monitor: monitor,
|
|
337
|
+
probeId: probeId,
|
|
338
|
+
monitorStepId: stepTwo.id,
|
|
339
|
+
}),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
// Step three follows step two — not step two, which follows step one.
|
|
343
|
+
expect(response.nextMonitorStepId?.toString()).toBe(
|
|
344
|
+
stepThree.id.toString(),
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test("the last step has no next step", async () => {
|
|
349
|
+
const response: ProbeApiIngestResponse =
|
|
350
|
+
await MonitorResourceUtil.monitorResource(
|
|
351
|
+
makeProbeResult({
|
|
352
|
+
monitor: monitor,
|
|
353
|
+
probeId: probeId,
|
|
354
|
+
monitorStepId: stepThree.id,
|
|
355
|
+
}),
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
expect(response.nextMonitorStepId).toBeUndefined();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test("hands probe agreement the named step, so it reads the right step's probe logs", async () => {
|
|
362
|
+
await MonitorResourceUtil.monitorResource(
|
|
363
|
+
makeProbeResult({
|
|
364
|
+
monitor: monitor,
|
|
365
|
+
probeId: probeId,
|
|
366
|
+
monitorStepId: stepTwo.id,
|
|
367
|
+
}),
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
expect(checkProbeAgreementSpy).toHaveBeenCalledTimes(1);
|
|
371
|
+
|
|
372
|
+
const agreementInput: { monitorStep: MonitorStep } =
|
|
373
|
+
checkProbeAgreementSpy.mock.calls[0]![0] as {
|
|
374
|
+
monitorStep: MonitorStep;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
expect(agreementInput.monitorStep.id.toString()).toBe(
|
|
378
|
+
stepTwo.id.toString(),
|
|
379
|
+
);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test("step 0 is still selected when the result names step 0", async () => {
|
|
383
|
+
const response: ProbeApiIngestResponse =
|
|
384
|
+
await MonitorResourceUtil.monitorResource(
|
|
385
|
+
makeProbeResult({
|
|
386
|
+
monitor: monitor,
|
|
387
|
+
probeId: probeId,
|
|
388
|
+
monitorStepId: stepOne.id,
|
|
389
|
+
}),
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
expect(stepPassedToEvaluator().id.toString()).toBe(stepOne.id.toString());
|
|
393
|
+
expect(response.criteriaMetId).toBe(criteriaIdOfStep(stepOne));
|
|
394
|
+
expect(response.ingestedMonitorStepId?.toString()).toBe(
|
|
395
|
+
stepOne.id.toString(),
|
|
396
|
+
);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test("an unknown step id falls back to step 0 rather than dropping the result", async () => {
|
|
400
|
+
// The step was deleted after this probe was scheduled.
|
|
401
|
+
const response: ProbeApiIngestResponse =
|
|
402
|
+
await MonitorResourceUtil.monitorResource(
|
|
403
|
+
makeProbeResult({
|
|
404
|
+
monitor: monitor,
|
|
405
|
+
probeId: probeId,
|
|
406
|
+
monitorStepId: ObjectID.generate(),
|
|
407
|
+
}),
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
expect(stepPassedToEvaluator().id.toString()).toBe(stepOne.id.toString());
|
|
411
|
+
expect(response.criteriaMetId).toBe(criteriaIdOfStep(stepOne));
|
|
412
|
+
expect(response.ingestedMonitorStepId?.toString()).toBe(
|
|
413
|
+
stepOne.id.toString(),
|
|
414
|
+
);
|
|
415
|
+
expect(response.nextMonitorStepId?.toString()).toBe(
|
|
416
|
+
stepTwo.id.toString(),
|
|
417
|
+
);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
describe("result carrying no step id", () => {
|
|
422
|
+
test("uses step 0", async () => {
|
|
423
|
+
/*
|
|
424
|
+
* Server monitors heartbeat in without a monitorStepId at all — the
|
|
425
|
+
* whole lookup is skipped and step 0 is the intended step.
|
|
426
|
+
*/
|
|
427
|
+
const stepOne: MonitorStep = makeStep("Step one criteria");
|
|
428
|
+
const stepTwo: MonitorStep = makeStep("Step two criteria");
|
|
429
|
+
|
|
430
|
+
const monitor: Monitor = makeMonitor({
|
|
431
|
+
monitorType: MonitorType.Server,
|
|
432
|
+
steps: [stepOne, stepTwo],
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
findOneByIdMock.mockResolvedValue(monitor);
|
|
436
|
+
|
|
437
|
+
const serverMonitorResponse: ServerMonitorResponse = {
|
|
438
|
+
projectId: monitor.projectId!,
|
|
439
|
+
monitorId: monitor.id!,
|
|
440
|
+
hostname: "test-host",
|
|
441
|
+
requestReceivedAt: OneUptimeDate.getCurrentDate(),
|
|
442
|
+
onlyCheckRequestReceivedAt: false,
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const response: ProbeApiIngestResponse =
|
|
446
|
+
await MonitorResourceUtil.monitorResource(serverMonitorResponse);
|
|
447
|
+
|
|
448
|
+
expect(stepPassedToEvaluator().id.toString()).toBe(stepOne.id.toString());
|
|
449
|
+
expect(response.criteriaMetId).toBe(criteriaIdOfStep(stepOne));
|
|
450
|
+
expect(response.ingestedMonitorStepId?.toString()).toBe(
|
|
451
|
+
stepOne.id.toString(),
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
});
|