Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress E2E Tests parallelization #3208

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
246d0b3
add sleep for agent heartbeat and a second loadScenario to have the a…
vicenteqa Dec 17, 2024
d8d8ccd
add yaml for parallelization testing purposes
vicenteqa Dec 17, 2024
8ddc6f1
align with master
vicenteqa Dec 17, 2024
0efd1d4
modify yaml name
vicenteqa Dec 17, 2024
00b728c
properly setup cypress-split
vicenteqa Dec 18, 2024
11dc3ce
fix cypress config, left undefined cypress split accidentally
vicenteqa Dec 18, 2024
d596413
add new selector and different assertion for better feedback and debu…
vicenteqa Dec 18, 2024
96789ab
execute hosts_overview tests first to check if that avoids issues
vicenteqa Dec 18, 2024
42d88c6
use specific selector for all cluster statuses
vicenteqa Dec 18, 2024
dbfcb09
modify test execution order in hosts overview
vicenteqa Dec 18, 2024
4f14c66
try running only this test in the CI
vicenteqa Dec 18, 2024
e1d2864
run test isolated to check if issue persists
vicenteqa Dec 18, 2024
9bd31ad
run test isolated to check if issue persists
vicenteqa Dec 18, 2024
c7b3290
try one thread only
vicenteqa Dec 18, 2024
441e1d9
try one thread only
vicenteqa Dec 18, 2024
14ad1c9
modifications on pipeline matrix
vicenteqa Dec 18, 2024
f432f7e
modifications on pipeline matrix
vicenteqa Dec 18, 2024
ce9e2b9
modifications on pipeline matrix
vicenteqa Dec 18, 2024
a9f3c36
redo cypress and check sequential run
vicenteqa Dec 18, 2024
7288119
modify yaml title
vicenteqa Dec 18, 2024
0c50871
run only hosts overview test
vicenteqa Dec 18, 2024
73b76c9
add matrix strategy
vicenteqa Dec 18, 2024
8383884
add split env variables
vicenteqa Dec 18, 2024
7034908
run whole hosts_overview file
vicenteqa Dec 18, 2024
15b9b64
try with all tests and 4 containers
vicenteqa Dec 18, 2024
53c173e
apply changes in CI pipeline and try 6 cores in POC pipeline
vicenteqa Dec 18, 2024
796bb36
add have.text instead of contains for total critical after stopping h…
vicenteqa Dec 18, 2024
530fed5
remove video attachment for tests
vicenteqa Dec 19, 2024
a5993d4
prepare test scenario with photofinish in pipeline to check if it imp…
vicenteqa Dec 19, 2024
7b45b21
try with 6 cores after recent changes
vicenteqa Dec 19, 2024
c472819
try 8 cores
vicenteqa Dec 19, 2024
0ebcfac
remove unnecessary load scenario
vicenteqa Dec 19, 2024
fd242bd
apply changes to main CI pipeline
vicenteqa Dec 19, 2024
a281e3d
align with master
vicenteqa Dec 20, 2024
bc92f77
bring back load scenario lines and remove it from ci to compare execu…
vicenteqa Dec 20, 2024
55bd49b
run photofinish prior to launch cypress tests
vicenteqa Dec 20, 2024
77166ea
add missing awaits
vicenteqa Dec 20, 2024
ca3bfae
revert change in deregister db instance test
vicenteqa Dec 20, 2024
43f967c
revert change critical 29 hosts health
vicenteqa Dec 20, 2024
09a331d
revert have.text vs contain
vicenteqa Dec 20, 2024
72c817d
remove sleep for agent heartbeat
vicenteqa Dec 20, 2024
1075ea7
add delay for start agent heart beat to reduces flakiness in hosts ov…
vicenteqa Dec 20, 2024
4473d68
signing this commit
vicenteqa Dec 20, 2024
7e8446a
run prettier
vicenteqa Dec 20, 2024
40b91b0
fix merge conflicts and adapt photofinish in before test
vicenteqa Dec 24, 2024
fb6973d
remove load photofinish from index.js and implement logic as a comman…
vicenteqa Dec 24, 2024
acd7891
fix eslint
vicenteqa Dec 24, 2024
a5d06dc
refactor to check if test data has already been loaded
vicenteqa Dec 27, 2024
d506731
align with master
vicenteqa Dec 27, 2024
7016a06
add job e2e test that pass if every parallel thread is ok
vicenteqa Dec 27, 2024
a587242
add job e2e test that pass if every parallel thread is ok
vicenteqa Dec 27, 2024
93b1bb8
add job e2e test that pass if every parallel thread is ok
vicenteqa Dec 27, 2024
7d51683
fix job name to match expected check
vicenteqa Dec 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ jobs:
name: End to end tests
needs: [elixir-deps, npm-deps, npm-e2e-deps]
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
containers: [1,2,3,4]
env:
MIX_ENV: dev
steps:
Expand Down Expand Up @@ -427,6 +431,8 @@ jobs:
- name: Cypress run
uses: cypress-io/github-action@v6
env:
SPLIT: ${{ strategy.job-total }}
SPLIT_INDEX: ${{ strategy.job-index }}
cypress_video: false
cypress_db_host: postgres
cypress_db_port: 5432
Expand Down
210 changes: 210 additions & 0 deletions .github/workflows/cypress_parallel_poc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
name: Cypress Parallelization POC

