From 47fc709a89ec438a5c89d25cd71ac120105dd038 Mon Sep 17 00:00:00 2001 From: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:48:18 +0000 Subject: [PATCH] [INFRA] Enable anomaly detection in hosts view (#177555) Closes https://github.com/elastic/kibana/issues/176522 ### What was done - Anomaly Detection top menu item appears in the Hosts View and Asset Details image image - Within the Hosts View and Asset Details page the Anomaly Detection flyout will present to users only with the Hosts option, hiding the Kubernetes option image - In the Anomaly tab, when the flyout is opened within the Hosts View and Asset details, it will only show hosts anomalies, and won't show the infra type dropdown image - Fixed the tab items margin --- .../tabs/anomalies/anomalies.tsx | 2 +- .../anomalies_table/annomaly_summary.tsx | 4 +- .../anomalies_table/anomalies_table.tsx | 51 +++-- .../anomalies_table/pagination.tsx | 0 .../anomaly_detection_flyout.tsx | 20 +- .../ml/anomaly_detection/flyout_home.tsx | 118 ++++++----- .../ml/anomaly_detection/job_setup_screen.tsx | 16 +- .../infra/public/pages/metrics/index.tsx | 14 +- .../apps/infra/metrics_anomalies.ts | 192 ++++++++++-------- 9 files changed, 239 insertions(+), 178 deletions(-) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx (90%) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx (91%) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/anomalies_table/pagination.tsx (100%) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/anomaly_detection_flyout.tsx (80%) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/flyout_home.tsx (81%) rename x-pack/plugins/observability_solution/infra/public/{pages/metrics/inventory_view => }/components/ml/anomaly_detection/job_setup_screen.tsx (94%) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/anomalies/anomalies.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/anomalies/anomalies.tsx index f42c340211b1b..33fb38fa612a7 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/anomalies/anomalies.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/anomalies/anomalies.tsx @@ -6,7 +6,7 @@ */ import React, { useMemo, useRef } from 'react'; -import { AnomaliesTable } from '../../../../pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/anomalies_table'; +import { AnomaliesTable } from '../../../ml/anomaly_detection/anomalies_table/anomalies_table'; import { useAssetDetailsRenderPropsContext } from '../../hooks/use_asset_details_render_props'; import { useDatePickerContext } from '../../hooks/use_date_picker'; import { useIntersectingState } from '../../hooks/use_intersecting_state'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx similarity index 90% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx index 09c8beeb2a1be..7c2f5e61363b1 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/annomaly_summary.tsx @@ -8,8 +8,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { MetricsHostsAnomaly } from '../../../../../../../../common/http_api/infra_ml/results'; -import { formatOneDecimalPlace } from '../../../../../../../../common/log_analysis'; +import { MetricsHostsAnomaly } from '../../../../../common/http_api/infra_ml/results'; +import { formatOneDecimalPlace } from '../../../../../common/log_analysis'; export const AnomalySummary = ({ anomaly }: { anomaly: MetricsHostsAnomaly }) => { const { actual, typical } = anomaly; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx similarity index 91% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx index 288f05496dd4e..0c1b656169033 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/anomalies_table.tsx @@ -31,21 +31,24 @@ import type { TimeRange } from '@kbn/es-query'; import { css } from '@emotion/react'; import type { SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common'; import { BehaviorSubject } from 'rxjs'; -import { datemathToEpochMillis } from '../../../../../../../utils/datemath'; -import { useSorting } from '../../../../../../../hooks/use_sorting'; -import { useMetricsK8sAnomaliesResults } from '../../../../hooks/use_metrics_k8s_anomalies'; -import { useMetricsHostsAnomaliesResults } from '../../../../hooks/use_metrics_hosts_anomalies'; +import { datemathToEpochMillis } from '../../../../utils/datemath'; +import { useSorting } from '../../../../hooks/use_sorting'; +import { useMetricsK8sAnomaliesResults } from '../../../../pages/metrics/inventory_view/hooks/use_metrics_k8s_anomalies'; +import { useMetricsHostsAnomaliesResults } from '../../../../pages/metrics/inventory_view/hooks/use_metrics_hosts_anomalies'; import type { Metric, MetricsHostsAnomaly, Sort, -} from '../../../../../../../../common/http_api/infra_ml/results'; +} from '../../../../../common/http_api/infra_ml/results'; import { PaginationControls } from './pagination'; import { AnomalySummary } from './annomaly_summary'; -import { AnomalySeverityIndicator } from '../../../../../../../components/logging/log_analysis_results/anomaly_severity_indicator'; -import { useSourceContext } from '../../../../../../../containers/metrics_source'; +import { AnomalySeverityIndicator } from '../../../logging/log_analysis_results/anomaly_severity_indicator'; +import { useSourceContext } from '../../../../containers/metrics_source'; import { createResultsUrl } from '../flyout_home'; -import { useWaffleViewState, WaffleViewState } from '../../../../hooks/use_waffle_view_state'; +import { + useWaffleViewState, + WaffleViewState, +} from '../../../../pages/metrics/inventory_view/hooks/use_waffle_view_state'; type JobType = 'k8s' | 'hosts'; type SortField = 'anomalyScore' | 'startTime'; @@ -200,6 +203,7 @@ interface Props { hideDatePicker?: boolean; // subject to watch the completition of the request request$?: BehaviorSubject<(() => Promise) | undefined>; + hideSelectGroup?: boolean; } const DEFAULT_DATE_RANGE: TimeRange = { @@ -213,6 +217,7 @@ export const AnomaliesTable = ({ dateRange = DEFAULT_DATE_RANGE, hideDatePicker = false, request$, + hideSelectGroup, }: Props) => { const [search, setSearch] = useState(''); const trackMetric = useUiTracker({ app: 'infra_metrics' }); @@ -501,20 +506,22 @@ export const AnomaliesTable = ({ isClearable={true} /> - - - + {!hideSelectGroup && ( + + + + )} )} diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/pagination.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/pagination.tsx similarity index 100% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomalies_table/pagination.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomalies_table/pagination.tsx diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomaly_detection_flyout.tsx similarity index 80% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomaly_detection_flyout.tsx index 4c9ea654914c6..dac65711e592f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/anomaly_detection_flyout.tsx @@ -8,15 +8,21 @@ import React, { useState, useCallback } from 'react'; import { EuiHeaderLink, EuiFlyout } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useSourceContext } from '../../../../../../containers/metrics_source'; +import { useSourceContext } from '../../../containers/metrics_source'; import { FlyoutHome } from './flyout_home'; import { JobSetupScreen } from './job_setup_screen'; -import { useInfraMLCapabilities } from '../../../../../../containers/ml/infra_ml_capabilities'; -import { MetricHostsModuleProvider } from '../../../../../../containers/ml/modules/metrics_hosts/module'; -import { MetricK8sModuleProvider } from '../../../../../../containers/ml/modules/metrics_k8s/module'; -import { useActiveKibanaSpace } from '../../../../../../hooks/use_kibana_space'; +import { useInfraMLCapabilities } from '../../../containers/ml/infra_ml_capabilities'; +import { MetricHostsModuleProvider } from '../../../containers/ml/modules/metrics_hosts/module'; +import { MetricK8sModuleProvider } from '../../../containers/ml/modules/metrics_k8s/module'; +import { useActiveKibanaSpace } from '../../../hooks/use_kibana_space'; -export const AnomalyDetectionFlyout = () => { +export const AnomalyDetectionFlyout = ({ + hideJobType, + hideSelectGroup, +}: { + hideJobType?: boolean; + hideSelectGroup?: boolean; +}) => { const { hasInfraMLSetupCapabilities } = useInfraMLCapabilities(); const [showFlyout, setShowFlyout] = useState(false); const [screenName, setScreenName] = useState<'home' | 'setup'>('home'); @@ -77,6 +83,8 @@ export const AnomalyDetectionFlyout = () => { hasSetupCapabilities={hasInfraMLSetupCapabilities} goToSetup={openJobSetup} closeFlyout={closeFlyout} + hideJobType={hideJobType} + hideSelectGroup={hideSelectGroup} /> )} {screenName === 'setup' && ( diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/flyout_home.tsx similarity index 81% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/flyout_home.tsx index 2e5db57604cea..680c1c63cca43 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/flyout_home.tsx @@ -29,22 +29,24 @@ import moment from 'moment'; import { MLJobsAwaitingNodeWarning } from '@kbn/ml-plugin/public'; import { FeatureFeedbackButton, useLinkProps } from '@kbn/observability-shared-plugin/public'; import { css } from '@emotion/react'; -import { KibanaEnvironmentContext } from '../../../../../../hooks/use_kibana'; -import { SubscriptionSplashPrompt } from '../../../../../../components/subscription_splash_content'; -import { useInfraMLCapabilitiesContext } from '../../../../../../containers/ml/infra_ml_capabilities'; import { MissingResultsPrivilegesPrompt, MissingSetupPrivilegesPrompt, -} from '../../../../../../components/logging/log_analysis_setup'; -import { useMetricHostsModuleContext } from '../../../../../../containers/ml/modules/metrics_hosts/module'; -import { useMetricK8sModuleContext } from '../../../../../../containers/ml/modules/metrics_k8s/module'; -import { LoadingPrompt } from '../../../../../../components/loading_page'; +} from '../../logging/log_analysis_setup'; +import { useMetricHostsModuleContext } from '../../../containers/ml/modules/metrics_hosts/module'; +import { useMetricK8sModuleContext } from '../../../containers/ml/modules/metrics_k8s/module'; +import { LoadingPrompt } from '../../loading_page'; import { AnomaliesTable } from './anomalies_table/anomalies_table'; +import { SubscriptionSplashPrompt } from '../../subscription_splash_content'; +import { useInfraMLCapabilitiesContext } from '../../../containers/ml/infra_ml_capabilities'; +import { KibanaEnvironmentContext } from '../../../hooks/use_kibana'; interface Props { hasSetupCapabilities: boolean; goToSetup(type: 'hosts' | 'kubernetes'): void; closeFlyout(): void; + hideJobType?: boolean; + hideSelectGroup?: boolean; } type Tab = 'jobs' | 'anomalies'; @@ -124,7 +126,7 @@ export const FlyoutHome = (props: Props) => { - +

{ hasSetupCapabilities={props.hasSetupCapabilities} createHosts={createHosts} createK8s={createK8s} + hideJobType={props.hideJobType} /> )} - {tab === 'anomalies' && } + {tab === 'anomalies' && ( + + )} ); @@ -294,18 +299,18 @@ interface CreateJobTab { hasK8sJobs: boolean; createHosts(): void; createK8s(): void; + hideJobType?: boolean; } const CreateJobTab = (props: CreateJobTab) => { return ( <> - {/* */} } - // title="Hosts" title={ { } /> - - } - title={ - - } - description={ - - } - footer={ - <> - {props.hasK8sJobs && ( - - - - )} - {!props.hasK8sJobs && ( - - - - )} - - } - /> - + {!props.hideJobType && ( + + } + title={ + + } + description={ + + } + footer={ + <> + {props.hasK8sJobs && ( + + + + )} + {!props.hasK8sJobs && ( + + + + )} + + } + /> + + )} ); diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/job_setup_screen.tsx similarity index 94% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx rename to x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/job_setup_screen.tsx index fd291f5eeb839..c17b73703fe97 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/job_setup_screen.tsx @@ -31,15 +31,15 @@ import moment, { Moment } from 'moment'; import { i18n } from '@kbn/i18n'; import { FeatureFeedbackButton, useUiTracker } from '@kbn/observability-shared-plugin/public'; import { css } from '@emotion/react'; -import { KibanaEnvironmentContext } from '../../../../../../hooks/use_kibana'; -import { useSourceContext } from '../../../../../../containers/metrics_source'; -import { useMetricK8sModuleContext } from '../../../../../../containers/ml/modules/metrics_k8s/module'; -import { useMetricHostsModuleContext } from '../../../../../../containers/ml/modules/metrics_hosts/module'; -import { FixedDatePicker } from '../../../../../../components/fixed_datepicker'; -import { DEFAULT_K8S_PARTITION_FIELD } from '../../../../../../containers/ml/modules/metrics_k8s/module_descriptor'; -import { MetricsExplorerKueryBar } from '../../../../metrics_explorer/components/kuery_bar'; -import { convertKueryToElasticSearchQuery } from '../../../../../../utils/kuery'; +import { useSourceContext } from '../../../containers/metrics_source'; +import { useMetricHostsModuleContext } from '../../../containers/ml/modules/metrics_hosts/module'; +import { useMetricK8sModuleContext } from '../../../containers/ml/modules/metrics_k8s/module'; +import { FixedDatePicker } from '../../fixed_datepicker'; +import { DEFAULT_K8S_PARTITION_FIELD } from '../../../containers/ml/modules/metrics_k8s/module_descriptor'; +import { convertKueryToElasticSearchQuery } from '../../../utils/kuery'; import { INFRA_ML_FLYOUT_FEEDBACK_LINK } from './flyout_home'; +import { KibanaEnvironmentContext } from '../../../hooks/use_kibana'; +import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar'; interface Props { jobType: 'hosts' | 'kubernetes'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/index.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/index.tsx index 877a48c4153ec..841c8a095330f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/index.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/index.tsx @@ -34,7 +34,7 @@ import { SourceLoadingPage } from '../../components/source_loading_page'; import { MetricsAlertDropdown } from '../../alerting/common/components/metrics_alert_dropdown'; import { AlertPrefillProvider } from '../../alerting/use_alert_prefill'; import { InfraMLCapabilitiesProvider } from '../../containers/ml/infra_ml_capabilities'; -import { AnomalyDetectionFlyout } from './inventory_view/components/ml/anomaly_detection/anomaly_detection_flyout'; +import { AnomalyDetectionFlyout } from '../../components/ml/anomaly_detection/anomaly_detection_flyout'; import { HeaderActionMenuContext } from '../../utils/header_action_menu_provider'; import { CreateDerivedIndexPattern, useSourceContext } from '../../containers/metrics_source'; import { NotFoundPage } from '../404'; @@ -91,6 +91,18 @@ export const InfrastructurePage = () => { {settingsTabTitle} + { + return ; + }} + /> + { + return ; + }} + /> {config.featureFlags.alertsAndRulesDropdownEnabled && ( )} diff --git a/x-pack/test/functional/apps/infra/metrics_anomalies.ts b/x-pack/test/functional/apps/infra/metrics_anomalies.ts index a222fa4d7a034..3b57a141af6f7 100644 --- a/x-pack/test/functional/apps/infra/metrics_anomalies.ts +++ b/x-pack/test/functional/apps/infra/metrics_anomalies.ts @@ -7,13 +7,14 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -import { ML_JOB_IDS } from './constants'; +import { HOSTS_VIEW_PATH, ML_JOB_IDS } from './constants'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); - const pageObjects = getPageObjects(['common', 'infraHome']); + const pageObjects = getPageObjects(['assetDetails', 'common', 'infraHome', 'infraHostsView']); const infraSourceConfigurationForm = getService('infraSourceConfigurationForm'); + const testSubjects = getService('testSubjects'); describe('Metrics UI Anomaly Flyout', function () { before(async () => { @@ -23,92 +24,117 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await kibanaServer.savedObjects.cleanStandardList(); }); - describe('with no anomalies present', () => { - it('renders the anomaly flyout', async () => { - await pageObjects.common.navigateToApp('infraOps'); - await pageObjects.infraHome.openAnomalyFlyout(); + describe('when opening the flyout', () => { + describe('in inventory page', () => { + it('renders the anomaly flyout in inventory page', async () => { + await pageObjects.common.navigateToApp('infraOps'); + await pageObjects.infraHome.openAnomalyFlyout(); + }); + it('shows both cards in create jobs tab Hosts and K8s', async () => { + await testSubjects.exists('infraHostsJobCard'); + await testSubjects.exists('infraK8sJobCard'); + }); }); - it('renders the anomaly table with no anomalies', async () => { - await pageObjects.infraHome.goToAnomaliesTab(); - await pageObjects.infraHome.clickHostsAnomaliesDropdown(); - await pageObjects.infraHome.getNoAnomaliesMsg(); - await pageObjects.infraHome.clickK8sAnomaliesDropdown(); - await pageObjects.infraHome.getNoAnomaliesMsg(); - await pageObjects.infraHome.closeFlyout(); + + describe('in hosts view', () => { + it('renders the anomaly flyout in hosts view page', async () => { + await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH); + await pageObjects.infraHome.openAnomalyFlyout(); + }); + + it('shows just Hosts create jobs card', async () => { + await testSubjects.exists('infraHostsJobCard'); + await testSubjects.missingOrFail('infraK8sJobCard'); + }); }); }); - describe('with anomalies present', () => { - before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_anomalies'); - // create the ml jobs saved objects - await Promise.all( - ML_JOB_IDS.map((id) => - kibanaServer.savedObjects.create({ - type: 'ml-job', - id: `anomaly-detector-${id}`, - overwrite: true, - attributes: { - job_id: id, - datafeed_id: `datafeed-${id}`, - type: 'anomaly-detector', - }, - }) - ) - ); - }); - after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_anomalies'); + describe('anomalies table in flyout', () => { + describe('with no anomalies present', () => { + it('renders the anomaly table with no anomalies', async () => { + await pageObjects.common.navigateToApp('infraOps'); + await pageObjects.infraHome.openAnomalyFlyout(); + await pageObjects.infraHome.goToAnomaliesTab(); + await pageObjects.infraHome.clickHostsAnomaliesDropdown(); + await pageObjects.infraHome.getNoAnomaliesMsg(); + await pageObjects.infraHome.clickK8sAnomaliesDropdown(); + await pageObjects.infraHome.getNoAnomaliesMsg(); + await pageObjects.infraHome.closeFlyout(); + }); }); - it('renders the anomaly table with anomalies', async () => { - // if the input value is unchanged the save button won't be available - // after the change of the settings action added in - // https://github.com/elastic/kibana/pull/175024 - // to avoid the mentioned issue we can change the value and put it back to 50 - await pageObjects.infraHome.goToSettings(); - await pageObjects.infraHome.setAnomaliesThreshold('51'); - await infraSourceConfigurationForm.saveInfraSettings(); - // default threshold should already be 50 but trying to prevent unknown flakiness by setting it - // https://github.com/elastic/kibana/issues/100445 - await pageObjects.infraHome.goToSettings(); - await pageObjects.infraHome.setAnomaliesThreshold('50'); - await infraSourceConfigurationForm.saveInfraSettings(); - await pageObjects.infraHome.goToInventory(); - await pageObjects.infraHome.openAnomalyFlyout(); - await pageObjects.infraHome.goToAnomaliesTab(); - await pageObjects.infraHome.clickHostsAnomaliesDropdown(); - await pageObjects.infraHome.setAnomaliesDate('Apr 21, 2021 @ 00:00:00.000'); - const hostAnomalies = await pageObjects.infraHome.findAnomalies(); - expect(hostAnomalies.length).to.be(2); - await pageObjects.infraHome.clickK8sAnomaliesDropdown(); - const k8sAnomalies = await pageObjects.infraHome.findAnomalies(); - expect(k8sAnomalies.length).to.be(1); - await pageObjects.infraHome.closeFlyout(); - }); - it('renders the anomaly table after a date change with no anomalies', async () => { - await pageObjects.infraHome.openAnomalyFlyout(); - await pageObjects.infraHome.goToAnomaliesTab(); - await pageObjects.infraHome.clickHostsAnomaliesDropdown(); - await pageObjects.infraHome.setAnomaliesDate('Apr 23, 2021 @ 11:00:00.000'); - await pageObjects.infraHome.getNoAnomaliesMsg(); - await pageObjects.infraHome.clickK8sAnomaliesDropdown(); - await pageObjects.infraHome.getNoAnomaliesMsg(); - await pageObjects.infraHome.closeFlyout(); - }); - it('renders more anomalies on threshold change', async () => { - await pageObjects.infraHome.goToSettings(); - await pageObjects.infraHome.setAnomaliesThreshold('25'); - await infraSourceConfigurationForm.saveInfraSettings(); - await pageObjects.infraHome.goToInventory(); - await pageObjects.infraHome.openAnomalyFlyout(); - await pageObjects.infraHome.goToAnomaliesTab(); - await pageObjects.infraHome.clickHostsAnomaliesDropdown(); - await pageObjects.infraHome.setAnomaliesDate('Apr 21, 2021 @ 00:00:00.000'); - const hostAnomalies = await pageObjects.infraHome.findAnomalies(); - expect(hostAnomalies.length).to.be(4); - await pageObjects.infraHome.clickK8sAnomaliesDropdown(); - const k8sAnomalies = await pageObjects.infraHome.findAnomalies(); - expect(k8sAnomalies.length).to.be(3); + + describe('with anomalies present', () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_anomalies'); + // create the ml jobs saved objects + await Promise.all( + ML_JOB_IDS.map((id) => + kibanaServer.savedObjects.create({ + type: 'ml-job', + id: `anomaly-detector-${id}`, + overwrite: true, + attributes: { + job_id: id, + datafeed_id: `datafeed-${id}`, + type: 'anomaly-detector', + }, + }) + ) + ); + }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_anomalies'); + }); + it('renders the anomaly table with anomalies', async () => { + // if the input value is unchanged the save button won't be available + // after the change of the settings action added in + // https://github.com/elastic/kibana/pull/175024 + // to avoid the mentioned issue we can change the value and put it back to 50 + await pageObjects.infraHome.goToSettings(); + await pageObjects.infraHome.setAnomaliesThreshold('51'); + await infraSourceConfigurationForm.saveInfraSettings(); + // default threshold should already be 50 but trying to prevent unknown flakiness by setting it + // https://github.com/elastic/kibana/issues/100445 + await pageObjects.infraHome.goToSettings(); + await pageObjects.infraHome.setAnomaliesThreshold('50'); + await infraSourceConfigurationForm.saveInfraSettings(); + await pageObjects.infraHome.goToInventory(); + await pageObjects.infraHome.openAnomalyFlyout(); + await pageObjects.infraHome.goToAnomaliesTab(); + await pageObjects.infraHome.clickHostsAnomaliesDropdown(); + await pageObjects.infraHome.setAnomaliesDate('Apr 21, 2021 @ 00:00:00.000'); + const hostAnomalies = await pageObjects.infraHome.findAnomalies(); + expect(hostAnomalies.length).to.be(2); + await pageObjects.infraHome.clickK8sAnomaliesDropdown(); + const k8sAnomalies = await pageObjects.infraHome.findAnomalies(); + expect(k8sAnomalies.length).to.be(1); + await pageObjects.infraHome.closeFlyout(); + }); + it('renders the anomaly table after a date change with no anomalies', async () => { + await pageObjects.infraHome.openAnomalyFlyout(); + await pageObjects.infraHome.goToAnomaliesTab(); + await pageObjects.infraHome.clickHostsAnomaliesDropdown(); + await pageObjects.infraHome.setAnomaliesDate('Apr 23, 2021 @ 11:00:00.000'); + await pageObjects.infraHome.getNoAnomaliesMsg(); + await pageObjects.infraHome.clickK8sAnomaliesDropdown(); + await pageObjects.infraHome.getNoAnomaliesMsg(); + await pageObjects.infraHome.closeFlyout(); + }); + it('renders more anomalies on threshold change', async () => { + await pageObjects.infraHome.goToSettings(); + await pageObjects.infraHome.setAnomaliesThreshold('25'); + await infraSourceConfigurationForm.saveInfraSettings(); + await pageObjects.infraHome.goToInventory(); + await pageObjects.infraHome.openAnomalyFlyout(); + await pageObjects.infraHome.goToAnomaliesTab(); + await pageObjects.infraHome.clickHostsAnomaliesDropdown(); + await pageObjects.infraHome.setAnomaliesDate('Apr 21, 2021 @ 00:00:00.000'); + const hostAnomalies = await pageObjects.infraHome.findAnomalies(); + expect(hostAnomalies.length).to.be(4); + await pageObjects.infraHome.clickK8sAnomaliesDropdown(); + const k8sAnomalies = await pageObjects.infraHome.findAnomalies(); + expect(k8sAnomalies.length).to.be(3); + }); }); }); });