From df76d1c5b1172516d8b68312ad6ff5d371cc7185 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 08:55:36 -0500 Subject: [PATCH 01/26] add new fixture --- .../unit/sources/fixtures/graphqlFixtures.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts index 6081ba8e5c68..eb3bd662caae 100644 --- a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts +++ b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts @@ -49,6 +49,27 @@ export const FAKE_PROJECT_NO_RUNS = { data: { cloudProjectBySlug: { __typename: export const FAKE_PROJECT_ONE_RUNNING_RUN = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 1, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[0] } }] } } } -export const FAKE_PROJECT_MULTIPLE_COMPLETED = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }] } } } +export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC = { + data: { + cloudProjectBySlug: { + __typename: 'CloudProject', + current: { + runNumber: 1, + status: 'RUNNING', + specs: [{ + 'groupIds': [ + 'Q2xvdWRSdW5Hcm91cDo2Njg4MzkyNjpsaW51eC1FbGVjdHJvbi0xMDYtZjlkOGIzNjdiNQ==', + ], + 'status': 'PASSED', + '__typename': 'CloudSpecRun', + }], + }, + }, + }, +} + +export const FAKE_PROJECT_MULTIPLE_COMPLETED = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [ + { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }, +] } } } export const FAKE_PROJECT_MULTIPLE_COMPLETED_PLUS_RUNNING = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 5, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[2] } }, { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }] } } } From 06ca95e42d9d8bd10d70f791ee710207536fe8da Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 09:30:42 -0500 Subject: [PATCH 02/26] update comment --- .../data-context/src/sources/RelevantRunSpecsDataSource.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts b/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts index 9b73c8a329ae..bbe863e70dee 100644 --- a/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts +++ b/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts @@ -99,10 +99,8 @@ export class RelevantRunSpecsDataSource { } /** - * Pulls runs from the current Cypress Cloud account and determines which runs are considered: - * - "current" the most recent completed run, or if not found, the most recent running run - * - "next" the most recent running run if a completed run is found - * @param shas list of Git commit shas to query the Cloud with for matching runs + * Pulls the specs that match the relevant run. + * @param runs - the current and (optionally) next relevant run */ async getRelevantRunSpecs (runs: RelevantRun): Promise { const projectSlug = await this.ctx.project.projectId() From 55abda9a99569d01322214d081e350f6a7ce651d Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 09:32:51 -0500 Subject: [PATCH 03/26] add unit test based on current functionality --- .../RelevantRunSpecsDataSource.spec.ts | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts diff --git a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts new file mode 100644 index 000000000000..b1cb0c7ba607 --- /dev/null +++ b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts @@ -0,0 +1,56 @@ +import { expect } from 'chai' +import sinon from 'sinon' + +import { DataContext } from '../../../src' +import { createTestDataContext } from '../helper' +import { RelevantRunSpecsDataSource, SPECS_EMPTY_RETURN } from '../../../src/sources' +import { FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC } from './fixtures/graphqlFixtures' + +describe('RelevantRunsDataSource', () => { + let ctx: DataContext + let dataSource: RelevantRunSpecsDataSource + + beforeEach(() => { + ctx = createTestDataContext('open') + dataSource = new RelevantRunSpecsDataSource(ctx) + }) + + describe('specs', () => { + it('returns empty when no specs found', async () => { + const specs = dataSource.specs + + expect(specs).to.eql({}) + }) + + it('returns specs when specs are found', () => { + // TODO + }) + }) + + describe('getRelevantRunSpecs()', async () => { + beforeEach(() => { + sinon.stub(ctx.project, 'projectId').resolves('test123') + }) + + it('returns no specs or statuses when no specs found for run', async () => { + const result = await dataSource.getRelevantRunSpecs({ current: 11111, next: 22222, commitsAhead: 0 }) + + expect(result).to.eql(SPECS_EMPTY_RETURN) + }) + + it('returns specs and statuses when they are found', async () => { + sinon.stub(ctx.cloud, 'executeRemoteGraphQL').resolves(FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC) + + const result = await dataSource.getRelevantRunSpecs({ current: 1, next: null, commitsAhead: 0 }) + + expect(result).to.eql({ + runSpecs: { current: { + completedSpecs: 1, + runNumber: 1, + totalSpecs: 1, + } }, + statuses: { current: 'RUNNING' }, + }) + }) + }) +}) From 97d560ac980a82de1c2aea7f4be971646186d8d9 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 10:02:30 -0500 Subject: [PATCH 04/26] add second test case based on current logic --- .../RelevantRunSpecsDataSource.spec.ts | 28 ++++++++++++- .../unit/sources/fixtures/graphqlFixtures.ts | 42 ++++++++++++++++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts index b1cb0c7ba607..b6383e8be4e3 100644 --- a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts @@ -4,7 +4,7 @@ import sinon from 'sinon' import { DataContext } from '../../../src' import { createTestDataContext } from '../helper' import { RelevantRunSpecsDataSource, SPECS_EMPTY_RETURN } from '../../../src/sources' -import { FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC } from './fixtures/graphqlFixtures' +import { FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS, FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC } from './fixtures/graphqlFixtures' describe('RelevantRunsDataSource', () => { let ctx: DataContext @@ -38,7 +38,7 @@ describe('RelevantRunsDataSource', () => { expect(result).to.eql(SPECS_EMPTY_RETURN) }) - it('returns specs and statuses when they are found', async () => { + it('returns expected specs and statuses when one run is found', async () => { sinon.stub(ctx.cloud, 'executeRemoteGraphQL').resolves(FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC) const result = await dataSource.getRelevantRunSpecs({ current: 1, next: null, commitsAhead: 0 }) @@ -52,5 +52,29 @@ describe('RelevantRunsDataSource', () => { statuses: { current: 'RUNNING' }, }) }) + + it('returns expected specs and statuses when one run is completed and one is running', async () => { + sinon.stub(ctx.cloud, 'executeRemoteGraphQL').resolves(FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS) + + const result = await dataSource.getRelevantRunSpecs({ current: 1, next: null, commitsAhead: 0 }) + + expect(result).to.eql({ + runSpecs: { current: { + completedSpecs: 2, + runNumber: 1, + totalSpecs: 2, + }, + next: { + completedSpecs: 0, + runNumber: 2, + totalSpecs: 0, + }, + }, + statuses: { + current: 'PASSED', + next: 'RUNNING', + }, + }) + }) }) }) diff --git a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts index eb3bd662caae..ba5325e29a82 100644 --- a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts +++ b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts @@ -49,6 +49,12 @@ export const FAKE_PROJECT_NO_RUNS = { data: { cloudProjectBySlug: { __typename: export const FAKE_PROJECT_ONE_RUNNING_RUN = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 1, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[0] } }] } } } +export const FAKE_PROJECT_MULTIPLE_COMPLETED = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [ + { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }, +] } } } + +export const FAKE_PROJECT_MULTIPLE_COMPLETED_PLUS_RUNNING = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 5, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[2] } }, { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }] } } } + export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC = { data: { cloudProjectBySlug: { @@ -58,7 +64,7 @@ export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC = { status: 'RUNNING', specs: [{ 'groupIds': [ - 'Q2xvdWRSdW5Hcm91cDo2Njg4MzkyNjpsaW51eC1FbGVjdHJvbi0xMDYtZjlkOGIzNjdiNQ==', + '1', ], 'status': 'PASSED', '__typename': 'CloudSpecRun', @@ -68,8 +74,32 @@ export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC = { }, } -export const FAKE_PROJECT_MULTIPLE_COMPLETED = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [ - { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }, -] } } } - -export const FAKE_PROJECT_MULTIPLE_COMPLETED_PLUS_RUNNING = { data: { cloudProjectBySlug: { __typename: 'CloudProject', runsByCommitShas: [{ runNumber: 5, status: 'RUNNING', commitInfo: { sha: FAKE_SHAS[2] } }, { runNumber: 4, status: 'FAILED', commitInfo: { sha: FAKE_SHAS[1] } }, { runNumber: 1, status: 'PASSED', commitInfo: { sha: FAKE_SHAS[0] } }] } } } +export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS = { + data: { + cloudProjectBySlug: { + __typename: 'CloudProject', + current: { + runNumber: 1, + status: 'PASSED', + specs: [{ + 'groupIds': [ + '1', '2', + ], + 'status': 'PASSED', + '__typename': 'CloudSpecRun', + }], + }, + next: { + runNumber: 2, + status: 'RUNNING', + specs: [{ + 'groupIds': [ + '3', '4', '5', + ], + 'status': 'PENDING', + '__typename': 'CloudSpecRun', + }], + }, + }, + }, +} From cd88393e9bd6a2fe00a5d85837305398d9e314d8 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 10:59:03 -0500 Subject: [PATCH 05/26] update test --- .../test/unit/sources/RelevantRunSpecsDataSource.spec.ts | 2 +- .../data-context/test/unit/sources/fixtures/graphqlFixtures.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts index b6383e8be4e3..bdda843973b2 100644 --- a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts @@ -67,7 +67,7 @@ describe('RelevantRunsDataSource', () => { next: { completedSpecs: 0, runNumber: 2, - totalSpecs: 0, + totalSpecs: 3, }, }, statuses: { diff --git a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts index ba5325e29a82..d977588e0482 100644 --- a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts +++ b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts @@ -96,7 +96,7 @@ export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS = { 'groupIds': [ '3', '4', '5', ], - 'status': 'PENDING', + 'status': 'UNCLAIMED', '__typename': 'CloudSpecRun', }], }, From 5ae892f4e0ed9a8e1adcf4ea8af987f5b5ebe690 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 11:26:28 -0500 Subject: [PATCH 06/26] [run ci] switch to new fields --- .../src/sources/RelevantRunSpecsDataSource.ts | 36 +++++++------------ .../RelevantRunSpecsDataSource.spec.ts | 12 +++---- .../unit/sources/fixtures/graphqlFixtures.ts | 29 ++++----------- 3 files changed, 26 insertions(+), 51 deletions(-) diff --git a/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts b/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts index bbe863e70dee..11ecf586b132 100644 --- a/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts +++ b/packages/data-context/src/sources/RelevantRunSpecsDataSource.ts @@ -4,7 +4,7 @@ import debugLib from 'debug' import { isEqual } from 'lodash' import type { DataContext } from '../DataContext' -import type { CloudSpecStatus, Query, RelevantRun, CurrentProjectRelevantRunSpecs, CloudSpecRun, CloudRun } from '../gen/graphcache-config.gen' +import type { Query, RelevantRun, CurrentProjectRelevantRunSpecs, CloudRun } from '../gen/graphcache-config.gen' import { Poller } from '../polling' import type { CloudRunStatus } from '@packages/graphql/src/gen/cloud-source-types.gen' @@ -55,8 +55,6 @@ export const SPECS_EMPTY_RETURN: RunSpecReturn = { statuses: {}, } -const INCOMPLETE_STATUSES: CloudSpecStatus[] = ['RUNNING', 'UNCLAIMED'] - export type RunSpecReturn = { runSpecs: CurrentProjectRelevantRunSpecs statuses: { @@ -86,18 +84,6 @@ export class RelevantRunSpecsDataSource { return this.#cached.runSpecs } - #calculateSpecMetadata (specs: CloudSpecRun[]) { - //mimic logic in Cloud to sum up the count of groups per spec to give the total spec counts - const countGroupsForSpec = (specs: CloudSpecRun[]) => { - return specs.map((spec) => spec.groupIds?.length || 0).reduce((acc, curr) => acc += curr, 0) - } - - return { - totalSpecs: countGroupsForSpec(specs), - completedSpecs: countGroupsForSpec(specs.filter((spec) => !INCOMPLETE_STATUSES.includes(spec.status || 'UNCLAIMED'))), - } - } - /** * Pulls the specs that match the relevant run. * @param runs - the current and (optionally) next relevant run @@ -151,22 +137,26 @@ export class RelevantRunSpecsDataSource { statuses: {}, } - if (cloudProject.current && cloudProject.current.runNumber && cloudProject.current.status) { + const { current, next } = cloudProject + + if (current && current.runNumber && current.status) { runSpecsToReturn.runSpecs.current = { - ...this.#calculateSpecMetadata(cloudProject.current.specs || []), - runNumber: cloudProject.current.runNumber, + totalSpecs: current.totalInstanceCount, + completedSpecs: current.completedInstanceCount, + runNumber: current.runNumber, } - runSpecsToReturn.statuses.current = cloudProject.current.status + runSpecsToReturn.statuses.current = current.status } - if (cloudProject.next && cloudProject.next.runNumber && cloudProject.next.status) { + if (next && next.runNumber && next.status) { runSpecsToReturn.runSpecs.next = { - ...this.#calculateSpecMetadata(cloudProject.next.specs || []), - runNumber: cloudProject.next.runNumber, + totalSpecs: next.totalInstanceCount, + completedSpecs: next.completedInstanceCount, + runNumber: next.runNumber, } - runSpecsToReturn.statuses.next = cloudProject.next.status + runSpecsToReturn.statuses.next = next.status } return runSpecsToReturn diff --git a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts index bdda843973b2..88bda953160a 100644 --- a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts @@ -4,7 +4,7 @@ import sinon from 'sinon' import { DataContext } from '../../../src' import { createTestDataContext } from '../helper' import { RelevantRunSpecsDataSource, SPECS_EMPTY_RETURN } from '../../../src/sources' -import { FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS, FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC } from './fixtures/graphqlFixtures' +import { FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_THREE_SPECS, FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC } from './fixtures/graphqlFixtures' describe('RelevantRunsDataSource', () => { let ctx: DataContext @@ -45,8 +45,8 @@ describe('RelevantRunsDataSource', () => { expect(result).to.eql({ runSpecs: { current: { - completedSpecs: 1, runNumber: 1, + completedSpecs: 1, totalSpecs: 1, } }, statuses: { current: 'RUNNING' }, @@ -54,19 +54,19 @@ describe('RelevantRunsDataSource', () => { }) it('returns expected specs and statuses when one run is completed and one is running', async () => { - sinon.stub(ctx.cloud, 'executeRemoteGraphQL').resolves(FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS) + sinon.stub(ctx.cloud, 'executeRemoteGraphQL').resolves(FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_THREE_SPECS) const result = await dataSource.getRelevantRunSpecs({ current: 1, next: null, commitsAhead: 0 }) expect(result).to.eql({ runSpecs: { current: { - completedSpecs: 2, runNumber: 1, - totalSpecs: 2, + completedSpecs: 3, + totalSpecs: 3, }, next: { - completedSpecs: 0, runNumber: 2, + completedSpecs: 0, totalSpecs: 3, }, }, diff --git a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts index d977588e0482..05b49fb5963b 100644 --- a/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts +++ b/packages/data-context/test/unit/sources/fixtures/graphqlFixtures.ts @@ -61,44 +61,29 @@ export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_SPEC = { __typename: 'CloudProject', current: { runNumber: 1, + completedInstanceCount: 1, + totalInstanceCount: 1, status: 'RUNNING', - specs: [{ - 'groupIds': [ - '1', - ], - 'status': 'PASSED', - '__typename': 'CloudSpecRun', - }], }, }, }, } -export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_TWO_SPECS = { +export const FAKE_PROJECT_ONE_RUNNING_RUN_ONE_COMPLETED_THREE_SPECS = { data: { cloudProjectBySlug: { __typename: 'CloudProject', current: { runNumber: 1, status: 'PASSED', - specs: [{ - 'groupIds': [ - '1', '2', - ], - 'status': 'PASSED', - '__typename': 'CloudSpecRun', - }], + completedInstanceCount: 3, + totalInstanceCount: 3, }, next: { runNumber: 2, status: 'RUNNING', - specs: [{ - 'groupIds': [ - '3', '4', '5', - ], - 'status': 'UNCLAIMED', - '__typename': 'CloudSpecRun', - }], + completedInstanceCount: 0, + totalInstanceCount: 3, }, }, }, From 89cbf00c427829ec01ea97faf58fa642675e593d Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 13:23:51 -0500 Subject: [PATCH 07/26] run ci From 75c030fcd275a3d290cb3e4d06482636f4a166b4 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Mon, 6 Feb 2023 15:30:10 -0500 Subject: [PATCH 08/26] accept runNumber arg in relevantRunSpecChange --- .../src/schemaTypes/objectTypes/gql-Subscription.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts index d7df835681aa..07ed3611ebb1 100644 --- a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts +++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts @@ -1,5 +1,5 @@ import type { PushFragmentData } from '@packages/data-context/src/actions' -import { enumType, list, nonNull, objectType, stringArg, subscriptionType } from 'nexus' +import { enumType, list, nonNull, objectType, stringArg, subscriptionType, intArg } from 'nexus' import { CurrentProject, DevState, Query } from '.' import { Spec } from './gql-Spec' import { RelevantRun } from './gql-RelevantRun' @@ -145,9 +145,12 @@ export const Subscription = subscriptionType({ t.field('relevantRunSpecChange', { type: Query, - description: 'Subscription that watches for a relevant run to the debug page to be RUNNING and returns updated spec counts until complete', + description: 'Subscription that watches for a specific run to the debug page to be RUNNING and returns updated spec counts until complete', + args: { + runNumber: nonNull(intArg()), + }, subscribe: (source, args, ctx) => { - return ctx.relevantRunSpecs.pollForSpecs() + return ctx.relevantRunSpecs.pollForSpecs(args.runNumber) }, resolve: async (root, args, ctx) => { return { From 174e5f1220fb242661459504f75f7c574902dbec Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Wed, 8 Feb 2023 17:07:41 -0500 Subject: [PATCH 09/26] formatting --- .../RelevantRunSpecsDataSource.spec.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts index 88bda953160a..7fb2e72dce30 100644 --- a/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/RelevantRunSpecsDataSource.spec.ts @@ -59,16 +59,17 @@ describe('RelevantRunsDataSource', () => { const result = await dataSource.getRelevantRunSpecs({ current: 1, next: null, commitsAhead: 0 }) expect(result).to.eql({ - runSpecs: { current: { - runNumber: 1, - completedSpecs: 3, - totalSpecs: 3, - }, - next: { - runNumber: 2, - completedSpecs: 0, - totalSpecs: 3, - }, + runSpecs: { + current: { + runNumber: 1, + completedSpecs: 3, + totalSpecs: 3, + }, + next: { + runNumber: 2, + completedSpecs: 0, + totalSpecs: 3, + }, }, statuses: { current: 'PASSED', From e502f2119f6fe7ec808866e5865e3b0775297b8a Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Wed, 8 Feb 2023 17:25:39 -0500 Subject: [PATCH 10/26] revert runNumber arg --- .../src/schemaTypes/objectTypes/gql-Subscription.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts index 07ed3611ebb1..d7df835681aa 100644 --- a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts +++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts @@ -1,5 +1,5 @@ import type { PushFragmentData } from '@packages/data-context/src/actions' -import { enumType, list, nonNull, objectType, stringArg, subscriptionType, intArg } from 'nexus' +import { enumType, list, nonNull, objectType, stringArg, subscriptionType } from 'nexus' import { CurrentProject, DevState, Query } from '.' import { Spec } from './gql-Spec' import { RelevantRun } from './gql-RelevantRun' @@ -145,12 +145,9 @@ export const Subscription = subscriptionType({ t.field('relevantRunSpecChange', { type: Query, - description: 'Subscription that watches for a specific run to the debug page to be RUNNING and returns updated spec counts until complete', - args: { - runNumber: nonNull(intArg()), - }, + description: 'Subscription that watches for a relevant run to the debug page to be RUNNING and returns updated spec counts until complete', subscribe: (source, args, ctx) => { - return ctx.relevantRunSpecs.pollForSpecs(args.runNumber) + return ctx.relevantRunSpecs.pollForSpecs() }, resolve: async (root, args, ctx) => { return { From 97131cfa9e24acfa9b500c5ea693560395c72597 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Wed, 8 Feb 2023 17:27:05 -0500 Subject: [PATCH 11/26] commit updated graphql files --- packages/graphql/schemas/cloud.graphql | 40 +++++++++++++++++++++++++ packages/graphql/schemas/schema.graphql | 40 +++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/packages/graphql/schemas/cloud.graphql b/packages/graphql/schemas/cloud.graphql index 0dae909ab716..cb87eade366f 100644 --- a/packages/graphql/schemas/cloud.graphql +++ b/packages/graphql/schemas/cloud.graphql @@ -347,6 +347,16 @@ type CloudProjectSpec implements Node { """ fromBranch: String! ): Float + + """ + Average duration the spec takes to run within the context of the provided CloudRun ids. + """ + averageDurationForRunIds( + """ + The ids for the CloudRuns to use to derive the average duration. When provided, the fromBranch argument is ignored, as the provided run ids define the search space. + """ + cloudRunIds: [ID!]! + ): Float flakyStatus( """ The number of runs to consider when counting flaky runs. @@ -359,6 +369,16 @@ type CloudProjectSpec implements Node { fromBranch: String! ): CloudProjectSpecFlakyResult + """ + The flaky metadata for the spec within the context of the provided CloudRun ids. + """ + flakyStatusForRunIds( + """ + The ids for the CloudRuns, ordered from most to least relevant, to use to derive the flaky status. + """ + cloudRunIds: [ID!]! + ): CloudProjectSpecFlakyResult + """ Globally unique identifier representing a concrete GraphQL ObjectType """ @@ -370,6 +390,16 @@ type CloudProjectSpec implements Node { fromBranch: String! ): Boolean + """ + Indicator that a spec is considered flaky within the context of the provided CloudRun ids. + """ + isConsideredFlakyForRunIds( + """ + The ids for the CloudRuns to use to derive the flake indicator. When provided, the fromBranch argument is ignored, as the provided run ids define the search space. + """ + cloudRunIds: [ID!]! + ): Boolean + """ Current DateTime on the server. Used in connection with CloudLatestRunUpdateSpecData. """ @@ -445,6 +475,16 @@ type CloudProjectSpecFlakyStatus { The last flaky run occurrence, interpreted as "n runs ago" - ex: a value of 5 means a flaky run last occurred 5 runs ago """ lastFlaky: Int + + """ + The associated commit_sha of the CloudRun containing the most recent flaky occurrence of the spec. + """ + lastFlakyRunCommitSha: String + + """ + The run number of the CloudRun containing the most recent flaky occurrence of the spec. + """ + lastFlakyRunNumber: Int severity: String } diff --git a/packages/graphql/schemas/schema.graphql b/packages/graphql/schemas/schema.graphql index c9a8cbf62921..7bcb71e19872 100644 --- a/packages/graphql/schemas/schema.graphql +++ b/packages/graphql/schemas/schema.graphql @@ -311,6 +311,16 @@ type CloudProjectSpec implements Node { """ fromBranch: String! ): Float + + """ + Average duration the spec takes to run within the context of the provided CloudRun ids. + """ + averageDurationForRunIds( + """ + The ids for the CloudRuns to use to derive the average duration. When provided, the fromBranch argument is ignored, as the provided run ids define the search space. + """ + cloudRunIds: [ID!]! + ): Float flakyStatus( """The number of runs to consider when counting flaky runs.""" flakyRunsWindow: Int! @@ -321,6 +331,16 @@ type CloudProjectSpec implements Node { fromBranch: String! ): CloudProjectSpecFlakyResult + """ + The flaky metadata for the spec within the context of the provided CloudRun ids. + """ + flakyStatusForRunIds( + """ + The ids for the CloudRuns, ordered from most to least relevant, to use to derive the flaky status. + """ + cloudRunIds: [ID!]! + ): CloudProjectSpecFlakyResult + """Globally unique identifier representing a concrete GraphQL ObjectType""" id: ID! isConsideredFlaky( @@ -328,6 +348,16 @@ type CloudProjectSpec implements Node { fromBranch: String! ): Boolean + """ + Indicator that a spec is considered flaky within the context of the provided CloudRun ids. + """ + isConsideredFlakyForRunIds( + """ + The ids for the CloudRuns to use to derive the flake indicator. When provided, the fromBranch argument is ignored, as the provided run ids define the search space. + """ + cloudRunIds: [ID!]! + ): Boolean + """ Current DateTime on the server. Used in connection with CloudLatestRunUpdateSpecData. """ @@ -380,6 +410,16 @@ type CloudProjectSpecFlakyStatus { The last flaky run occurrence, interpreted as "n runs ago" - ex: a value of 5 means a flaky run last occurred 5 runs ago """ lastFlaky: Int + + """ + The associated commit_sha of the CloudRun containing the most recent flaky occurrence of the spec. + """ + lastFlakyRunCommitSha: String + + """ + The run number of the CloudRun containing the most recent flaky occurrence of the spec. + """ + lastFlakyRunNumber: Int severity: String } From 6ec7f8786f54af5d83cf6c596baeab6985770520 Mon Sep 17 00:00:00 2001 From: Mark Noonan Date: Wed, 8 Feb 2023 21:02:26 -0500 Subject: [PATCH 12/26] update conditional logic and test --- packages/app/src/debug/DebugContainer.cy.tsx | 47 ++++++++++++++++++++ packages/app/src/debug/DebugContainer.vue | 10 ++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/app/src/debug/DebugContainer.cy.tsx b/packages/app/src/debug/DebugContainer.cy.tsx index 0a995496efe8..797b029faad5 100644 --- a/packages/app/src/debug/DebugContainer.cy.tsx +++ b/packages/app/src/debug/DebugContainer.cy.tsx @@ -241,6 +241,8 @@ describe('', () => { result.currentProject.cloudProject.runByNumber = { ...CloudRunStubs.running, runNumber: 1, + completedInstanceCount: 2, + totalInstanceCount: 3, } as typeof test } }, @@ -255,6 +257,51 @@ describe('', () => { }) }) + it('does not render DebugPendingRunSplash and DebugNewRelevantRunBar at the same time', () => { + cy.mountFragment(DebugSpecsFragmentDoc, { + variableTypes: DebugSpecVariableTypes, + variables: { + hasNextRun: false, + runNumber: 1, + nextRunNumber: -1, + }, + onResult: (result) => { + if (result.currentProject?.cloudProject?.__typename === 'CloudProject') { + const test = result.currentProject.cloudProject.runByNumber + + // Testing this to confirm we are "making impossible states impossible" in the UI, + // and document the expectation in this scenario. For clarity, + // we do not expect a 'RUNNING` current and next run at the same time, so + // the data below represents an invalid state. + + result.currentProject.cloudProject.runByNumber = { + ...CloudRunStubs.running, + runNumber: 1, + completedInstanceCount: 2, + totalInstanceCount: 3, + } as typeof test + + result.currentProject.cloudProject.nextRun = { + ...CloudRunStubs.running, + runNumber: 1, + completedInstanceCount: 5, + totalInstanceCount: 6, + } as typeof test + } + }, + render: (gqlVal) => , + }) + + cy.findByTestId('debug-header').should('be.visible') + cy.findByTestId('debug-pending-splash') + .should('be.visible') + .within(() => { + cy.findByTestId('debug-pending-counts').should('have.text', '0 of 0 specs completed') + }) + + cy.findByTestId('newer-relevant-run').should('not.exist') + }) + it('renders specs and tests when completed run available', () => { cy.mountFragment(DebugSpecsFragmentDoc, { variableTypes: DebugSpecVariableTypes, diff --git a/packages/app/src/debug/DebugContainer.vue b/packages/app/src/debug/DebugContainer.vue index 6c5371a005da..01cbacbdc756 100644 --- a/packages/app/src/debug/DebugContainer.vue +++ b/packages/app/src/debug/DebugContainer.vue @@ -28,15 +28,15 @@ :gql="run" :commits-ahead="props.commitsAhead" /> - - + +