on:
workflow_dispatch:
pull_request:
types: [opened, synchronize]


env:
MIX_ENV: test
NODE_VERSION: "20"
MANTAINERS: '["cdimonaco", "dottorblaster", "janvhs", "nelsonkopliku", "arbulu89","jagabomb","emaksy", "balanza", "gagandeepb"]'
RG_TEST_LABEL: regression
INTEGRATION_TEST_LABEL: integration

jobs:
elixir-deps:
name: Elixir ${{ matrix.mix_env }} dependencies
runs-on: ubuntu-20.04
strategy:
matrix:
include:
- mix_env: dev
- mix_env: test
balanza marked this conversation as resolved.
Show resolved Hide resolved
env:
MIX_ENV: ${{ matrix.mix_env }}
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup
id: setup-elixir
uses: erlef/setup-beam@v1
with:
version-file: .tool-versions
version-type: strict
env:
ImageOS: ubuntu20
- name: Retrieve Cached Dependencies
uses: actions/cache@v4
id: mix-cache
with:
path: |
deps
_build/${{ matrix.mix_env }}
priv/plts
key: ${{ runner.os }}-${{ steps.setup-elixir.outputs.otp-version }}-${{ steps.setup-elixir.outputs.elixir-version }}-${{ hashFiles('mix.lock') }}
- name: Install Dependencies
if: steps.mix-cache.outputs.cache-hit != 'true'
run: |
mkdir -p priv/plts
mix local.rebar --force
mix local.hex --force
mix deps.get
mix deps.compile --warnings-as-errors
mix dialyzer --plt

