From 43dfbda6d4a3bc8455764e7d8ab1aac413dde8f8 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:38:17 +1000 Subject: [PATCH] [8.x] [Dataset quality] Adding size column and estimated size to serverless (#193998) (#194520) # Backport This will backport the following commits from `main` to `8.x`: - [[Dataset quality] Adding size column and estimated size to serverless (#193998)](https://github.com/elastic/kibana/pull/193998) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: Yngrid Coello --- .../dataset_quality/README.md | 16 +++---- .../dataset_quality/common/api_types.ts | 6 +-- .../summary_panel/summary_panel.tsx | 5 +- .../dataset_quality/table/columns.tsx | 4 +- .../overview/summary/index.tsx | 15 +++--- .../hooks/use_dataset_quality_table.tsx | 4 -- .../hooks/use_overview_summary_panel.ts | 6 +-- .../public/hooks/use_summary_panel.ts | 10 +--- .../src/defaults.ts | 1 - .../src/state_machine.ts | 5 -- .../dataset_quality_controller/src/types.ts | 1 - .../get_data_stream_details/index.ts | 44 +++++++++++++----- .../get_data_streams_metering_stats/index.ts | 46 +++++++++++++++++++ .../server/routes/data_streams/routes.ts | 10 ++-- .../data_stream_details.ts | 22 +++++++-- .../data_stream_settings.ts | 2 +- .../dataset_quality_details.ts | 8 ++-- .../dataset_quality/dataset_quality_table.ts | 11 +++++ 18 files changed, 144 insertions(+), 72 deletions(-) create mode 100644 x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_metering_stats/index.ts diff --git a/x-pack/plugins/observability_solution/dataset_quality/README.md b/x-pack/plugins/observability_solution/dataset_quality/README.md index 8aaba88966d0c..356393aa5237f 100755 --- a/x-pack/plugins/observability_solution/dataset_quality/README.md +++ b/x-pack/plugins/observability_solution/dataset_quality/README.md @@ -92,34 +92,34 @@ unset FLEET_PACKAGE_REGISTRY_PORT ### Functional Tests -### Stateful -#### FTR Server +#### Stateful +##### FTR Server ``` yarn test:ftr:server --config ./x-pack/test/functional/apps/dataset_quality/config.ts ``` -#### FTR Runner +##### FTR Runner ``` yarn test:ftr:runner --config ./x-pack/test/functional/apps/dataset_quality/config.ts --include ./x-pack/test/functional/apps/dataset_quality/index.ts ``` -#### Running Individual Tests +##### Running Individual Tests ``` yarn test:ftr:runner --config ./x-pack/test/functional/apps/dataset_quality/config.ts --include ./x-pack/test/functional/apps/dataset_quality/$1 ``` -### Serverless +#### Serverless -#### Server +##### Server ``` yarn test:ftr:server --config ./x-pack/test_serverless/functional/test_suites/observability/config.ts ``` -#### Runner +##### Runner ``` yarn test:ftr:runner --config ./x-pack/test_serverless/functional/test_suites/observability/config.ts --include ./x-pack/test_serverless/functional/test_suites/observability/dataset_quality/index.ts ``` -#### Running Individual Tests +##### Running Individual Tests ``` yarn test:ftr:runner --config ./x-pack/test_serverless/functional/test_suites/observability/config.ts --include ./x-pack/test_serverless/functional/test_suites/observability/dataset_quality/$1 ``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts index 6a514650b195d..8bcce166b936f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts @@ -31,7 +31,7 @@ export const dataStreamStatRt = rt.intersection([ sizeBytes: rt.number, lastActivity: rt.number, integration: rt.string, - totalDocs: rt.union([rt.null, rt.number]), // rt.null is only needed for https://github.com/elastic/kibana/issues/178954 + totalDocs: rt.number, }), ]); @@ -132,7 +132,7 @@ export const dataStreamDetailsRt = rt.partial({ lastActivity: rt.number, degradedDocsCount: rt.number, docsCount: rt.number, - sizeBytes: rt.union([rt.null, rt.number]), // rt.null is only needed for https://github.com/elastic/kibana/issues/178954 + sizeBytes: rt.number, services: rt.record(rt.string, rt.array(rt.string)), hosts: rt.record(rt.string, rt.array(rt.string)), userPrivileges: userPrivilegesRt, @@ -158,7 +158,7 @@ export const getDataStreamsSettingsResponseRt = rt.exact(dataStreamSettingsRt); export const getDataStreamsDetailsResponseRt = rt.exact(dataStreamDetailsRt); export const dataStreamsEstimatedDataInBytesRT = rt.type({ - estimatedDataInBytes: rt.union([rt.number, rt.null]), // Null in serverless: https://github.com/elastic/kibana/issues/178954 + estimatedDataInBytes: rt.number, }); export const getDataStreamsEstimatedDataInBytesResponseRt = rt.exact( diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/summary_panel/summary_panel.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/summary_panel/summary_panel.tsx index 9100e25fdce8f..a913e60939e52 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/summary_panel/summary_panel.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/summary_panel/summary_panel.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { useSummaryPanelContext } from '../../../hooks'; import { DatasetsQualityIndicators } from './datasets_quality_indicators'; import { DatasetsActivity } from './datasets_activity'; import { EstimatedData } from './estimated_data'; @@ -16,17 +15,15 @@ import { EstimatedData } from './estimated_data'; // Allow for lazy loading // eslint-disable-next-line import/no-default-export export default function SummaryPanel() { - const { isEstimatedDataDisabled } = useSummaryPanelContext(); return ( - - {!isEstimatedDataDisabled && } + diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/table/columns.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/table/columns.tsx index da6bbf1628d10..68ec09897f7c2 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/table/columns.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/table/columns.tsx @@ -161,7 +161,6 @@ export const getDatasetQualityTableColumns = ({ loadingDataStreamStats, loadingDegradedStats, showFullDatasetNames, - isSizeStatsAvailable, isActiveDataset, timeRange, urlService, @@ -172,7 +171,6 @@ export const getDatasetQualityTableColumns = ({ loadingDataStreamStats: boolean; loadingDegradedStats: boolean; showFullDatasetNames: boolean; - isSizeStatsAvailable: boolean; isActiveDataset: (lastActivity: number) => boolean; timeRange: TimeRangeConfig; urlService: BrowserUrlService; @@ -226,7 +224,7 @@ export const getDatasetQualityTableColumns = ({ ), width: '160px', }, - ...(isSizeStatsAvailable && canUserMonitorDataset && canUserMonitorAnyDataStream + ...(canUserMonitorDataset && canUserMonitorAnyDataStream ? [ { name: ( diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/overview/summary/index.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/overview/summary/index.tsx index 707c900a248a1..752b224b6973a 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/overview/summary/index.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality_details/overview/summary/index.tsx @@ -26,7 +26,6 @@ export default function Summary() { const { isSummaryPanelLoading, totalDocsCount, - sizeInBytesAvailable, sizeInBytes, isUserAllowedToSeeSizeInBytes, totalServicesCount, @@ -41,14 +40,12 @@ export default function Summary() { value={totalDocsCount} isLoading={isSummaryPanelLoading} /> - {sizeInBytesAvailable && ( - - )} + { const { page, rowsPerPage, sort } = useSelector(service, (state) => state.context.table); - const isSizeStatsAvailable = useSelector(service, (state) => state.context.isSizeStatsAvailable); const canUserMonitorDataset = useSelector( service, (state) => state.context.datasetUserPrivileges.canMonitor @@ -102,7 +101,6 @@ export const useDatasetQualityTable = () => { loadingDataStreamStats, loadingDegradedStats, showFullDatasetNames, - isSizeStatsAvailable, isActiveDataset: isActive, timeRange, urlService: url, @@ -114,7 +112,6 @@ export const useDatasetQualityTable = () => { loadingDataStreamStats, loadingDegradedStats, showFullDatasetNames, - isSizeStatsAvailable, isActive, timeRange, url, @@ -211,6 +208,5 @@ export const useDatasetQualityTable = () => { canUserMonitorAnyDataStream, toggleInactiveDatasets, toggleFullDatasetNames, - isSizeStatsAvailable, }; }; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_overview_summary_panel.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_overview_summary_panel.ts index 5cdd820c9b4ae..084210774f958 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_overview_summary_panel.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_overview_summary_panel.ts @@ -26,10 +26,9 @@ export const useOverviewSummaryPanel = () => { .map((key: string) => services[key].length) .reduce((a, b) => a + b, 0); - const totalDocsCount = formatNumber(dataStreamDetails?.docsCount ?? 0, NUMBER_FORMAT); + const totalDocsCount = formatNumber(dataStreamDetails.docsCount, NUMBER_FORMAT); - const sizeInBytesAvailable = dataStreamDetails?.sizeBytes !== null; - const sizeInBytes = formatNumber(dataStreamDetails?.sizeBytes ?? 0, BYTE_NUMBER_FORMAT); + const sizeInBytes = formatNumber(dataStreamDetails.sizeBytes, BYTE_NUMBER_FORMAT); const isUserAllowedToSeeSizeInBytes = dataStreamDetails?.userPrivileges?.canMonitor ?? true; const hosts = dataStreamDetails?.hosts ?? {}; @@ -57,7 +56,6 @@ export const useOverviewSummaryPanel = () => { return { totalDocsCount, - sizeInBytesAvailable, sizeInBytes, isUserAllowedToSeeSizeInBytes, totalServicesCount, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_summary_panel.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_summary_panel.ts index ce8acd58b7507..a85dc9c21d222 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_summary_panel.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_summary_panel.ts @@ -14,13 +14,8 @@ import { filterInactiveDatasets } from '../utils'; const useSummaryPanel = () => { const { service } = useDatasetQualityContext(); - const { - filteredItems, - isSizeStatsAvailable, - canUserMonitorDataset, - canUserMonitorAnyDataStream, - loading, - } = useDatasetQualityTable(); + const { filteredItems, canUserMonitorDataset, canUserMonitorAnyDataStream, loading } = + useDatasetQualityTable(); const { timeRange } = useSelector(service, (state) => state.context.filters); @@ -84,7 +79,6 @@ const useSummaryPanel = () => { isEstimatedDataLoading, estimatedData, - isEstimatedDataDisabled: !isSizeStatsAvailable, isDatasetsActivityLoading, datasetsActivity, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts index d0b2b9978080a..41cfa859ec977 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts @@ -55,6 +55,5 @@ export const DEFAULT_CONTEXT: DefaultDatasetQualityControllerState = { types: [DEFAULT_DATASET_TYPE], }, datasets: [], - isSizeStatsAvailable: true, nonAggregatableDatasets: [], }; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts index 127e56a755c86..a803d73448263 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts @@ -323,13 +323,8 @@ export const createPureDatasetQualityControllerStateMachine = ( const dataStreamStats = event.data.dataStreamsStats as DataStreamStat[]; const datasetUserPrivileges = event.data.datasetUserPrivileges; - // Check if any DataStreamStat has null; to check for serverless - const isSizeStatsAvailable = - !dataStreamStats.length || dataStreamStats.some((stat) => stat.totalDocs !== null); - return { dataStreamStats, - isSizeStatsAvailable, datasetUserPrivileges, }; } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts index 624fef066afcb..a5e03cfb480ff 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts @@ -60,7 +60,6 @@ export interface WithNonAggregatableDatasets { export interface WithDatasets { datasets: DataStreamStat[]; - isSizeStatsAvailable: boolean; } export interface WithIntegrations { diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts index 4aeeb1087ba89..c24ac84b10772 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts @@ -6,7 +6,7 @@ */ import { badRequest } from '@hapi/boom'; -import type { ElasticsearchClient } from '@kbn/core/server'; +import type { ElasticsearchClient, IScopedClusterClient } from '@kbn/core/server'; import { findInventoryFields, InventoryItemType, @@ -20,6 +20,7 @@ import { DataStreamDetails, DataStreamSettings } from '../../../../common/api_ty import { createDatasetQualityESClient } from '../../../utils'; import { dataStreamService, datasetQualityPrivileges } from '../../../services'; import { getDataStreams } from '../get_data_streams'; +import { getDataStreamsMeteringStats } from '../get_data_streams_metering_stats'; export async function getDataStreamSettings({ esClient, @@ -51,7 +52,7 @@ export async function getDataStreamDetails({ end, isServerless, }: { - esClient: ElasticsearchClient; + esClient: IScopedClusterClient; dataStream: string; start: number; end: number; @@ -59,14 +60,22 @@ export async function getDataStreamDetails({ }): Promise { throwIfInvalidDataStreamParams(dataStream); + // Query datastreams as the current user as the Kibana internal user may not have all the required permissions + const esClientAsCurrentUser = esClient.asCurrentUser; + const esClientAsSecondaryAuthUser = esClient.asSecondaryAuthUser; + const hasAccessToDataStream = ( - await datasetQualityPrivileges.getHasIndexPrivileges(esClient, [dataStream], ['monitor']) + await datasetQualityPrivileges.getHasIndexPrivileges( + esClientAsCurrentUser, + [dataStream], + ['monitor'] + ) )[dataStream]; const esDataStream = hasAccessToDataStream ? ( await getDataStreams({ - esClient, + esClient: esClientAsCurrentUser, datasetQuery: dataStream, }) ).dataStreams[0] @@ -74,18 +83,19 @@ export async function getDataStreamDetails({ try { const dataStreamSummaryStats = await getDataStreamSummaryStats( - esClient, + esClientAsCurrentUser, dataStream, start, end ); - const whenSizeStatsNotAvailable = NaN; // This will indicate size cannot be calculated - const avgDocSizeInBytes = isServerless - ? whenSizeStatsNotAvailable - : hasAccessToDataStream && dataStreamSummaryStats.docsCount > 0 - ? await getAvgDocSizeInBytes(esClient, dataStream) - : 0; + const avgDocSizeInBytes = + hasAccessToDataStream && dataStreamSummaryStats.docsCount > 0 + ? isServerless + ? await getMeteringAvgDocSizeInBytes(esClientAsSecondaryAuthUser, dataStream) + : await getAvgDocSizeInBytes(esClientAsCurrentUser, dataStream) + : 0; + const sizeBytes = Math.ceil(avgDocSizeInBytes * dataStreamSummaryStats.docsCount); return { @@ -172,6 +182,18 @@ async function getDataStreamSummaryStats( }; } +async function getMeteringAvgDocSizeInBytes(esClient: ElasticsearchClient, index: string) { + const meteringStats = await getDataStreamsMeteringStats({ + esClient, + dataStreams: [index], + }); + + const docCount = meteringStats[index].totalDocs ?? 0; + const sizeInBytes = meteringStats[index].sizeBytes ?? 0; + + return docCount ? sizeInBytes / docCount : 0; +} + async function getAvgDocSizeInBytes(esClient: ElasticsearchClient, index: string) { const indexStats = await esClient.indices.stats({ index }); const docCount = indexStats._all.total?.docs?.count ?? 0; diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_metering_stats/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_metering_stats/index.ts new file mode 100644 index 0000000000000..bdf30533cbed9 --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_metering_stats/index.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClient } from '@kbn/core/server'; + +export interface MeteringStatsResponse { + datastreams: Array<{ + name: string; + num_docs: number; + size_in_bytes: number; + }>; +} + +export async function getDataStreamsMeteringStats({ + esClient, + dataStreams, +}: { + esClient: ElasticsearchClient; + dataStreams: string[]; +}): Promise> { + if (!dataStreams.length) { + return {}; + } + + const { datastreams: dataStreamsStats } = await esClient.transport.request( + { + method: 'GET', + path: `/_metering/stats/` + dataStreams.join(','), + } + ); + + return dataStreamsStats.reduce( + (acc, dataStream) => ({ + ...acc, + [dataStream.name]: { + sizeBytes: dataStream.size_in_bytes, + totalDocs: dataStream.num_docs, + }, + }), + {} + ); +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts index c23b917a18e82..869e60c6bfaa3 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts @@ -26,6 +26,7 @@ import { getDegradedDocsPaginated } from './get_degraded_docs'; import { getNonAggregatableDataStreams } from './get_non_aggregatable_data_streams'; import { getDegradedFields } from './get_degraded_fields'; import { getDegradedFieldValues } from './get_degraded_field_values'; +import { getDataStreamsMeteringStats } from './get_data_streams_metering_stats'; const statsRoute = createDatasetQualityServerRoute({ endpoint: 'GET /internal/dataset_quality/data_streams/stats', @@ -50,6 +51,7 @@ const statsRoute = createDatasetQualityServerRoute({ // Query datastreams as the current user as the Kibana internal user may not have all the required permissions const esClient = coreContext.elasticsearch.client.asCurrentUser; + const esClientAsSecondaryAuthUser = coreContext.elasticsearch.client.asSecondaryAuthUser; const { dataStreams, datasetUserPrivileges } = await getDataStreams({ esClient, @@ -62,7 +64,10 @@ const statsRoute = createDatasetQualityServerRoute({ }); const dataStreamsStats = isServerless - ? {} + ? await getDataStreamsMeteringStats({ + esClient: esClientAsSecondaryAuthUser, + dataStreams: privilegedDataStreams.map((stream) => stream.name), + }) : await getDataStreamsStats({ esClient, dataStreams: privilegedDataStreams.map((stream) => stream.name), @@ -271,8 +276,7 @@ const dataStreamDetailsRoute = createDatasetQualityServerRoute({ const { start, end } = params.query; const coreContext = await context.core; - // Query datastreams as the current user as the Kibana internal user may not have all the required permissions - const esClient = coreContext.elasticsearch.client.asCurrentUser; + const esClient = coreContext.elasticsearch.client; const isServerless = (await getEsCapabilities()).serverless; const dataStreamDetails = await getDataStreamDetails({ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts index 61e4878856de3..50a1f51a86449 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_details.ts @@ -20,6 +20,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { const synthtrace = getService('logSynthtraceEsClient'); const svlUserManager = getService('svlUserManager'); const svlCommonApi = getService('svlCommonApi'); + const retry = getService('retry'); const start = '2023-12-11T18:00:00.000Z'; const end = '2023-12-11T18:01:00.000Z'; const type = 'logs'; @@ -56,7 +57,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { before(async () => { roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); internalReqHeader = svlCommonApi.getInternalRequestHeader(); - return synthtrace.index([ + await synthtrace.index([ timerange(start, end) .interval('1m') .rate(1) @@ -96,9 +97,24 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { expect(resp.body).empty(); }); - it('returns "sizeBytes" as null in serverless', async () => { + it('returns "sizeBytes" correctly', async () => { + // Metering stats api is cached and refreshed every 30 seconds + await retry.waitForWithTimeout('Metering stats cache is refreshed', 31000, async () => { + const detailsResponse = await callApi( + `${type}-${dataset}-${namespace}`, + roleAuthc, + internalReqHeader + ); + if (detailsResponse.body.sizeBytes === 0) { + throw new Error("Metering stats cache hasn't refreshed"); + } + return true; + }); + const resp = await callApi(`${type}-${dataset}-${namespace}`, roleAuthc, internalReqHeader); - expect(resp.body.sizeBytes).to.be(null); + + expect(isNaN(resp.body.sizeBytes as number)).to.be(false); + expect(resp.body.sizeBytes).to.be.greaterThan(0); }); it('returns service.name and host.name correctly', async () => { diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts index d9fc208e971be..52a1c51d24917 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/dataset_quality_api_integration/data_stream_settings.ts @@ -56,7 +56,7 @@ export default function ({ getService }: DatasetQualityFtrContextProvider) { before(async () => { roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); internalReqHeader = svlCommonApi.getInternalRequestHeader(); - return synthtrace.index([ + await synthtrace.index([ timerange(start, end) .interval('1m') .rate(1) diff --git a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts index a007ddc6c10a7..521a0b782b3a1 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_details.ts @@ -35,7 +35,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const browser = getService('browser'); const to = '2024-01-01T12:00:00.000Z'; - const excludeKeysFromServerless = ['size']; // https://github.com/elastic/kibana/issues/178954 const apacheAccessDatasetName = 'apache.access'; const apacheAccessDataStreamName = `logs-${apacheAccessDatasetName}-${productionNamespace}`; @@ -93,7 +92,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { getLogsForDataset({ to, count: 10, dataset: bitbucketDatasetName }), ]); - await PageObjects.svlCommonPage.loginWithPrivilegedRole(); + await PageObjects.svlCommonPage.loginAsAdmin(); }); after(async () => { @@ -172,12 +171,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { dataStream: apacheAccessDataStreamName, }); - const { docsCountTotal, degradedDocs, services, hosts } = - await PageObjects.datasetQuality.parseOverviewSummaryPanelKpis(excludeKeysFromServerless); + const { docsCountTotal, degradedDocs, services, hosts, size } = + await PageObjects.datasetQuality.parseOverviewSummaryPanelKpis(); expect(parseInt(docsCountTotal, 10)).to.be(226); expect(parseInt(degradedDocs, 10)).to.be(1); expect(parseInt(services, 10)).to.be(3); expect(parseInt(hosts, 10)).to.be(52); + expect(parseInt(size, 10)).to.be.greaterThan(0); }); }); diff --git a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_table.ts b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_table.ts index 30b5a7831d68e..80214767c92d2 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_table.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/dataset_quality_table.ts @@ -112,6 +112,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(degradedDocsColCellTexts).to.eql(['0%', '0%', '0%', '100%']); }); + it('shows the value in the size column', async () => { + const cols = await PageObjects.datasetQuality.parseDatasetTable(); + + const sizeColCellTexts = await cols.Size.getCellTexts(); + const sizeGreaterThanZero = sizeColCellTexts[3]; + const sizeEqualToZero = sizeColCellTexts[2]; + + expect(sizeGreaterThanZero).to.not.eql('0.0 KB'); + expect(sizeEqualToZero).to.eql('0.0 B'); + }); + it('shows dataset from integration', async () => { const cols = await PageObjects.datasetQuality.parseDatasetTable(); const datasetNameCol = cols['Data Set Name'];