@oneuptime/common 13.0.8 → 14.0.0
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/AuditLog.ts +23 -15
- package/Models/DatabaseModels/GlobalConfig.ts +24 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/BaseAPI.ts +26 -5
- package/Server/API/GlobalConfigAPI.ts +228 -462
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/StatusPageAPI.ts +100 -42
- package/Server/API/TeamMemberAPI.ts +10 -1
- package/Server/Enterprise/EnterpriseEdition.ts +649 -0
- package/Server/Enterprise/EnterpriseFeature.ts +48 -0
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
- package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
- package/Server/EnvironmentConfig.ts +147 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +56 -4
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
- package/Server/Utils/EditionEnforcement.ts +233 -0
- package/Server/Utils/FrontendEnvironment.ts +41 -2
- package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
- package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
- package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
- package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
- package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
- package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
- package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
- package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
- package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
- package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
- package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
- package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
- package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
- package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +181 -0
- package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
- package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
- package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
- package/Types/Database/CanonicalModelInstance.ts +102 -0
- package/Types/Database/TableColumn.ts +20 -6
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
- package/Types/IP/IPv6.ts +6 -1
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
- package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +26 -5
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectOIDC.js +24 -16
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +24 -16
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +93 -43
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +8 -1
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +84 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +71 -740
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +63 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +90 -17
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -4
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +214 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +24 -6
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +71 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +10 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -16
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +31 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
- package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +449 -261
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +59 -11
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
- package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
- package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js +19 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
- package/build/dist/Types/IP/IPv6.js +6 -1
- package/build/dist/Types/IP/IPv6.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HostAddressUtil.js +80 -0
- package/build/dist/Utils/HostAddressUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
- package/jest.config.json +3 -1
- package/package.json +1 -1
- package/test-setup.sh +103 -34
- package/tsconfig.json +13 -0
- package/Server/API/EnterpriseLicenseAPI.ts +0 -925
- package/Server/API/TeamComplianceAPI.ts +0 -158
- package/Server/Middleware/SCIMAuthorization.ts +0 -141
- package/Server/Services/TeamComplianceService.ts +0 -733
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
- package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
- package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
- package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
- package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
- package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
- package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
- package/build/dist/Server/Services/TeamComplianceService.js +0 -537
- package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import Redis from "../../../../Server/Infrastructure/Redis";
|
|
2
2
|
import {
|
|
3
3
|
buildRedisInfoSnapshot,
|
|
4
|
-
COUNTER_WINDOW_IN_SECONDS,
|
|
5
|
-
getCounterDelta,
|
|
6
|
-
getRedisHealthSnapshot,
|
|
7
4
|
getRedisInfoSnapshot,
|
|
8
5
|
parseRedisInfo,
|
|
9
|
-
|
|
6
|
+
readInfoSnapshot,
|
|
10
7
|
RedisInfoSnapshot,
|
|
11
|
-
RedisCounterSample,
|
|
12
|
-
shouldRollCounterSamples,
|
|
13
8
|
} from "../../../../Server/Utils/InstanceHealth/RedisHealth";
|
|
14
9
|
import Dictionary from "../../../../Types/Dictionary";
|
|
15
|
-
import { afterEach,
|
|
10
|
+
import { afterEach, describe, expect, test } from "@jest/globals";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* The INFO half of Redis/Valkey health, which the admin health API reads. The
|
|
14
|
+
* counter-delta half (getRedisHealthSnapshot and the stored samples) belongs
|
|
15
|
+
* to the Enterprise instance-health worker, and its tests live with it in
|
|
16
|
+
* ee/Tests/Server/Workers/InstanceHealth/RedisHealth.test.ts.
|
|
17
|
+
*/
|
|
16
18
|
|
|
17
19
|
const INFO_FIXTURE: string = [
|
|
18
20
|
"# Server",
|
|
@@ -59,37 +61,6 @@ function makeClient(overrides: Partial<FakeRedisClient> = {}): FakeRedisClient {
|
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
/*
|
|
63
|
-
* The INFO fixture reports uptime_in_seconds:86400. Deltas are measured against
|
|
64
|
-
* the OLDER of the two retained samples, so `olderAgeInSeconds` is what controls
|
|
65
|
-
* the reported window; `newerAgeInSeconds` controls when the pair next rolls.
|
|
66
|
-
*/
|
|
67
|
-
function storedSamples(data: {
|
|
68
|
-
evictedKeys: number;
|
|
69
|
-
rejectedConnections: number;
|
|
70
|
-
olderAgeInSeconds: number;
|
|
71
|
-
newerAgeInSeconds?: number;
|
|
72
|
-
}): string {
|
|
73
|
-
const newerAge: number = data.newerAgeInSeconds ?? data.olderAgeInSeconds;
|
|
74
|
-
|
|
75
|
-
return JSON.stringify({
|
|
76
|
-
older: {
|
|
77
|
-
evictedKeys: data.evictedKeys,
|
|
78
|
-
rejectedConnections: data.rejectedConnections,
|
|
79
|
-
uptimeInSeconds: 86400 - data.olderAgeInSeconds,
|
|
80
|
-
},
|
|
81
|
-
newer: {
|
|
82
|
-
evictedKeys: data.evictedKeys,
|
|
83
|
-
rejectedConnections: data.rejectedConnections,
|
|
84
|
-
uptimeInSeconds: 86400 - newerAge,
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function sample(uptimeInSeconds: number): RedisCounterSample {
|
|
90
|
-
return { evictedKeys: 1, rejectedConnections: 1, uptimeInSeconds };
|
|
91
|
-
}
|
|
92
|
-
|
|
93
64
|
function connectClient(client: FakeRedisClient): void {
|
|
94
65
|
jest.spyOn(Redis, "getClient").mockReturnValue(client as never);
|
|
95
66
|
jest.spyOn(Redis, "isConnected").mockReturnValue(true);
|
|
@@ -211,83 +182,6 @@ describe("RedisHealth", () => {
|
|
|
211
182
|
});
|
|
212
183
|
});
|
|
213
184
|
|
|
214
|
-
describe("getCounterDelta", () => {
|
|
215
|
-
test("returns the increase between two samples", () => {
|
|
216
|
-
expect(
|
|
217
|
-
getCounterDelta({ current: 30, previous: 10, didRestart: false }),
|
|
218
|
-
).toBe(20);
|
|
219
|
-
expect(
|
|
220
|
-
getCounterDelta({ current: 10, previous: 10, didRestart: false }),
|
|
221
|
-
).toBe(0);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
/*
|
|
225
|
-
* Redis counters restart at zero, so a decrease or a shorter uptime means
|
|
226
|
-
* the previous sample describes a different server lifetime entirely.
|
|
227
|
-
*/
|
|
228
|
-
test("reports no delta across a restart", () => {
|
|
229
|
-
expect(
|
|
230
|
-
getCounterDelta({ current: 5, previous: 900, didRestart: false }),
|
|
231
|
-
).toBeNull();
|
|
232
|
-
expect(
|
|
233
|
-
getCounterDelta({ current: 900, previous: 5, didRestart: true }),
|
|
234
|
-
).toBeNull();
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
describe("shouldRollCounterSamples", () => {
|
|
239
|
-
test("seeds a pair when there is none", () => {
|
|
240
|
-
expect(
|
|
241
|
-
shouldRollCounterSamples({
|
|
242
|
-
previous: null,
|
|
243
|
-
currentUptimeInSeconds: 100,
|
|
244
|
-
didRestart: false,
|
|
245
|
-
}),
|
|
246
|
-
).toBe(true);
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
test("re-seeds after a restart", () => {
|
|
250
|
-
expect(
|
|
251
|
-
shouldRollCounterSamples({
|
|
252
|
-
previous: { older: sample(999999), newer: sample(999999) },
|
|
253
|
-
currentUptimeInSeconds: 10,
|
|
254
|
-
didRestart: true,
|
|
255
|
-
}),
|
|
256
|
-
).toBe(true);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
/*
|
|
260
|
-
* The roll is gated on the NEWER sample's age. Rolling on the older one
|
|
261
|
-
* would restart the lookback from a five-minute-old baseline, which is the
|
|
262
|
-
* tumbling-window behaviour the pair exists to avoid.
|
|
263
|
-
*/
|
|
264
|
-
test("holds while the newer sample is younger than the window", () => {
|
|
265
|
-
expect(
|
|
266
|
-
shouldRollCounterSamples({
|
|
267
|
-
previous: {
|
|
268
|
-
older: sample(1000 - COUNTER_WINDOW_IN_SECONDS),
|
|
269
|
-
newer: sample(1000),
|
|
270
|
-
},
|
|
271
|
-
currentUptimeInSeconds: 1000 + COUNTER_WINDOW_IN_SECONDS - 1,
|
|
272
|
-
didRestart: false,
|
|
273
|
-
}),
|
|
274
|
-
).toBe(false);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
test("rolls once the newer sample reaches the window", () => {
|
|
278
|
-
expect(
|
|
279
|
-
shouldRollCounterSamples({
|
|
280
|
-
previous: {
|
|
281
|
-
older: sample(1000 - COUNTER_WINDOW_IN_SECONDS),
|
|
282
|
-
newer: sample(1000),
|
|
283
|
-
},
|
|
284
|
-
currentUptimeInSeconds: 1000 + COUNTER_WINDOW_IN_SECONDS,
|
|
285
|
-
didRestart: false,
|
|
286
|
-
}),
|
|
287
|
-
).toBe(true);
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
185
|
describe("getRedisInfoSnapshot", () => {
|
|
292
186
|
test("returns null when Redis is not connected", async () => {
|
|
293
187
|
jest.spyOn(Redis, "getClient").mockReturnValue(makeClient() as never);
|
|
@@ -346,326 +240,52 @@ describe("RedisHealth", () => {
|
|
|
346
240
|
});
|
|
347
241
|
});
|
|
348
242
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
test("
|
|
355
|
-
jest.spyOn(Redis, "getClient").mockReturnValue(null);
|
|
356
|
-
|
|
357
|
-
expect(await getRedisHealthSnapshot()).toBeNull();
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
test("seeds the pair and reports no delta on the first run", async () => {
|
|
243
|
+
/*
|
|
244
|
+
* The Enterprise worker's snapshot builds on this read, so it must use only
|
|
245
|
+
* the client it is handed and must never touch the counter sample itself.
|
|
246
|
+
*/
|
|
247
|
+
describe("readInfoSnapshot", () => {
|
|
248
|
+
test("reads INFO from the client it is given", async () => {
|
|
361
249
|
const client: FakeRedisClient = makeClient();
|
|
362
|
-
|
|
250
|
+
const getClient: jest.SpyInstance = jest.spyOn(Redis, "getClient");
|
|
363
251
|
|
|
364
|
-
const snapshot:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
expect(snapshot?.evictedKeysDelta).toBeNull();
|
|
368
|
-
expect(snapshot?.rejectedConnectionsDelta).toBeNull();
|
|
369
|
-
expect(snapshot?.counterWindowInSeconds).toBeNull();
|
|
370
|
-
|
|
371
|
-
const seeded: {
|
|
372
|
-
evictedKeys: number;
|
|
373
|
-
rejectedConnections: number;
|
|
374
|
-
uptimeInSeconds: number;
|
|
375
|
-
} = {
|
|
376
|
-
evictedKeys: 17,
|
|
377
|
-
rejectedConnections: 5,
|
|
378
|
-
uptimeInSeconds: 86400,
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
expect(client.set).toHaveBeenCalledWith(
|
|
382
|
-
"oneuptime-instance-health-redis-sample",
|
|
383
|
-
JSON.stringify({ older: seeded, newer: seeded }),
|
|
384
|
-
"EX",
|
|
385
|
-
3600,
|
|
252
|
+
const snapshot: RedisInfoSnapshot = await readInfoSnapshot(
|
|
253
|
+
client as never,
|
|
386
254
|
);
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
/*
|
|
390
|
-
* The previous release stored a single sample. An upgrade must keep using it
|
|
391
|
-
* as a baseline rather than discarding it and going blind for a window.
|
|
392
|
-
*/
|
|
393
|
-
test("accepts a single-sample payload written by an older release", async () => {
|
|
394
|
-
const client: FakeRedisClient = makeClient({
|
|
395
|
-
get: jest.fn().mockResolvedValue(
|
|
396
|
-
JSON.stringify({
|
|
397
|
-
evictedKeys: 10,
|
|
398
|
-
rejectedConnections: 1,
|
|
399
|
-
uptimeInSeconds: 80000,
|
|
400
|
-
}),
|
|
401
|
-
),
|
|
402
|
-
});
|
|
403
|
-
connectClient(client);
|
|
404
|
-
|
|
405
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
406
|
-
await getRedisHealthSnapshot();
|
|
407
|
-
|
|
408
|
-
expect(snapshot?.evictedKeysDelta).toBe(7);
|
|
409
|
-
expect(snapshot?.counterWindowInSeconds).toBe(6400);
|
|
410
|
-
});
|
|
411
255
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
});
|
|
422
|
-
connectClient(client);
|
|
423
|
-
|
|
424
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
425
|
-
await getRedisHealthSnapshot();
|
|
426
|
-
|
|
427
|
-
expect(snapshot?.evictedKeysDelta).toBe(7);
|
|
428
|
-
expect(snapshot?.rejectedConnectionsDelta).toBe(4);
|
|
256
|
+
expect(client.info).toHaveBeenCalledTimes(1);
|
|
257
|
+
expect(getClient).not.toHaveBeenCalled();
|
|
258
|
+
expect(snapshot.memoryUtilizationPercent).toBe(50);
|
|
259
|
+
expect(snapshot.evictedKeys).toBe(17);
|
|
260
|
+
expect(snapshot.rejectedConnections).toBe(5);
|
|
261
|
+
expect(snapshot.uptimeInSeconds).toBe(86400);
|
|
262
|
+
// maxclients is in INFO, so there is no CONFIG round trip.
|
|
263
|
+
expect(snapshot.maxClients).toBe(10000);
|
|
264
|
+
expect(client.call).not.toHaveBeenCalled();
|
|
429
265
|
});
|
|
430
266
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
* reporting the same window's activity instead of resetting to zero the
|
|
434
|
-
* moment one quiet interval passes.
|
|
435
|
-
*/
|
|
436
|
-
test("holds the pair inside the window and keeps reporting the window's delta", async () => {
|
|
437
|
-
const client: FakeRedisClient = makeClient({
|
|
438
|
-
get: jest.fn().mockResolvedValue(
|
|
439
|
-
storedSamples({
|
|
440
|
-
evictedKeys: 10,
|
|
441
|
-
rejectedConnections: 1,
|
|
442
|
-
olderAgeInSeconds: COUNTER_WINDOW_IN_SECONDS - 60,
|
|
443
|
-
}),
|
|
444
|
-
),
|
|
445
|
-
});
|
|
446
|
-
connectClient(client);
|
|
267
|
+
test("never reads, writes or refreshes the counter sample", async () => {
|
|
268
|
+
const client: FakeRedisClient = makeClient();
|
|
447
269
|
|
|
448
|
-
|
|
449
|
-
await getRedisHealthSnapshot();
|
|
270
|
+
await readInfoSnapshot(client as never);
|
|
450
271
|
|
|
451
|
-
expect(
|
|
272
|
+
expect(client.get).not.toHaveBeenCalled();
|
|
452
273
|
expect(client.set).not.toHaveBeenCalled();
|
|
453
|
-
// The held baseline still needs its TTL kept alive.
|
|
454
|
-
expect(client.expire).toHaveBeenCalledWith(
|
|
455
|
-
"oneuptime-instance-health-redis-sample",
|
|
456
|
-
3600,
|
|
457
|
-
);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
test("rolls the pair once the newer sample has aged past the window", async () => {
|
|
461
|
-
const client: FakeRedisClient = makeClient({
|
|
462
|
-
get: jest.fn().mockResolvedValue(
|
|
463
|
-
storedSamples({
|
|
464
|
-
evictedKeys: 10,
|
|
465
|
-
rejectedConnections: 1,
|
|
466
|
-
olderAgeInSeconds: COUNTER_WINDOW_IN_SECONDS * 2,
|
|
467
|
-
newerAgeInSeconds: COUNTER_WINDOW_IN_SECONDS,
|
|
468
|
-
}),
|
|
469
|
-
),
|
|
470
|
-
});
|
|
471
|
-
connectClient(client);
|
|
472
|
-
|
|
473
|
-
await getRedisHealthSnapshot();
|
|
474
|
-
|
|
475
|
-
expect(client.set).toHaveBeenCalled();
|
|
476
274
|
expect(client.expire).not.toHaveBeenCalled();
|
|
477
275
|
});
|
|
478
276
|
|
|
479
|
-
|
|
480
|
-
* The whole point of keeping two samples: right after a roll the lookback
|
|
481
|
-
* must still span a full window. With a single rolling baseline the tick
|
|
482
|
-
* after a roll would compare against a 5-minute-old sample, so one quiet
|
|
483
|
-
* tick there would resolve the notification and the next burst of the same
|
|
484
|
-
* incident would re-notify every master admin.
|
|
485
|
-
*/
|
|
486
|
-
test("still looks back a full window on the tick after a roll", async () => {
|
|
487
|
-
const client: FakeRedisClient = makeClient({
|
|
488
|
-
get: jest.fn().mockResolvedValue(
|
|
489
|
-
storedSamples({
|
|
490
|
-
evictedKeys: 10,
|
|
491
|
-
rejectedConnections: 1,
|
|
492
|
-
olderAgeInSeconds: COUNTER_WINDOW_IN_SECONDS + 300,
|
|
493
|
-
newerAgeInSeconds: 300,
|
|
494
|
-
}),
|
|
495
|
-
),
|
|
496
|
-
});
|
|
497
|
-
connectClient(client);
|
|
498
|
-
|
|
499
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
500
|
-
await getRedisHealthSnapshot();
|
|
501
|
-
|
|
502
|
-
expect(snapshot?.counterWindowInSeconds).toBe(
|
|
503
|
-
COUNTER_WINDOW_IN_SECONDS + 300,
|
|
504
|
-
);
|
|
505
|
-
expect(snapshot?.evictedKeysDelta).toBe(7);
|
|
506
|
-
// Not due to roll again yet, so the pair is left alone.
|
|
507
|
-
expect(client.set).not.toHaveBeenCalled();
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
/*
|
|
511
|
-
* The window is what the deltas actually span, not a nominal constant, so a
|
|
512
|
-
* held-longer-than-usual baseline is reported honestly rather than being
|
|
513
|
-
* described as "the last 30 minutes".
|
|
514
|
-
*/
|
|
515
|
-
test("reports the window actually spanned", async () => {
|
|
516
|
-
const client: FakeRedisClient = makeClient({
|
|
517
|
-
get: jest.fn().mockResolvedValue(
|
|
518
|
-
storedSamples({
|
|
519
|
-
evictedKeys: 10,
|
|
520
|
-
rejectedConnections: 1,
|
|
521
|
-
olderAgeInSeconds: 7200,
|
|
522
|
-
}),
|
|
523
|
-
),
|
|
524
|
-
});
|
|
525
|
-
connectClient(client);
|
|
526
|
-
|
|
527
|
-
expect((await getRedisHealthSnapshot())?.counterWindowInSeconds).toBe(
|
|
528
|
-
7200,
|
|
529
|
-
);
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
test("still returns a snapshot when the TTL refresh fails", async () => {
|
|
533
|
-
const client: FakeRedisClient = makeClient({
|
|
534
|
-
get: jest.fn().mockResolvedValue(
|
|
535
|
-
storedSamples({
|
|
536
|
-
evictedKeys: 10,
|
|
537
|
-
rejectedConnections: 1,
|
|
538
|
-
olderAgeInSeconds: 60,
|
|
539
|
-
}),
|
|
540
|
-
),
|
|
541
|
-
expire: jest.fn().mockRejectedValue(new Error("NOPERM")),
|
|
542
|
-
});
|
|
543
|
-
connectClient(client);
|
|
544
|
-
|
|
545
|
-
expect((await getRedisHealthSnapshot())?.evictedKeysDelta).toBe(7);
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
/*
|
|
549
|
-
* A baseline that outlived a Redis restart would otherwise subtract a large
|
|
550
|
-
* pre-restart total from a small post-restart one and invent a spike.
|
|
551
|
-
*/
|
|
552
|
-
test("suppresses deltas when the samples predate a restart", async () => {
|
|
553
|
-
const client: FakeRedisClient = makeClient({
|
|
554
|
-
get: jest.fn().mockResolvedValue(
|
|
555
|
-
storedSamples({
|
|
556
|
-
evictedKeys: 10,
|
|
557
|
-
rejectedConnections: 1,
|
|
558
|
-
// Longer uptime than Redis now reports, so it must have restarted.
|
|
559
|
-
olderAgeInSeconds: -913599,
|
|
560
|
-
}),
|
|
561
|
-
),
|
|
562
|
-
});
|
|
563
|
-
connectClient(client);
|
|
564
|
-
|
|
565
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
566
|
-
await getRedisHealthSnapshot();
|
|
567
|
-
|
|
568
|
-
expect(snapshot?.evictedKeysDelta).toBeNull();
|
|
569
|
-
expect(snapshot?.rejectedConnectionsDelta).toBeNull();
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
test("ignores a corrupt stored sample", async () => {
|
|
573
|
-
const client: FakeRedisClient = makeClient({
|
|
574
|
-
get: jest.fn().mockResolvedValue("{not json"),
|
|
575
|
-
});
|
|
576
|
-
connectClient(client);
|
|
577
|
-
|
|
578
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
579
|
-
await getRedisHealthSnapshot();
|
|
580
|
-
|
|
581
|
-
expect(snapshot?.evictedKeysDelta).toBeNull();
|
|
582
|
-
expect(client.set).toHaveBeenCalled();
|
|
583
|
-
});
|
|
584
|
-
|
|
585
|
-
test("ignores stored samples with non-numeric counters", async () => {
|
|
586
|
-
const client: FakeRedisClient = makeClient({
|
|
587
|
-
get: jest.fn().mockResolvedValue(
|
|
588
|
-
JSON.stringify({
|
|
589
|
-
older: {
|
|
590
|
-
evictedKeys: "lots",
|
|
591
|
-
rejectedConnections: 1,
|
|
592
|
-
uptimeInSeconds: 80000,
|
|
593
|
-
},
|
|
594
|
-
newer: {
|
|
595
|
-
evictedKeys: "lots",
|
|
596
|
-
rejectedConnections: 1,
|
|
597
|
-
uptimeInSeconds: 80000,
|
|
598
|
-
},
|
|
599
|
-
}),
|
|
600
|
-
),
|
|
601
|
-
});
|
|
602
|
-
connectClient(client);
|
|
603
|
-
|
|
604
|
-
expect((await getRedisHealthSnapshot())?.evictedKeysDelta).toBeNull();
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
// Losing the baseline must never fail the evaluation that produced it.
|
|
608
|
-
test("still returns a snapshot when the baseline cannot be written", async () => {
|
|
609
|
-
const client: FakeRedisClient = makeClient({
|
|
610
|
-
set: jest.fn().mockRejectedValue(new Error("READONLY")),
|
|
611
|
-
});
|
|
612
|
-
connectClient(client);
|
|
613
|
-
|
|
614
|
-
expect((await getRedisHealthSnapshot())?.memoryUtilizationPercent).toBe(
|
|
615
|
-
50,
|
|
616
|
-
);
|
|
617
|
-
});
|
|
618
|
-
|
|
619
|
-
/*
|
|
620
|
-
* Under the default noeviction policy Redis rejects SET once it is out of
|
|
621
|
-
* memory but still serves EXPIRE. If a failed write also skipped the TTL
|
|
622
|
-
* refresh, the baseline would expire exactly when memory is full and
|
|
623
|
-
* eviction detection would go blind for good — every later write fails the
|
|
624
|
-
* same way, so the key would never come back.
|
|
625
|
-
*/
|
|
626
|
-
test("keeps the baseline alive when the roll write is rejected", async () => {
|
|
277
|
+
test("falls back to CONFIG GET when INFO omits maxclients", async () => {
|
|
627
278
|
const client: FakeRedisClient = makeClient({
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
evictedKeys: 10,
|
|
631
|
-
rejectedConnections: 1,
|
|
632
|
-
olderAgeInSeconds: COUNTER_WINDOW_IN_SECONDS * 2,
|
|
633
|
-
newerAgeInSeconds: COUNTER_WINDOW_IN_SECONDS,
|
|
634
|
-
}),
|
|
635
|
-
),
|
|
636
|
-
set: jest
|
|
637
|
-
.fn()
|
|
638
|
-
.mockRejectedValue(
|
|
639
|
-
new Error(
|
|
640
|
-
"OOM command not allowed when used memory > 'maxmemory'.",
|
|
641
|
-
),
|
|
642
|
-
),
|
|
279
|
+
info: jest.fn().mockResolvedValue("connected_clients:50"),
|
|
280
|
+
call: jest.fn().mockResolvedValue(["maxclients", "200"]),
|
|
643
281
|
});
|
|
644
|
-
connectClient(client);
|
|
645
|
-
|
|
646
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
647
|
-
await getRedisHealthSnapshot();
|
|
648
282
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
"oneuptime-instance-health-redis-sample",
|
|
652
|
-
3600,
|
|
283
|
+
const snapshot: RedisInfoSnapshot = await readInfoSnapshot(
|
|
284
|
+
client as never,
|
|
653
285
|
);
|
|
654
|
-
// The old baseline is still usable, so the delta survives.
|
|
655
|
-
expect(snapshot?.evictedKeysDelta).toBe(7);
|
|
656
|
-
});
|
|
657
286
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
get: jest.fn().mockRejectedValue(new Error("NOPERM")),
|
|
661
|
-
});
|
|
662
|
-
connectClient(client);
|
|
663
|
-
|
|
664
|
-
const snapshot: RedisHealthSnapshot | null =
|
|
665
|
-
await getRedisHealthSnapshot();
|
|
666
|
-
|
|
667
|
-
expect(snapshot?.evictedKeysDelta).toBeNull();
|
|
668
|
-
expect(snapshot?.usedMemoryInBytes).toBe(1073741824);
|
|
287
|
+
expect(client.call).toHaveBeenCalledWith("CONFIG", "GET", "maxclients");
|
|
288
|
+
expect(snapshot.clientUtilizationPercent).toBe(25);
|
|
669
289
|
});
|
|
670
290
|
});
|
|
671
291
|
});
|