npm-deps:
name: Npm dependencies
runs-on: ubuntu-20.04
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Retrieve Cached Dependencies
uses: actions/cache@v4
id: npm-cache
with:
path: |
assets/node_modules
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-${{ hashFiles('assets/package-lock.json') }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install NPM dependencies
if: steps.npm-cache.outputs.cache-hit != 'true'
run: cd assets && npm install

npm-e2e-deps:
name: Npm E2E dependencies
runs-on: ubuntu-20.04
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Retrieve Cached Dependencies
uses: actions/cache@v4
id: npm-e2e-cache
with:
path: |
test/e2e/node_modules
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-${{ hashFiles('test/e2e/package-lock.json') }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install E2E NPM dependencies
if: steps.npm-e2e-cache.outputs.cache-hit != 'true'
run: cd test/e2e && npm install

test-e2e:
name: End to end tests
needs: [elixir-deps, npm-deps, npm-e2e-deps]
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
containers: [1,2,3,4,5,6]
env:
MIX_ENV: dev
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
access_token: ${{ github.token }}
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup
id: setup-elixir
uses: erlef/setup-beam@v1
with:
version-file: .tool-versions
version-type: strict
env:
ImageOS: ubuntu20
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Retrieve Cached Dependencies
uses: actions/cache@v4
id: mix-cache
with:
path: |
deps
_build/dev
priv/plts
key: ${{ runner.os }}-${{ steps.setup-elixir.outputs.otp-version }}-${{ steps.setup-elixir.outputs.elixir-version }}-${{ hashFiles('mix.lock') }}
- name: Retrieve NPM Cached Dependencies
uses: actions/cache@v4
id: npm-cache
with:
path: |
assets/node_modules
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-${{ hashFiles('assets/package-lock.json') }}
- name: Retrieve E2E NPM Cached Dependencies
uses: actions/cache@v4
id: npm-e2e-cache
with:
path: |
test/e2e/node_modules
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-${{ hashFiles('test/e2e/package-lock.json') }}
- name: Check Eslint and JS Code Format
run: cd test/e2e && npm run lint && npm run format:check
- name: "Docker compose dependencies"
uses: isbang/compose-action@v2.0.2
with:
compose-file: "./docker-compose.yaml"
down-flags: "--volumes"
- name: Mix setup
run: mix setup
- name: Run trento detached
run: mix phx.server &
- name: Install photofinish
uses: jaxxstorm/action-install-gh-release@v1.14.0
with:
repo: trento-project/photofinish
tag: v1.4.1
cache: enable
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Give executable permissions to photofinish
run: chmod +x $(whereis photofinish | cut -d" " -f2)
- name: Cypress run
uses: cypress-io/github-action@v6
env:
SPLIT: ${{ strategy.job-total }}
SPLIT_INDEX: ${{ strategy.job-index }}
cypress_video: false
cypress_db_host: postgres
cypress_db_port: 5432
cypress_photofinish_binary: $(whereis photofinish | cut -d" " -f2)
with:
working-directory: test/e2e
wait-on-timeout: 30
config: baseUrl=http://localhost:4000
- name: Upload cypress test screenshots
uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-screenshots
path: test/e2e/cypress/screenshots/
1 change: 1 addition & 0 deletions test/e2e/cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = defineConfig({
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config);
},
video: true,
testIsolation: false,
baseUrl: 'http://localhost:4000',
},
Expand Down
26 changes: 20 additions & 6 deletions test/e2e/cypress/e2e/databases_overview.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { createUserRequestFactory } from '@lib/test-utils/factories';
context('Databases Overview', () => {
before(() => {
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.loadScenario('healthy-29-node-SAP-cluster');

cy.visit('/databases');
cy.url().should('include', '/databases');
});
Expand Down Expand Up @@ -59,12 +61,24 @@ context('Databases Overview', () => {
});

it('should not deregister database instances if the SAP system using the database is deregistered', () => {
cy.deregisterHost(nwqSystem.ascsInstance.id);
cy.contains(
'p',
`The SAP System ${nwqSystem.sid} has been deregistered.`
);
cy.get('.table-row-group > div.table-row').should('have.length', 9);
const collapsedTableRowsSelector = '.table-row-group > div.table-row';
cy.get(collapsedTableRowsSelector).then((collapsedTableRows) => {
const amountOfDatabaseInstances = collapsedTableRows.length;

cy.get(collapsedTableRowsSelector).should(
'have.length',
amountOfDatabaseInstances
);
cy.deregisterHost(nwqSystem.ascsInstance.id);
cy.contains(
'p',
`The SAP System ${nwqSystem.sid} has been deregistered.`
);
cy.get(collapsedTableRowsSelector).should(
'have.length',
amountOfDatabaseInstances
);
});
});
});

Expand Down
1 change: 1 addition & 0 deletions test/e2e/cypress/e2e/home.cy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
context('Homepage', () => {
before(() => {
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.visit('/');
cy.url().should('include', '/');
Expand Down
27 changes: 19 additions & 8 deletions test/e2e/cypress/e2e/hosts_overview.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const NEXT_PAGE_SELECTOR = '[aria-label="next-page"]';

context('Hosts Overview', () => {
before(() => {
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.visit('/hosts');
cy.url().should('include', '/hosts');
Expand Down Expand Up @@ -170,11 +171,18 @@ context('Hosts Overview', () => {
});

it('should show health status of the entire cluster of 29 hosts with partial pagination', () => {
cy.get('.tn-health-container .tn-health-passing', {
timeout: 15000,
}).should('contain', 12);
cy.get('.tn-health-container .tn-health-warning').should('contain', 12);
cy.get('.tn-health-container .tn-health-critical').should('contain', 5);
cy.get(
'.tn-health-container .tn-health-passing p[class="font-semibold"]',
{
timeout: 25000,
}
).should('have.text', 12);
cy.get(
'.tn-health-container .tn-health-warning p[class="font-semibold"]'
).should('have.text', 12);
cy.get(
'.tn-health-container .tn-health-critical p[class="font-semibold"]'
).should('have.text', 5);
});

it('should show the correct health on the hosts when the agents are sending the heartbeat', () => {
Expand Down Expand Up @@ -271,9 +279,12 @@ context('Hosts Overview', () => {
});

it('should show health status of the entire cluster of 29 hosts with critical health', () => {
cy.get('.tn-health-container .tn-health-critical', {
timeout: 15000,
}).should('contain', 29);
cy.get(
'.tn-health-container .tn-health-critical p[class="font-semibold',
{
timeout: 20000,
}
).should('have.text', 29);
});

it('should show a critical health on the hosts when the agents are not sending the heartbeat', () => {
Expand Down
1 change: 1 addition & 0 deletions test/e2e/cypress/e2e/sap_systems_overview.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

context('SAP Systems Overview', () => {
before(() => {
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.loadScenario('healthy-29-node-SAP-cluster');
cy.visit('/sap_systems');
cy.url().should('include', '/sap_systems');
Expand Down
20 changes: 13 additions & 7 deletions test/e2e/cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@
*/
// eslint-disable-next-line no-unused-vars

const cypressSplit = require('cypress-split');
const http = require('http');
const webpack = require('@cypress/webpack-preprocessor');
let heartbeatsIntervals = [];

module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
cypressSplit(on, config);
on('task', {
startAgentHeartbeat(agents) {
const { web_api_host, web_api_port, heartbeat_interval } = config.env;
const sleep = (ms = 0) =>
new Promise((resolve) => setTimeout(resolve, ms));
const heartbeat = (agentId) =>
http
.request({
Expand All @@ -37,13 +41,15 @@ module.exports = (on, config) => {
})
.end();

agents.forEach((agentId) => {
heartbeat(agentId);
let interval = setInterval(
() => heartbeat(agentId),
heartbeat_interval
);
heartbeatsIntervals.push(interval);
sleep(500).then(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: ‏Do you think we can better understand why it is needed, to remove it?
Sleeps on arbitrary time spans are often cause of flakiness, as they may depend on the running machine

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of arbitrary waits either and I know they should be avoided as a good practice, for the moment I don't have a conclusive answer tbh but I noticed that with a bit of delay the hosts_overview test flakiness is reduced a lot so I added it as a contingency measure, we can remove it if you want or even we can try the test flakiness tool designed by @gagandeepb then try with and without the arbitrary sleep and compare results.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have an alternative so I guess I must live with it 🤷‍♂️

agents.forEach((agentId) => {
heartbeat(agentId);
let interval = setInterval(
() => heartbeat(agentId),
heartbeat_interval
);
heartbeatsIntervals.push(interval);
});
});
return null;
},
Expand Down
Loading
Loading