From 836ac841ba13bba1761b2ba51d67b0bb11d0ec59 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Mon, 15 Jun 2020 16:19:35 -0600 Subject: [PATCH 01/18] Pass the job name to the code coverage ingestion script, intro the 2 new indexes. --- src/dev/code_coverage/ingest_coverage/constants.js | 4 ++++ src/dev/code_coverage/shell_scripts/ingest_coverage.sh | 4 ++++ vars/kibanaCoverage.groovy | 10 +++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/constants.js b/src/dev/code_coverage/ingest_coverage/constants.js index a7303f0778d1ce..140ce0eb85290f 100644 --- a/src/dev/code_coverage/ingest_coverage/constants.js +++ b/src/dev/code_coverage/ingest_coverage/constants.js @@ -19,3 +19,7 @@ export const COVERAGE_INDEX = process.env.COVERAGE_INDEX || 'kibana_code_coverage'; export const TOTALS_INDEX = process.env.TOTALS_INDEX || `kibana_total_code_coverage`; +export const RESEARCH_COVERAGE_INDEX = + process.env.RESEARCH_COVERAGE_INDEX || 'qa_research_code_coverage'; +export const RESEARCH_TOTALS_INDEX = + process.env.RESEARCH_TOTALS_INDEX || `qa_research_total_code_coverage`; diff --git a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh index b7064a1e426717..9233a746a29005 100644 --- a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh +++ b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh @@ -11,6 +11,10 @@ CI_RUN_URL=$2 export CI_RUN_URL echo "### debug CI_RUN_URL: ${CI_RUN_URL}" +COVERAGE_JOB_NAME=$3 +export COVERAGE_JOB_NAME +echo "### debug COVERAGE_JOB_NAME: ${COVERAGE_JOB_NAME}" + ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" export ES_HOST diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index 66b16566418b59..30ec0f3e3dc2f5 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -125,21 +125,21 @@ def uploadCombinedReports() { ) } -def ingestData(buildNum, buildUrl, title) { +def ingestData(jobName, buildNum, buildUrl, title) { kibanaPipeline.bash(""" source src/dev/ci_setup/setup_env.sh yarn kbn bootstrap --prefer-offline # Using existing target/kibana-coverage folder - . src/dev/code_coverage/shell_scripts/ingest_coverage.sh ${buildNum} ${buildUrl} + . src/dev/code_coverage/shell_scripts/ingest_coverage.sh ${buildNum} ${buildUrl} ${jobName} """, title) } -def ingestWithVault(buildNum, buildUrl, title) { +def ingestWithVault(jobName, buildNum, buildUrl, title) { def vaultSecret = 'secret/kibana-issues/prod/coverage/elasticsearch' withVaultSecret(secret: vaultSecret, secret_field: 'host', variable_name: 'HOST_FROM_VAULT') { withVaultSecret(secret: vaultSecret, secret_field: 'username', variable_name: 'USER_FROM_VAULT') { withVaultSecret(secret: vaultSecret, secret_field: 'password', variable_name: 'PASS_FROM_VAULT') { - ingestData(buildNum, buildUrl, title) + ingestData(jobName, buildNum, buildUrl, title) } } } @@ -149,7 +149,7 @@ def ingest(timestamp, title) { withEnv([ "TIME_STAMP=${timestamp}", ]) { - ingestWithVault(BUILD_NUMBER, BUILD_URL, title) + ingestWithVault(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, title) } } From 5ea498c6a8d364101563ef0c0f1e7d81b391f831 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Mon, 15 Jun 2020 16:41:31 -0600 Subject: [PATCH 02/18] Change the payload such that the the pipeline data point is an expando prop. --- src/dev/code_coverage/ingest_coverage/ingest.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index d6c55a9a655b8b..8eaffaa9fcad47 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -53,6 +53,7 @@ async function send(idx, redacted, requestBody) { } export function maybeTeamAssign(index, body) { - const payload = index === TOTALS_INDEX ? body : { ...body, pipeline }; + const withTeam = { body, pipeline }; + const payload = index === TOTALS_INDEX ? body : withTeam; return payload; } From 5aa4738fca015e0984d75e5ca6d1ffca13e960ab Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Tue, 16 Jun 2020 13:40:53 -0600 Subject: [PATCH 03/18] Add more constants and more tests, and fixup broken tests. --- .../ingest_coverage/__tests__/ingest.test.js | 37 --------- .../__tests__/ingest_helpers.test.js | 75 +++++++++++++++++++ .../ingest_coverage/constants.js | 9 +++ .../code_coverage/ingest_coverage/ingest.js | 27 ++++--- .../ingest_coverage/ingest_helpers.js | 25 +++++++ .../integration_tests/ingest_coverage.test.js | 42 +++++------ .../coverage-summary-NO-total.json | 0 7 files changed, 143 insertions(+), 72 deletions(-) delete mode 100644 src/dev/code_coverage/ingest_coverage/__tests__/ingest.test.js create mode 100644 src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js delete mode 100644 src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/ingest.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/ingest.test.js deleted file mode 100644 index ad5b4da0873b90..00000000000000 --- a/src/dev/code_coverage/ingest_coverage/__tests__/ingest.test.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { maybeTeamAssign } from '../ingest'; -import { COVERAGE_INDEX, TOTALS_INDEX } from '../constants'; - -describe(`Ingest fns`, () => { - describe(`maybeTeamAssign fn`, () => { - describe(`against the coverage index`, () => { - it(`should have the pipeline prop`, () => { - expect(maybeTeamAssign(COVERAGE_INDEX, {})).to.have.property('pipeline'); - }); - }); - describe(`against the totals index`, () => { - it(`should not have the pipeline prop`, () => { - expect(maybeTeamAssign(TOTALS_INDEX, {})).not.to.have.property('pipeline'); - }); - }); - }); -}); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js new file mode 100644 index 00000000000000..7ca7279e0d64ce --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { maybeTeamAssign, whichIndex } from '../ingest_helpers'; +import { + TOTALS_INDEX, + RESEARCH_TOTALS_INDEX, + RESEARCH_COVERAGE_INDEX, + // COVERAGE_INDEX, +} from '../constants'; + +describe(`Ingest Helper fns`, () => { + describe(`whichIndex`, () => { + describe(`against the research job`, () => { + const whichIndexAgainstResearchJob = whichIndex(true); + describe(`against the totals index`, () => { + const isTotal = true; + it(`should return the Research Totals Index`, () => { + const actual = whichIndexAgainstResearchJob(isTotal); + expect(actual).to.be(RESEARCH_TOTALS_INDEX); + }); + }); + describe(`against the coverage index`, () => { + it(`should return the Research Totals Index`, () => { + const isTotal = false; + const actual = whichIndexAgainstResearchJob(isTotal); + expect(actual).to.be(RESEARCH_COVERAGE_INDEX); + }); + }); + }); + describe(`against the "prod" job`, () => { + const whichIndexAgainstProdJob = whichIndex(false); + describe(`against the totals index`, () => { + const isTotal = true; + it(`should return the "Prod" Totals Index`, () => { + const actual = whichIndexAgainstProdJob(isTotal); + expect(actual).to.be(TOTALS_INDEX); + }); + }); + }); + }); + describe(`maybeTeamAssign`, () => { + describe(`against a coverage index`, () => { + it(`should have the pipeline prop`, () => { + const actual = maybeTeamAssign(true, { a: 'blah' }); + expect(actual).to.have.property('pipeline'); + }); + }); + describe(`against a totals index`, () => { + describe(`for "prod"`, () => { + it(`should not have the pipeline prop`, () => { + const actual = maybeTeamAssign(false, { b: 'blah' }); + expect(actual).not.to.have.property('pipeline'); + }); + }); + }); + }); +}); diff --git a/src/dev/code_coverage/ingest_coverage/constants.js b/src/dev/code_coverage/ingest_coverage/constants.js index 140ce0eb85290f..ddee7106f44903 100644 --- a/src/dev/code_coverage/ingest_coverage/constants.js +++ b/src/dev/code_coverage/ingest_coverage/constants.js @@ -18,8 +18,17 @@ */ export const COVERAGE_INDEX = process.env.COVERAGE_INDEX || 'kibana_code_coverage'; + export const TOTALS_INDEX = process.env.TOTALS_INDEX || `kibana_total_code_coverage`; + export const RESEARCH_COVERAGE_INDEX = process.env.RESEARCH_COVERAGE_INDEX || 'qa_research_code_coverage'; + export const RESEARCH_TOTALS_INDEX = process.env.RESEARCH_TOTALS_INDEX || `qa_research_total_code_coverage`; + +export const TEAM_ASSIGNMENT_PIPELINE_NAME = process.env.PIPELINE_NAME || 'team_assignment'; + +export const CODE_COVERAGE_CI_JOB_NAME = 'elastic+kibana+code-coverage'; +export const RESEARCH_CI_JOB_NAME = 'elastic+kibana+qa-research'; +export const CI_JOB_NAME = process.env.COVERAGE_JOB_NAME || RESEARCH_CI_JOB_NAME; diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 8eaffaa9fcad47..a1d0991bab3c43 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -19,19 +19,30 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; -import { COVERAGE_INDEX, TOTALS_INDEX } from './constants'; -import { errMsg, redact } from './ingest_helpers'; +import { + // COVERAGE_INDEX, + // TOTALS_INDEX, + RESEARCH_CI_JOB_NAME, + // TEAM_ASSIGNMENT_PIPELINE_NAME, + // RESEARCH_TOTALS_INDEX, + // RESEARCH_COVERAGE_INDEX, +} from './constants'; +import { errMsg, redact, maybeTeamAssign, whichIndex } from './ingest_helpers'; import { noop } from './utils'; import { right, left } from './either'; const node = process.env.ES_HOST || 'http://localhost:9200'; + const client = new Client({ node }); -const pipeline = process.env.PIPELINE_NAME || 'team_assignment'; const redacted = redact(node); export const ingest = (log) => async (body) => { - const index = body.isTotal ? TOTALS_INDEX : COVERAGE_INDEX; - const maybeWithPipeline = maybeTeamAssign(index, body); + const isTotal = !!body.isTotal; + const isResearchJob = process.env.COVERAGE_JOB_NAME === RESEARCH_CI_JOB_NAME ? true : false; + const index = whichIndex(isResearchJob)(isTotal); + const isACoverageIndex = isTotal ? false : true; + + const maybeWithPipeline = maybeTeamAssign(isACoverageIndex, body); const withIndex = { index, body: maybeWithPipeline }; const dontSend = noop; @@ -51,9 +62,3 @@ async function send(idx, redacted, requestBody) { throw createFailError(errMsg(idx, redacted, requestBody, e)); } } - -export function maybeTeamAssign(index, body) { - const withTeam = { body, pipeline }; - const payload = index === TOTALS_INDEX ? body : withTeam; - return payload; -} diff --git a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js index 11e5755bb02820..9198795addc84a 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js +++ b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js @@ -20,6 +20,13 @@ import { always, pretty } from './utils'; import chalk from 'chalk'; import { fromNullable } from './either'; +import { + COVERAGE_INDEX, + RESEARCH_COVERAGE_INDEX, + RESEARCH_TOTALS_INDEX, + TEAM_ASSIGNMENT_PIPELINE_NAME, + TOTALS_INDEX, +} from './constants'; export function errMsg(index, redacted, body, e) { const orig = fromNullable(e.body).fold( @@ -59,3 +66,21 @@ function color(whichColor) { return chalk[whichColor].bgWhiteBright(x); }; } + +export function maybeTeamAssign(isACoverageIndex, body) { + const doAddTeam = isACoverageIndex ? true : false; + const payload = doAddTeam ? { body, pipeline: TEAM_ASSIGNMENT_PIPELINE_NAME } : body; + return payload; +} + +export function whichIndex(isResearchJob) { + return (isTotal) => + isTotal ? whichTotalsIndex(isResearchJob) : whichCoverageIndex(isResearchJob); +} +function whichTotalsIndex(isResearchJob) { + return isResearchJob ? RESEARCH_TOTALS_INDEX : TOTALS_INDEX; +} + +function whichCoverageIndex(isResearchJob) { + return isResearchJob ? RESEARCH_COVERAGE_INDEX : COVERAGE_INDEX; +} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index 013adc8b6b0af1..786197a493209c 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -70,8 +70,8 @@ describe('Ingesting coverage', () => { }); describe(`vcsInfo`, () => { - let vcsInfo; describe(`without a commit msg in the vcs info file`, () => { + let vcsInfo; const args = [ 'scripts/ingest_coverage.js', '--verbose', @@ -93,9 +93,6 @@ describe('Ingesting coverage', () => { }); }); describe(`team assignment`, () => { - let shouldNotHavePipelineOut = ''; - let shouldIndeedHavePipelineOut = ''; - const args = [ 'scripts/ingest_coverage.js', '--verbose', @@ -103,29 +100,26 @@ describe('Ingesting coverage', () => { 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', '--path', ]; - const teamAssignRE = /pipeline:/; - beforeAll(async () => { - const summaryPath = 'jest-combined/coverage-summary-just-total.json'; - const resolved = resolve(MOCKS_DIR, summaryPath); - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - shouldNotHavePipelineOut = stdout; - }); - beforeAll(async () => { - const summaryPath = 'jest-combined/coverage-summary-manual-mix.json'; - const resolved = resolve(MOCKS_DIR, summaryPath); - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - shouldIndeedHavePipelineOut = stdout; - }); - - it(`should not occur when going to the totals index`, () => { - expect(teamAssignRE.test(shouldNotHavePipelineOut)).to.not.be.ok(); + it(`should not occur when going to the totals index`, async () => { + const shouldNotHavePipelineOut = await prokJustTotalOrNot(true, args); + const actual = teamAssignRE.test(shouldNotHavePipelineOut); + expect(actual).to.not.be.ok(); }); - it(`should indeed occur when going to the coverage index`, () => { - expect(teamAssignRE.test(shouldIndeedHavePipelineOut)).to.be.ok(); + it(`should indeed occur when going to the coverage index`, async () => { + const shouldIndeedHavePipelineOut = await prokJustTotalOrNot(false, args); + const actual = teamAssignRE.test(shouldIndeedHavePipelineOut); + expect(actual).to.be.ok(); }); }); }); +async function prokJustTotalOrNot(isTotal, args) { + const justTotalPath = 'jest-combined/coverage-summary-just-total.json'; + const notJustTotalPath = 'jest-combined/coverage-summary-manual-mix.json'; + + const resolved = resolve(MOCKS_DIR, isTotal ? justTotalPath : notJustTotalPath); + const opts = [...args, resolved]; + const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); + return stdout; +} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-NO-total.json deleted file mode 100644 index e69de29bb2d1d6..00000000000000 From fac507b13d9fd232bef1180e251845d8b3d5c2fb Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 13:27:16 -0600 Subject: [PATCH 04/18] Tally Ho! All tests passing, again --- .ci/Jenkinsfile_coverage | 2 +- .../code_coverage/ingest_coverage/ingest.js | 54 ++++++++++++------- vars/kibanaCoverage.groovy | 4 +- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage index 650ef94e1d3da6..2c59ada756ae78 100644 --- a/.ci/Jenkinsfile_coverage +++ b/.ci/Jenkinsfile_coverage @@ -28,7 +28,7 @@ def handleIngestion(timestamp) { kibanaCoverage.collectVcsInfo("### Collect VCS Info") kibanaCoverage.generateReports("### Merge coverage reports") kibanaCoverage.uploadCombinedReports() - kibanaCoverage.ingest(timestamp, '### Injest && Upload') + kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, '### Injest && Upload') kibanaCoverage.uploadCoverageStaticSite(timestamp) } diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index a1d0991bab3c43..b06923cf9c60df 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -19,16 +19,9 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; -import { - // COVERAGE_INDEX, - // TOTALS_INDEX, - RESEARCH_CI_JOB_NAME, - // TEAM_ASSIGNMENT_PIPELINE_NAME, - // RESEARCH_TOTALS_INDEX, - // RESEARCH_COVERAGE_INDEX, -} from './constants'; +import { RESEARCH_CI_JOB_NAME } from './constants'; import { errMsg, redact, maybeTeamAssign, whichIndex } from './ingest_helpers'; -import { noop } from './utils'; +import { pretty } from './utils'; import { right, left } from './either'; const node = process.env.ES_HOST || 'http://localhost:9200'; @@ -42,23 +35,46 @@ export const ingest = (log) => async (body) => { const index = whichIndex(isResearchJob)(isTotal); const isACoverageIndex = isTotal ? false : true; - const maybeWithPipeline = maybeTeamAssign(isACoverageIndex, body); - const withIndex = { index, body: maybeWithPipeline }; - const dontSend = noop; + const payload = maybeTeamAssign(isACoverageIndex, body); - log.verbose(withIndex); + const stringified = pretty(payload); + const payloadWithIndex = { index, body: stringified }; - process.env.NODE_ENV === 'integration_test' - ? left(null) - : right(withIndex).fold(dontSend, async function doSend(finalPayload) { - await send(index, redacted, finalPayload); - }); + const justLog = dontSendButLog(log); + const doSendToIndex = doSend(index); + const doSendRedacted = doSendToIndex(redacted)(log); + + eitherSendOrNotAndParseForPrint(payloadWithIndex).fold(justLog, doSendRedacted); }; async function send(idx, redacted, requestBody) { try { await client.index(requestBody); } catch (e) { - throw createFailError(errMsg(idx, redacted, requestBody, e)); + const { body } = requestBody; + const parsed = parse(body); + throw createFailError(errMsg(idx, redacted, parsed, e)); } } + +function doSend(index) { + return (redacted) => (log) => async (payload) => { + const { body } = payload; + log.verbose(`\n### Sent: \n\t### Index: ${index}\n\t### payload.body: ${body}`); + await send(index, redacted, payload); + }; +} + +function dontSendButLog(log) { + return (payload) => log.verbose(payload); +} + +function eitherSendOrNotAndParseForPrint(payload) { + const { body } = payload; + const parsed = parse(body); + return process.env.NODE_ENV === 'integration_test' ? left(parsed) : right(payload); +} + +function parse(body) { + return JSON.parse(body); +} diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index 30ec0f3e3dc2f5..ac278d441a36df 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -145,11 +145,11 @@ def ingestWithVault(jobName, buildNum, buildUrl, title) { } } -def ingest(timestamp, title) { +def ingest(jobName, buildNumber, buildUrl, timestamp, title) { withEnv([ "TIME_STAMP=${timestamp}", ]) { - ingestWithVault(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, title) + ingestWithVault(jobName, buildNumber, buildUrl, title) } } From 3d27e4fc9265f398c5a5fa78c4538836912240e6 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 14:24:32 -0600 Subject: [PATCH 05/18] Minor fixups --- .../code_coverage/ingest_coverage/ingest.js | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index b06923cf9c60df..303f3548a526e5 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -21,13 +21,13 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; import { RESEARCH_CI_JOB_NAME } from './constants'; import { errMsg, redact, maybeTeamAssign, whichIndex } from './ingest_helpers'; -import { pretty } from './utils'; +import { pretty, green } from './utils'; import { right, left } from './either'; const node = process.env.ES_HOST || 'http://localhost:9200'; const client = new Client({ node }); -const redacted = redact(node); +const redactedEsHostUrl = redact(node); export const ingest = (log) => async (body) => { const isTotal = !!body.isTotal; @@ -42,26 +42,30 @@ export const ingest = (log) => async (body) => { const justLog = dontSendButLog(log); const doSendToIndex = doSend(index); - const doSendRedacted = doSendToIndex(redacted)(log); + const doSendRedacted = doSendToIndex(redactedEsHostUrl)(log); eitherSendOrNotAndParseForPrint(payloadWithIndex).fold(justLog, doSendRedacted); }; -async function send(idx, redacted, requestBody) { +async function send(idx, redactedEsHostUrl, requestBody) { try { await client.index(requestBody); } catch (e) { const { body } = requestBody; const parsed = parse(body); - throw createFailError(errMsg(idx, redacted, parsed, e)); + throw createFailError(errMsg(idx, redactedEsHostUrl, parsed, e)); } } function doSend(index) { - return (redacted) => (log) => async (payload) => { + return (redactedEsHostUrl) => (log) => async (payload) => { const { body } = payload; - log.verbose(`\n### Sent: \n\t### Index: ${index}\n\t### payload.body: ${body}`); - await send(index, redacted, payload); + log.verbose( + `\n### Sent: \n\t### ES Host: ${redactedEsHostUrl}\n\t### Index: ${green( + index + )}\n\t### payload.body: ${body}` + ); + await send(index, redactedEsHostUrl, payload); }; } From e17a7ded136f0708d11cdcf4d9e0c3040053cf5c Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 16:31:51 -0600 Subject: [PATCH 06/18] Typo --- .ci/Jenkinsfile_coverage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage index 2c59ada756ae78..d6600256bab7bf 100644 --- a/.ci/Jenkinsfile_coverage +++ b/.ci/Jenkinsfile_coverage @@ -28,7 +28,7 @@ def handleIngestion(timestamp) { kibanaCoverage.collectVcsInfo("### Collect VCS Info") kibanaCoverage.generateReports("### Merge coverage reports") kibanaCoverage.uploadCombinedReports() - kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, '### Injest && Upload') + kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, '### Ingest && Upload') kibanaCoverage.uploadCoverageStaticSite(timestamp) } From 78dcc3f665bfb4c4c1b915cb8de45bcefd6081de Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 17:52:32 -0600 Subject: [PATCH 07/18] Change process.js to OR to a moment utc ts, instead of just depending on an env var. --- src/dev/code_coverage/ingest_coverage/process.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dev/code_coverage/ingest_coverage/process.js b/src/dev/code_coverage/ingest_coverage/process.js index 6b9c8f09febfe9..85a42cfffa6e2c 100644 --- a/src/dev/code_coverage/ingest_coverage/process.js +++ b/src/dev/code_coverage/ingest_coverage/process.js @@ -36,13 +36,17 @@ import { import { resolve } from 'path'; import { createReadStream } from 'fs'; import readline from 'readline'; +import * as moment from 'moment'; const ROOT = '../../../..'; const COVERAGE_INGESTION_KIBANA_ROOT = process.env.COVERAGE_INGESTION_KIBANA_ROOT || resolve(__dirname, ROOT); const ms = process.env.DELAY || 0; const staticSiteUrlBase = process.env.STATIC_SITE_URL_BASE || 'https://kibana-coverage.elastic.dev'; -const addPrePopulatedTimeStamp = addTimeStamp(process.env.TIME_STAMP); +const format = 'YYYY-MM-DDTHH:mm:SS'; +// eslint-disable-next-line import/namespace +const formatted = `${moment.utc().format(format)}Z`; +const addPrePopulatedTimeStamp = addTimeStamp(process.env.TIME_STAMP || formatted); const preamble = pipe(statsAndstaticSiteUrl, rootDirAndOrigPath, buildId, addPrePopulatedTimeStamp); const addTestRunnerAndStaticSiteUrl = pipe(testRunner, staticSite(staticSiteUrlBase)); From de3d33d7e8ec5b92efa27d41f7330d218c4f225f Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 17:53:16 -0600 Subject: [PATCH 08/18] Spread the body into the obj. --- src/dev/code_coverage/ingest_coverage/ingest_helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js index 9198795addc84a..ec49b07e92e6b7 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js +++ b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js @@ -69,7 +69,7 @@ function color(whichColor) { export function maybeTeamAssign(isACoverageIndex, body) { const doAddTeam = isACoverageIndex ? true : false; - const payload = doAddTeam ? { body, pipeline: TEAM_ASSIGNMENT_PIPELINE_NAME } : body; + const payload = doAddTeam ? { ...body, pipeline: TEAM_ASSIGNMENT_PIPELINE_NAME } : body; return payload; } From 609eae4ea6ed030d475505188750e474cd92cdfc Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 17:54:02 -0600 Subject: [PATCH 09/18] Normalize the logging. --- .../code_coverage/ingest_coverage/ingest.js | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 303f3548a526e5..a3591013b7121f 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -42,43 +42,51 @@ export const ingest = (log) => async (body) => { const justLog = dontSendButLog(log); const doSendToIndex = doSend(index); - const doSendRedacted = doSendToIndex(redactedEsHostUrl)(log); + const doSendRedacted = doSendToIndex(redactedEsHostUrl)(log)(client); - eitherSendOrNotAndParseForPrint(payloadWithIndex).fold(justLog, doSendRedacted); + eitherSendOrNot(payloadWithIndex).fold(justLog, doSendRedacted); }; -async function send(idx, redactedEsHostUrl, requestBody) { +function doSend(index) { + return (redactedEsHostUrl) => (log) => (client) => async (payload) => { + const logF = logSend(true)(redactedEsHostUrl)(index)(log); + await send(logF, index, redactedEsHostUrl, client, payload); + }; +} + +function dontSendButLog(log) { + return (payload) => { + console.log(`\n### log: \n\t${log}`); + console.log(`\n### payload: \n\t${payload}`); + // logSend(false)(?)(log)(payload); + }; +} + +async function send(logF, idx, redactedEsHostUrl, client, requestBody) { try { await client.index(requestBody); + logF(requestBody); } catch (e) { - const { body } = requestBody; - const parsed = parse(body); - throw createFailError(errMsg(idx, redactedEsHostUrl, parsed, e)); + // const { body } = requestBody; + // const parsed = parse(body); + throw createFailError(errMsg(idx, redactedEsHostUrl, requestBody, e)); } } -function doSend(index) { - return (redactedEsHostUrl) => (log) => async (payload) => { - const { body } = payload; +function logSend(actuallySent) { + return (redactedEsHostUrl) => (idx) => (log) => (payload) => log.verbose( - `\n### Sent: \n\t### ES Host: ${redactedEsHostUrl}\n\t### Index: ${green( - index - )}\n\t### payload.body: ${body}` + `### ${actuallySent ? 'Sent' : 'Fake Sent'}: +\t### ES Host: ${redactedEsHostUrl} +\t### Index: ${green(idx)} +\t### payload: ${pretty(payload)}` ); - await send(index, redactedEsHostUrl, payload); - }; } -function dontSendButLog(log) { - return (payload) => log.verbose(payload); +function eitherSendOrNot(payload) { + return process.env.NODE_ENV === 'integration_test' ? left(payload) : right(payload); } -function eitherSendOrNotAndParseForPrint(payload) { - const { body } = payload; - const parsed = parse(body); - return process.env.NODE_ENV === 'integration_test' ? left(parsed) : right(payload); -} - -function parse(body) { - return JSON.parse(body); -} +// function parse(body) { +// return JSON.parse(body); +// } From ae43cc2110d4dcd662f2228afc7b25b985c10f42 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Wed, 17 Jun 2020 17:59:55 -0600 Subject: [PATCH 10/18] Fixup err handling. --- src/dev/code_coverage/ingest_coverage/ingest.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index a3591013b7121f..9af957baa9d28f 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -67,9 +67,9 @@ async function send(logF, idx, redactedEsHostUrl, client, requestBody) { await client.index(requestBody); logF(requestBody); } catch (e) { - // const { body } = requestBody; - // const parsed = parse(body); - throw createFailError(errMsg(idx, redactedEsHostUrl, requestBody, e)); + const { body } = requestBody; + const parsed = parse(body); + throw createFailError(errMsg(idx, redactedEsHostUrl, parsed, e)); } } @@ -87,6 +87,6 @@ function eitherSendOrNot(payload) { return process.env.NODE_ENV === 'integration_test' ? left(payload) : right(payload); } -// function parse(body) { -// return JSON.parse(body); -// } +function parse(body) { + return JSON.parse(body); +} From fe7607f6b6a1e4279868999151904f52699d3638 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Thu, 18 Jun 2020 12:55:33 -0600 Subject: [PATCH 11/18] Fixup logging and enhance err handling, and skip some integration tests (for now). --- .../code_coverage/ingest_coverage/ingest.js | 40 +++--- .../ingest_coverage/ingest_helpers.js | 3 + .../integration_tests/ingest_coverage.test.js | 120 +++++++++--------- 3 files changed, 84 insertions(+), 79 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 9af957baa9d28f..9ba09eb2d12ab9 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -19,8 +19,8 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; -import { RESEARCH_CI_JOB_NAME } from './constants'; -import { errMsg, redact, maybeTeamAssign, whichIndex } from './ingest_helpers'; +import { RESEARCH_CI_JOB_NAME, TEAM_ASSIGNMENT_PIPELINE_NAME } from './constants'; +import { errMsg, redact, whichIndex } from './ingest_helpers'; import { pretty, green } from './utils'; import { right, left } from './either'; @@ -28,37 +28,38 @@ const node = process.env.ES_HOST || 'http://localhost:9200'; const client = new Client({ node }); const redactedEsHostUrl = redact(node); +const parse = JSON.parse.bind(null); +const isResearchJob = process.env.COVERAGE_JOB_NAME === RESEARCH_CI_JOB_NAME ? true : false; export const ingest = (log) => async (body) => { const isTotal = !!body.isTotal; - const isResearchJob = process.env.COVERAGE_JOB_NAME === RESEARCH_CI_JOB_NAME ? true : false; const index = whichIndex(isResearchJob)(isTotal); const isACoverageIndex = isTotal ? false : true; - const payload = maybeTeamAssign(isACoverageIndex, body); + const stringified = pretty(body); + const pipeline = TEAM_ASSIGNMENT_PIPELINE_NAME; - const stringified = pretty(payload); - const payloadWithIndex = { index, body: stringified }; + const finalPayload = isACoverageIndex + ? { index, body: stringified, pipeline } + : { index, body: stringified }; const justLog = dontSendButLog(log); const doSendToIndex = doSend(index); const doSendRedacted = doSendToIndex(redactedEsHostUrl)(log)(client); - eitherSendOrNot(payloadWithIndex).fold(justLog, doSendRedacted); + eitherSendOrNot(finalPayload).fold(justLog, doSendRedacted); }; function doSend(index) { return (redactedEsHostUrl) => (log) => (client) => async (payload) => { - const logF = logSend(true)(redactedEsHostUrl)(index)(log); + const logF = logSend(true)(redactedEsHostUrl)(log); await send(logF, index, redactedEsHostUrl, client, payload); }; } function dontSendButLog(log) { return (payload) => { - console.log(`\n### log: \n\t${log}`); - console.log(`\n### payload: \n\t${payload}`); - // logSend(false)(?)(log)(payload); + logSend(false)(null)(log)(payload); }; } @@ -74,19 +75,20 @@ async function send(logF, idx, redactedEsHostUrl, client, requestBody) { } function logSend(actuallySent) { - return (redactedEsHostUrl) => (idx) => (log) => (payload) => + return (redactedEsHostUrl) => (log) => (payload) => { + const { index, body } = payload; log.verbose( `### ${actuallySent ? 'Sent' : 'Fake Sent'}: -\t### ES Host: ${redactedEsHostUrl} -\t### Index: ${green(idx)} -\t### payload: ${pretty(payload)}` +${redactedEsHostUrl ? `\t### ES Host: ${redactedEsHostUrl}` : ''} +\t### Index: ${green(index)} +\t### payload.body: ${pretty(body)}` ); + }; } - function eitherSendOrNot(payload) { return process.env.NODE_ENV === 'integration_test' ? left(payload) : right(payload); } -function parse(body) { - return JSON.parse(body); -} +// function parse(body) { +// return JSON.parse(body); +// } diff --git a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js index ec49b07e92e6b7..86bcf039770829 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js +++ b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js @@ -45,6 +45,9 @@ ${orig} ### Troubleshooting Hint: ${red('Perhaps the coverage data was not merged properly?\n')} + +### Error.meta (stringified): +${pretty(e.meta)} `; } diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index 786197a493209c..bbc6d10c8b5551 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -34,40 +34,40 @@ const env = { }; describe('Ingesting coverage', () => { - const verboseArgs = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - '--path', - ]; + // const verboseArgs = [ + // 'scripts/ingest_coverage.js', + // '--verbose', + // '--vcsInfoPath', + // 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', + // '--path', + // ]; const summaryPath = 'jest-combined/coverage-summary-manual-mix.json'; const resolved = resolve(MOCKS_DIR, summaryPath); - describe(`staticSiteUrl`, () => { - let actualUrl = ''; - const siteUrlRegex = /staticSiteUrl:\s*(.+,)/; - - beforeAll(async () => { - const opts = [...verboseArgs, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - actualUrl = siteUrlRegex.exec(stdout)[1]; - }); - - it('should contain the static host', () => { - const staticHost = /https:\/\/kibana-coverage\.elastic\.dev/; - expect(staticHost.test(actualUrl)).ok(); - }); - it('should contain the timestamp', () => { - const timeStamp = /\d{4}-\d{2}-\d{2}T\d{2}.*\d{2}.*\d{2}Z/; - expect(timeStamp.test(actualUrl)).ok(); - }); - it('should contain the folder structure', () => { - const folderStructure = /(?:.*|.*-combined)\//; - expect(folderStructure.test(actualUrl)).ok(); - }); - }); + // describe(`staticSiteUrl`, () => { + // let actualUrl = ''; + // const siteUrlRegex = /"staticSiteUrl":\s*(.+,)/; + // + // beforeAll(async () => { + // const opts = [...verboseArgs, resolved]; + // const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); + // actualUrl = siteUrlRegex.exec(stdout)[1]; + // }); + // + // it('should contain the static host', () => { + // const staticHost = /https:\/\/kibana-coverage\.elastic\.dev/; + // expect(staticHost.test(actualUrl)).ok(); + // }); + // it('should contain the timestamp', () => { + // const timeStamp = /\d{4}-\d{2}-\d{2}T\d{2}.*\d{2}.*\d{2}Z/; + // expect(timeStamp.test(actualUrl)).ok(); + // }); + // it('should contain the folder structure', () => { + // const folderStructure = /(?:.*|.*-combined)\//; + // expect(folderStructure.test(actualUrl)).ok(); + // }); + // }); describe(`vcsInfo`, () => { describe(`without a commit msg in the vcs info file`, () => { @@ -92,34 +92,34 @@ describe('Ingesting coverage', () => { }); }); }); - describe(`team assignment`, () => { - const args = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - '--path', - ]; - const teamAssignRE = /pipeline:/; - - it(`should not occur when going to the totals index`, async () => { - const shouldNotHavePipelineOut = await prokJustTotalOrNot(true, args); - const actual = teamAssignRE.test(shouldNotHavePipelineOut); - expect(actual).to.not.be.ok(); - }); - it(`should indeed occur when going to the coverage index`, async () => { - const shouldIndeedHavePipelineOut = await prokJustTotalOrNot(false, args); - const actual = teamAssignRE.test(shouldIndeedHavePipelineOut); - expect(actual).to.be.ok(); - }); - }); + // describe(`team assignment`, () => { + // const args = [ + // 'scripts/ingest_coverage.js', + // '--verbose', + // '--vcsInfoPath', + // 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', + // '--path', + // ]; + // const teamAssignRE = /pipeline:/; + // + // it(`should not occur when going to the totals index`, async () => { + // const shouldNotHavePipelineOut = await prokJustTotalOrNot(true, args); + // const actual = teamAssignRE.test(shouldNotHavePipelineOut); + // expect(actual).to.not.be.ok(); + // }); + // it(`should indeed occur when going to the coverage index`, async () => { + // const shouldIndeedHavePipelineOut = await prokJustTotalOrNot(false, args); + // const actual = teamAssignRE.test(shouldIndeedHavePipelineOut); + // expect(actual).to.be.ok(); + // }); + // }); }); -async function prokJustTotalOrNot(isTotal, args) { - const justTotalPath = 'jest-combined/coverage-summary-just-total.json'; - const notJustTotalPath = 'jest-combined/coverage-summary-manual-mix.json'; - - const resolved = resolve(MOCKS_DIR, isTotal ? justTotalPath : notJustTotalPath); - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - return stdout; -} +// async function prokJustTotalOrNot(isTotal, args) { +// const justTotalPath = 'jest-combined/coverage-summary-just-total.json'; +// const notJustTotalPath = 'jest-combined/coverage-summary-manual-mix.json'; +// +// const resolved = resolve(MOCKS_DIR, isTotal ? justTotalPath : notJustTotalPath); +// const opts = [...args, resolved]; +// const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); +// return stdout; +// } From e1684a71401722cc1f2a0f396025bca6debfec9c Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Thu, 18 Jun 2020 20:05:06 -0600 Subject: [PATCH 12/18] Button things up by... fixing the integ tests by a bit of test-only stdout and, add another unit test --- .../__tests__/transforms.test.js | 38 ++++-- .../code_coverage/ingest_coverage/ingest.js | 8 +- .../integration_tests/ingest_coverage.test.js | 121 +++++++++--------- 3 files changed, 91 insertions(+), 76 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js index 8c982b792ed3b2..2fd1d5cbe8d48d 100644 --- a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js +++ b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js @@ -32,17 +32,33 @@ describe(`Transform fn`, () => { }); }); describe(`coveredFilePath`, () => { - it(`should remove the jenkins workspace path`, () => { - const obj = { - staticSiteUrl: - '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/x-pack/plugins/reporting/server/browsers/extract/unzip.js', - COVERAGE_INGESTION_KIBANA_ROOT: - '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana', - }; - expect(coveredFilePath(obj)).to.have.property( - 'coveredFilePath', - 'x-pack/plugins/reporting/server/browsers/extract/unzip.js' - ); + describe(`in the code-coverage job`, () => { + it(`should remove the jenkins workspace path`, () => { + const obj = { + staticSiteUrl: + '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/x-pack/plugins/reporting/server/browsers/extract/unzip.js', + COVERAGE_INGESTION_KIBANA_ROOT: + '/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana', + }; + expect(coveredFilePath(obj)).to.have.property( + 'coveredFilePath', + 'x-pack/plugins/reporting/server/browsers/extract/unzip.js' + ); + }); + }); + describe(`in the qa research job`, () => { + it(`should remove the jenkins workspace path`, () => { + const obj = { + staticSiteUrl: + '/var/lib/jenkins/workspace/elastic+kibana+qa-research/kibana/x-pack/plugins/reporting/server/browsers/extract/unzip.js', + COVERAGE_INGESTION_KIBANA_ROOT: + '/var/lib/jenkins/workspace/elastic+kibana+qa-research/kibana', + }; + expect(coveredFilePath(obj)).to.have.property( + 'coveredFilePath', + 'x-pack/plugins/reporting/server/browsers/extract/unzip.js' + ); + }); }); }); describe(`itemizeVcs`, () => { diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 9ba09eb2d12ab9..b4996615a2dc44 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -81,14 +81,12 @@ function logSend(actuallySent) { `### ${actuallySent ? 'Sent' : 'Fake Sent'}: ${redactedEsHostUrl ? `\t### ES Host: ${redactedEsHostUrl}` : ''} \t### Index: ${green(index)} -\t### payload.body: ${pretty(body)}` +\t### payload.body: ${body} +${process.env.NODE_ENV === 'integration_test' ? `ingest-pipe=>${payload.pipeline}` : ''} +` ); }; } function eitherSendOrNot(payload) { return process.env.NODE_ENV === 'integration_test' ? left(payload) : right(payload); } - -// function parse(body) { -// return JSON.parse(body); -// } diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index bbc6d10c8b5551..2a65839f85ac31 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -34,40 +34,40 @@ const env = { }; describe('Ingesting coverage', () => { - // const verboseArgs = [ - // 'scripts/ingest_coverage.js', - // '--verbose', - // '--vcsInfoPath', - // 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - // '--path', - // ]; + const verboseArgs = [ + 'scripts/ingest_coverage.js', + '--verbose', + '--vcsInfoPath', + 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', + '--path', + ]; const summaryPath = 'jest-combined/coverage-summary-manual-mix.json'; const resolved = resolve(MOCKS_DIR, summaryPath); - // describe(`staticSiteUrl`, () => { - // let actualUrl = ''; - // const siteUrlRegex = /"staticSiteUrl":\s*(.+,)/; - // - // beforeAll(async () => { - // const opts = [...verboseArgs, resolved]; - // const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - // actualUrl = siteUrlRegex.exec(stdout)[1]; - // }); - // - // it('should contain the static host', () => { - // const staticHost = /https:\/\/kibana-coverage\.elastic\.dev/; - // expect(staticHost.test(actualUrl)).ok(); - // }); - // it('should contain the timestamp', () => { - // const timeStamp = /\d{4}-\d{2}-\d{2}T\d{2}.*\d{2}.*\d{2}Z/; - // expect(timeStamp.test(actualUrl)).ok(); - // }); - // it('should contain the folder structure', () => { - // const folderStructure = /(?:.*|.*-combined)\//; - // expect(folderStructure.test(actualUrl)).ok(); - // }); - // }); + describe(`staticSiteUrl`, () => { + let actualUrl = ''; + const siteUrlRegex = /"staticSiteUrl":\s*(.+,)/; + + beforeAll(async () => { + const opts = [...verboseArgs, resolved]; + const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); + actualUrl = siteUrlRegex.exec(stdout)[1]; + }); + + it('should contain the static host', () => { + const staticHost = /https:\/\/kibana-coverage\.elastic\.dev/; + expect(staticHost.test(actualUrl)).ok(); + }); + it('should contain the timestamp', () => { + const timeStamp = /\d{4}-\d{2}-\d{2}T\d{2}.*\d{2}.*\d{2}Z/; + expect(timeStamp.test(actualUrl)).ok(); + }); + it('should contain the folder structure', () => { + const folderStructure = /(?:.*|.*-combined)\//; + expect(folderStructure.test(actualUrl)).ok(); + }); + }); describe(`vcsInfo`, () => { describe(`without a commit msg in the vcs info file`, () => { @@ -92,34 +92,35 @@ describe('Ingesting coverage', () => { }); }); }); - // describe(`team assignment`, () => { - // const args = [ - // 'scripts/ingest_coverage.js', - // '--verbose', - // '--vcsInfoPath', - // 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - // '--path', - // ]; - // const teamAssignRE = /pipeline:/; - // - // it(`should not occur when going to the totals index`, async () => { - // const shouldNotHavePipelineOut = await prokJustTotalOrNot(true, args); - // const actual = teamAssignRE.test(shouldNotHavePipelineOut); - // expect(actual).to.not.be.ok(); - // }); - // it(`should indeed occur when going to the coverage index`, async () => { - // const shouldIndeedHavePipelineOut = await prokJustTotalOrNot(false, args); - // const actual = teamAssignRE.test(shouldIndeedHavePipelineOut); - // expect(actual).to.be.ok(); - // }); - // }); + describe(`team assignment`, () => { + const args = [ + 'scripts/ingest_coverage.js', + '--verbose', + '--vcsInfoPath', + 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', + '--path', + ]; + + it(`should not occur when going to the totals index`, async () => { + const teamAssignRE = /"pipeline":/; + const shouldNotHavePipelineOut = await prokJustTotalOrNot(true, args); + const actual = teamAssignRE.test(shouldNotHavePipelineOut); + expect(actual).to.not.be.ok(); + }); + it(`should indeed occur when going to the coverage index`, async () => { + const shouldIndeedHavePipelineOut = await prokJustTotalOrNot(false, args); + const onlyForTestingRe = /ingest-pipe=>team_assignment/; + const actual = onlyForTestingRe.test(shouldIndeedHavePipelineOut); + expect(actual).to.be.ok(); + }); + }); }); -// async function prokJustTotalOrNot(isTotal, args) { -// const justTotalPath = 'jest-combined/coverage-summary-just-total.json'; -// const notJustTotalPath = 'jest-combined/coverage-summary-manual-mix.json'; -// -// const resolved = resolve(MOCKS_DIR, isTotal ? justTotalPath : notJustTotalPath); -// const opts = [...args, resolved]; -// const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); -// return stdout; -// } +async function prokJustTotalOrNot(isTotal, args) { + const justTotalPath = 'jest-combined/coverage-summary-just-total.json'; + const notJustTotalPath = 'jest-combined/coverage-summary-manual-mix.json'; + + const resolved = resolve(MOCKS_DIR, isTotal ? justTotalPath : notJustTotalPath); + const opts = [...args, resolved]; + const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); + return stdout; +} From e5fe7e0f9ed9d7d46434b2a0996838b5d9270b7e Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Fri, 19 Jun 2020 04:14:03 -0600 Subject: [PATCH 13/18] Fixup code owners, maybe. lol --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e6f6e83253c8bb..28cc58a96ca636 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,6 +132,7 @@ # Quality Assurance /src/dev/code_coverage @elastic/kibana-qa +/vars/kibanaCoverage.groovy @elastic/kibana-qa /test/functional/services/common @elastic/kibana-qa /test/functional/services/lib @elastic/kibana-qa /test/functional/services/remote @elastic/kibana-qa From 88e5b3dfc01fb312276e81d8590c559aea8f7ca7 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Fri, 19 Jun 2020 17:34:36 -0600 Subject: [PATCH 14/18] Fixup code owners, again, maybe. lol --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 28cc58a96ca636..7bec5e262f5238 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,7 +132,7 @@ # Quality Assurance /src/dev/code_coverage @elastic/kibana-qa -/vars/kibanaCoverage.groovy @elastic/kibana-qa +/vars/*Coverage.groovy @elastic/kibana-qa /test/functional/services/common @elastic/kibana-qa /test/functional/services/lib @elastic/kibana-qa /test/functional/services/remote @elastic/kibana-qa From f23634e2c8fc7eacdc25a2f3badf77e6e80ceb8b Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Mon, 29 Jun 2020 11:53:00 -0600 Subject: [PATCH 15/18] Fixup ordinality per Dima --- .../code_coverage/shell_scripts/ingest_coverage.sh | 11 +++++------ vars/kibanaCoverage.groovy | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh index 9233a746a29005..89175094631a55 100644 --- a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh +++ b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh @@ -3,18 +3,17 @@ echo "### Ingesting Code Coverage" echo "" +COVERAGE_JOB_NAME=$1 +export COVERAGE_JOB_NAME +echo "### debug COVERAGE_JOB_NAME: ${COVERAGE_JOB_NAME}" -BUILD_ID=$1 +BUILD_ID=$2 export BUILD_ID -CI_RUN_URL=$2 +CI_RUN_URL=$3 export CI_RUN_URL echo "### debug CI_RUN_URL: ${CI_RUN_URL}" -COVERAGE_JOB_NAME=$3 -export COVERAGE_JOB_NAME -echo "### debug COVERAGE_JOB_NAME: ${COVERAGE_JOB_NAME}" - ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" export ES_HOST diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index ac278d441a36df..8e677e42ec29c9 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -130,7 +130,7 @@ def ingestData(jobName, buildNum, buildUrl, title) { source src/dev/ci_setup/setup_env.sh yarn kbn bootstrap --prefer-offline # Using existing target/kibana-coverage folder - . src/dev/code_coverage/shell_scripts/ingest_coverage.sh ${buildNum} ${buildUrl} ${jobName} + . src/dev/code_coverage/shell_scripts/ingest_coverage.sh ${jobName} ${buildNum} ${buildUrl} """, title) } From 36f70c9d6736d1fb4575e007d67a0c8155c7e0d3 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Mon, 29 Jun 2020 12:13:00 -0600 Subject: [PATCH 16/18] Break up a "heavy" fn, per CR. --- src/dev/code_coverage/ingest_coverage/ingest.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index b4996615a2dc44..43f0663ad0359e 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -74,19 +74,22 @@ async function send(logF, idx, redactedEsHostUrl, client, requestBody) { } } -function logSend(actuallySent) { - return (redactedEsHostUrl) => (log) => (payload) => { - const { index, body } = payload; - log.verbose( - `### ${actuallySent ? 'Sent' : 'Fake Sent'}: +const sendMsg = (actuallySent, redactedEsHostUrl, payload) => { + const { index, body } = payload; + return `### ${actuallySent ? 'Sent' : 'Fake Sent'}: ${redactedEsHostUrl ? `\t### ES Host: ${redactedEsHostUrl}` : ''} \t### Index: ${green(index)} \t### payload.body: ${body} ${process.env.NODE_ENV === 'integration_test' ? `ingest-pipe=>${payload.pipeline}` : ''} -` - ); +`; +}; + +function logSend(actuallySent) { + return (redactedEsHostUrl) => (log) => (payload) => { + log.verbose(sendMsg(actuallySent, redactedEsHostUrl, payload)); }; } + function eitherSendOrNot(payload) { return process.env.NODE_ENV === 'integration_test' ? left(payload) : right(payload); } From 93939bd74c94a890d5c22f99cc9ed164502b6c05 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Tue, 30 Jun 2020 14:00:40 -0600 Subject: [PATCH 17/18] Add a delay of 100 ms as we are overloading the ES queue size. Error: 12:14:44 ### Orig Err: 12:14:44 { 12:14:44 "root_cause": [ 12:14:44 { 12:14:44 "type": "es_rejected_execution_exception", 12:14:44 "reason": "rejected execution of org.elasticsearch.ingest.IngestService$3@373f5932 on EsThreadPoolExecutor[name = instance-0000000015/write, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@759beb77[Running, pool size = 2, active threads = 2, queued tasks = 199, completed tasks = 695890]]" 12:14:44 } --- src/dev/code_coverage/shell_scripts/ingest_coverage.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh index 9a05ea5f639d52..d3cf31fc0f427f 100644 --- a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh +++ b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh @@ -20,6 +20,9 @@ export ES_HOST STATIC_SITE_URL_BASE='https://kibana-coverage.elastic.dev' export STATIC_SITE_URL_BASE +DELAY=100 +export DELAY + for x in jest functional; do echo "### Ingesting coverage for ${x}" From 0f77d09f305b5a9c0e5a2ca7ddce18429891f3d3 Mon Sep 17 00:00:00 2001 From: Tre' Seymour Date: Tue, 30 Jun 2020 14:04:11 -0600 Subject: [PATCH 18/18] Add single quotes around job name and build url, per Brian. --- vars/kibanaCoverage.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index 8e677e42ec29c9..e511d7a8fc15ea 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -130,7 +130,7 @@ def ingestData(jobName, buildNum, buildUrl, title) { source src/dev/ci_setup/setup_env.sh yarn kbn bootstrap --prefer-offline # Using existing target/kibana-coverage folder - . src/dev/code_coverage/shell_scripts/ingest_coverage.sh ${jobName} ${buildNum} ${buildUrl} + . src/dev/code_coverage/shell_scripts/ingest_coverage.sh '${jobName}' ${buildNum} '${buildUrl}' """, title) }