@oneuptime/common 13.0.1 → 13.0.4
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/AnalyticsModels/RumSession.ts +34 -0
- package/Models/DatabaseModels/AlertEpisodeLabelRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodeOnCallRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodeOwnerRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodePrivacyRule.ts +2 -2
- package/Models/DatabaseModels/AlertGroupingRule.ts +2 -2
- package/Models/DatabaseModels/AlertLabelRule.ts +2 -2
- package/Models/DatabaseModels/AlertOnCallRule.ts +2 -2
- package/Models/DatabaseModels/AlertOwnerRule.ts +2 -2
- package/Models/DatabaseModels/AlertPrivacyRule.ts +2 -2
- package/Models/DatabaseModels/AlertReminderRule.ts +6 -4
- package/Models/DatabaseModels/AutoRemediationRule.ts +2 -2
- package/Models/DatabaseModels/CephClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/CephClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/CloudResourceLabelRule.ts +2 -2
- package/Models/DatabaseModels/CloudResourceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DashboardLabelRule.ts +2 -2
- package/Models/DatabaseModels/DashboardOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.ts +11 -0
- package/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.ts +44 -0
- package/Models/DatabaseModels/DockerHostLabelRule.ts +2 -2
- package/Models/DatabaseModels/DockerHostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DockerSwarmClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/DockerSwarmClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/HostLabelRule.ts +2 -2
- package/Models/DatabaseModels/HostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeOnCallRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodePrivacyRule.ts +2 -2
- package/Models/DatabaseModels/IncidentGroupingRule.ts +2 -2
- package/Models/DatabaseModels/IncidentLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncidentOnCallRule.ts +2 -2
- package/Models/DatabaseModels/IncidentOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentPrivacyRule.ts +2 -2
- package/Models/DatabaseModels/IncidentReminderRule.ts +6 -4
- package/Models/DatabaseModels/IncidentSlaRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicy.ts +3 -4
- package/Models/DatabaseModels/IncomingCallPolicyLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicyOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.ts +254 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/IoTFleetLabelRule.ts +2 -2
- package/Models/DatabaseModels/IoTFleetOwnerRule.ts +2 -2
- package/Models/DatabaseModels/KubernetesClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/KubernetesClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/MonitorLabelRule.ts +2 -2
- package/Models/DatabaseModels/MonitorOwnerRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceLabelRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyLabelRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.ts +2 -2
- package/Models/DatabaseModels/PodmanHostLabelRule.ts +2 -2
- package/Models/DatabaseModels/PodmanHostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ProxmoxClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/ProxmoxClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RumApplicationLabelRule.ts +2 -2
- package/Models/DatabaseModels/RumApplicationOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RunbookLabelRule.ts +2 -2
- package/Models/DatabaseModels/RunbookOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RunbookRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceLabelRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceReminderRule.ts +6 -4
- package/Models/DatabaseModels/ServerlessFunctionLabelRule.ts +2 -2
- package/Models/DatabaseModels/ServerlessFunctionOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ServiceLabelRule.ts +2 -2
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +283 -4
- package/Models/DatabaseModels/ServiceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageLabelRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageOwnerRule.ts +2 -2
- package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +2 -2
- package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/WorkflowLabelRule.ts +2 -2
- package/Models/DatabaseModels/WorkflowOwnerRule.ts +2 -2
- package/Server/API/TelemetryAPI.ts +323 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.ts +111 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.ts +644 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.ts +72 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/MultipartFormData.ts +46 -21
- package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodeOnCallRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +21 -0
- package/Server/Services/AlertGroupingEngineService.ts +27 -0
- package/Server/Services/AlertLabelRuleEngineService.ts +27 -0
- package/Server/Services/AlertOnCallRuleEngineService.ts +27 -0
- package/Server/Services/AlertOwnerRuleEngineService.ts +27 -0
- package/Server/Services/AlertPrivacyRuleEngineService.ts +27 -0
- package/Server/Services/AlertReminderRuleService.ts +65 -33
- package/Server/Services/AutoRemediationRuleEngineService.ts +90 -8
- package/Server/Services/CephClusterLabelRuleEngineService.ts +20 -0
- package/Server/Services/CephClusterOwnerRuleEngineService.ts +20 -0
- package/Server/Services/CloudResourceLabelRuleEngineService.ts +20 -0
- package/Server/Services/CloudResourceOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DashboardLabelRuleEngineService.ts +20 -0
- package/Server/Services/DashboardOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DatabaseService.ts +409 -6
- package/Server/Services/DockerHostLabelRuleEngineService.ts +20 -0
- package/Server/Services/DockerHostOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +23 -0
- package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +23 -0
- package/Server/Services/HostLabelRuleEngineService.ts +13 -0
- package/Server/Services/HostOwnerRuleEngineService.ts +13 -0
- package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodeOnCallRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +21 -0
- package/Server/Services/IncidentGroupingEngineService.ts +64 -13
- package/Server/Services/IncidentLabelRuleEngineService.ts +64 -9
- package/Server/Services/IncidentOnCallRuleEngineService.ts +64 -10
- package/Server/Services/IncidentOwnerRuleEngineService.ts +64 -10
- package/Server/Services/IncidentPrivacyRuleEngineService.ts +64 -10
- package/Server/Services/IncidentReminderRuleService.ts +66 -34
- package/Server/Services/IncidentSlaRuleService.ts +55 -12
- package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +20 -0
- package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +20 -0
- package/Server/Services/IncomingCallPolicyPhoneNumberService.ts +184 -0
- package/Server/Services/IncomingCallPolicyService.ts +276 -5
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTFleetLabelRuleEngineService.ts +20 -0
- package/Server/Services/IoTFleetOwnerRuleEngineService.ts +20 -0
- package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +23 -0
- package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +23 -0
- package/Server/Services/LabelService.ts +50 -7
- package/Server/Services/MonitorLabelRuleEngineService.ts +20 -0
- package/Server/Services/MonitorOwnerRuleEngineService.ts +20 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +2 -0
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +93 -1
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +26 -0
- package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +25 -0
- package/Server/Services/NetworkDeviceService.ts +2 -0
- package/Server/Services/NetworkSiteAssignmentRuleService.ts +90 -1
- package/Server/Services/NetworkSiteService.ts +242 -29
- package/Server/Services/NetworkSiteTypeService.ts +177 -77
- package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +20 -0
- package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +20 -0
- package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +22 -0
- package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +22 -0
- package/Server/Services/PodmanHostLabelRuleEngineService.ts +20 -0
- package/Server/Services/PodmanHostOwnerRuleEngineService.ts +20 -0
- package/Server/Services/ProjectCallSMSConfigService.ts +156 -7
- package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +25 -0
- package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +25 -0
- package/Server/Services/RumApplicationLabelRuleEngineService.ts +22 -0
- package/Server/Services/RumApplicationOwnerRuleEngineService.ts +22 -0
- package/Server/Services/RunbookLabelRuleEngineService.ts +20 -0
- package/Server/Services/RunbookOwnerRuleEngineService.ts +20 -0
- package/Server/Services/RunbookRuleEngineService.ts +18 -1
- package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +62 -10
- package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +62 -11
- package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +48 -18
- package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +25 -0
- package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +25 -0
- package/Server/Services/ServiceLabelRuleEngineService.ts +20 -0
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +675 -12
- package/Server/Services/ServiceLevelObjectiveService.ts +55 -13
- package/Server/Services/ServiceOwnerRuleEngineService.ts +20 -0
- package/Server/Services/StatusPageLabelRuleEngineService.ts +20 -0
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +31 -2
- package/Server/Services/StatusPageMonitorRuleService.ts +34 -1
- package/Server/Services/StatusPageOwnerRuleEngineService.ts +20 -0
- package/Server/Services/UserService.ts +23 -50
- package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +25 -0
- package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +25 -0
- package/Server/Services/WorkflowLabelRuleEngineService.ts +20 -0
- package/Server/Services/WorkflowOwnerRuleEngineService.ts +20 -0
- package/Server/Static/Brand/README.md +10 -5
- package/Server/Static/Brand/favicons/oneuptime-up-v1.svg +8 -0
- package/Server/Types/Database/QueryHelper.ts +88 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +19 -2
- package/Server/Utils/IncomingCallPhoneNumber.ts +29 -16
- package/Server/Utils/Profiling.ts +13 -1
- package/Server/Utils/Rules/MonitorRuleCriteriaCache.ts +38 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +498 -0
- package/Server/Utils/Telemetry.ts +3 -1
- package/Server/Utils/VendorAssets.ts +3 -0
- package/Tests/App/Dashboard/AIInsightViewTriage.test.tsx +348 -0
- package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +476 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +25 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +449 -24
- package/Tests/App/Dashboard/DashboardPersistentSideMenuLayouts.test.tsx +702 -0
- package/Tests/App/Dashboard/ExceptionsLandingRedirect.test.tsx +63 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +150 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +279 -100
- package/Tests/App/Dashboard/InventoryItemSideMenu.test.tsx +155 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +11 -0
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +215 -71
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +347 -0
- package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +263 -0
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +413 -17
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +138 -0
- package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +940 -0
- package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +378 -0
- package/Tests/App/Dashboard/TelemetryIngestionKeyForm.test.tsx +735 -0
- package/Tests/App/Dashboard/TwoFactorStatus.test.tsx +275 -108
- package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +13 -3
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +127 -4
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -4
- package/Tests/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.test.ts +362 -0
- package/Tests/Models/DatabaseModels/RuleBaseModel.test.ts +69 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +181 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1303 -145
- package/Tests/Server/API/UserTwoFactorSelfService.test.ts +407 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +611 -0
- package/Tests/Server/Middleware/MultipartFormData.test.ts +61 -3
- package/Tests/Server/Middleware/TelemetryIngestionDisabled.test.ts +211 -0
- package/Tests/Server/Services/AlertIncidentRuleCriteriaEngineServices.test.ts +651 -0
- package/Tests/Server/Services/AutoRemediationRuleEngineService.test.ts +79 -0
- package/Tests/Server/Services/DatabaseServiceRelationOnlyRuleRollout.test.ts +330 -0
- package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +522 -0
- package/Tests/Server/Services/IncidentSlaRuleCriteriaCorrelation.test.ts +99 -0
- package/Tests/Server/Services/IncomingCallPolicyPhoneNumberService.test.ts +1540 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +179 -2
- package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +170 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +559 -53
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +122 -55
- package/Tests/Server/Services/ReminderRuleCriteria.test.ts +173 -0
- package/Tests/Server/Services/ResourceRuleCriteriaEngineServices.test.ts +170 -0
- package/Tests/Server/Services/ScheduledMaintenanceRuleCriteriaCorrelation.test.ts +154 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +2450 -470
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +464 -121
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +281 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +132 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +159 -14
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +6 -8
- package/Tests/Server/Services/UserTwoFactorAuthAdmin.test.ts +203 -34
- package/Tests/Server/Types/Database/QueryHelperJsonArrayObjects.test.ts +128 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +190 -1
- package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +461 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +25 -0
- package/Tests/Server/Utils/Billing/BillingFailureNoticeThrottle.test.ts +359 -0
- package/Tests/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.test.ts +318 -0
- package/Tests/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.test.ts +220 -0
- package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +1043 -0
- package/Tests/Server/Utils/Execute.test.ts +302 -0
- package/Tests/Server/Utils/GracefulShutdown.test.ts +565 -0
- package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +36 -20
- package/Tests/Server/Utils/LoggerCore.test.ts +597 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtil.test.ts +1109 -0
- package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +750 -0
- package/Tests/Server/Utils/ProductAnalytics.test.ts +404 -0
- package/Tests/Server/Utils/Profiling.test.ts +366 -0
- package/Tests/Server/Utils/Rules/MonitorRuleCriteriaCache.test.ts +99 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +558 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +711 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +522 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +17 -0
- package/Tests/Types/Dashboard/DashboardTemplateEditorialInvariants.test.ts +659 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +97 -0
- package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +1179 -0
- package/Tests/Types/Database/AccessControl/OwnedThrough.test.ts +136 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilCorePaths.test.ts +1014 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +9 -6
- package/Tests/Types/Rules/RuleCriteriaFieldRegistry.test.ts +276 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +180 -1
- package/Tests/Types/Telemetry/LlmConventions.test.ts +495 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +13 -6
- package/Tests/UI/Components/Alert.test.tsx +532 -93
- package/Tests/UI/Components/Feed.test.tsx +241 -0
- package/Tests/UI/Components/Forms/BasicFormStepNavigation.test.tsx +368 -0
- package/Tests/UI/Components/Forms/FormSummary.test.tsx +454 -0
- package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +290 -0
- package/Tests/UI/Components/Forms/ModelFormRuleCriteria.test.tsx +331 -0
- package/Tests/UI/Components/IconOpticalSize.test.tsx +79 -31
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +6 -6
- package/Tests/UI/Components/NavBar.test.tsx +91 -2
- package/Tests/UI/Components/PencilButton.test.tsx +211 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaBuilder.test.tsx +510 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +350 -0
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +50 -0
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +329 -0
- package/Tests/UI/Components/useFeedItems.test.tsx +107 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +401 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +1 -1
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +7 -1
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +2 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +1069 -5
- package/Tests/UI/Rum/ReplayHeader.test.tsx +579 -2
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +23 -5
- package/Tests/UI/Rum/ReplayRail.test.tsx +143 -1
- package/Tests/UI/Rum/ReplayRenderBudget.test.tsx +338 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +179 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +210 -3
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +180 -1
- package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +405 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +13 -16
- package/Tests/UI/Rum/SessionReplayFacets.test.tsx +199 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +58 -21
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +2 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +717 -4
- package/Tests/UI/Rum/SessionReplayUsersPage.test.tsx +435 -0
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +577 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +1 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -1
- package/Tests/UI/Utils/LabelRuleImportExport.test.ts +192 -0
- package/Tests/UI/Utils/Navigation.test.ts +30 -0
- package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +880 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +158 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +93 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +138 -0
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +174 -0
- package/Tests/Utils/Rules/RuleCriteriaMatcher.test.ts +1424 -0
- package/Tests/Utils/Rum/SessionIdentity.test.ts +72 -0
- package/Tests/Utils/Rum/SessionReplayHealth.test.ts +884 -0
- package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +374 -28
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +118 -0
- package/Types/Dashboard/DashboardTemplates.ts +465 -0
- package/Types/OnCallDutyPolicy/Layer.ts +12 -0
- package/Types/Rules/RuleCriteria.ts +51 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +449 -0
- package/Types/Rum/SessionReplay.ts +75 -0
- package/Types/Rum/SessionReplayApi.ts +93 -0
- package/UI/Components/Alerts/Alert.tsx +102 -72
- package/UI/Components/Button/Button.tsx +4 -1
- package/UI/Components/Dropdown/Dropdown.tsx +2 -0
- package/UI/Components/Feed/Feed.tsx +15 -0
- package/UI/Components/Feed/useFeedItems.ts +227 -0
- package/UI/Components/Forms/BasicForm.tsx +42 -21
- package/UI/Components/Forms/ModelForm.tsx +80 -1
- package/UI/Components/Icon/Icon.tsx +3 -35
- package/UI/Components/ModelTable/ModelTable.tsx +19 -0
- package/UI/Components/Navbar/NavBar.tsx +1 -0
- package/UI/Components/RuleCriteria/RuleCriteriaBuilder.tsx +735 -0
- package/UI/Components/RuleCriteria/RuleCriteriaModelForm.tsx +209 -0
- package/UI/Components/RuleCriteria/RuleCriteriaModelTable.tsx +205 -0
- package/UI/Components/RuleCriteria/RuleCriteriaSummary.tsx +123 -0
- package/UI/Components/Table/Table.tsx +3 -0
- package/UI/Components/Table/TableBody.tsx +3 -0
- package/UI/Components/Table/TableRow.tsx +8 -2
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +14 -2
- package/UI/Styles/Theme.css +1 -0
- package/UI/Utils/LabelRuleImportExport.ts +114 -6
- package/UI/Utils/Navigation.ts +1 -2
- package/UI/esbuild-config.js +46 -0
- package/Utils/Faker.ts +93 -6
- package/Utils/LabelRuleImportExport.ts +295 -2
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +108 -8
- package/Utils/NetworkSite/CidrMatchUtil.ts +102 -0
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +152 -2
- package/Utils/Rules/RuleCriteriaMatcher.ts +931 -0
- package/Utils/Rum/SessionIdentity.ts +16 -0
- package/Utils/Slo/SloBurnRateRuleState.ts +87 -33
- package/Utils/Telemetry/OriginAllowList.ts +74 -0
- package/build/dist/Models/AnalyticsModels/RumSession.js +32 -0
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/AlertReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AutoRemediationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DashboardLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js +50 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/HostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/HostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/HostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/HostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/IncidentReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +3 -4
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.js +277 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/MonitorLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +281 -4
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +211 -4
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js +301 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MultipartFormData.js +38 -21
- package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertGroupingEngineService.js +21 -0
- package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js +44 -26
- package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +54 -11
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +235 -10
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostLabelRuleEngineService.js +12 -0
- package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js +12 -0
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +39 -13
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +39 -9
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentReminderRuleService.js +44 -26
- package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSlaRuleService.js +33 -12
- package/build/dist/Server/Services/IncidentSlaRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js +127 -0
- package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js.map +1 -0
- package/build/dist/Server/Services/IncomingCallPolicyService.js +187 -4
- package/build/dist/Server/Services/IncomingCallPolicyService.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/Services/IoTFleetLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +39 -7
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +2 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +57 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +2 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +56 -1
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +187 -22
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +126 -51
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js +115 -6
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookRuleEngineService.js +12 -0
- package/build/dist/Server/Services/RunbookRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +38 -9
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +38 -10
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +32 -14
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +554 -12
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +50 -14
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +25 -2
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +19 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +14 -49
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +67 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +21 -4
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +9 -3
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -1
- package/build/dist/Server/Utils/Profiling.js +10 -1
- package/build/dist/Server/Utils/Profiling.js.map +1 -1
- package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js +30 -0
- package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +344 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +1 -1
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +2 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +425 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +11 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteria.js +18 -0
- package/build/dist/Types/Rules/RuleCriteria.js.map +1 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +435 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +64 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/UI/Components/Alerts/Alert.js +63 -41
- package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +3 -1
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/Feed.js +4 -1
- package/build/dist/UI/Components/Feed/Feed.js.map +1 -1
- package/build/dist/UI/Components/Feed/useFeedItems.js +137 -0
- package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -0
- package/build/dist/UI/Components/Forms/BasicForm.js +38 -19
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +65 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +3 -35
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +12 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js +383 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js +124 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js +126 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js +63 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +1 -1
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +4 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +3 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +14 -2
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +1 -1
- package/build/dist/UI/Utils/LabelRuleImportExport.js +81 -5
- package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/Utils/Faker.js +76 -6
- package/build/dist/Utils/Faker.js.map +1 -1
- package/build/dist/Utils/LabelRuleImportExport.js +157 -3
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +81 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +77 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +109 -2
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -1
- package/build/dist/Utils/Rules/RuleCriteriaMatcher.js +526 -0
- package/build/dist/Utils/Rules/RuleCriteriaMatcher.js.map +1 -0
- package/build/dist/Utils/Rum/SessionIdentity.js +13 -1
- package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js +28 -15
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -1
- package/build/dist/Utils/Telemetry/OriginAllowList.js +61 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
- package/package.json +20 -20
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import AlertSeverity from "../../../Models/DatabaseModels/AlertSeverity";
|
|
2
2
|
import Alert from "../../../Models/DatabaseModels/Alert";
|
|
3
3
|
import AlertStateTimeline from "../../../Models/DatabaseModels/AlertStateTimeline";
|
|
4
|
+
import Incident from "../../../Models/DatabaseModels/Incident";
|
|
5
|
+
import IncidentStateTimeline from "../../../Models/DatabaseModels/IncidentStateTimeline";
|
|
4
6
|
import MonitorStatus from "../../../Models/DatabaseModels/MonitorStatus";
|
|
5
7
|
import ServiceLevelObjective from "../../../Models/DatabaseModels/ServiceLevelObjective";
|
|
6
8
|
import ServiceLevelObjectiveBurnRateRule from "../../../Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule";
|
|
@@ -10,6 +12,8 @@ import User from "../../../Models/DatabaseModels/User";
|
|
|
10
12
|
import AlertService from "../../../Server/Services/AlertService";
|
|
11
13
|
import AlertSeverityService from "../../../Server/Services/AlertSeverityService";
|
|
12
14
|
import AlertStateTimelineService from "../../../Server/Services/AlertStateTimelineService";
|
|
15
|
+
import IncidentService from "../../../Server/Services/IncidentService";
|
|
16
|
+
import IncidentStateTimelineService from "../../../Server/Services/IncidentStateTimelineService";
|
|
13
17
|
import MonitorStatusService from "../../../Server/Services/MonitorStatusService";
|
|
14
18
|
import ServiceLevelObjectiveService from "../../../Server/Services/ServiceLevelObjectiveService";
|
|
15
19
|
import ServiceLevelObjectiveBurnRateRuleService from "../../../Server/Services/ServiceLevelObjectiveBurnRateRuleService";
|
|
@@ -23,6 +27,7 @@ import DeleteBy from "../../../Server/Types/Database/DeleteBy";
|
|
|
23
27
|
import OwnerTableRegistry from "../../../Server/Types/Database/Permissions/OwnerTableRegistry";
|
|
24
28
|
import UpdateBy from "../../../Server/Types/Database/UpdateBy";
|
|
25
29
|
import { OnCreate, OnUpdate } from "../../../Server/Types/Database/Hooks";
|
|
30
|
+
import logger from "../../../Server/Utils/Logger";
|
|
26
31
|
import URL from "../../../Types/API/URL";
|
|
27
32
|
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
28
33
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
@@ -38,9 +43,14 @@ import { describe, expect, it, beforeEach, afterEach } from "@jest/globals";
|
|
|
38
43
|
* - a brand new SLO must come out of onCreateSuccess already carrying the
|
|
39
44
|
* two canonical Google-SRE multi-window burn rate rules, with thresholds
|
|
40
45
|
* scaled to the compliance window (30 days == the textbook 14.4x / 6x),
|
|
41
|
-
* - disabling or deleting an SLO must resolve
|
|
42
|
-
*
|
|
43
|
-
*
|
|
46
|
+
* - disabling or deleting an SLO must resolve everything its burn-rate
|
|
47
|
+
* rules left open - the Alerts they raised AND the Incidents they
|
|
48
|
+
* declared - because the evaluation worker skips SLOs it no longer sees
|
|
49
|
+
* and would otherwise leave on-call escalations running forever,
|
|
50
|
+
* - and that resolution, while it must attempt every rule, must still
|
|
51
|
+
* REACH its caller: the worker's guard path only commits the SLO's new
|
|
52
|
+
* status once the resolve succeeded, so a swallowed failure strands the
|
|
53
|
+
* records permanently,
|
|
44
54
|
* - getDueSlos must keep selecting every column the evaluation worker
|
|
45
55
|
* reads - a dropped column silently produces wrong SLI math.
|
|
46
56
|
*/
|
|
@@ -59,6 +69,12 @@ const SEVERITY_ID: ObjectID = new ObjectID(
|
|
|
59
69
|
const RESOLVED_STATE_ID: ObjectID = new ObjectID(
|
|
60
70
|
"66666666-6666-4666-8666-666666666666",
|
|
61
71
|
);
|
|
72
|
+
const RESOLVED_INCIDENT_STATE_ID: ObjectID = new ObjectID(
|
|
73
|
+
"77777777-7777-4777-8777-777777777777",
|
|
74
|
+
);
|
|
75
|
+
const THIRD_RULE_ID: ObjectID = new ObjectID(
|
|
76
|
+
"88888888-8888-4888-8888-888888888888",
|
|
77
|
+
);
|
|
62
78
|
|
|
63
79
|
const TARGET_PERCENTAGE_ERROR_MESSAGE: string =
|
|
64
80
|
"SLO target must be greater than 0 and at most 99.999. A 100% target leaves no error budget.";
|
|
@@ -168,6 +184,14 @@ function makeAlert(id: ObjectID): Alert {
|
|
|
168
184
|
return alert;
|
|
169
185
|
}
|
|
170
186
|
|
|
187
|
+
function makeIncident(id: ObjectID): Incident {
|
|
188
|
+
const incident: Incident = new Incident();
|
|
189
|
+
incident._id = id.toString();
|
|
190
|
+
incident.id = id;
|
|
191
|
+
incident.projectId = PROJECT_ID;
|
|
192
|
+
return incident;
|
|
193
|
+
}
|
|
194
|
+
|
|
171
195
|
function makeUser(id: ObjectID): User {
|
|
172
196
|
const user: User = new User();
|
|
173
197
|
user._id = id.toString();
|
|
@@ -984,6 +1008,35 @@ describe("ServiceLevelObjectiveService.onCreateSuccess - burn rate rule seeding
|
|
|
984
1008
|
});
|
|
985
1009
|
}
|
|
986
1010
|
|
|
1011
|
+
/*
|
|
1012
|
+
* The seeder sets NEITHER output flag, so both rules take the column
|
|
1013
|
+
* defaults - shouldCreateAlert true, shouldCreateIncident false. That
|
|
1014
|
+
* omission is the whole safety property of the incident feature: an existing
|
|
1015
|
+
* install that upgrades keeps seeding alert-only rules, and OneUptime never
|
|
1016
|
+
* starts declaring Incidents on a user's behalf until they turn it on
|
|
1017
|
+
* themselves. Asserting the ABSENCE of the keys (not `false`) is deliberate:
|
|
1018
|
+
* an explicit false here would still be the seeder taking a position on a
|
|
1019
|
+
* column whose default already says it.
|
|
1020
|
+
*/
|
|
1021
|
+
it("seeds rules that carry neither output flag, so an upgrade never starts declaring incidents", async () => {
|
|
1022
|
+
await runOnCreateSuccess({
|
|
1023
|
+
windowType: SloWindowType.Rolling,
|
|
1024
|
+
windowDays: 30,
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
const rules: Array<ServiceLevelObjectiveBurnRateRule> = seededRules();
|
|
1028
|
+
expect(rules).toHaveLength(2);
|
|
1029
|
+
|
|
1030
|
+
for (const rule of rules) {
|
|
1031
|
+
expect(rule.shouldCreateIncident).toBeUndefined();
|
|
1032
|
+
expect(rule.shouldCreateAlert).toBeUndefined();
|
|
1033
|
+
|
|
1034
|
+
// And no incident wiring either - severity or on-call policies.
|
|
1035
|
+
expect(rule.incidentSeverityId).toBeUndefined();
|
|
1036
|
+
expect(rule.incidentOnCallDutyPolicies).toBeUndefined();
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
|
|
987
1040
|
it("keeps every seeded threshold rounded to two decimals", async () => {
|
|
988
1041
|
// 0.02 * 24 * 13 = 6.24 and 0.05 * 24 * 13 / 6 = 2.6 in exact arithmetic.
|
|
989
1042
|
await runOnCreateSuccess({
|
|
@@ -1224,13 +1277,16 @@ describe("ServiceLevelObjectiveService.onCreateSuccess - default alert severity"
|
|
|
1224
1277
|
});
|
|
1225
1278
|
|
|
1226
1279
|
describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
1227
|
-
let
|
|
1280
|
+
let resolveAlertsAndIncidentsSpy: jest.SpyInstance;
|
|
1228
1281
|
let updateOneByIdSpy: jest.SpyInstance;
|
|
1229
1282
|
let findOneByIdSpy: jest.SpyInstance;
|
|
1230
1283
|
|
|
1231
1284
|
beforeEach(() => {
|
|
1232
|
-
|
|
1233
|
-
.spyOn(
|
|
1285
|
+
resolveAlertsAndIncidentsSpy = jest
|
|
1286
|
+
.spyOn(
|
|
1287
|
+
ServiceLevelObjectiveService,
|
|
1288
|
+
"resolveOpenBurnRateAlertsAndIncidentsForSlo",
|
|
1289
|
+
)
|
|
1234
1290
|
.mockResolvedValue(undefined);
|
|
1235
1291
|
|
|
1236
1292
|
updateOneByIdSpy = jest
|
|
@@ -1246,43 +1302,52 @@ describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
|
1246
1302
|
jest.restoreAllMocks();
|
|
1247
1303
|
});
|
|
1248
1304
|
|
|
1249
|
-
it("resolves the open burn rate alerts of every SLO that was just disabled", async () => {
|
|
1305
|
+
it("resolves the open burn rate alerts and incidents of every SLO that was just disabled", async () => {
|
|
1250
1306
|
await callHook("onUpdateSuccess", makeOnUpdate({ isEnabled: false }), [
|
|
1251
1307
|
SLO_ID,
|
|
1252
1308
|
OTHER_RULE_ID,
|
|
1253
1309
|
]);
|
|
1254
1310
|
|
|
1255
|
-
expect(
|
|
1256
|
-
expect(
|
|
1311
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenCalledTimes(2);
|
|
1312
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenNthCalledWith(1, {
|
|
1257
1313
|
sloId: SLO_ID,
|
|
1258
1314
|
projectId: PROJECT_ID,
|
|
1259
1315
|
});
|
|
1260
|
-
expect(
|
|
1316
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenNthCalledWith(2, {
|
|
1261
1317
|
sloId: OTHER_RULE_ID,
|
|
1262
1318
|
projectId: PROJECT_ID,
|
|
1263
1319
|
});
|
|
1264
1320
|
});
|
|
1265
1321
|
|
|
1266
|
-
it("does not resolve
|
|
1322
|
+
it("does not resolve anything when the SLO is being enabled", async () => {
|
|
1267
1323
|
await callHook("onUpdateSuccess", makeOnUpdate({ isEnabled: true }), [
|
|
1268
1324
|
SLO_ID,
|
|
1269
1325
|
]);
|
|
1270
1326
|
|
|
1271
|
-
expect(
|
|
1327
|
+
expect(resolveAlertsAndIncidentsSpy).not.toHaveBeenCalled();
|
|
1272
1328
|
});
|
|
1273
1329
|
|
|
1274
|
-
it("skips
|
|
1330
|
+
it("skips resolution for a disabled SLO row it cannot re-read", async () => {
|
|
1275
1331
|
findOneByIdSpy.mockResolvedValue(null);
|
|
1276
1332
|
|
|
1277
1333
|
await callHook("onUpdateSuccess", makeOnUpdate({ isEnabled: false }), [
|
|
1278
1334
|
SLO_ID,
|
|
1279
1335
|
]);
|
|
1280
1336
|
|
|
1281
|
-
expect(
|
|
1337
|
+
expect(resolveAlertsAndIncidentsSpy).not.toHaveBeenCalled();
|
|
1282
1338
|
});
|
|
1283
1339
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1340
|
+
/*
|
|
1341
|
+
* resolveOpenBurnRateAlertsAndIncidentsForSlo rethrows now, so that the
|
|
1342
|
+
* worker's guard path can decline to commit its new status and retry next
|
|
1343
|
+
* tick. This hook deliberately does NOT inherit that: it owns its own
|
|
1344
|
+
* try/catch so a dead Alert or Incident service cannot fail the update that
|
|
1345
|
+
* disabled the SLO - the disable is the user's edit, and refusing it would
|
|
1346
|
+
* be worse than a stale open record. Pinned so the propagation change stays
|
|
1347
|
+
* confined to the worker's caller.
|
|
1348
|
+
*/
|
|
1349
|
+
it("swallows a throwing resolve for one disabled SLO and still handles the rest", async () => {
|
|
1350
|
+
resolveAlertsAndIncidentsSpy
|
|
1286
1351
|
.mockRejectedValueOnce(new Error("alert service down"))
|
|
1287
1352
|
.mockResolvedValueOnce(undefined);
|
|
1288
1353
|
|
|
@@ -1293,7 +1358,22 @@ describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
|
1293
1358
|
]),
|
|
1294
1359
|
).resolves.toBeDefined();
|
|
1295
1360
|
|
|
1296
|
-
expect(
|
|
1361
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenCalledTimes(2);
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
it("swallows a throwing resolve even when the disabled SLO is the only one", async () => {
|
|
1365
|
+
resolveAlertsAndIncidentsSpy.mockRejectedValue(
|
|
1366
|
+
new Error("incident state timeline write failed"),
|
|
1367
|
+
);
|
|
1368
|
+
|
|
1369
|
+
const onUpdate: OnUpdate<ServiceLevelObjective> = makeOnUpdate({
|
|
1370
|
+
isEnabled: false,
|
|
1371
|
+
});
|
|
1372
|
+
|
|
1373
|
+
// Still returns the onUpdate it was handed, so the update itself lands.
|
|
1374
|
+
await expect(callHook("onUpdateSuccess", onUpdate, [SLO_ID])).resolves.toBe(
|
|
1375
|
+
onUpdate,
|
|
1376
|
+
);
|
|
1297
1377
|
});
|
|
1298
1378
|
|
|
1299
1379
|
const evaluationConfigFields: Array<{ label: string; data: SloFields }> = [
|
|
@@ -1348,14 +1428,14 @@ describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
|
1348
1428
|
expect(updateOneByIdSpy).toHaveBeenCalledTimes(2);
|
|
1349
1429
|
});
|
|
1350
1430
|
|
|
1351
|
-
it("neither resolves
|
|
1431
|
+
it("neither resolves records nor forces re-evaluation for an unrelated field change", async () => {
|
|
1352
1432
|
await callHook(
|
|
1353
1433
|
"onUpdateSuccess",
|
|
1354
1434
|
makeOnUpdate({ description: "just a doc tweak" }),
|
|
1355
1435
|
[SLO_ID],
|
|
1356
1436
|
);
|
|
1357
1437
|
|
|
1358
|
-
expect(
|
|
1438
|
+
expect(resolveAlertsAndIncidentsSpy).not.toHaveBeenCalled();
|
|
1359
1439
|
expect(updateOneByIdSpy).not.toHaveBeenCalled();
|
|
1360
1440
|
});
|
|
1361
1441
|
|
|
@@ -1369,14 +1449,14 @@ describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
|
1369
1449
|
).resolves.toBeDefined();
|
|
1370
1450
|
});
|
|
1371
1451
|
|
|
1372
|
-
it("both resolves
|
|
1452
|
+
it("both resolves records and forces re-evaluation when a disable is bundled with a config change", async () => {
|
|
1373
1453
|
await callHook(
|
|
1374
1454
|
"onUpdateSuccess",
|
|
1375
1455
|
makeOnUpdate({ isEnabled: false, windowDays: 7 }),
|
|
1376
1456
|
[SLO_ID],
|
|
1377
1457
|
);
|
|
1378
1458
|
|
|
1379
|
-
expect(
|
|
1459
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenCalledTimes(1);
|
|
1380
1460
|
expect(updateOneByIdSpy).toHaveBeenCalledTimes(1);
|
|
1381
1461
|
});
|
|
1382
1462
|
|
|
@@ -1394,12 +1474,15 @@ describe("ServiceLevelObjectiveService.onUpdateSuccess", () => {
|
|
|
1394
1474
|
});
|
|
1395
1475
|
|
|
1396
1476
|
describe("ServiceLevelObjectiveService.onBeforeDelete", () => {
|
|
1397
|
-
let
|
|
1477
|
+
let resolveAlertsAndIncidentsSpy: jest.SpyInstance;
|
|
1398
1478
|
let findBySpy: jest.SpyInstance;
|
|
1399
1479
|
|
|
1400
1480
|
beforeEach(() => {
|
|
1401
|
-
|
|
1402
|
-
.spyOn(
|
|
1481
|
+
resolveAlertsAndIncidentsSpy = jest
|
|
1482
|
+
.spyOn(
|
|
1483
|
+
ServiceLevelObjectiveService,
|
|
1484
|
+
"resolveOpenBurnRateAlertsAndIncidentsForSlo",
|
|
1485
|
+
)
|
|
1403
1486
|
.mockResolvedValue(undefined);
|
|
1404
1487
|
|
|
1405
1488
|
findBySpy = jest.spyOn(ServiceLevelObjectiveService, "findBy");
|
|
@@ -1418,7 +1501,7 @@ describe("ServiceLevelObjectiveService.onBeforeDelete", () => {
|
|
|
1418
1501
|
} as unknown as DeleteBy<ServiceLevelObjective>;
|
|
1419
1502
|
}
|
|
1420
1503
|
|
|
1421
|
-
it("resolves the open burn rate alerts of every SLO about to be deleted", async () => {
|
|
1504
|
+
it("resolves the open burn rate alerts and incidents of every SLO about to be deleted", async () => {
|
|
1422
1505
|
const first: ServiceLevelObjective = makeSlo({
|
|
1423
1506
|
_id: SLO_ID.toString(),
|
|
1424
1507
|
id: SLO_ID,
|
|
@@ -1434,12 +1517,12 @@ describe("ServiceLevelObjectiveService.onBeforeDelete", () => {
|
|
|
1434
1517
|
|
|
1435
1518
|
const result: unknown = await callHook("onBeforeDelete", makeDeleteBy());
|
|
1436
1519
|
|
|
1437
|
-
expect(
|
|
1438
|
-
expect(
|
|
1520
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenCalledTimes(2);
|
|
1521
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenNthCalledWith(1, {
|
|
1439
1522
|
sloId: SLO_ID,
|
|
1440
1523
|
projectId: PROJECT_ID,
|
|
1441
1524
|
});
|
|
1442
|
-
expect(
|
|
1525
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenNthCalledWith(2, {
|
|
1443
1526
|
sloId: OTHER_RULE_ID,
|
|
1444
1527
|
projectId: PROJECT_ID,
|
|
1445
1528
|
});
|
|
@@ -1479,45 +1562,110 @@ describe("ServiceLevelObjectiveService.onBeforeDelete", () => {
|
|
|
1479
1562
|
|
|
1480
1563
|
await callHook("onBeforeDelete", makeDeleteBy());
|
|
1481
1564
|
|
|
1482
|
-
expect(
|
|
1565
|
+
expect(resolveAlertsAndIncidentsSpy).not.toHaveBeenCalled();
|
|
1483
1566
|
});
|
|
1484
1567
|
|
|
1485
|
-
|
|
1568
|
+
/*
|
|
1569
|
+
* The rule-level resolve propagates its failure now, but a delete the user
|
|
1570
|
+
* asked for must still go through: the hook's own try/catch is what keeps
|
|
1571
|
+
* "the Alert service is down" from making SLOs undeletable. It also has to
|
|
1572
|
+
* keep going, or one unreachable project would strand every later row's
|
|
1573
|
+
* records in the same delete.
|
|
1574
|
+
*/
|
|
1575
|
+
it("does not block the delete when the now-propagating resolve throws", async () => {
|
|
1486
1576
|
findBySpy.mockResolvedValue([
|
|
1487
1577
|
makeSlo({ _id: SLO_ID.toString(), id: SLO_ID, projectId: PROJECT_ID }),
|
|
1578
|
+
makeSlo({
|
|
1579
|
+
_id: OTHER_RULE_ID.toString(),
|
|
1580
|
+
id: OTHER_RULE_ID,
|
|
1581
|
+
projectId: PROJECT_ID,
|
|
1582
|
+
}),
|
|
1488
1583
|
]);
|
|
1489
|
-
|
|
1584
|
+
resolveAlertsAndIncidentsSpy.mockRejectedValue(
|
|
1585
|
+
new Error("alert service down"),
|
|
1586
|
+
);
|
|
1490
1587
|
|
|
1491
1588
|
await expect(
|
|
1492
1589
|
callHook("onBeforeDelete", makeDeleteBy()),
|
|
1493
1590
|
).resolves.toBeDefined();
|
|
1591
|
+
|
|
1592
|
+
expect(resolveAlertsAndIncidentsSpy).toHaveBeenCalledTimes(2);
|
|
1494
1593
|
});
|
|
1495
1594
|
});
|
|
1496
1595
|
|
|
1497
|
-
describe("ServiceLevelObjectiveService.
|
|
1596
|
+
describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsAndIncidentsForSlo", () => {
|
|
1597
|
+
/*
|
|
1598
|
+
* The clear that follows each rule's resolve writes to the database through
|
|
1599
|
+
* the hookless column path, so every test in here has to stub it or it
|
|
1600
|
+
* reaches a connection that does not exist. The two tests that are ABOUT
|
|
1601
|
+
* the clear re-spy on it to assert; the rest just need it silent.
|
|
1602
|
+
*/
|
|
1603
|
+
beforeEach(() => {
|
|
1604
|
+
jest
|
|
1605
|
+
.spyOn(
|
|
1606
|
+
ServiceLevelObjectiveBurnRateRuleService,
|
|
1607
|
+
"clearOpenOutputStateForRule",
|
|
1608
|
+
)
|
|
1609
|
+
.mockResolvedValue(undefined);
|
|
1610
|
+
});
|
|
1611
|
+
|
|
1498
1612
|
afterEach(() => {
|
|
1499
1613
|
jest.restoreAllMocks();
|
|
1500
1614
|
});
|
|
1501
1615
|
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1616
|
+
/*
|
|
1617
|
+
* The rule-level resolver always runs BOTH passes, so any test that lets it
|
|
1618
|
+
* run for real has to give the incident pass something to find - otherwise
|
|
1619
|
+
* it would reach the real IncidentService.
|
|
1620
|
+
*/
|
|
1621
|
+
function mockNoOpenIncidents(): jest.SpyInstance {
|
|
1622
|
+
return jest.spyOn(IncidentService, "findBy").mockResolvedValue([]);
|
|
1623
|
+
}
|
|
1509
1624
|
|
|
1510
|
-
|
|
1625
|
+
function mockResolveForRule(): jest.SpyInstance {
|
|
1626
|
+
return jest
|
|
1511
1627
|
.spyOn(
|
|
1512
1628
|
ServiceLevelObjectiveBurnRateRuleService,
|
|
1513
|
-
"
|
|
1629
|
+
"resolveOpenAlertsAndIncidentsForRule",
|
|
1514
1630
|
)
|
|
1515
1631
|
.mockResolvedValue(undefined);
|
|
1632
|
+
}
|
|
1516
1633
|
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1634
|
+
function mockClearOutputState(): jest.SpyInstance {
|
|
1635
|
+
return jest
|
|
1636
|
+
.spyOn(
|
|
1637
|
+
ServiceLevelObjectiveBurnRateRuleService,
|
|
1638
|
+
"clearOpenOutputStateForRule",
|
|
1639
|
+
)
|
|
1640
|
+
.mockResolvedValue(undefined);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
function mockRules(
|
|
1644
|
+
rules: Array<ServiceLevelObjectiveBurnRateRule>,
|
|
1645
|
+
): jest.SpyInstance {
|
|
1646
|
+
return jest
|
|
1647
|
+
.spyOn(ServiceLevelObjectiveBurnRateRuleService, "findBy")
|
|
1648
|
+
.mockResolvedValue(rules);
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
function resolveForSlo(): Promise<void> {
|
|
1652
|
+
return ServiceLevelObjectiveService.resolveOpenBurnRateAlertsAndIncidentsForSlo(
|
|
1653
|
+
{
|
|
1654
|
+
sloId: SLO_ID,
|
|
1655
|
+
projectId: PROJECT_ID,
|
|
1656
|
+
},
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
it("delegates to every burn rate rule of the SLO with the auto-resolve root cause", async () => {
|
|
1661
|
+
const ruleFindBySpy: jest.SpyInstance = mockRules([
|
|
1662
|
+
makeBurnRateRule(RULE_ID),
|
|
1663
|
+
makeBurnRateRule(OTHER_RULE_ID),
|
|
1664
|
+
]);
|
|
1665
|
+
|
|
1666
|
+
const resolveForRuleSpy: jest.SpyInstance = mockResolveForRule();
|
|
1667
|
+
|
|
1668
|
+
await resolveForSlo();
|
|
1521
1669
|
|
|
1522
1670
|
const ruleFindByArg: { query: Record<string, unknown> } = ruleFindBySpy.mock
|
|
1523
1671
|
.calls[0]![0] as { query: Record<string, unknown> };
|
|
@@ -1527,12 +1675,19 @@ describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo", () => {
|
|
|
1527
1675
|
});
|
|
1528
1676
|
|
|
1529
1677
|
expect(resolveForRuleSpy).toHaveBeenCalledTimes(2);
|
|
1678
|
+
|
|
1679
|
+
/*
|
|
1680
|
+
* One call per rule covering both outputs - not resolveOpenAlertsForRule.
|
|
1681
|
+
* The root cause is deliberately output-neutral ("Auto-resolved...", not
|
|
1682
|
+
* "Alert auto-resolved..."), because the same string is stamped onto the
|
|
1683
|
+
* Incident timeline as well.
|
|
1684
|
+
*/
|
|
1530
1685
|
expect(resolveForRuleSpy).toHaveBeenNthCalledWith(1, {
|
|
1531
1686
|
serviceLevelObjectiveId: SLO_ID,
|
|
1532
1687
|
burnRateRuleId: RULE_ID,
|
|
1533
1688
|
projectId: PROJECT_ID,
|
|
1534
1689
|
rootCause:
|
|
1535
|
-
"
|
|
1690
|
+
"Auto-resolved because the Service Level Objective was disabled or deleted.",
|
|
1536
1691
|
});
|
|
1537
1692
|
expect(resolveForRuleSpy).toHaveBeenNthCalledWith(
|
|
1538
1693
|
2,
|
|
@@ -1540,76 +1695,201 @@ describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo", () => {
|
|
|
1540
1695
|
);
|
|
1541
1696
|
});
|
|
1542
1697
|
|
|
1543
|
-
|
|
1698
|
+
/*
|
|
1699
|
+
* This path deliberately does NOT stamp the resolve columns — they drive a
|
|
1700
|
+
* live rule's re-fire suppression, and disabling an SLO is not a burn rate
|
|
1701
|
+
* that recovered. But the evaluation worker reads the CREATED columns to
|
|
1702
|
+
* decide whether an output is already open, so leaving those set told the
|
|
1703
|
+
* worker "an alert is already open" about an alert this very call had just
|
|
1704
|
+
* closed: re-enable the SLO mid-outage and the rule declared nothing for
|
|
1705
|
+
* the rest of the burn, while the dashboard showed a red "Firing" pill.
|
|
1706
|
+
*/
|
|
1707
|
+
it("forgets what each rule had open, so a re-enabled SLO can declare again", async () => {
|
|
1708
|
+
mockRules([makeBurnRateRule(RULE_ID), makeBurnRateRule(OTHER_RULE_ID)]);
|
|
1709
|
+
mockResolveForRule();
|
|
1710
|
+
|
|
1711
|
+
const clearSpy: jest.SpyInstance = mockClearOutputState();
|
|
1712
|
+
|
|
1713
|
+
await resolveForSlo();
|
|
1714
|
+
|
|
1715
|
+
expect(clearSpy).toHaveBeenCalledTimes(2);
|
|
1716
|
+
expect(clearSpy).toHaveBeenNthCalledWith(1, {
|
|
1717
|
+
burnRateRuleId: RULE_ID,
|
|
1718
|
+
clearAlert: true,
|
|
1719
|
+
clearIncident: true,
|
|
1720
|
+
});
|
|
1721
|
+
expect(clearSpy).toHaveBeenNthCalledWith(2, {
|
|
1722
|
+
burnRateRuleId: OTHER_RULE_ID,
|
|
1723
|
+
clearAlert: true,
|
|
1724
|
+
clearIncident: true,
|
|
1725
|
+
});
|
|
1726
|
+
});
|
|
1727
|
+
|
|
1728
|
+
it("does not forget anything for a rule whose resolve threw", async () => {
|
|
1729
|
+
mockRules([makeBurnRateRule(RULE_ID)]);
|
|
1730
|
+
|
|
1544
1731
|
jest
|
|
1545
|
-
.spyOn(
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1732
|
+
.spyOn(
|
|
1733
|
+
ServiceLevelObjectiveBurnRateRuleService,
|
|
1734
|
+
"resolveOpenAlertsAndIncidentsForRule",
|
|
1735
|
+
)
|
|
1736
|
+
.mockRejectedValue(new Error("resolve failed"));
|
|
1737
|
+
|
|
1738
|
+
const clearSpy: jest.SpyInstance = mockClearOutputState();
|
|
1739
|
+
jest.spyOn(logger, "error").mockImplementation((): void => {});
|
|
1740
|
+
|
|
1741
|
+
await expect(resolveForSlo()).rejects.toThrow("resolve failed");
|
|
1742
|
+
|
|
1743
|
+
/*
|
|
1744
|
+
* The record is still open. Clearing the rule's columns would make the
|
|
1745
|
+
* worker declare a second one on top of it.
|
|
1746
|
+
*/
|
|
1747
|
+
expect(clearSpy).not.toHaveBeenCalled();
|
|
1748
|
+
});
|
|
1749
|
+
|
|
1750
|
+
/*
|
|
1751
|
+
* Why the failure has to PROPAGATE, not just get logged:
|
|
1752
|
+
*
|
|
1753
|
+
* the evaluation worker's Paused / Misconfigured guard calls this and only
|
|
1754
|
+
* commits the SLO's new status once it comes back clean, precisely so that a
|
|
1755
|
+
* failed resolve leaves the old status in place and the next tick retries
|
|
1756
|
+
* the whole transition. While this method swallowed the error the guard saw
|
|
1757
|
+
* a success, committed the status, and the next tick found no transition
|
|
1758
|
+
* left to make - the Alert and the Incident stayed open with their on-call
|
|
1759
|
+
* escalations running, and nothing ever retried them. The record was
|
|
1760
|
+
* stranded for good.
|
|
1761
|
+
*
|
|
1762
|
+
* The loop still has to attempt every rule first, though: one unreachable
|
|
1763
|
+
* rule must not stop the SLO's other rules from being closed. So the shape
|
|
1764
|
+
* is "try all, remember the first failure, rethrow at the end".
|
|
1765
|
+
*/
|
|
1766
|
+
it("attempts every rule, logs the failure, and then rejects with the error the failing rule threw", async () => {
|
|
1767
|
+
mockRules([
|
|
1768
|
+
makeBurnRateRule(RULE_ID),
|
|
1769
|
+
makeBurnRateRule(OTHER_RULE_ID),
|
|
1770
|
+
makeBurnRateRule(THIRD_RULE_ID),
|
|
1771
|
+
]);
|
|
1772
|
+
|
|
1773
|
+
const failure: Error = new Error("alert state timeline write failed");
|
|
1550
1774
|
|
|
1551
1775
|
const resolveForRuleSpy: jest.SpyInstance = jest
|
|
1552
1776
|
.spyOn(
|
|
1553
1777
|
ServiceLevelObjectiveBurnRateRuleService,
|
|
1554
|
-
"
|
|
1778
|
+
"resolveOpenAlertsAndIncidentsForRule",
|
|
1555
1779
|
)
|
|
1556
|
-
.
|
|
1780
|
+
.mockResolvedValueOnce(undefined)
|
|
1781
|
+
.mockRejectedValueOnce(failure)
|
|
1557
1782
|
.mockResolvedValueOnce(undefined);
|
|
1558
1783
|
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
projectId: PROJECT_ID,
|
|
1563
|
-
}),
|
|
1564
|
-
).resolves.toBeUndefined();
|
|
1784
|
+
const loggerErrorSpy: jest.SpyInstance = jest
|
|
1785
|
+
.spyOn(logger, "error")
|
|
1786
|
+
.mockImplementation((): void => {});
|
|
1565
1787
|
|
|
1566
|
-
expect(
|
|
1788
|
+
await expect(resolveForSlo()).rejects.toBe(failure);
|
|
1789
|
+
|
|
1790
|
+
// The middle rule failing did not abort the loop - the third still ran.
|
|
1791
|
+
expect(resolveForRuleSpy).toHaveBeenCalledTimes(3);
|
|
1792
|
+
|
|
1793
|
+
// And the operator still gets the per-rule context the rethrow cannot carry.
|
|
1794
|
+
expect(loggerErrorSpy).toHaveBeenCalledTimes(1);
|
|
1795
|
+
expect(String(loggerErrorSpy.mock.calls[0]![0])).toContain(
|
|
1796
|
+
OTHER_RULE_ID.toString(),
|
|
1797
|
+
);
|
|
1567
1798
|
});
|
|
1568
1799
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1800
|
+
/*
|
|
1801
|
+
* The FIRST error, not the last. The caller retries the whole SLO either
|
|
1802
|
+
* way, but surfacing whatever happened to fail last would bury the original
|
|
1803
|
+
* cause behind a downstream symptom.
|
|
1804
|
+
*/
|
|
1805
|
+
it("rejects with the first error when more than one rule fails", async () => {
|
|
1806
|
+
mockRules([
|
|
1807
|
+
makeBurnRateRule(RULE_ID),
|
|
1808
|
+
makeBurnRateRule(OTHER_RULE_ID),
|
|
1809
|
+
makeBurnRateRule(THIRD_RULE_ID),
|
|
1810
|
+
]);
|
|
1811
|
+
|
|
1812
|
+
const firstFailure: Error = new Error("first rule exploded");
|
|
1813
|
+
const lastFailure: Error = new Error("third rule exploded");
|
|
1573
1814
|
|
|
1574
1815
|
const resolveForRuleSpy: jest.SpyInstance = jest
|
|
1575
1816
|
.spyOn(
|
|
1576
1817
|
ServiceLevelObjectiveBurnRateRuleService,
|
|
1577
|
-
"
|
|
1818
|
+
"resolveOpenAlertsAndIncidentsForRule",
|
|
1578
1819
|
)
|
|
1579
|
-
.
|
|
1820
|
+
.mockRejectedValueOnce(firstFailure)
|
|
1821
|
+
.mockResolvedValueOnce(undefined)
|
|
1822
|
+
.mockRejectedValueOnce(lastFailure);
|
|
1580
1823
|
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1824
|
+
jest.spyOn(logger, "error").mockImplementation((): void => {});
|
|
1825
|
+
|
|
1826
|
+
await expect(resolveForSlo()).rejects.toBe(firstFailure);
|
|
1827
|
+
|
|
1828
|
+
expect(resolveForRuleSpy).toHaveBeenCalledTimes(3);
|
|
1829
|
+
});
|
|
1830
|
+
|
|
1831
|
+
it("resolves without throwing when no rule fails", async () => {
|
|
1832
|
+
mockRules([makeBurnRateRule(RULE_ID), makeBurnRateRule(OTHER_RULE_ID)]);
|
|
1833
|
+
|
|
1834
|
+
const resolveForRuleSpy: jest.SpyInstance = mockResolveForRule();
|
|
1835
|
+
|
|
1836
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
1837
|
+
|
|
1838
|
+
expect(resolveForRuleSpy).toHaveBeenCalledTimes(2);
|
|
1839
|
+
});
|
|
1840
|
+
|
|
1841
|
+
/*
|
|
1842
|
+
* A row with no id is SKIPPED, not failed: `continue` must never touch the
|
|
1843
|
+
* remembered error. Counting it as a failure would make a wholly successful
|
|
1844
|
+
* pass reject, and the worker would then retry the same SLO forever.
|
|
1845
|
+
*/
|
|
1846
|
+
it("skips a rule row that came back without an id, and does not count it as a failure", async () => {
|
|
1847
|
+
mockRules([
|
|
1848
|
+
new ServiceLevelObjectiveBurnRateRule(),
|
|
1849
|
+
makeBurnRateRule(RULE_ID),
|
|
1850
|
+
]);
|
|
1851
|
+
|
|
1852
|
+
const resolveForRuleSpy: jest.SpyInstance = mockResolveForRule();
|
|
1853
|
+
|
|
1854
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
1855
|
+
|
|
1856
|
+
expect(resolveForRuleSpy).toHaveBeenCalledTimes(1);
|
|
1857
|
+
expect(resolveForRuleSpy).toHaveBeenCalledWith(
|
|
1858
|
+
expect.objectContaining({ burnRateRuleId: RULE_ID }),
|
|
1859
|
+
);
|
|
1860
|
+
});
|
|
1861
|
+
|
|
1862
|
+
it("resolves cleanly when every rule row lacks an id", async () => {
|
|
1863
|
+
mockRules([
|
|
1864
|
+
new ServiceLevelObjectiveBurnRateRule(),
|
|
1865
|
+
new ServiceLevelObjectiveBurnRateRule(),
|
|
1866
|
+
]);
|
|
1867
|
+
|
|
1868
|
+
const resolveForRuleSpy: jest.SpyInstance = mockResolveForRule();
|
|
1869
|
+
|
|
1870
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
1585
1871
|
|
|
1586
1872
|
expect(resolveForRuleSpy).not.toHaveBeenCalled();
|
|
1587
1873
|
});
|
|
1588
1874
|
|
|
1589
1875
|
it("is a no-op when the SLO has no burn rate rules", async () => {
|
|
1590
|
-
|
|
1591
|
-
.spyOn(ServiceLevelObjectiveBurnRateRuleService, "findBy")
|
|
1592
|
-
.mockResolvedValue([]);
|
|
1876
|
+
mockRules([]);
|
|
1593
1877
|
|
|
1594
|
-
const resolveForRuleSpy: jest.SpyInstance =
|
|
1595
|
-
.spyOn(
|
|
1596
|
-
ServiceLevelObjectiveBurnRateRuleService,
|
|
1597
|
-
"resolveOpenAlertsForRule",
|
|
1598
|
-
)
|
|
1599
|
-
.mockResolvedValue(undefined);
|
|
1878
|
+
const resolveForRuleSpy: jest.SpyInstance = mockResolveForRule();
|
|
1600
1879
|
|
|
1601
|
-
await
|
|
1602
|
-
sloId: SLO_ID,
|
|
1603
|
-
projectId: PROJECT_ID,
|
|
1604
|
-
});
|
|
1880
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
1605
1881
|
|
|
1606
1882
|
expect(resolveForRuleSpy).not.toHaveBeenCalled();
|
|
1607
1883
|
});
|
|
1608
1884
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1885
|
+
/*
|
|
1886
|
+
* Straight through the real rule-level resolver: the fingerprint is the only
|
|
1887
|
+
* thing tying an SLO's rule to the records it opened, so one wrong character
|
|
1888
|
+
* turns the disable path into a silent no-op. Both tables are keyed off the
|
|
1889
|
+
* SAME fingerprint - one rule, one series.
|
|
1890
|
+
*/
|
|
1891
|
+
it("queries the open alerts and the open incidents of each rule by that rule's exact fingerprint", async () => {
|
|
1892
|
+
mockRules([makeBurnRateRule(RULE_ID)]);
|
|
1613
1893
|
|
|
1614
1894
|
const alertFindBySpy: jest.SpyInstance = jest
|
|
1615
1895
|
.spyOn(AlertService, "findBy")
|
|
@@ -1619,40 +1899,73 @@ describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo", () => {
|
|
|
1619
1899
|
.spyOn(AlertStateTimelineService, "getResolvedStateIdForProject")
|
|
1620
1900
|
.mockResolvedValue(RESOLVED_STATE_ID);
|
|
1621
1901
|
|
|
1622
|
-
const
|
|
1902
|
+
const alertTimelineCreateSpy: jest.SpyInstance = jest
|
|
1623
1903
|
.spyOn(AlertStateTimelineService, "create")
|
|
1624
1904
|
.mockResolvedValue(new AlertStateTimeline());
|
|
1625
1905
|
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1906
|
+
const incidentFindBySpy: jest.SpyInstance = jest
|
|
1907
|
+
.spyOn(IncidentService, "findBy")
|
|
1908
|
+
.mockResolvedValue([makeIncident(ObjectID.generate())]);
|
|
1909
|
+
|
|
1910
|
+
jest
|
|
1911
|
+
.spyOn(IncidentStateTimelineService, "getResolvedStateIdForProject")
|
|
1912
|
+
.mockResolvedValue(RESOLVED_INCIDENT_STATE_ID);
|
|
1913
|
+
|
|
1914
|
+
const incidentTimelineCreateSpy: jest.SpyInstance = jest
|
|
1915
|
+
.spyOn(IncidentStateTimelineService, "create")
|
|
1916
|
+
.mockResolvedValue(new IncidentStateTimeline());
|
|
1917
|
+
|
|
1918
|
+
await resolveForSlo();
|
|
1919
|
+
|
|
1920
|
+
const fingerprint: string = `slo:${SLO_ID.toString()}:burn-rule:${RULE_ID.toString()}`;
|
|
1630
1921
|
|
|
1631
1922
|
const alertFindByArg: { query: Record<string, unknown> } = alertFindBySpy
|
|
1632
1923
|
.mock.calls[0]![0] as { query: Record<string, unknown> };
|
|
1633
|
-
|
|
1634
1924
|
expect(alertFindByArg.query).toEqual({
|
|
1635
1925
|
projectId: PROJECT_ID,
|
|
1636
|
-
seriesFingerprint:
|
|
1926
|
+
seriesFingerprint: fingerprint,
|
|
1637
1927
|
currentAlertState: { isResolvedState: false },
|
|
1638
1928
|
});
|
|
1639
1929
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
timelineCreateSpy.mock.calls[0]![0] as {
|
|
1644
|
-
data: { alertStateId: ObjectID; rootCause: string };
|
|
1930
|
+
const incidentFindByArg: { query: Record<string, unknown> } =
|
|
1931
|
+
incidentFindBySpy.mock.calls[0]![0] as {
|
|
1932
|
+
query: Record<string, unknown>;
|
|
1645
1933
|
};
|
|
1646
|
-
expect(
|
|
1647
|
-
|
|
1934
|
+
expect(incidentFindByArg.query).toEqual({
|
|
1935
|
+
projectId: PROJECT_ID,
|
|
1936
|
+
seriesFingerprint: fingerprint,
|
|
1937
|
+
currentIncidentState: { isResolvedState: false },
|
|
1938
|
+
});
|
|
1939
|
+
|
|
1940
|
+
// And both actually resolved, through their own state timeline tables.
|
|
1941
|
+
expect(alertTimelineCreateSpy).toHaveBeenCalledTimes(1);
|
|
1942
|
+
const alertTimelineArg: {
|
|
1943
|
+
data: { alertStateId: ObjectID; rootCause: string };
|
|
1944
|
+
} = alertTimelineCreateSpy.mock.calls[0]![0] as {
|
|
1945
|
+
data: { alertStateId: ObjectID; rootCause: string };
|
|
1946
|
+
};
|
|
1947
|
+
expect(alertTimelineArg.data.alertStateId).toEqual(RESOLVED_STATE_ID);
|
|
1948
|
+
expect(alertTimelineArg.data.rootCause).toContain(
|
|
1949
|
+
"Service Level Objective was disabled or deleted",
|
|
1950
|
+
);
|
|
1951
|
+
|
|
1952
|
+
expect(incidentTimelineCreateSpy).toHaveBeenCalledTimes(1);
|
|
1953
|
+
const incidentTimelineArg: {
|
|
1954
|
+
data: { incidentStateId: ObjectID; rootCause: string };
|
|
1955
|
+
} = incidentTimelineCreateSpy.mock.calls[0]![0] as {
|
|
1956
|
+
data: { incidentStateId: ObjectID; rootCause: string };
|
|
1957
|
+
};
|
|
1958
|
+
expect(incidentTimelineArg.data.incidentStateId).toEqual(
|
|
1959
|
+
RESOLVED_INCIDENT_STATE_ID,
|
|
1960
|
+
);
|
|
1961
|
+
expect(incidentTimelineArg.data.rootCause).toContain(
|
|
1648
1962
|
"Service Level Objective was disabled or deleted",
|
|
1649
1963
|
);
|
|
1650
1964
|
});
|
|
1651
1965
|
|
|
1652
1966
|
it("tolerates the benign same-state race without rethrowing", async () => {
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
.mockResolvedValue([makeBurnRateRule(RULE_ID)]);
|
|
1967
|
+
mockRules([makeBurnRateRule(RULE_ID)]);
|
|
1968
|
+
mockNoOpenIncidents();
|
|
1656
1969
|
|
|
1657
1970
|
jest
|
|
1658
1971
|
.spyOn(AlertService, "findBy")
|
|
@@ -1668,18 +1981,42 @@ describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo", () => {
|
|
|
1668
1981
|
new BadDataException("Alert state cannot be same as previous state."),
|
|
1669
1982
|
);
|
|
1670
1983
|
|
|
1671
|
-
await expect(
|
|
1672
|
-
ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo({
|
|
1673
|
-
sloId: SLO_ID,
|
|
1674
|
-
projectId: PROJECT_ID,
|
|
1675
|
-
}),
|
|
1676
|
-
).resolves.toBeUndefined();
|
|
1984
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
1677
1985
|
});
|
|
1678
1986
|
|
|
1679
|
-
|
|
1987
|
+
/*
|
|
1988
|
+
* The incident twin of the race above. It matters more now that the SLO-level
|
|
1989
|
+
* method rethrows: a benign duplicate-state race leaking out would make the
|
|
1990
|
+
* worker's guard refuse to commit and retry the same already-resolved
|
|
1991
|
+
* incident on every single tick.
|
|
1992
|
+
*/
|
|
1993
|
+
it("tolerates the benign same-state race on the incident side too", async () => {
|
|
1994
|
+
mockRules([makeBurnRateRule(RULE_ID)]);
|
|
1995
|
+
|
|
1996
|
+
jest.spyOn(AlertService, "findBy").mockResolvedValue([]);
|
|
1997
|
+
|
|
1680
1998
|
jest
|
|
1681
|
-
.spyOn(
|
|
1682
|
-
.mockResolvedValue([
|
|
1999
|
+
.spyOn(IncidentService, "findBy")
|
|
2000
|
+
.mockResolvedValue([makeIncident(ObjectID.generate())]);
|
|
2001
|
+
|
|
2002
|
+
jest
|
|
2003
|
+
.spyOn(IncidentStateTimelineService, "getResolvedStateIdForProject")
|
|
2004
|
+
.mockResolvedValue(RESOLVED_INCIDENT_STATE_ID);
|
|
2005
|
+
|
|
2006
|
+
jest
|
|
2007
|
+
.spyOn(IncidentStateTimelineService, "create")
|
|
2008
|
+
.mockRejectedValue(
|
|
2009
|
+
new BadDataException(
|
|
2010
|
+
"Incident state cannot be same as previous state.",
|
|
2011
|
+
),
|
|
2012
|
+
);
|
|
2013
|
+
|
|
2014
|
+
await expect(resolveForSlo()).resolves.toBeUndefined();
|
|
2015
|
+
});
|
|
2016
|
+
|
|
2017
|
+
it("keeps resolving the remaining open alerts when one alert throws, and still reports it", async () => {
|
|
2018
|
+
mockRules([makeBurnRateRule(RULE_ID)]);
|
|
2019
|
+
mockNoOpenIncidents();
|
|
1683
2020
|
|
|
1684
2021
|
jest
|
|
1685
2022
|
.spyOn(AlertService, "findBy")
|
|
@@ -1697,12 +2034,15 @@ describe("ServiceLevelObjectiveService.resolveOpenBurnRateAlertsForSlo", () => {
|
|
|
1697
2034
|
.mockRejectedValueOnce(new Error("write conflict"))
|
|
1698
2035
|
.mockResolvedValueOnce(new AlertStateTimeline());
|
|
1699
2036
|
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
2037
|
+
jest.spyOn(logger, "error").mockImplementation((): void => {});
|
|
2038
|
+
|
|
2039
|
+
/*
|
|
2040
|
+
* The per-record isolation goes all the way down — the second alert is
|
|
2041
|
+
* still resolved — but the failure travels all the way up, so the worker's
|
|
2042
|
+
* guard path does not commit a status change that would make this
|
|
2043
|
+
* one-shot and strand the first alert forever.
|
|
2044
|
+
*/
|
|
2045
|
+
await expect(resolveForSlo()).rejects.toThrow("write conflict");
|
|
1706
2046
|
|
|
1707
2047
|
expect(timelineCreateSpy).toHaveBeenCalledTimes(2);
|
|
1708
2048
|
});
|
|
@@ -2013,7 +2353,10 @@ describe("ServiceLevelObjectiveService - applying the monitor label rule", () =>
|
|
|
2013
2353
|
.spyOn(ServiceLevelObjectiveService, "findOneById")
|
|
2014
2354
|
.mockResolvedValue(makeSlo({ projectId: PROJECT_ID }));
|
|
2015
2355
|
jest
|
|
2016
|
-
.spyOn(
|
|
2356
|
+
.spyOn(
|
|
2357
|
+
ServiceLevelObjectiveService,
|
|
2358
|
+
"resolveOpenBurnRateAlertsAndIncidentsForSlo",
|
|
2359
|
+
)
|
|
2017
2360
|
.mockResolvedValue(undefined);
|
|
2018
2361
|
jest.spyOn(AlertSeverityService, "findOneBy").mockResolvedValue(null);
|
|
2019
2362
|
jest
|