1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-20 00:08:02 +01:00

task: Add Unit test result check task (#3695)

After a Team Retro, one of our squads felt like we needed more data on
our test suites. This is the first effort to make our test results
easier to grab. It uses the test-reporter action to add a github check
to our main build and PR builds with our test results.

This at least should make it easier to parse which tests are failing.
However, it does not give us trends. So it does not yet make it easier
to decide which tests are flaky just from a quick view.

---------

Co-authored-by: Gastón Fournier <gaston@getunleash.io>
This commit is contained in:
Christopher Kolstad 2023-05-25 13:03:54 +02:00 committed by GitHub
parent 417b335be6
commit 3409b0c5a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 135 additions and 9 deletions

View File

@ -41,7 +41,7 @@ jobs:
- run: yarn
- run: yarn build:frontend
- run: yarn lint
- run: yarn run test
- run: yarn run test:report # This adds test results as github check to the workflow
env:
CI: true
TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

View File

@ -20,4 +20,3 @@ jobs:
- run: yarn install --frozen-lockfile --ignore-scripts
- run: yarn lint
- run: yarn build:backend
#- run: yarn build:frontend # not needed

View File

@ -0,0 +1,45 @@
name: TestReport
on:
pull_request:
paths-ignore:
- website/**
- coverage/**
jobs:
testreport:
runs-on: ubuntu-latest
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
# Set health checks to wait until postgres has started
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v3
- name: Use Node.js 18
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'
- run: yarn install --frozen-lockfile --ignore-scripts
- run: yarn build:backend
- run: yarn test:report
env:
CI: true
TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
- name: Upload test report to build # Done this way since external PRs would not be able to write the check. See https://github.com/marketplace/actions/test-reporter#recommended-setup-for-public-repositories
uses: actions/upload-artifact@v3
if: success() || failure()
with:
name: test-results
path: ./reports/jest-junit.xml

View File

@ -0,0 +1,16 @@
name: 'Attach Test report'
on:
workflow_run:
workflows: [TestReport]
types:
- completed
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: dorny/test-reporter@v1
with:
artifact: test-results # artifact name
name: Unit Tests # Name of the check run which will be created
path: '*.xml' # Path to test results (inside artifact .zip)
reporter: jest-junit

1
.gitignore vendored
View File

@ -56,3 +56,4 @@ frontend/build
# Generated docs
website/docs/reference/api/**/sidebar.js
website/docs/generated
reports/jest-junit.xml

View File

@ -50,6 +50,7 @@
"test": "NODE_ENV=test PORT=4243 jest",
"test:unit": "NODE_ENV=test PORT=4243 jest --testPathIgnorePatterns=src/test/e2e --testPathIgnorePatterns=dist",
"test:docker": "./scripts/docker-postgres.sh",
"test:report": "NODE_ENV=test PORT=4243 jest --reporters=\"default\" --reporters=\"jest-junit\"",
"test:docker:cleanup": "docker rm -f unleash-postgres",
"test:watch": "yarn test --watch",
"test:coverage": "NODE_ENV=test PORT=4243 jest --coverage --testLocationInResults --outputFile=\"coverage/report.json\" --forceExit --testTimeout=10000",
@ -61,6 +62,16 @@
"preversion": "./scripts/check-release.sh",
"heroku-postbuild": "cd frontend && yarn && yarn build"
},
"jest-junit": {
"suiteName": "Unleash Unit Tests",
"outputDirectory": "./reports",
"outputName": "jest-junit.xml",
"uniqueOutputName": "false",
"classNameTemplate": "{classname}-{title}",
"titleTemplate": "{classname}-{title}",
"ancestorSeparator": " ",
"usePathForSuiteName": "true"
},
"jest": {
"automock": false,
"maxWorkers": 4,
@ -193,6 +204,7 @@
"fetch-mock": "9.11.0",
"husky": "8.0.3",
"jest": "29.5.0",
"jest-junit": "^16.0.0",
"lint-staged": "13.2.2",
"nock": "13.3.1",
"openapi-enforcer": "1.22.3",

View File

@ -149,6 +149,7 @@ exports[`should create default config 1`] = `
"preHook": undefined,
"preRouterHook": undefined,
"prometheusApi": undefined,
"publicFolder": undefined,
"secureHeaders": false,
"segmentValuesLimit": 1000,
"server": {

View File

@ -40,7 +40,7 @@ export default async function getApp(
const app = express();
const baseUriPath = config.server.baseUriPath || '';
const publicFolder = findPublicFolder();
const publicFolder = config.publicFolder || findPublicFolder();
let indexHTML = await loadIndexHTML(config, publicFolder);
app.set('trust proxy', true);

View File

@ -497,6 +497,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
clientFeatureCaching,
accessControlMaxAge,
prometheusApi,
publicFolder: options.publicFolder,
};
}

View File

@ -116,6 +116,7 @@ export interface IUnleashOptions {
flagResolver?: IFlagResolver;
accessControlMaxAge?: number;
prometheusApi?: string;
publicFolder?: string;
}
export interface IEmailOption {
@ -203,4 +204,5 @@ export interface IUnleashConfig {
clientFeatureCaching: IClientCachingOption;
accessControlMaxAge: number;
prometheusApi?: string;
publicFolder?: string;
}

View File

@ -17,7 +17,9 @@ export async function loadIndexHTML(
indexHTML = await res.text();
} else {
indexHTML = fs
.readFileSync(path.join(publicFolder, 'index.html'))
.readFileSync(
path.join(config.publicFolder || publicFolder, 'index.html'),
)
.toString();
}

View File

@ -1,10 +1,9 @@
import fs from 'fs';
import path from 'path';
import { rewriteHTML } from './rewriteHTML';
import { findPublicFolder } from './findPublicFolder';
const input = fs
.readFileSync(path.join(findPublicFolder(), 'index.html'))
.readFileSync(path.join(__dirname, '../../test/examples', 'index.html'))
.toString();
test('rewriteHTML substitutes meta tag with existing rewrite value', () => {

View File

@ -11,7 +11,7 @@ export const rewriteHTML = (
const faviconPrefix = cdnPrefix ? 'https://cdn.getunleash.io' : '';
result = result.replace(/::faviconPrefix::/gi, faviconPrefix);
result = result.replace(/::uiFlags::/gi, uiFlags);
result = result.replace(/::uiFlags::/gi, uiFlags || '{}');
result = result.replace(
/\/static/gi,

View File

@ -6,6 +6,7 @@ import {
} from '../../lib/types/option';
import getLogger from '../fixtures/no-logger';
import { createConfig } from '../../lib/create-config';
import path from 'path';
function mergeAll<T>(objects: Partial<T>[]): T {
return merge.all<T>(objects.filter((i) => i));
@ -28,7 +29,8 @@ export function createTestConfig(config?: IUnleashOptions): IUnleashConfig {
embedProxyFrontend: true,
},
},
publicFolder: path.join(__dirname, '../examples'),
};
const options = mergeAll<IUnleashOptions>([testConfig, config]);
const options = mergeAll<IUnleashOptions>([testConfig, config || {}]);
return createConfig(options);
}

View File

@ -104,7 +104,7 @@ test('adding a root role to a group with a project role should fail', async () =
description: 'root_group',
});
stores.accessStore.addGroupToRole(group.id, 1, 'test', 'default');
await stores.accessStore.addGroupToRole(group.id, 1, 'test', 'default');
await expect(() => {
return groupService.updateGroup(

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="::faviconPrefix::/favicon.ico" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="baseUriPath" content="::baseUriPath::" />
<meta name="cdnPrefix" content="::cdnPrefix::" />
<meta name="uiFlags" content="::uiFlags::" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="unleash" />
<title>Unleash</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Sen:wght@400;700;800&display=swap"
rel="stylesheet"
/>
<script type="module" crossorigin src="/static/index-6328a762.js"></script>
<link rel="stylesheet" href="/static/index-66c635eb.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@ -4466,6 +4466,16 @@ jest-haste-map@^29.5.0:
optionalDependencies:
fsevents "^2.3.2"
jest-junit@^16.0.0:
version "16.0.0"
resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-16.0.0.tgz#d838e8c561cf9fdd7eb54f63020777eee4136785"
integrity sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==
dependencies:
mkdirp "^1.0.4"
strip-ansi "^6.0.1"
uuid "^8.3.2"
xml "^1.0.1"
jest-leak-detector@^29.5.0:
version "29.5.0"
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c"
@ -7322,6 +7332,11 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
@ -7485,6 +7500,11 @@ write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
xml@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"