@oneuptime/common 12.0.13 → 12.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/StatusPageAPI.ts +29 -4
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/EnvironmentConfig.ts +7 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -0
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/LogAggregationService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Analytics.test.ts +187 -0
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/Utils/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +5 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
|
@@ -0,0 +1,987 @@
|
|
|
1
|
+
import EvaluateOverTime, {
|
|
2
|
+
OverTimeCriteriaValue,
|
|
3
|
+
OverTimeEvaluation,
|
|
4
|
+
OverTimeEvaluationStatus,
|
|
5
|
+
} from "../../../../../Server/Utils/Monitor/Criteria/EvaluateOverTime";
|
|
6
|
+
import MetricService from "../../../../../Server/Services/MetricService";
|
|
7
|
+
import FindBy from "../../../../../Server/Types/AnalyticsDatabase/FindBy";
|
|
8
|
+
import { JSONObject } from "../../../../../Types/JSON";
|
|
9
|
+
import Metric from "../../../../../Models/AnalyticsModels/Metric";
|
|
10
|
+
import InBetween from "../../../../../Types/BaseDatabase/InBetween";
|
|
11
|
+
import MonitorMetricType from "../../../../../Types/Monitor/MonitorMetricType";
|
|
12
|
+
import {
|
|
13
|
+
CheckOn,
|
|
14
|
+
CriteriaFilter,
|
|
15
|
+
EvaluateOverTimeType,
|
|
16
|
+
FilterType,
|
|
17
|
+
NoDataPolicy,
|
|
18
|
+
} from "../../../../../Types/Monitor/CriteriaFilter";
|
|
19
|
+
import ObjectID from "../../../../../Types/ObjectID";
|
|
20
|
+
import {
|
|
21
|
+
afterEach,
|
|
22
|
+
beforeEach,
|
|
23
|
+
describe,
|
|
24
|
+
expect,
|
|
25
|
+
jest,
|
|
26
|
+
test,
|
|
27
|
+
} from "@jest/globals";
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* Everything here is anchored to a fixed "now" so the window arithmetic -
|
|
31
|
+
* which is the whole point of these tests - never depends on the wall clock.
|
|
32
|
+
*/
|
|
33
|
+
const NOW: Date = new Date("2026-08-20T12:00:00.000Z");
|
|
34
|
+
|
|
35
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
36
|
+
"11111111-1111-4111-8111-111111111111",
|
|
37
|
+
);
|
|
38
|
+
const MONITOR_ID: ObjectID = new ObjectID(
|
|
39
|
+
"22222222-2222-4222-8222-222222222222",
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
/** A Metric row as the analytics layer hands it back. */
|
|
43
|
+
function sample(input: { value: number; minutesAgo: number }): Metric {
|
|
44
|
+
const metric: Metric = new Metric();
|
|
45
|
+
metric.value = input.value;
|
|
46
|
+
metric.time = new Date(NOW.getTime() - input.minutesAgo * 60 * 1000);
|
|
47
|
+
return metric;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A run of samples one per minute ending at `now`, oldest first.
|
|
52
|
+
* `values[0]` is the oldest.
|
|
53
|
+
*/
|
|
54
|
+
function everyMinute(values: Array<number>): Array<Metric> {
|
|
55
|
+
return values.map((value: number, index: number) => {
|
|
56
|
+
return sample({
|
|
57
|
+
value: value,
|
|
58
|
+
minutesAgo: values.length - 1 - index,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function criteria(overrides: Partial<CriteriaFilter> = {}): CriteriaFilter {
|
|
64
|
+
return {
|
|
65
|
+
checkOn: CheckOn.ResponseStatusCode,
|
|
66
|
+
filterType: FilterType.NotEqualTo,
|
|
67
|
+
value: 200,
|
|
68
|
+
evaluateOverTime: true,
|
|
69
|
+
evaluateOverTimeOptions: {
|
|
70
|
+
timeValueInMinutes: 5,
|
|
71
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
72
|
+
},
|
|
73
|
+
...overrides,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/*
|
|
78
|
+
* The metric read is stubbed in memory rather than through a typed spy so
|
|
79
|
+
* every query it receives can be asserted on directly.
|
|
80
|
+
*/
|
|
81
|
+
let findByCalls: Array<FindBy<Metric>> = [];
|
|
82
|
+
let findByResult: Array<Metric> = [];
|
|
83
|
+
let findByError: Error | null = null;
|
|
84
|
+
|
|
85
|
+
function mockSamples(metrics: Array<Metric>): void {
|
|
86
|
+
findByResult = metrics;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function lastQuery(): JSONObject {
|
|
90
|
+
return findByCalls[0]!.query as unknown as JSONObject;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function lastSelect(): JSONObject {
|
|
94
|
+
return findByCalls[0]!.select as unknown as JSONObject;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function evaluate(input: {
|
|
98
|
+
criteriaFilter: CriteriaFilter;
|
|
99
|
+
monitoringInterval?: string | undefined;
|
|
100
|
+
miscData?: JSONObject | undefined;
|
|
101
|
+
}): Promise<OverTimeEvaluation> {
|
|
102
|
+
return EvaluateOverTime.evaluateOverTime({
|
|
103
|
+
projectId: PROJECT_ID,
|
|
104
|
+
monitorId: MONITOR_ID,
|
|
105
|
+
criteriaFilter: input.criteriaFilter,
|
|
106
|
+
monitoringInterval: input.monitoringInterval,
|
|
107
|
+
miscData: input.miscData,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
describe("EvaluateOverTime", () => {
|
|
112
|
+
beforeEach(() => {
|
|
113
|
+
jest.useFakeTimers();
|
|
114
|
+
jest.setSystemTime(NOW);
|
|
115
|
+
|
|
116
|
+
findByCalls = [];
|
|
117
|
+
findByResult = [];
|
|
118
|
+
findByError = null;
|
|
119
|
+
|
|
120
|
+
jest
|
|
121
|
+
.spyOn(MetricService, "findBy")
|
|
122
|
+
.mockImplementation((findBy: FindBy<Metric>): Promise<Array<Metric>> => {
|
|
123
|
+
findByCalls.push(findBy);
|
|
124
|
+
|
|
125
|
+
if (findByError) {
|
|
126
|
+
return Promise.reject(findByError);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return Promise.resolve(findByResult);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
afterEach(() => {
|
|
134
|
+
jest.useRealTimers();
|
|
135
|
+
jest.restoreAllMocks();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe("when the filter does not evaluate over time", () => {
|
|
139
|
+
test("reports NotConfigured when evaluateOverTime is false", async () => {
|
|
140
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
141
|
+
criteriaFilter: criteria({ evaluateOverTime: false }),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.NotConfigured);
|
|
145
|
+
expect(findByCalls).toHaveLength(0);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("reports NotConfigured when the options are missing", async () => {
|
|
149
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
150
|
+
criteriaFilter: criteria({ evaluateOverTimeOptions: undefined }),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.NotConfigured);
|
|
154
|
+
expect(findByCalls).toHaveLength(0);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe("query shape", () => {
|
|
159
|
+
test("scopes the window, the project, the monitor and the series", async () => {
|
|
160
|
+
mockSamples(everyMinute([200, 200, 200, 200, 200]));
|
|
161
|
+
|
|
162
|
+
await evaluate({ criteriaFilter: criteria() });
|
|
163
|
+
|
|
164
|
+
expect(findByCalls).toHaveLength(1);
|
|
165
|
+
|
|
166
|
+
const query: JSONObject = lastQuery();
|
|
167
|
+
|
|
168
|
+
expect(query["projectId"]).toBe(PROJECT_ID);
|
|
169
|
+
expect(query["primaryEntityId"]).toBe(MONITOR_ID);
|
|
170
|
+
expect(query["name"]).toBe(MonitorMetricType.ResponseStatusCode);
|
|
171
|
+
|
|
172
|
+
const time: InBetween<Date> = query["time"] as InBetween<Date>;
|
|
173
|
+
expect(time).toBeInstanceOf(InBetween);
|
|
174
|
+
expect((time.startValue as Date).toISOString()).toBe(
|
|
175
|
+
"2026-08-20T11:55:00.000Z",
|
|
176
|
+
);
|
|
177
|
+
expect((time.endValue as Date).toISOString()).toBe(NOW.toISOString());
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("selects the sample time as well as the value", async () => {
|
|
181
|
+
mockSamples(everyMinute([200]));
|
|
182
|
+
|
|
183
|
+
await evaluate({ criteriaFilter: criteria() });
|
|
184
|
+
|
|
185
|
+
const select: JSONObject = lastSelect();
|
|
186
|
+
|
|
187
|
+
expect(select["value"]).toBe(true);
|
|
188
|
+
expect(select["time"]).toBe(true);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("passes misc data through as an attribute filter", async () => {
|
|
192
|
+
mockSamples(everyMinute([10]));
|
|
193
|
+
|
|
194
|
+
await evaluate({
|
|
195
|
+
criteriaFilter: criteria({ checkOn: CheckOn.DiskUsagePercent }),
|
|
196
|
+
miscData: { diskPath: "/var" },
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const query: JSONObject = lastQuery();
|
|
200
|
+
|
|
201
|
+
expect(query["attributes"]).toEqual({ diskPath: "/var" });
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe("CheckOns that no series records", () => {
|
|
206
|
+
/*
|
|
207
|
+
* These used to throw inside a try/catch that reset the value to
|
|
208
|
+
* undefined, which sent the evaluator down its instantaneous fallback -
|
|
209
|
+
* an over-time filter that quietly was not one.
|
|
210
|
+
*/
|
|
211
|
+
test("reports Unsupported instead of throwing", async () => {
|
|
212
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
213
|
+
criteriaFilter: criteria({ checkOn: CheckOn.ResponseBody }),
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Unsupported);
|
|
217
|
+
expect(findByCalls).toHaveLength(0);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("neither do incoming requests or SNMP OID existence", async () => {
|
|
221
|
+
for (const checkOn of [CheckOn.IncomingRequest, CheckOn.SnmpOidExists]) {
|
|
222
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
223
|
+
criteriaFilter: criteria({ checkOn: checkOn }),
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Unsupported);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
expect(findByCalls).toHaveLength(0);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("Is Request Timeout has no series of its own", async () => {
|
|
233
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
234
|
+
criteriaFilter: criteria({ checkOn: CheckOn.IsRequestTimeout }),
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Unsupported);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
describe("CheckOns that share the generic probe series", () => {
|
|
242
|
+
/*
|
|
243
|
+
* DNS / SNMP / External Status Page probes write into the shared online
|
|
244
|
+
* and response-time series. Their CheckOns had no entry in the metric
|
|
245
|
+
* map at all, so "evaluate over time" was a no-op for every one of them.
|
|
246
|
+
*/
|
|
247
|
+
const onlineCheckOns: Array<CheckOn> = [
|
|
248
|
+
CheckOn.DnsIsOnline,
|
|
249
|
+
CheckOn.SnmpIsOnline,
|
|
250
|
+
CheckOn.ExternalStatusPageIsOnline,
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
for (const checkOn of onlineCheckOns) {
|
|
254
|
+
test(`${checkOn} reads the online series`, async () => {
|
|
255
|
+
mockSamples(everyMinute([0, 0, 0, 0, 0]));
|
|
256
|
+
|
|
257
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
258
|
+
criteriaFilter: criteria({
|
|
259
|
+
checkOn: checkOn,
|
|
260
|
+
filterType: FilterType.False,
|
|
261
|
+
value: undefined,
|
|
262
|
+
}),
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
expect(lastQuery()["name"]).toBe(MonitorMetricType.IsOnline);
|
|
266
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
267
|
+
// 0 maps to false for online-style series.
|
|
268
|
+
expect(result.value).toEqual([false, false, false, false, false]);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const responseTimeCheckOns: Array<CheckOn> = [
|
|
273
|
+
CheckOn.DnsResponseTime,
|
|
274
|
+
CheckOn.SnmpResponseTime,
|
|
275
|
+
CheckOn.ExternalStatusPageResponseTime,
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
for (const checkOn of responseTimeCheckOns) {
|
|
279
|
+
test(`${checkOn} reads the response time series`, async () => {
|
|
280
|
+
mockSamples(everyMinute([10, 20, 30, 40, 50]));
|
|
281
|
+
|
|
282
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
283
|
+
criteriaFilter: criteria({ checkOn: checkOn }),
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
expect(lastQuery()["name"]).toBe(MonitorMetricType.ResponseTime);
|
|
287
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
288
|
+
expect(result.value).toEqual([10, 20, 30, 40, 50]);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
describe("empty and unreadable windows", () => {
|
|
294
|
+
test("an empty window is InsufficientData, not an empty array", async () => {
|
|
295
|
+
mockSamples([]);
|
|
296
|
+
|
|
297
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
298
|
+
criteriaFilter: criteria(),
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
302
|
+
expect(result.sampleCount).toBe(0);
|
|
303
|
+
expect(result.isReadError).toBe(false);
|
|
304
|
+
expect(result.noDataReason).toContain("No data was recorded");
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test("a failed read is InsufficientData and is flagged as an error", async () => {
|
|
308
|
+
findByError = new Error("clickhouse unavailable");
|
|
309
|
+
|
|
310
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
311
|
+
criteriaFilter: criteria(),
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
315
|
+
expect(result.isReadError).toBe(true);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
/*
|
|
319
|
+
* The dashboard persists the window dropdown's STRING value while
|
|
320
|
+
* Terraform and the API send a number - both must behave the same.
|
|
321
|
+
*/
|
|
322
|
+
test("accepts a window length that arrives as a string", async () => {
|
|
323
|
+
mockSamples(everyMinute([404, 404, 404, 404, 404]));
|
|
324
|
+
|
|
325
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
326
|
+
criteriaFilter: criteria({
|
|
327
|
+
evaluateOverTimeOptions: {
|
|
328
|
+
timeValueInMinutes: "5" as unknown as number,
|
|
329
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
330
|
+
},
|
|
331
|
+
}),
|
|
332
|
+
monitoringInterval: "* * * * *",
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
336
|
+
|
|
337
|
+
const time: InBetween<Date> = lastQuery()["time"] as InBetween<Date>;
|
|
338
|
+
expect((time.startValue as Date).toISOString()).toBe(
|
|
339
|
+
"2026-08-20T11:55:00.000Z",
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("an unparseable window length cannot be evaluated", async () => {
|
|
344
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
345
|
+
criteriaFilter: criteria({
|
|
346
|
+
evaluateOverTimeOptions: {
|
|
347
|
+
timeValueInMinutes: "not-a-number" as unknown as number,
|
|
348
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
349
|
+
},
|
|
350
|
+
}),
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
354
|
+
expect(findByCalls).toHaveLength(0);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("a window of zero minutes cannot be evaluated", async () => {
|
|
358
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
359
|
+
criteriaFilter: criteria({
|
|
360
|
+
evaluateOverTimeOptions: {
|
|
361
|
+
timeValueInMinutes: 0,
|
|
362
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
363
|
+
},
|
|
364
|
+
}),
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
368
|
+
expect(findByCalls).toHaveLength(0);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test("rows with no value are dropped", async () => {
|
|
372
|
+
const withoutValue: Metric = new Metric();
|
|
373
|
+
withoutValue.time = NOW;
|
|
374
|
+
|
|
375
|
+
mockSamples([...everyMinute([200, 200, 200, 200, 200]), withoutValue]);
|
|
376
|
+
|
|
377
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
378
|
+
criteriaFilter: criteria(),
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
expect(result.sampleCount).toBe(5);
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
describe("All Values needs the window to actually be covered", () => {
|
|
386
|
+
/*
|
|
387
|
+
* This is the bug from #2321. Array.every() is trivially true on a
|
|
388
|
+
* single element, so one bad probe satisfied "all values over the last
|
|
389
|
+
* five minutes" - on a brand new monitor, or any time the window had not
|
|
390
|
+
* filled up.
|
|
391
|
+
*/
|
|
392
|
+
test("a single sample cannot satisfy a five minute window", async () => {
|
|
393
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
394
|
+
|
|
395
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
396
|
+
criteriaFilter: criteria(),
|
|
397
|
+
monitoringInterval: "* * * * *",
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
401
|
+
expect(result.sampleCount).toBe(1);
|
|
402
|
+
expect(result.noDataReason).toContain("not enough to cover");
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
test("a partially filled window cannot satisfy it either", async () => {
|
|
406
|
+
mockSamples([
|
|
407
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
408
|
+
sample({ value: 404, minutesAgo: 0 }),
|
|
409
|
+
]);
|
|
410
|
+
|
|
411
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
412
|
+
criteriaFilter: criteria(),
|
|
413
|
+
monitoringInterval: "* * * * *",
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
test("a fully covered window evaluates", async () => {
|
|
420
|
+
mockSamples(everyMinute([404, 404, 404, 404, 404]));
|
|
421
|
+
|
|
422
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
423
|
+
criteriaFilter: criteria(),
|
|
424
|
+
monitoringInterval: "* * * * *",
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
428
|
+
expect(result.value).toEqual([404, 404, 404, 404, 404]);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
/*
|
|
432
|
+
* A monitor polled once every five minutes can only ever put one sample
|
|
433
|
+
* in a five minute window, so that one sample IS the whole window.
|
|
434
|
+
*/
|
|
435
|
+
test("one sample covers the window when the monitor polls that slowly", async () => {
|
|
436
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
437
|
+
|
|
438
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
439
|
+
criteriaFilter: criteria(),
|
|
440
|
+
monitoringInterval: "*/5 * * * *",
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("tolerates a probe skipping a beat at the start of the window", async () => {
|
|
447
|
+
/*
|
|
448
|
+
* Oldest sample sits 1.5 intervals into the window, which is the
|
|
449
|
+
* documented jitter allowance - still covered.
|
|
450
|
+
*/
|
|
451
|
+
mockSamples([
|
|
452
|
+
sample({ value: 404, minutesAgo: 3.5 }),
|
|
453
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
454
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
455
|
+
sample({ value: 404, minutesAgo: 0 }),
|
|
456
|
+
]);
|
|
457
|
+
|
|
458
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
459
|
+
criteriaFilter: criteria(),
|
|
460
|
+
monitoringInterval: "* * * * *",
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test("rejects a gap wider than the jitter allowance", async () => {
|
|
467
|
+
mockSamples([
|
|
468
|
+
sample({ value: 404, minutesAgo: 3.4 }),
|
|
469
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
470
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
471
|
+
sample({ value: 404, minutesAgo: 0 }),
|
|
472
|
+
]);
|
|
473
|
+
|
|
474
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
475
|
+
criteriaFilter: criteria(),
|
|
476
|
+
monitoringInterval: "* * * * *",
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
/*
|
|
483
|
+
* Coverage has two edges. Samples that stop part way through the window
|
|
484
|
+
* say nothing about the minutes since, so they must not satisfy
|
|
485
|
+
* "all values over the last N minutes" either.
|
|
486
|
+
*/
|
|
487
|
+
test("rejects a window whose samples stopped part way through", async () => {
|
|
488
|
+
mockSamples([
|
|
489
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
490
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
491
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
492
|
+
]);
|
|
493
|
+
|
|
494
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
495
|
+
criteriaFilter: criteria(),
|
|
496
|
+
monitoringInterval: "* * * * *",
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
/*
|
|
503
|
+
* Metric writes are not synchronous, so the newest sample can lag the
|
|
504
|
+
* check that produced it. One interval of lag must not stall the filter.
|
|
505
|
+
*/
|
|
506
|
+
test("tolerates the newest sample lagging by one interval", async () => {
|
|
507
|
+
mockSamples([
|
|
508
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
509
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
510
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
511
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
512
|
+
]);
|
|
513
|
+
|
|
514
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
515
|
+
criteriaFilter: criteria(),
|
|
516
|
+
monitoringInterval: "* * * * *",
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
test("the trailing tolerance is exactly one and a half intervals", async () => {
|
|
523
|
+
mockSamples([
|
|
524
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
525
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
526
|
+
sample({ value: 404, minutesAgo: 1.5 }),
|
|
527
|
+
]);
|
|
528
|
+
|
|
529
|
+
const onTheBoundary: OverTimeEvaluation = await evaluate({
|
|
530
|
+
criteriaFilter: criteria(),
|
|
531
|
+
monitoringInterval: "* * * * *",
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
expect(onTheBoundary.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
535
|
+
|
|
536
|
+
mockSamples([
|
|
537
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
538
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
539
|
+
sample({ value: 404, minutesAgo: 1.6 }),
|
|
540
|
+
]);
|
|
541
|
+
|
|
542
|
+
const pastTheBoundary: OverTimeEvaluation = await evaluate({
|
|
543
|
+
criteriaFilter: criteria(),
|
|
544
|
+
monitoringInterval: "* * * * *",
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
expect(pastTheBoundary.status).toBe(
|
|
548
|
+
OverTimeEvaluationStatus.InsufficientData,
|
|
549
|
+
);
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
/*
|
|
553
|
+
* A probe's clock running slightly ahead of ours dates a sample in the
|
|
554
|
+
* future. That is still fresh data, not a gap.
|
|
555
|
+
*/
|
|
556
|
+
test("a sample dated slightly in the future does not break coverage", async () => {
|
|
557
|
+
mockSamples([
|
|
558
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
559
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
560
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
561
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
562
|
+
sample({ value: 404, minutesAgo: -0.5 }),
|
|
563
|
+
]);
|
|
564
|
+
|
|
565
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
566
|
+
criteriaFilter: criteria(),
|
|
567
|
+
monitoringInterval: "* * * * *",
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
/*
|
|
574
|
+
* A monitoringInterval that is not a cron (the label form this repo's
|
|
575
|
+
* own Terraform examples write) must not be trusted as a cadence - the
|
|
576
|
+
* samples themselves are the only evidence left.
|
|
577
|
+
*/
|
|
578
|
+
test("an unparseable schedule falls back to the sampled cadence", async () => {
|
|
579
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
580
|
+
|
|
581
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
582
|
+
criteriaFilter: criteria(),
|
|
583
|
+
monitoringInterval: "Every 5 minutes",
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
test("infers the cadence from the samples when no schedule is configured", async () => {
|
|
590
|
+
mockSamples(everyMinute([404, 404, 404, 404, 404]));
|
|
591
|
+
|
|
592
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
593
|
+
criteriaFilter: criteria(),
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
test("a lone sample with no schedule cannot cover the window", async () => {
|
|
600
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
601
|
+
|
|
602
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
603
|
+
criteriaFilter: criteria(),
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
/*
|
|
610
|
+
* Several probes write into the same series, so samples interleave and
|
|
611
|
+
* the window holds many more rows than one per interval. That must not
|
|
612
|
+
* be mistaken for a gap.
|
|
613
|
+
*/
|
|
614
|
+
test("handles several probes writing into the same series", async () => {
|
|
615
|
+
const metrics: Array<Metric> = [];
|
|
616
|
+
|
|
617
|
+
for (let minutesAgo: number = 4; minutesAgo >= 0; minutesAgo--) {
|
|
618
|
+
metrics.push(sample({ value: 404, minutesAgo: minutesAgo }));
|
|
619
|
+
metrics.push(sample({ value: 404, minutesAgo: minutesAgo - 0.1 }));
|
|
620
|
+
metrics.push(sample({ value: 404, minutesAgo: minutesAgo - 0.2 }));
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
mockSamples(metrics);
|
|
624
|
+
|
|
625
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
626
|
+
criteriaFilter: criteria(),
|
|
627
|
+
monitoringInterval: "* * * * *",
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
631
|
+
expect(result.sampleCount).toBe(15);
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test("rows arriving out of order are still judged correctly", async () => {
|
|
635
|
+
mockSamples([
|
|
636
|
+
sample({ value: 404, minutesAgo: 0 }),
|
|
637
|
+
sample({ value: 404, minutesAgo: 4 }),
|
|
638
|
+
sample({ value: 404, minutesAgo: 2 }),
|
|
639
|
+
sample({ value: 404, minutesAgo: 1 }),
|
|
640
|
+
sample({ value: 404, minutesAgo: 3 }),
|
|
641
|
+
]);
|
|
642
|
+
|
|
643
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
644
|
+
criteriaFilter: criteria(),
|
|
645
|
+
monitoringInterval: "* * * * *",
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
describe("evaluation types other than All Values", () => {
|
|
653
|
+
/*
|
|
654
|
+
* "Any Value" is documented to fire on a single breaching sample, so the
|
|
655
|
+
* coverage guard must not touch it.
|
|
656
|
+
*/
|
|
657
|
+
test("Any Value evaluates off a single sample", async () => {
|
|
658
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
659
|
+
|
|
660
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
661
|
+
criteriaFilter: criteria({
|
|
662
|
+
evaluateOverTimeOptions: {
|
|
663
|
+
timeValueInMinutes: 5,
|
|
664
|
+
evaluateOverTimeType: EvaluateOverTimeType.AnyValue,
|
|
665
|
+
},
|
|
666
|
+
}),
|
|
667
|
+
monitoringInterval: "* * * * *",
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
671
|
+
expect(result.value).toEqual([404]);
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test("Any Value is not gated on coverage at all", async () => {
|
|
675
|
+
// Samples cover only the first minute of a five minute window.
|
|
676
|
+
mockSamples([
|
|
677
|
+
sample({ value: 404, minutesAgo: 5 }),
|
|
678
|
+
sample({ value: 404, minutesAgo: 4.5 }),
|
|
679
|
+
]);
|
|
680
|
+
|
|
681
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
682
|
+
criteriaFilter: criteria({
|
|
683
|
+
evaluateOverTimeOptions: {
|
|
684
|
+
timeValueInMinutes: 5,
|
|
685
|
+
evaluateOverTimeType: EvaluateOverTimeType.AnyValue,
|
|
686
|
+
},
|
|
687
|
+
}),
|
|
688
|
+
monitoringInterval: "* * * * *",
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
test("Average aggregates the window", async () => {
|
|
695
|
+
mockSamples(everyMinute([10, 20, 30]));
|
|
696
|
+
|
|
697
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
698
|
+
criteriaFilter: criteria({
|
|
699
|
+
checkOn: CheckOn.ResponseTime,
|
|
700
|
+
evaluateOverTimeOptions: {
|
|
701
|
+
timeValueInMinutes: 5,
|
|
702
|
+
evaluateOverTimeType: EvaluateOverTimeType.Average,
|
|
703
|
+
},
|
|
704
|
+
}),
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
708
|
+
expect(result.value).toBe(20);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
test("Sum aggregates the window", async () => {
|
|
712
|
+
mockSamples(everyMinute([10, 20, 30]));
|
|
713
|
+
|
|
714
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
715
|
+
criteriaFilter: criteria({
|
|
716
|
+
checkOn: CheckOn.ResponseTime,
|
|
717
|
+
evaluateOverTimeOptions: {
|
|
718
|
+
timeValueInMinutes: 5,
|
|
719
|
+
evaluateOverTimeType: EvaluateOverTimeType.Sum,
|
|
720
|
+
},
|
|
721
|
+
}),
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
expect(result.value).toBe(60);
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
test("Maximum Value aggregates the window", async () => {
|
|
728
|
+
mockSamples(everyMinute([10, 90, 30]));
|
|
729
|
+
|
|
730
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
731
|
+
criteriaFilter: criteria({
|
|
732
|
+
checkOn: CheckOn.ResponseTime,
|
|
733
|
+
evaluateOverTimeOptions: {
|
|
734
|
+
timeValueInMinutes: 5,
|
|
735
|
+
evaluateOverTimeType: EvaluateOverTimeType.MaximumValue,
|
|
736
|
+
},
|
|
737
|
+
}),
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
expect(result.value).toBe(90);
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
test("Minimum Value aggregates the window", async () => {
|
|
744
|
+
mockSamples(everyMinute([10, 90, 30]));
|
|
745
|
+
|
|
746
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
747
|
+
criteriaFilter: criteria({
|
|
748
|
+
checkOn: CheckOn.ResponseTime,
|
|
749
|
+
evaluateOverTimeOptions: {
|
|
750
|
+
timeValueInMinutes: 5,
|
|
751
|
+
evaluateOverTimeType: EvaluateOverTimeType.MunimumValue,
|
|
752
|
+
},
|
|
753
|
+
}),
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
expect(result.value).toBe(10);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
/*
|
|
760
|
+
* Math.min/max/average over an empty array produce Infinity, -Infinity
|
|
761
|
+
* and NaN. None of those are arrays, so the old empty-window guard never
|
|
762
|
+
* saw them and "Minimum Value greater than <anything>" was a guaranteed
|
|
763
|
+
* false alarm on a monitor with no data. An empty window is now reported
|
|
764
|
+
* before any aggregate is computed.
|
|
765
|
+
*/
|
|
766
|
+
test("an empty window never reaches the aggregates", async () => {
|
|
767
|
+
const aggregateTypes: Array<EvaluateOverTimeType> = [
|
|
768
|
+
EvaluateOverTimeType.Average,
|
|
769
|
+
EvaluateOverTimeType.Sum,
|
|
770
|
+
EvaluateOverTimeType.MaximumValue,
|
|
771
|
+
EvaluateOverTimeType.MunimumValue,
|
|
772
|
+
];
|
|
773
|
+
|
|
774
|
+
for (const evaluateOverTimeType of aggregateTypes) {
|
|
775
|
+
mockSamples([]);
|
|
776
|
+
|
|
777
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
778
|
+
criteriaFilter: criteria({
|
|
779
|
+
checkOn: CheckOn.ResponseTime,
|
|
780
|
+
evaluateOverTimeOptions: {
|
|
781
|
+
timeValueInMinutes: 5,
|
|
782
|
+
evaluateOverTimeType: evaluateOverTimeType,
|
|
783
|
+
},
|
|
784
|
+
}),
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.InsufficientData);
|
|
788
|
+
expect(result.value).toBeUndefined();
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
test("an aggregate of exactly zero is still a real value", async () => {
|
|
793
|
+
mockSamples(everyMinute([0, 0, 0]));
|
|
794
|
+
|
|
795
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
796
|
+
criteriaFilter: criteria({
|
|
797
|
+
checkOn: CheckOn.CPUUsagePercent,
|
|
798
|
+
evaluateOverTimeOptions: {
|
|
799
|
+
timeValueInMinutes: 5,
|
|
800
|
+
evaluateOverTimeType: EvaluateOverTimeType.Average,
|
|
801
|
+
},
|
|
802
|
+
}),
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
expect(result.status).toBe(OverTimeEvaluationStatus.Evaluated);
|
|
806
|
+
expect(result.value).toBe(0);
|
|
807
|
+
});
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
describe("boolean series", () => {
|
|
811
|
+
test("1 becomes true and everything else becomes false", async () => {
|
|
812
|
+
mockSamples(everyMinute([1, 0, 1, 1, 0]));
|
|
813
|
+
|
|
814
|
+
const result: OverTimeEvaluation = await evaluate({
|
|
815
|
+
criteriaFilter: criteria({
|
|
816
|
+
checkOn: CheckOn.IsOnline,
|
|
817
|
+
filterType: FilterType.False,
|
|
818
|
+
value: undefined,
|
|
819
|
+
}),
|
|
820
|
+
monitoringInterval: "* * * * *",
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
expect(result.value).toEqual([true, false, true, true, false]);
|
|
824
|
+
});
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
describe("getOverTimeValueForCriteriaFilter", () => {
|
|
828
|
+
function resolve(input: {
|
|
829
|
+
criteriaFilter: CriteriaFilter;
|
|
830
|
+
monitoringInterval?: string | undefined;
|
|
831
|
+
}): Promise<OverTimeCriteriaValue> {
|
|
832
|
+
return EvaluateOverTime.getOverTimeValueForCriteriaFilter({
|
|
833
|
+
projectId: PROJECT_ID,
|
|
834
|
+
monitorId: MONITOR_ID,
|
|
835
|
+
criteriaFilter: input.criteriaFilter,
|
|
836
|
+
monitoringInterval: input.monitoringInterval,
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
test("hands back the window when it is usable", async () => {
|
|
841
|
+
mockSamples(everyMinute([404, 404, 404, 404, 404]));
|
|
842
|
+
|
|
843
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
844
|
+
criteriaFilter: criteria(),
|
|
845
|
+
monitoringInterval: "* * * * *",
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
expect(result.earlyReturn).toBeNull();
|
|
849
|
+
expect(result.value).toEqual([404, 404, 404, 404, 404]);
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
test("lets a filter that does not evaluate over time carry on", async () => {
|
|
853
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
854
|
+
criteriaFilter: criteria({ evaluateOverTime: false }),
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
expect(result.earlyReturn).toBeNull();
|
|
858
|
+
expect(result.value).toBeUndefined();
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
test("lets a CheckOn with no series carry on with its live value", async () => {
|
|
862
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
863
|
+
criteriaFilter: criteria({ checkOn: CheckOn.ResponseBody }),
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
expect(result.earlyReturn).toBeNull();
|
|
867
|
+
expect(result.value).toBeUndefined();
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
test("does not fire by default while the window is still filling", async () => {
|
|
871
|
+
mockSamples([sample({ value: 404, minutesAgo: 0 })]);
|
|
872
|
+
|
|
873
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
874
|
+
criteriaFilter: criteria(),
|
|
875
|
+
monitoringInterval: "* * * * *",
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
expect(result.earlyReturn).toEqual({ result: null });
|
|
879
|
+
expect(result.value).toBeUndefined();
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
test("Ignore is the default even when nothing was ever recorded", async () => {
|
|
883
|
+
mockSamples([]);
|
|
884
|
+
|
|
885
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
886
|
+
criteriaFilter: criteria(),
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
expect(result.earlyReturn).toEqual({ result: null });
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
test("Trigger fires with a no-data root cause", async () => {
|
|
893
|
+
mockSamples([]);
|
|
894
|
+
|
|
895
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
896
|
+
criteriaFilter: criteria({
|
|
897
|
+
evaluateOverTimeOptions: {
|
|
898
|
+
timeValueInMinutes: 5,
|
|
899
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
900
|
+
onNoDataPolicy: NoDataPolicy.Trigger,
|
|
901
|
+
},
|
|
902
|
+
}),
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
expect(result.earlyReturn?.result).toContain(
|
|
906
|
+
CheckOn.ResponseStatusCode as string,
|
|
907
|
+
);
|
|
908
|
+
expect(result.earlyReturn?.result).toContain("no data");
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
test("Treat As Zero substitutes zero for a numeric series", async () => {
|
|
912
|
+
mockSamples([]);
|
|
913
|
+
|
|
914
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
915
|
+
criteriaFilter: criteria({
|
|
916
|
+
checkOn: CheckOn.ResponseTime,
|
|
917
|
+
evaluateOverTimeOptions: {
|
|
918
|
+
timeValueInMinutes: 5,
|
|
919
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
920
|
+
onNoDataPolicy: NoDataPolicy.TreatAsZero,
|
|
921
|
+
},
|
|
922
|
+
}),
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
expect(result.earlyReturn).toBeNull();
|
|
926
|
+
expect(result.value).toEqual([0]);
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
test("Treat As Zero substitutes false for an online series", async () => {
|
|
930
|
+
mockSamples([]);
|
|
931
|
+
|
|
932
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
933
|
+
criteriaFilter: criteria({
|
|
934
|
+
checkOn: CheckOn.IsOnline,
|
|
935
|
+
filterType: FilterType.False,
|
|
936
|
+
value: undefined,
|
|
937
|
+
evaluateOverTimeOptions: {
|
|
938
|
+
timeValueInMinutes: 5,
|
|
939
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
940
|
+
onNoDataPolicy: NoDataPolicy.TreatAsZero,
|
|
941
|
+
},
|
|
942
|
+
}),
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
expect(result.value).toEqual([false]);
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
/*
|
|
949
|
+
* A metric store we could not read tells us nothing about the monitor.
|
|
950
|
+
* Reporting that as a breach would turn every ClickHouse hiccup into an
|
|
951
|
+
* incident, so Trigger is deliberately not honoured here.
|
|
952
|
+
*/
|
|
953
|
+
test("a read failure is not substituted with zero either", async () => {
|
|
954
|
+
findByError = new Error("clickhouse unavailable");
|
|
955
|
+
|
|
956
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
957
|
+
criteriaFilter: criteria({
|
|
958
|
+
checkOn: CheckOn.ResponseTime,
|
|
959
|
+
evaluateOverTimeOptions: {
|
|
960
|
+
timeValueInMinutes: 5,
|
|
961
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
962
|
+
onNoDataPolicy: NoDataPolicy.TreatAsZero,
|
|
963
|
+
},
|
|
964
|
+
}),
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
expect(result.earlyReturn).toEqual({ result: null });
|
|
968
|
+
expect(result.value).toBeUndefined();
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
test("a read failure never fires, even under the Trigger policy", async () => {
|
|
972
|
+
findByError = new Error("clickhouse unavailable");
|
|
973
|
+
|
|
974
|
+
const result: OverTimeCriteriaValue = await resolve({
|
|
975
|
+
criteriaFilter: criteria({
|
|
976
|
+
evaluateOverTimeOptions: {
|
|
977
|
+
timeValueInMinutes: 5,
|
|
978
|
+
evaluateOverTimeType: EvaluateOverTimeType.AllValues,
|
|
979
|
+
onNoDataPolicy: NoDataPolicy.Trigger,
|
|
980
|
+
},
|
|
981
|
+
}),
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
expect(result.earlyReturn).toEqual({ result: null });
|
|
985
|
+
});
|
|
986
|
+
});
|
|
987
|
+
});
|