diff --git a/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz b/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz index 8c927ea8da475..68705c9d6a2b9 100644 Binary files a/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz and b/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz differ diff --git a/test/functional/fixtures/es_archiver/dashboard/current/kibana/mappings.json b/test/functional/fixtures/es_archiver/dashboard/current/kibana/mappings.json index 5eef2a3740c6d..57a732b9f86a6 100644 --- a/test/functional/fixtures/es_archiver/dashboard/current/kibana/mappings.json +++ b/test/functional/fixtures/es_archiver/dashboard/current/kibana/mappings.json @@ -271,4 +271,4 @@ } } } -} \ No newline at end of file +} diff --git a/x-pack/test/api_integration/apis/reporting/bwc_existing_indexes.js b/x-pack/test/api_integration/apis/reporting/bwc_existing_indexes.js new file mode 100644 index 0000000000000..37294895a89a4 --- /dev/null +++ b/x-pack/test/api_integration/apis/reporting/bwc_existing_indexes.js @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as GenerationUrls from './generation_urls'; + + +/** + * This file tests the situation when a reporting index spans releases. By default reporting indexes are created + * on a weekly basis, but this is configurable so it is possible a user has this set to yearly. In that event, it + * is possible report data is getting posted to an index that was created by a very old version. We don't have a + * reporting index migration plan, so this test is important to ensure BWC, or that in the event we decide to make + * a major change in a major release, we handle it properly. + */ + +export default function ({ getService }) { + const esArchiver = getService('esArchiver'); + const reportingAPI = getService('reportingAPI'); + const usageAPI = getService('usageAPI'); + + describe('BWC report generation into existing indexes', async () => { + let expectedCompletedReportCount; + let cleanupIndexAlias; + + describe('existing 6_2 index', () => { + before('load data and add index alias', async () => { + await reportingAPI.deleteAllReportingIndexes(); + await esArchiver.load('reporting/bwc/6_2'); + + // The index name in the 6_2 archive. + const ARCHIVED_REPORTING_INDEX = '.reporting-2018.03.11'; + cleanupIndexAlias = await reportingAPI.coerceReportsIntoExistingIndex(ARCHIVED_REPORTING_INDEX); + + const stats = await usageAPI.getUsageStats(); + expectedCompletedReportCount = await reportingAPI.getCompletedReportCount(stats); + }); + + after('remove index alias', async () => { + await cleanupIndexAlias(); + }); + + // Might not be great test practice to lump all these jobs together but reporting takes awhile and it'll be + // more efficient to post them all up front, then sequentially. + it('multiple jobs posted', async () => { + const reportPaths = []; + reportPaths.push(await reportingAPI.postJob(GenerationUrls.CSV_DISCOVER_KUERY_AND_FILTER_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_DASHBOARD_FILTER_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_PIE_VISUALIZATION_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRINT_DASHBOARD_6_3)); + reportPaths.push(await reportingAPI.postJob( + GenerationUrls.PDF_PRINT_PIE_VISUALIZATION_FILTER_AND_SAVED_SEARCH_6_3)); + + await reportingAPI.expectAllJobsToFinishSuccessfully(reportPaths); + }).timeout(1540000); + + it('jobs completed successfully', async () => { + const stats = await usageAPI.getUsageStats(); + expectedCompletedReportCount += 5; + reportingAPI.expectCompletedReportCount(stats, expectedCompletedReportCount); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/reporting/bwc_generation_urls.js b/x-pack/test/api_integration/apis/reporting/bwc_generation_urls.js new file mode 100644 index 0000000000000..dc953b7622704 --- /dev/null +++ b/x-pack/test/api_integration/apis/reporting/bwc_generation_urls.js @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as GenerationUrls from './generation_urls'; + +export default function ({ getService }) { + const reportingAPI = getService('reportingAPI'); + const usageAPI = getService('usageAPI'); + + describe('BWC report generation urls', () => { + describe('6_2', () => { + before(async () => { + await reportingAPI.deleteAllReportingIndexes(); + }); + + // Might not be great test practice to lump all these jobs together but reporting takes awhile and it'll be + // more efficient to post them all up front, then sequentially. + it('multiple jobs posted', async () => { + const reportPaths = []; + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRINT_DASHBOARD_6_2)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_VISUALIZATION_6_2)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.CSV_DISCOVER_FILTER_QUERY_6_2)); + + await reportingAPI.expectAllJobsToFinishSuccessfully(reportPaths); + }).timeout(1540000); + + it('jobs completed successfully', async () => { + const stats = await usageAPI.getUsageStats(); + reportingAPI.expectCompletedReportCount(stats, 3); + }); + }); + + // 6.3 urls currently being tested as part of the "bwc_existing_indexes" test suite. Reports are time consuming, + // don't replicate tests if we don't need to, so no specific 6_3 url tests here. + }); +} diff --git a/x-pack/test/api_integration/apis/reporting/generate_pdf.js b/x-pack/test/api_integration/apis/reporting/generate_pdf.js deleted file mode 100644 index e7caf9af7fac6..0000000000000 --- a/x-pack/test/api_integration/apis/reporting/generate_pdf.js +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from 'expect.js'; -import { indexTimestamp } from '../../../../plugins/reporting/server/lib/esqueue/helpers/index_timestamp'; - -function removeWhitespace(str) { - return str.replace(/\s/g, ''); -} - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esSupertest = getService('esSupertest'); - const esArchiver = getService('esArchiver'); - const log = getService('log'); - - async function waitForJobToFinish(downloadReportPath) { - const PDF_IS_PENDING_CODE = 503; - - const statusCode = await new Promise(resolve => { - const intervalId = setInterval(async () => { - - const response = await supertest - .get(downloadReportPath) - .responseType('blob') - .set('kbn-xsrf', 'xxx'); - log.debug(`Report at path ${downloadReportPath} returned code ${response.statusCode}`); - if (response.statusCode !== PDF_IS_PENDING_CODE) { - clearInterval(intervalId); - resolve(response.statusCode); - } - }, 1500); - }); - - expect(statusCode).to.be(200); - } - - describe('generate pdf API', () => { - let downloadReportPath; - let completedReportCount; - - before('load reporting archive', async () => { - await esArchiver.load('reporting/6_2'); - - // If we don't include this archive, the report would generate visualizations with no data. It's included - // here, even though we can't verify how the visualizations actually look, because the existence of data - // means more code paths are tested. Cnsider the bug we ran into when a const keyword remained in an untranspiled - // file. It's possible that without data, the flow of control would never have run into that keyword. - await esArchiver.load('logstash_functional'); - - const { body } = await supertest - .get('/api/_kibana/v1/stats') - .set('kbn-xsrf', 'xxx') - .expect(200); - completedReportCount = body.reporting.status.completed; - }); - - after(async () => { - await esArchiver.unload('reporting/6_2'); - await esArchiver.unload('logstash_functional'); - }); - - describe('with an existing reporting index', async () => { - let timestampForIndex; - let stats; - // The index name in the 6_2 archive. - const ARCHIVED_REPORTING_INDEX = '.reporting-2018.03.11'; - - // Adding an index alias coerces the report to be generated on an existing index which means any new - // index schema won't be applied. This is important if a point release updated the schema. Reports may still - // be inserted into an existing index before the new schema is applied. - before('add index alias', async () => { - timestampForIndex = indexTimestamp('week', '.'); - await esSupertest - .post('/_aliases') - .send({ - actions: [ - { - add: { index: ARCHIVED_REPORTING_INDEX, alias: `.reporting-${timestampForIndex}` } - } - ] - }) - .expect(200); - }); - - after('remove index alias', async () => { - await esSupertest - .post('/_aliases') - .send({ - actions: [ - { - remove: { index: ARCHIVED_REPORTING_INDEX, alias: `.reporting-${timestampForIndex}` } - } - ] - }) - .expect(200); - }); - - it('successfully posts a visualization print layout pdf job url generated from v6.2', async () => { - // Grabbed from a report generation url from 6.2 - const jobParams = removeWhitespace(` - (browserTimezone:America%2FNew_York,layout:(id:print), - objectType:visualization,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0), - time:(from:!%272015-09-19T00:02:06.633Z!%27,interval:auto,mode:absolute,timezone:America%252FNew_York, - to:!%272015-09-24T06:40:33.165Z!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27!%27), - uiState:(vis:(defaultColors:(!%270%2B-%2B1!%27:!%27rgb(247,252,245)!%27,!%271%2B-%2B2!%27:!%27rgb(199,233,192) - !%27,!%272%2B-%2B3!%27:!%27rgb(116,196,118)!%27,!%273%2B-%2B3!%27:!%27rgb(35,139,69)!%27))), - vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27, - params:(field:bytes,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27, - otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms),(enabled:!!t,id:!%273!%27, - params:(field:ip,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27, - otherBucket:!!f,otherBucketLabel:Other,size:5),schema:group,type:terms)),params:(addLegend:!!t, - addTooltip:!!t,colorSchema:Greens,colorsNumber:4,colorsRange:!!(),enableHover:!!f,invertColors:!!f, - legendPosition:right,percentageMode:!!f,setColorRange:!!f,times:!!(),type:heatmap, - valueAxes:!!((id:ValueAxis-1,labels:(color:%2523555,rotate:0,show:!!f),scale:(defaultYExtents:!!f, - type:linear),show:!!f,type:value))),title:!%27bytes%2Bheatmap!%27,type:heatmap))%27, - savedObjectId:dae7e680-2891-11e8-88fd-5754aa989b85)`); - - const { body } = await supertest - .post(`/api/reporting/generate/printablePdf?jobParams=${jobParams}`) - .set('kbn-xsrf', 'xxx') - .expect(200); - downloadReportPath = body.path; - }); - - it('report completes', async () => { - await waitForJobToFinish(downloadReportPath); - }).timeout(540000); - - it('successful job marked as completed', async () => { - const { body } = await supertest - .get(`/api/_kibana/v1/stats`) - .set('kbn-xsrf', 'xxx') - .expect(200); - stats = body; - completedReportCount++; - expect(stats.reporting.status.completed).to.be(completedReportCount); - }); - - // These are new stats as of v6.3 so these numbers won't include any of the reports already in the archive. Hence, - // these values won't add up to stats.reporting.status.completed. - it('1 count for visualize app', async () => { - expect(stats.reporting.lastDay.printable_pdf.app.visualization).to.be(1); - expect(stats.reporting.last7Days.printable_pdf.app.visualization).to.be(1); - expect(stats.reporting.printable_pdf.app.visualization).to.be(1); - }); - - it('0 counts for dashboard app', async () => { - expect(stats.reporting.lastDay.printable_pdf.app.dashboard).to.be(0); - expect(stats.reporting.last7Days.printable_pdf.app.dashboard).to.be(0); - expect(stats.reporting.printable_pdf.app.dashboard).to.be(0); - }); - - it('0 counts for preserve layout', async () => { - expect(stats.reporting.lastDay.printable_pdf.layout.preserve_layout).to.be(0); - expect(stats.reporting.last7Days.printable_pdf.layout.preserve_layout).to.be(0); - expect(stats.reporting.printable_pdf.layout.preserve_layout).to.be(0); - }); - - it('1 count for print layout', async () => { - expect(stats.reporting.lastDay.printable_pdf.layout.print).to.be(1); - expect(stats.reporting.last7Days.printable_pdf.layout.print).to.be(1); - expect(stats.reporting.printable_pdf.layout.print).to.be(1); - }); - - it('successfully posts a dashboard preview layout pdf job url generated from v6.2', async () => { - // Grabbed from a report generation url from 6.2 - const jobParams = removeWhitespace(` - (browserTimezone:America%2FNew_York,layout:(dimensions:(height:656,width:1504),id:preserve_layout), - objectType:dashboard,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0), - time:(from:!%272015-09-19T00:02:06.633Z!%27,interval:auto,mode:absolute,timezone:America%252FNew_York, - to:!%272015-09-24T06:40:33.165Z!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f, - options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((gridData:(h:3,i:!%271!%27,w:6,x:0,y:0), - id:Visualization-PieChart,panelIndex:!%271!%27,type:visualization,version:!%276.2.3!%27), - (gridData:(h:3,i:!%272!%27,w:6,x:6,y:0),id:Visualization-MetricChart,panelIndex:!%272!%27, - type:visualization,version:!%276.2.3!%27),(gridData:(h:3,i:!%273!%27,w:6,x:0,y:3), - id:Visualization%25E2%2598%25BA-VerticalBarChart,panelIndex:!%273!%27,type:visualization, - version:!%276.2.3!%27),(gridData:(h:3,i:!%274!%27,w:6,x:6,y:3),id:e495f810-2892-11e8-88fd-5754aa989b85, - panelIndex:!%274!%27,type:search,version:!%276.2.3!%27)),query:(language:lucene,query:!%27!%27), - timeRestore:!!t,title:!%27Small%2BReporting%2BDashboard!%27,viewMode:view)%27, - savedObjectId:%276799db00-2893-11e8-88fd-5754aa989b85%27)`); - const { body } = await supertest - .post(`/api/reporting/generate/printablePdf?jobParams=${jobParams}`) - .set('kbn-xsrf', 'xxx') - .expect(200); - - downloadReportPath = body.path; - }); - - it('report completes', async () => { - await waitForJobToFinish(downloadReportPath); - }).timeout(540000); - - describe('stats updated', async () => { - it('with count of completed reports', async () => { - const { body } = await supertest - .get(`/api/_kibana/v1/stats`) - .set('kbn-xsrf', 'xxx') - .expect(200); - stats = body; - completedReportCount++; - expect(stats.reporting.status.completed).to.be(completedReportCount); - }); - - it('with 1 count for dashboard app', async () => { - expect(stats.reporting.lastDay.printable_pdf.app.dashboard).to.be(1); - expect(stats.reporting.last7Days.printable_pdf.app.dashboard).to.be(1); - expect(stats.reporting.printable_pdf.app.dashboard).to.be(1); - }); - - it('with 1 count for preserve layout', async () => { - expect(stats.reporting.lastDay.printable_pdf.layout.preserve_layout).to.be(1); - expect(stats.reporting.last7Days.printable_pdf.layout.preserve_layout).to.be(1); - expect(stats.reporting.printable_pdf.layout.preserve_layout).to.be(1); - }); - }); - }); - - describe('with a new reporting index', async () => { - let timestampForIndex; - let stats; - - before('delete any existing index alias', async () => { - timestampForIndex = indexTimestamp('week', '.'); - await esSupertest - .delete(`/.reporting-${timestampForIndex}`); - }); - - after('delete new reporting indexes', async () => { - await esSupertest - .delete(`/.reporting-${timestampForIndex}`); - }); - - it('successfully posts a visualization print layout pdf job url generated from v6.2', async () => { - // Grabbed from a report generation url from 6.2 - const jobParams = removeWhitespace(` - (browserTimezone:America%2FNew_York,layout:(id:print), - objectType:visualization,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0), - time:(from:!%272015-09-19T00:02:06.633Z!%27,interval:auto,mode:absolute,timezone:America%252FNew_York, - to:!%272015-09-24T06:40:33.165Z!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27!%27), - uiState:(vis:(defaultColors:(!%270%2B-%2B1!%27:!%27rgb(247,252,245)!%27,!%271%2B-%2B2!%27:!%27rgb(199,233,192) - !%27,!%272%2B-%2B3!%27:!%27rgb(116,196,118)!%27,!%273%2B-%2B3!%27:!%27rgb(35,139,69)!%27))), - vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27, - params:(field:bytes,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27, - otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms),(enabled:!!t,id:!%273!%27, - params:(field:ip,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27, - otherBucket:!!f,otherBucketLabel:Other,size:5),schema:group,type:terms)),params:(addLegend:!!t, - addTooltip:!!t,colorSchema:Greens,colorsNumber:4,colorsRange:!!(),enableHover:!!f,invertColors:!!f, - legendPosition:right,percentageMode:!!f,setColorRange:!!f,times:!!(),type:heatmap, - valueAxes:!!((id:ValueAxis-1,labels:(color:%2523555,rotate:0,show:!!f),scale:(defaultYExtents:!!f, - type:linear),show:!!f,type:value))),title:!%27bytes%2Bheatmap!%27,type:heatmap))%27, - savedObjectId:dae7e680-2891-11e8-88fd-5754aa989b85)`); - const { body } = await supertest - .post(`/api/reporting/generate/printablePdf?jobParams=${jobParams}`) - .set('kbn-xsrf', 'xxx') - .expect(200); - - downloadReportPath = body.path; - }); - - it('report completes', async () => { - await waitForJobToFinish(downloadReportPath); - }); - - describe('stats updated', async () => { - it('with count of completed reports', async () => { - const { body } = await supertest - .get(`/api/_kibana/v1/stats`) - .set('kbn-xsrf', 'xxx') - .expect(200); - stats = body; - completedReportCount++; - expect(stats.reporting.status.completed).to.be(completedReportCount); - }); - - it('with 2 counts for visualize app', async () => { - expect(stats.reporting.lastDay.printable_pdf.app.visualization).to.be(2); - expect(stats.reporting.last7Days.printable_pdf.app.visualization).to.be(2); - expect(stats.reporting.printable_pdf.app.visualization).to.be(2); - }); - - it('with 2 counts for print layout', async () => { - expect(stats.reporting.lastDay.printable_pdf.layout.print).to.be(2); - expect(stats.reporting.last7Days.printable_pdf.layout.print).to.be(2); - expect(stats.reporting.printable_pdf.layout.print).to.be(2); - }); - }); - }); - }); -} diff --git a/x-pack/test/api_integration/apis/reporting/generation_urls.js b/x-pack/test/api_integration/apis/reporting/generation_urls.js new file mode 100644 index 0000000000000..35bb40089a56f --- /dev/null +++ b/x-pack/test/api_integration/apis/reporting/generation_urls.js @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// These all have the domain name portion stripped out. The api infrastructure assumes it when we post to it anyhow. + +/* eslint-disable max-len */ +export const PDF_PRINT_DASHBOARD_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F2ae34a60-3dd4-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!(),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%27145ced90-3dcb-11e8-8660-4d65aa086b3c!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:e2023110-3dcb-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:visualization,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!f,title:!%27couple%2Bpanels!%27,viewMode:view)%27),title:%27couple%20panels%27)'; +export const PDF_PRESERVE_DASHBOARD_FILTER_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:439,width:1362),id:preserve_layout),objectType:dashboard,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fdashboard%2F61c58ad0-3dd3-11e8-b2b9-5d5dc1715159%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:animal,negate:!!f,params:(query:dog,type:phrase),type:phrase,value:dog),query:(match:(animal:(query:dog,type:phrase))))),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((embeddableConfig:(),gridData:(h:15,i:!%271!%27,w:24,x:0,y:0),id:!%2750643b60-3dd3-11e8-b2b9-5d5dc1715159!%27,panelIndex:!%271!%27,type:visualization,version:!%276.3.0!%27),(embeddableConfig:(),gridData:(h:15,i:!%272!%27,w:24,x:24,y:0),id:a16d1990-3dca-11e8-8660-4d65aa086b3c,panelIndex:!%272!%27,type:search,version:!%276.3.0!%27)),query:(language:lucene,query:!%27!%27),timeRestore:!!t,title:!%27dashboard%2Bwith%2Bfilter!%27,viewMode:view)%27),title:%27dashboard%20with%20filter%27)'; +export const PDF_PRESERVE_PIE_VISUALIZATION_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:441,width:1002),id:preserve_layout),objectType:visualization,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fvisualize%2Fedit%2F3fe22200-3dcb-11e8-8660-4d65aa086b3c%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:bytes,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Rendering%2BTest:%2Bpie!%27,type:pie))%27),title:%27Rendering%20Test:%20pie%27)'; +export const PDF_PRINT_PIE_VISUALIZATION_FILTER_AND_SAVED_SEARCH_6_3 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:visualization,relativeUrls:!(%27%2Fapp%2Fkibana%23%2Fvisualize%2Fedit%2Fbefdb6b0-3e59-11e8-9fc3-39e49624228e%3F_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:animal.keyword,negate:!!f,params:(query:dog,type:phrase),type:phrase,value:dog),query:(match:(animal.keyword:(query:dog,type:phrase))))),linked:!!t,query:(language:lucene,query:!%27!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:name.keyword,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Filter%2BTest:%2Banimals:%2Blinked%2Bto%2Bsearch%2Bwith%2Bfilter!%27,type:pie))%27),title:%27Filter%20Test:%20animals:%20linked%20to%20search%20with%20filter%27)'; +export const CSV_DISCOVER_KUERY_AND_FILTER_6_3 = '/api/reporting/generate/csv?jobParams=(conflictedTypesFields:!(),fields:!(%27@timestamp%27,agent,bytes,clientip),indexPatternId:%270bf35f60-3dc9-11e8-8660-4d65aa086b3c%27,metaFields:!(_source,_id,_type,_index,_score),searchRequest:(body:(_source:(excludes:!(),includes:!(%27@timestamp%27,agent,bytes,clientip)),docvalue_fields:!(%27@timestamp%27),query:(bool:(filter:!((bool:(minimum_should_match:1,should:!((match:(clientip:%2773.14.212.83%27)))))),must:!((range:(bytes:(gte:100,lt:1000))),(range:(%27@timestamp%27:(format:epoch_millis,gte:1369165215770,lte:1526931615770)))),must_not:!(),should:!())),script_fields:(),sort:!((%27@timestamp%27:(order:desc,unmapped_type:boolean))),stored_fields:!(%27@timestamp%27,agent,bytes,clientip),version:!t),index:%27logstash-*%27),title:%27Bytes%20and%20kuery%20in%20saved%20search%20with%20filter%27,type:search)'; + +export const PDF_PRINT_DASHBOARD_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(id:print),objectType:dashboard,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(description:!%27!%27,filters:!!((!%27$state!%27:(store:appState),meta:(alias:!!n,disabled:!!f,field:isDog,index:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,key:isDog,negate:!!f,params:(value:!!t),type:phrase,value:true),script:(script:(inline:!%27boolean%2Bcompare(Supplier%2Bs,%2Bdef%2Bv)%2B%257Breturn%2Bs.get()%2B%253D%253D%2Bv%3B%257Dcompare(()%2B-%253E%2B%257B%2Breturn%2Bdoc%255B!!!%27animal.keyword!!!%27%255D.value%2B%253D%253D%2B!!!%27dog!!!%27%2B%257D,%2Bparams.value)%3B!%27,lang:painless,params:(value:!!t))))),fullScreenMode:!!f,options:(darkTheme:!!f,hidePanelTitles:!!f,useMargins:!!t),panels:!!((gridData:(h:3,i:!%274!%27,w:6,x:6,y:0),id:edb65990-53ca-11e8-b481-c9426d020fcd,panelIndex:!%274!%27,type:visualization,version:!%276.2.4!%27),(gridData:(h:3,i:!%275!%27,w:6,x:0,y:0),id:!%270644f890-53cb-11e8-b481-c9426d020fcd!%27,panelIndex:!%275!%27,type:visualization,version:!%276.2.4!%27)),query:(language:lucene,query:!%27weightLbs:%253E15!%27),timeRestore:!!t,title:!%27Animal%2BWeights%2B(created%2Bin%2B6.2)!%27,viewMode:view)%27,savedObjectId:%271b2f47b0-53cb-11e8-b481-c9426d020fcd%27)'; +export const PDF_PRESERVE_VISUALIZATION_6_2 = '/api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FNew_York,layout:(dimensions:(height:441,width:1002),id:preserve_layout),objectType:visualization,queryString:%27_g%3D(refreshInterval:(display:Off,pause:!!f,value:0),time:(from:!%27Mon%2BApr%2B09%2B2018%2B17:56:08%2BGMT-0400!%27,mode:absolute,to:!%27Wed%2BApr%2B11%2B2018%2B17:56:08%2BGMT-0400!%27))%26_a%3D(filters:!!(),linked:!!f,query:(language:lucene,query:!%27weightLbs:%253E10!%27),uiState:(),vis:(aggs:!!((enabled:!!t,id:!%271!%27,params:(),schema:metric,type:count),(enabled:!!t,id:!%272!%27,params:(field:weightLbs,missingBucket:!!f,missingBucketLabel:Missing,order:desc,orderBy:!%271!%27,otherBucket:!!f,otherBucketLabel:Other,size:5),schema:segment,type:terms)),params:(addLegend:!!t,addTooltip:!!t,isDonut:!!t,labels:(last_level:!!t,show:!!f,truncate:100,values:!!t),legendPosition:right,type:pie),title:!%27Weight%2Bin%2Blbs%2Bpie%2Bcreated%2Bin%2B6.2!%27,type:pie))%27,savedObjectId:%270644f890-53cb-11e8-b481-c9426d020fcd%27)'; +export const CSV_DISCOVER_FILTER_QUERY_6_2 = '/api/reporting/generate/csv?jobParams=(conflictedTypesFields:!(),fields:!(%27@timestamp%27,animal,sound,weightLbs),indexPatternId:a0f483a0-3dc9-11e8-8660-4d65aa086b3c,metaFields:!(_source,_id,_type,_index,_score),searchRequest:(body:(_source:(excludes:!(),includes:!(%27@timestamp%27,animal,sound,weightLbs)),docvalue_fields:!(%27@timestamp%27),query:(bool:(filter:!(),must:!((query_string:(analyze_wildcard:!t,default_field:%27*%27,query:%27weightLbs:%3E10%27)),(match_phrase:(sound.keyword:(query:growl))),(range:(%27@timestamp%27:(format:epoch_millis,gte:1523310968000,lte:1523483768000)))),must_not:!(),should:!())),script_fields:(),sort:!((%27@timestamp%27:(order:desc,unmapped_type:boolean))),stored_fields:!(%27@timestamp%27,animal,sound,weightLbs),version:!t),index:%27animals-*%27),title:%27Search%20created%20in%206.2%27,type:search)'; diff --git a/x-pack/test/api_integration/apis/reporting/index.js b/x-pack/test/api_integration/apis/reporting/index.js index 71109de34fbc6..361394dcbbf08 100644 --- a/x-pack/test/api_integration/apis/reporting/index.js +++ b/x-pack/test/api_integration/apis/reporting/index.js @@ -4,8 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -export default function ({ loadTestFile }) { +export default function ({ loadTestFile, getService }) { + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + describe('reporting', () => { - loadTestFile(require.resolve('./generate_pdf')); + before(async () => { + await esArchiver.load('../../../../test/functional/fixtures/es_archiver/dashboard/current/kibana'); + await esArchiver.load('../../../../test/functional/fixtures/es_archiver/dashboard/current/data'); + + await kibanaServer.uiSettings.update({ + 'dateFormat:tz': 'UTC', + 'defaultIndex': '0bf35f60-3dc9-11e8-8660-4d65aa086b3c' + }); + }); + + after(async () => { + await esArchiver.unload('../../../../test/functional/fixtures/es_archiver/dashboard/current/kibana'); + await esArchiver.unload('../../../../test/functional/fixtures/es_archiver/dashboard/current/data'); + }); + + loadTestFile(require.resolve('./bwc_existing_indexes')); + loadTestFile(require.resolve('./bwc_generation_urls')); + loadTestFile(require.resolve('./usage')); }); } diff --git a/x-pack/test/api_integration/apis/reporting/usage.js b/x-pack/test/api_integration/apis/reporting/usage.js new file mode 100644 index 0000000000000..dbe73df955758 --- /dev/null +++ b/x-pack/test/api_integration/apis/reporting/usage.js @@ -0,0 +1,147 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from 'expect.js'; +import * as GenerationUrls from "./generation_urls"; + +export default function ({ getService }) { + const esArchiver = getService('esArchiver'); + const reportingAPI = getService('reportingAPI'); + const usageAPI = getService('usageAPI'); + + describe('reporting usage', () => { + before(async () => { + await reportingAPI.deleteAllReportingIndexes(); + }); + + describe('initial usage', () => { + let usage; + + before(async () => { + usage = await usageAPI.getUsageStats(); + }); + + it('shows reporting as available and enabled', async () => { + expect(usage.reporting.available).to.be(true); + expect(usage.reporting.enabled).to.be(true); + }); + + it('is using phantom browser', async () => { + expect(usage.reporting.browser_type).to.be('phantom'); + }); + + it('all counts are 0', async () => { + reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 0); + reportingAPI.expectAllTimePdfAppStats(usage, 'visualization', 0); + reportingAPI.expectRecentPdfAppStats(usage, 'dashboard', 0); + reportingAPI.expectAllTimePdfAppStats(usage, 'dashboard', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'preserve_layout', 0); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'preserve_layout', 0); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'print', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'print', 0); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'csv', 0); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'csv', 0); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 0); + }); + }); + + describe('includes usage from reporting indexes', () => { + it('generated from 6.2', async () => { + await esArchiver.load('reporting/bwc/6_2'); + const usage = await usageAPI.getUsageStats(); + + reportingAPI.expectRecentJobTypeTotalStats(usage, 'csv', 0); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0); + + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'csv', 1); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 7); + + // These statistics weren't tracked until 6.3 + reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 0); + reportingAPI.expectRecentPdfAppStats(usage, 'dashboard', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'preserve_layout', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'print', 0); + reportingAPI.expectAllTimePdfAppStats(usage, 'visualization', 0); + reportingAPI.expectAllTimePdfAppStats(usage, 'dashboard', 0); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'preserve_layout', 0); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'print', 0); + }); + + + it('generated from 6.3', async () => { + await esArchiver.load('reporting/bwc/6_3'); + const usage = await usageAPI.getUsageStats(); + + reportingAPI.expectRecentJobTypeTotalStats(usage, 'csv', 0); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0); + reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 0); + reportingAPI.expectRecentPdfAppStats(usage, 'dashboard', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'preserve_layout', 0); + reportingAPI.expectRecentPdfLayoutStats(usage, 'print', 0); + + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'csv', 3); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 19); + reportingAPI.expectAllTimePdfAppStats(usage, 'visualization', 3); + reportingAPI.expectAllTimePdfAppStats(usage, 'dashboard', 3); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'preserve_layout', 3); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'print', 3); + }); + }); + + describe('usage updated when new jobs are posted', async () => { + it('post jobs', async () => { + const reportPaths = []; + reportPaths.push(await reportingAPI.postJob(GenerationUrls.CSV_DISCOVER_KUERY_AND_FILTER_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_DASHBOARD_FILTER_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_PIE_VISUALIZATION_6_3)); + reportPaths.push(await reportingAPI.postJob(GenerationUrls.PDF_PRINT_DASHBOARD_6_3)); + reportPaths.push(await reportingAPI.postJob( + GenerationUrls.PDF_PRINT_PIE_VISUALIZATION_FILTER_AND_SAVED_SEARCH_6_3)); + + await reportingAPI.expectAllJobsToFinishSuccessfully(reportPaths); + }).timeout(1540000); + + it('usage updated', async () => { + const usage = await usageAPI.getUsageStats(); + + reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 2); + reportingAPI.expectRecentPdfAppStats(usage, 'dashboard', 2); + reportingAPI.expectRecentPdfLayoutStats(usage, 'preserve_layout', 2); + reportingAPI.expectRecentPdfLayoutStats(usage, 'print', 2); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'csv', 1); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 4); + + reportingAPI.expectAllTimePdfAppStats(usage, 'visualization', 5); + reportingAPI.expectAllTimePdfAppStats(usage, 'dashboard', 5); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'preserve_layout', 5); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'print', 5); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'csv', 4); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 23); + }); + }); + + describe('deprecated API', () => { + it('shows correct stats', async () => { + const usage = await usageAPI.getUsageStatsFromDeprecatedPre64Endpoint(); + + reportingAPI.expectRecentPdfAppStats(usage, 'visualization', 2); + reportingAPI.expectRecentPdfAppStats(usage, 'dashboard', 2); + reportingAPI.expectRecentPdfLayoutStats(usage, 'preserve_layout', 2); + reportingAPI.expectRecentPdfLayoutStats(usage, 'print', 2); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'csv', 1); + reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 4); + + reportingAPI.expectAllTimePdfAppStats(usage, 'visualization', 5); + reportingAPI.expectAllTimePdfAppStats(usage, 'dashboard', 5); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'preserve_layout', 5); + reportingAPI.expectAllTimePdfLayoutStats(usage, 'print', 5); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'csv', 4); + reportingAPI.expectAllTimeJobTypeTotalStats(usage, 'printable_pdf', 23); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/xpack_main/usage/usage.js b/x-pack/test/api_integration/apis/xpack_main/usage/usage.js index 1d4036a43329e..a550ec14bcb1e 100644 --- a/x-pack/test/api_integration/apis/xpack_main/usage/usage.js +++ b/x-pack/test/api_integration/apis/xpack_main/usage/usage.js @@ -7,45 +7,29 @@ import expect from 'expect.js'; export default function ({ getService }) { - const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); + const usageAPI = getService('usageAPI'); describe('/api/_xpack/usage', () => { before('load archives', async () => { - // Using this archive because it includes reports as well as a range of visualization types. - await esArchiver.load('reporting/6_2'); - // Not really neccessary to have data indexes, but it feels incomplete to leave out, and it is possible that - // having data available could potentially interefere with the stats api (unlikely... but possible). - await esArchiver.load('logstash_functional'); + await esArchiver.load('../../../../test/functional/fixtures/es_archiver/dashboard/current/kibana'); }); after(async () => { - await esArchiver.unload('reporting/6_2'); - await esArchiver.unload('logstash_functional'); + await esArchiver.unload('../../../../test/functional/fixtures/es_archiver/dashboard/current/kibana'); }); it('should return xpack usage data', async () => { - const { body } = await supertest - .get(`/api/_xpack/usage`) - .set('kbn-xsrf', 'xxx') - .expect(200); + const usage = await usageAPI.getUsageStats(); - expect(body.cluster_uuid).to.be.a('string'); - expect(body.kibana.dashboard.total).to.be(3); - expect(body.kibana.visualization.total).to.be(18); - expect(body.kibana.search.total).to.be(1); - expect(body.kibana.index_pattern.total).to.be(1); - expect(body.kibana.timelion_sheet.total).to.be(0); - expect(body.kibana.graph_workspace.total).to.be(0); - expect(body.reporting.available).to.be(true); - expect(body.reporting.enabled).to.be(true); - expect(body.reporting.browser_type).to.be('phantom'); - expect(body.reporting._all).to.be(8); - expect(body.reporting.csv.available).to.be(true); - expect(body.reporting.csv.total).to.be(1); - expect(body.reporting.printable_pdf.available).to.be(true); - expect(body.reporting.printable_pdf.total).to.be(7); + expect(usage.cluster_uuid).to.be.a('string'); + expect(usage.kibana.dashboard.total).to.be(26); + expect(usage.kibana.visualization.total).to.be(47); + expect(usage.kibana.search.total).to.be(5); + expect(usage.kibana.index_pattern.total).to.be(3); + expect(usage.kibana.timelion_sheet.total).to.be(0); + expect(usage.kibana.graph_workspace.total).to.be(0); }); }); } diff --git a/x-pack/test/api_integration/config.js b/x-pack/test/api_integration/config.js index 23b8622e60012..132bca09bc588 100644 --- a/x-pack/test/api_integration/config.js +++ b/x-pack/test/api_integration/config.js @@ -4,7 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SupertestWithoutAuthProvider } from './services'; +import { + SupertestWithoutAuthProvider, + ReportingAPIProvider, + UsageAPIProvider, +} from './services'; export default async function ({ readConfigFile }) { @@ -22,6 +26,9 @@ export default async function ({ readConfigFile }) { supertestWithoutAuth: SupertestWithoutAuthProvider, es: kibanaCommonConfig.get('services.es'), esArchiver: kibanaCommonConfig.get('services.esArchiver'), + reportingAPI: ReportingAPIProvider, + usageAPI: UsageAPIProvider, + kibanaServer: kibanaCommonConfig.get('services.kibanaServer'), }, esArchiver: xPackFunctionalTestsConfig.get('esArchiver'), junit: { diff --git a/x-pack/test/api_integration/services/index.js b/x-pack/test/api_integration/services/index.js index eb3e2cddb88ed..8c2ef3b84fb95 100644 --- a/x-pack/test/api_integration/services/index.js +++ b/x-pack/test/api_integration/services/index.js @@ -5,3 +5,5 @@ */ export { SupertestWithoutAuthProvider } from './supertest_without_auth'; +export { ReportingAPIProvider } from './reporting_api'; +export { UsageAPIProvider } from './usage_api'; diff --git a/x-pack/test/api_integration/services/reporting_api.js b/x-pack/test/api_integration/services/reporting_api.js new file mode 100644 index 0000000000000..361ed94c5066a --- /dev/null +++ b/x-pack/test/api_integration/services/reporting_api.js @@ -0,0 +1,135 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from 'expect.js'; +import { indexTimestamp } from '../../../plugins/reporting/server/lib/esqueue/helpers/index_timestamp'; + +function removeWhitespace(str) { + return str.replace(/\s/g, ''); +} + +export function ReportingAPIProvider({ getService }) { + const log = getService('log'); + const supertest = getService('supertest'); + const esSupertest = getService('esSupertest'); + + return { + async waitForJobToFinish(downloadReportPath) { + log.debug(`Waiting for job to finish: ${downloadReportPath}`); + const JOB_IS_PENDING_CODE = 503; + + const statusCode = await new Promise(resolve => { + const intervalId = setInterval(async () => { + + const response = await supertest + .get(downloadReportPath) + .responseType('blob') + .set('kbn-xsrf', 'xxx'); + log.debug(`Report at path ${downloadReportPath} returned code ${response.statusCode}`); + if (response.statusCode !== JOB_IS_PENDING_CODE) { + clearInterval(intervalId); + resolve(response.statusCode); + } + }, 1500); + }); + + expect(statusCode).to.be(200); + }, + + async expectAllJobsToFinishSuccessfully(jobPaths) { + await Promise.all(jobPaths.map(async (path) => { + await this.waitForJobToFinish(path); + })); + }, + + async postJob(apiPath) { + log.debug(`ReportingAPI.postJob(${apiPath})`); + const { body } = await supertest + .post(removeWhitespace(apiPath)) + .set('kbn-xsrf', 'xxx') + .expect(200); + return body.path; + }, + + /** + * + * @return {Promise} A function to call to clean up the index alias that was added. + */ + async coerceReportsIntoExistingIndex(indexName) { + log.debug(`ReportingAPI.coerceReportsIntoExistingIndex(${indexName})`); + + // Adding an index alias coerces the report to be generated on an existing index which means any new + // index schema won't be applied. This is important if a point release updated the schema. Reports may still + // be inserted into an existing index before the new schema is applied. + const timestampForIndex = indexTimestamp('week', '.'); + await esSupertest + .post('/_aliases') + .send({ + actions: [ + { + add: { index: indexName, alias: `.reporting-${timestampForIndex}` } + } + ] + }) + .expect(200); + + return async () => { + await esSupertest + .post('/_aliases') + .send({ + actions: [ + { + remove: { index: indexName, alias: `.reporting-${timestampForIndex}` } + } + ] + }) + .expect(200); + }; + }, + + async deleteAllReportingIndexes() { + log.debug('ReportingAPI.deleteAllReportingIndexes'); + await esSupertest + .delete('/.reporting*') + .expect(200); + }, + + expectRecentPdfAppStats(stats, app, count) { + expect(stats.reporting.lastDay.printable_pdf.app[app]).to.be(count); + expect(stats.reporting.last7Days.printable_pdf.app[app]).to.be(count); + }, + + expectAllTimePdfAppStats(stats, app, count) { + expect(stats.reporting.printable_pdf.app[app]).to.be(count); + }, + + expectRecentPdfLayoutStats(stats, layout, count) { + expect(stats.reporting.lastDay.printable_pdf.layout[layout]).to.be(count); + expect(stats.reporting.last7Days.printable_pdf.layout[layout]).to.be(count); + }, + + expectAllTimePdfLayoutStats(stats, layout, count) { + expect(stats.reporting.printable_pdf.layout[layout]).to.be(count); + }, + + expectRecentJobTypeTotalStats(stats, jobType, count) { + expect(stats.reporting.lastDay[jobType].total).to.be(count); + expect(stats.reporting.last7Days[jobType].total).to.be(count); + }, + + expectAllTimeJobTypeTotalStats(stats, jobType, count) { + expect(stats.reporting[jobType].total).to.be(count); + }, + + getCompletedReportCount(stats) { + return stats.reporting.status.completed; + }, + + expectCompletedReportCount(stats, count) { + expect(this.getCompletedReportCount(stats)).to.be(count); + } + }; +} diff --git a/x-pack/test/api_integration/services/usage_api.js b/x-pack/test/api_integration/services/usage_api.js new file mode 100644 index 0000000000000..34222928b0378 --- /dev/null +++ b/x-pack/test/api_integration/services/usage_api.js @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + + +export function UsageAPIProvider({ getService }) { + const supertest = getService('supertest'); + + return { + async getUsageStats() { + const { body } = await supertest + .get('/api/_xpack/usage') + .set('kbn-xsrf', 'xxx') + .expect(200); + return body; + }, + + async getUsageStatsFromDeprecatedPre64Endpoint() { + const { body } = await supertest + .get('/api/_kibana/v1/stats') + .set('kbn-xsrf', 'xxx') + .expect(200); + return body; + }, + }; +} diff --git a/x-pack/test/functional/es_archives/reporting/6_2/data.json.gz b/x-pack/test/functional/es_archives/reporting/6_2/data.json.gz deleted file mode 100644 index 662c8aa3b4d57..0000000000000 Binary files a/x-pack/test/functional/es_archives/reporting/6_2/data.json.gz and /dev/null differ diff --git a/x-pack/test/functional/es_archives/reporting/6_2/mappings.json b/x-pack/test/functional/es_archives/reporting/6_2/mappings.json deleted file mode 100644 index 48cd01eb935c9..0000000000000 --- a/x-pack/test/functional/es_archives/reporting/6_2/mappings.json +++ /dev/null @@ -1,362 +0,0 @@ -{ - "type": "index", - "value": { - "index": ".kibana", - "settings": { - "index": { - "number_of_shards": "1", - "number_of_replicas": "1" - } - }, - "mappings": { - "doc": { - "properties": { - "config": { - "dynamic": "true", - "properties": { - "buildNum": { - "type": "keyword" - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "xPackMonitoring:showBanner": { - "type": "boolean" - } - } - }, - "dashboard": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "optionsJSON": { - "type": "text" - }, - "panelsJSON": { - "type": "text" - }, - "refreshInterval": { - "properties": { - "display": { - "type": "keyword" - }, - "pause": { - "type": "boolean" - }, - "section": { - "type": "integer" - }, - "value": { - "type": "integer" - } - } - }, - "timeFrom": { - "type": "keyword" - }, - "timeRestore": { - "type": "boolean" - }, - "timeTo": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "graph-workspace": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" - } - } - }, - "index-pattern": { - "dynamic": "strict", - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - } - } - }, - "search": { - "dynamic": "strict", - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "server": { - "dynamic": "strict", - "properties": { - "uuid": { - "type": "keyword" - } - } - }, - "timelion-sheet": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "dynamic": "strict", - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } - } - } - } - }, - "visualization": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" - } - } - } - } - } - } - } -} - -{ - "type": "index", - "value": { - "index": ".reporting-2018.03.11", - "settings": { - "index": { - "number_of_shards": "1", - "auto_expand_replicas": "0-1", - "number_of_replicas": "0" - } - }, - "mappings": { - "esqueue": { - "properties": { - "attempts": { - "type": "short" - }, - "completed_at": { - "type": "date" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "jobtype": { - "type": "keyword" - }, - "max_attempts": { - "type": "short" - }, - "output": { - "properties": { - "content": { - "type": "object", - "enabled": false - }, - "content_type": { - "type": "keyword" - }, - "max_size_reached": { - "type": "boolean" - } - } - }, - "payload": { - "type": "object", - "enabled": false - }, - "priority": { - "type": "byte" - }, - "process_expiration": { - "type": "date" - }, - "started_at": { - "type": "date" - }, - "status": { - "type": "keyword" - }, - "timeout": { - "type": "long" - } - } - } - } - } -} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/reporting/bwc/6_2/data.json.gz b/x-pack/test/functional/es_archives/reporting/bwc/6_2/data.json.gz new file mode 100644 index 0000000000000..a953e82525bd1 Binary files /dev/null and b/x-pack/test/functional/es_archives/reporting/bwc/6_2/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/reporting/bwc/6_2/mappings.json b/x-pack/test/functional/es_archives/reporting/bwc/6_2/mappings.json new file mode 100644 index 0000000000000..5fc2b2dd7fe90 --- /dev/null +++ b/x-pack/test/functional/es_archives/reporting/bwc/6_2/mappings.json @@ -0,0 +1,70 @@ +{ + "type": "index", + "value": { + "index": ".reporting-2018.03.11", + "settings": { + "index": { + "number_of_shards": "1", + "auto_expand_replicas": "0-1", + "number_of_replicas": "0" + } + }, + "mappings": { + "esqueue": { + "properties": { + "attempts": { + "type": "short" + }, + "completed_at": { + "type": "date" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "jobtype": { + "type": "keyword" + }, + "max_attempts": { + "type": "short" + }, + "output": { + "properties": { + "content": { + "type": "object", + "enabled": false + }, + "content_type": { + "type": "keyword" + }, + "max_size_reached": { + "type": "boolean" + } + } + }, + "payload": { + "type": "object", + "enabled": false + }, + "priority": { + "type": "byte" + }, + "process_expiration": { + "type": "date" + }, + "started_at": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "timeout": { + "type": "long" + } + } + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/reporting/bwc/6_3/data.json.gz b/x-pack/test/functional/es_archives/reporting/bwc/6_3/data.json.gz new file mode 100644 index 0000000000000..0b567d8c6a9ce Binary files /dev/null and b/x-pack/test/functional/es_archives/reporting/bwc/6_3/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/reporting/bwc/6_3/mappings.json b/x-pack/test/functional/es_archives/reporting/bwc/6_3/mappings.json new file mode 100644 index 0000000000000..26faaa7d7be47 --- /dev/null +++ b/x-pack/test/functional/es_archives/reporting/bwc/6_3/mappings.json @@ -0,0 +1,92 @@ +{ + "type": "index", + "value": { + "index": ".reporting-2018.05.06", + "settings": { + "index": { + "number_of_shards": "1", + "auto_expand_replicas": "0-1", + "number_of_replicas": "0" + } + }, + "mappings": { + "esqueue": { + "properties": { + "attempts": { + "type": "short" + }, + "completed_at": { + "type": "date" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "jobtype": { + "type": "keyword" + }, + "max_attempts": { + "type": "short" + }, + "meta": { + "properties": { + "layout": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "objectType": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + } + } + }, + "output": { + "properties": { + "content": { + "type": "object", + "enabled": false + }, + "content_type": { + "type": "keyword" + }, + "max_size_reached": { + "type": "boolean" + } + } + }, + "payload": { + "type": "object", + "enabled": false + }, + "priority": { + "type": "byte" + }, + "process_expiration": { + "type": "date" + }, + "started_at": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "timeout": { + "type": "long" + } + } + } + } + } +} diff --git a/x-pack/test/functional/es_archives/reporting/current/reporting/data.json.gz b/x-pack/test/functional/es_archives/reporting/current/reporting/data.json.gz new file mode 100644 index 0000000000000..02028bee8ecec Binary files /dev/null and b/x-pack/test/functional/es_archives/reporting/current/reporting/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/reporting/current/reporting/mappings.json b/x-pack/test/functional/es_archives/reporting/current/reporting/mappings.json new file mode 100644 index 0000000000000..e47a7c789a8ee --- /dev/null +++ b/x-pack/test/functional/es_archives/reporting/current/reporting/mappings.json @@ -0,0 +1,92 @@ +{ + "type": "index", + "value": { + "index": ".reporting-2018.05.06", + "settings": { + "index": { + "number_of_shards": "1", + "auto_expand_replicas": "0-1", + "number_of_replicas": "0" + } + }, + "mappings": { + "esqueue": { + "properties": { + "attempts": { + "type": "short" + }, + "completed_at": { + "type": "date" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "jobtype": { + "type": "keyword" + }, + "max_attempts": { + "type": "short" + }, + "meta": { + "properties": { + "layout": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "objectType": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + } + } + }, + "output": { + "properties": { + "content": { + "type": "object", + "enabled": false + }, + "content_type": { + "type": "keyword" + }, + "max_size_reached": { + "type": "boolean" + } + } + }, + "payload": { + "type": "object", + "enabled": false + }, + "priority": { + "type": "byte" + }, + "process_expiration": { + "type": "date" + }, + "started_at": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "timeout": { + "type": "long" + } + } + } + } + } +} \ No newline at end of file