Skip to content

Commit

Permalink
Migrate reporting FTRs from the Stats Usage API
Browse files Browse the repository at this point in the history
  • Loading branch information
afharo committed Feb 22, 2023
1 parent 64a5b97 commit c418438
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 204 deletions.
4 changes: 3 additions & 1 deletion src/plugins/telemetry_collection_manager/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ export interface BasicStatsPayload {
version: string;
cluster_stats: object;
collection?: string;
stack_stats: object;
// Needed for testing to make fields easier to access
// eslint-disable-next-line @typescript-eslint/no-explicit-any
stack_stats: Record<string, any>;
}

export interface UsageStatsPayload extends BasicStatsPayload {
Expand Down
54 changes: 22 additions & 32 deletions x-pack/test/api_integration/services/usage_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,39 @@
* 2.0.
*/

import { TelemetryCollectionManagerPlugin } from '@kbn/telemetry-collection-manager-plugin/server/plugin';
import { UsageStatsPayload } from '@kbn/telemetry-collection-manager-plugin/server';
import { FtrProviderContext } from '../ftr_provider_context';

export function UsageAPIProvider({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const supertestNoAuth = getService('supertestWithoutAuth');

return {
async getUsageStatsNoAuth(): Promise<undefined> {
const { body } = await supertestNoAuth
.get('/api/stats?extended=true')
.set('kbn-xsrf', 'xxx')
.expect(401);
return body.usage;
},

/**
* Public stats API: it returns the usage in camelCase format
*/
async getUsageStats() {
const { body } = await supertest
.get('/api/stats?extended=true')
.set('kbn-xsrf', 'xxx')
.expect(200);
return body.usage;
},
async function getTelemetryStats(payload: {
unencrypted: true;
refreshCache?: boolean;
}): Promise<Array<{ clusterUuid: string; stats: UsageStatsPayload }>>;
async function getTelemetryStats(payload: {
unencrypted: false;
refreshCache?: boolean;
}): Promise<Array<{ clusterUuid: string; stats: string }>>;
async function getTelemetryStats(payload: {
unencrypted?: boolean;
refreshCache?: boolean;
}): Promise<Array<{ clusterUuid: string; stats: UsageStatsPayload | string }>> {
const { body } = await supertest
.post('/api/telemetry/v2/clusters/_stats')
.set('kbn-xsrf', 'xxx')
.send({ refreshCache: true, ...payload })
.expect(200);
return body;
}

return {
/**
* Retrieve the stats via the private telemetry API:
* It returns the usage in as a string encrypted blob or the plain payload if `unencrypted: false`
*
* @param payload Request parameters to retrieve the telemetry stats
*/
async getTelemetryStats(payload: {
unencrypted?: boolean;
refreshCache?: boolean;
}): Promise<ReturnType<TelemetryCollectionManagerPlugin['getStats']>> {
const { body } = await supertest
.post('/api/telemetry/v2/clusters/_stats')
.set('kbn-xsrf', 'xxx')
.send({ refreshCache: true, ...payload })
.expect(200);
return body;
},
getTelemetryStats,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
`--xpack.reporting.capture.maxAttempts=1`,
`--xpack.reporting.csv.maxSizeBytes=6000`,
'--xpack.reporting.roles.enabled=false', // Reporting access control is implemented by sub-feature application privileges
// for testing set buffer duration to 0 to immediately flush counters into saved objects.
'--usageCollection.usageCounters.bufferDuration=0',
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import expect from '@kbn/expect';
import { BasicStatsPayload } from '@kbn/telemetry-collection-manager-plugin/server/types';
import { createPdfV2Params, createPngV2Params } from '..';
import { FtrProviderContext } from '../../ftr_provider_context';

Expand Down Expand Up @@ -35,10 +36,11 @@ export default function ({ getService }: FtrProviderContext) {
describe('server', function () {
this.tags('skipCloud');
it('configuration settings of the tests_server', async () => {
const usage = await usageAPI.getUsageStats();
expect(usage.kibana_config_usage.xpack_reporting_capture_max_attempts).to.be(1);
expect(usage.kibana_config_usage.xpack_reporting_csv_max_size_bytes).to.be(6000);
expect(usage.kibana_config_usage.xpack_reporting_roles_enabled).to.be(false);
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
const usage = stats.stack_stats.kibana.plugins;
expect(usage.kibana_config_usage['xpack.reporting.capture.maxAttempts']).to.be(1);
expect(usage.kibana_config_usage['xpack.reporting.csv.maxSizeBytes']).to.be(6000);
expect(usage.kibana_config_usage['xpack.reporting.roles.enabled']).to.be(false);
});
});

Expand All @@ -52,12 +54,12 @@ export default function ({ getService }: FtrProviderContext) {
DIAG_SCREENSHOT = '/api/reporting/diagnose/screenshot',
}

let initialStats: any;
let stats: any;
let initialStats: BasicStatsPayload;
let stats: BasicStatsPayload;
const CALL_COUNT = 3;

before('call APIs', async () => {
initialStats = await usageAPI.getUsageStats();
[{ stats: initialStats }] = await usageAPI.getTelemetryStats({ unencrypted: true });

await Promise.all(
Object.keys(paths).map(async (key) => {
Expand All @@ -73,30 +75,36 @@ export default function ({ getService }: FtrProviderContext) {
await waitOnAggregation();

// determine the result usage count
stats = await usageAPI.getUsageStats();
[{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
});

it('job listing', async () => {
expect(getUsageCount(initialStats, `get ${paths.LIST}`)).to.be(0);
expect(getUsageCount(stats, `get ${paths.LIST}`)).to.be(CALL_COUNT);
const initialCount = getUsageCount(initialStats, `get ${paths.LIST}`);
expect(getUsageCount(stats, `get ${paths.LIST}`)).to.be(CALL_COUNT + initialCount);
});

it('job count', async () => {
expect(getUsageCount(initialStats, `get ${paths.COUNT}`)).to.be(0);
expect(getUsageCount(stats, `get ${paths.COUNT}`)).to.be(CALL_COUNT);
const initialCount = getUsageCount(initialStats, `get ${paths.COUNT}`);
expect(getUsageCount(stats, `get ${paths.COUNT}`)).to.be(CALL_COUNT + initialCount);
});

it('job info', async () => {
expect(
getUsageCount(initialStats, `get /api/reporting/jobs/info/{docId}:printable_pdf`)
).to.be(0);
const initialCount = getUsageCount(
initialStats,
`get /api/reporting/jobs/info/{docId}:printable_pdf`
);
expect(getUsageCount(stats, `get /api/reporting/jobs/info/{docId}:printable_pdf`)).to.be(
CALL_COUNT
CALL_COUNT + initialCount
);
});
});

describe('downloading and deleting', () => {
let initialStats: BasicStatsPayload;
before('gather initial stats', async () => {
[{ stats: initialStats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
});

it('downloading', async () => {
try {
await Promise.all([
Expand All @@ -119,12 +127,14 @@ export default function ({ getService }: FtrProviderContext) {
log.info(`waiting on aggregation completed.`);

log.info(`calling getUsageStats...`);
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
const initialCount = getUsageCount(
initialStats,
`get /api/reporting/jobs/download/{docId}:printable_pdf`
);
expect(
getUsageCount(
await usageAPI.getUsageStats(),
`get /api/reporting/jobs/download/{docId}:printable_pdf`
)
).to.be(3);
getUsageCount(stats, `get /api/reporting/jobs/download/{docId}:printable_pdf`)
).to.be(3 + initialCount);
});

it('deleting', async () => {
Expand All @@ -145,17 +155,19 @@ export default function ({ getService }: FtrProviderContext) {
log.info(`waiting on aggregation completed.`);

log.info(`calling getUsageStats...`);
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
const initialCount = getUsageCount(
initialStats,
`delete /api/reporting/jobs/delete/{docId}:csv_searchsource`
);
expect(
getUsageCount(
await usageAPI.getUsageStats(),
`delete /api/reporting/jobs/delete/{docId}:csv_searchsource`
)
).to.be(1);
getUsageCount(stats, `delete /api/reporting/jobs/delete/{docId}:csv_searchsource`)
).to.be(1 + initialCount);
});
});

describe('API counters: job generation', () => {
let stats: any;
let stats: BasicStatsPayload;

before(async () => {
// call generation APIs
Expand All @@ -172,7 +184,7 @@ export default function ({ getService }: FtrProviderContext) {

await waitOnAggregation();

stats = await usageAPI.getUsageStats();
[{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
});

it('PNG', async () => {
Expand Down Expand Up @@ -201,10 +213,10 @@ export default function ({ getService }: FtrProviderContext) {
});
};

const getUsageCount = (checkUsage: any, counterName: string): number => {
const getUsageCount = (checkUsage: BasicStatsPayload, counterName: string): number => {
return (
checkUsage.usage_counters.daily_events.find(
(item: any) => item.counter_name === counterName
checkUsage.stack_stats.kibana.plugins.usage_counters.dailyEvents.find(
(item: any) => item.counterName === counterName
)?.total || 0
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export default function ({ getService }: FtrProviderContext) {
describe('from archive data', () => {
it('generated from 6.2', async () => {
await esArchiver.load('x-pack/test/functional/es_archives/reporting/bwc/6_2');
const usage = await usageAPI.getUsageStats();
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
const usage = stats.stack_stats.kibana.plugins.reporting;

reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0);
reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 7);
Expand All @@ -36,7 +37,8 @@ export default function ({ getService }: FtrProviderContext) {

it('generated from 6.3', async () => {
await esArchiver.load('x-pack/test/functional/es_archives/reporting/bwc/6_3');
const usage = await usageAPI.getUsageStats();
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
const usage = stats.stack_stats.kibana.plugins.reporting;

reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0);
reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,8 @@
*/

import expect from '@kbn/expect';
import { ReportingUsageType } from '@kbn/reporting-plugin/server/usage/types';
import { FtrProviderContext } from '../../ftr_provider_context';
import { UsageStats } from '../../services/usage';

type ReportingUsage = UsageStats['reporting'];
interface ReportingUsageApiResponse {
all: ReportingUsage['_all'];
csv_searchsource: ReportingUsage['csv_searchsource'];
pngv_2: ReportingUsage['PNGV2'];
printable_pdf_v_2: ReportingUsage['printable_pdf_v2'];
}

const DATA_ARCHIVE_PATH = 'x-pack/test/functional/es_archives/reporting/errors';

Expand All @@ -26,12 +18,13 @@ export default function ({ getService }: FtrProviderContext) {
const usageAPI = getService('usageAPI');

describe(`error codes`, () => {
let reporting: ReportingUsageApiResponse;
let reporting: ReportingUsageType;

before(async () => {
await reportingAPI.deleteAllReports();
await esArchiver.load(DATA_ARCHIVE_PATH);
({ reporting } = await usageAPI.getUsageStats());
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
reporting = stats.stack_stats.kibana.plugins.reporting;
});

after(async () => {
Expand All @@ -40,10 +33,10 @@ export default function ({ getService }: FtrProviderContext) {
});

it('includes error code statistics', async () => {
expect(reporting.all).equal(3);
expect(reporting._all).equal(3);
expectSnapshot(
['csv_searchsource', 'pngv_2', 'printable_pdf_v_2'].map((k) => {
const field = reporting[k as keyof Omit<ReportingUsageApiResponse, 'all'>];
(['csv_searchsource', 'PNGV2', 'printable_pdf_v2'] as const).map((k) => {
const field = reporting[k];
return { key: k, error_codes: field.error_codes, total: field.total };
})
).toMatchInline(`
Expand All @@ -55,15 +48,15 @@ export default function ({ getService }: FtrProviderContext) {
},
Object {
"error_codes": undefined,
"key": "pngv_2",
"key": "PNGV2",
"total": 0,
},
Object {
"error_codes": Object {
"queue_timeout_error": 1,
"unknown_error": 1,
},
"key": "printable_pdf_v_2",
"key": "printable_pdf_v2",
"total": 3,
},
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import expect from '@kbn/expect';
import { ReportingUsageType } from '@kbn/reporting-plugin/server/usage/types';
import { FtrProviderContext } from '../../ftr_provider_context';
import { UsageStats } from '../../services/usage';

// eslint-disable-next-line import/no-default-export
export default function ({ getService }: FtrProviderContext) {
Expand All @@ -16,18 +16,19 @@ export default function ({ getService }: FtrProviderContext) {
const usageAPI = getService('usageAPI');

describe('initial state', () => {
let usage: UsageStats;
let usage: ReportingUsageType;

before(async () => {
await retry.try(async () => {
// use retry for stability - usage API could return 503
usage = (await usageAPI.getUsageStats()) as UsageStats;
const [{ stats }] = await usageAPI.getTelemetryStats({ unencrypted: true });
usage = stats.stack_stats.kibana.plugins.reporting;
});
});

it('shows reporting as available and enabled', async () => {
expect(usage.reporting.available).to.be(true);
expect(usage.reporting.enabled).to.be(true);
expect(usage.available).to.be(true);
expect(usage.enabled).to.be(true);
});

it('all counts are 0', async () => {
Expand Down
Loading

0 comments on commit c418438

Please sign in to comment.