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

Refactor performance tests artifacts handling #48684

Merged
merged 32 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dff85c2
Pass test results file path as an env var
WunderBart Mar 2, 2023
2c67257
Use the WP_ARTIFACTS_PATH as results base dir
WunderBart Mar 6, 2023
9d2ecae
tmp: Fail tests to verify if CI uploads artifacts correctly
WunderBart Mar 6, 2023
880bc3e
Fix env var declaration
WunderBart Mar 6, 2023
e23254e
Try defining the artifacts variable in the job config
WunderBart Mar 6, 2023
d8f7333
See if the artifacts upload to correct path
WunderBart Mar 6, 2023
68adfa4
Add workspace root to artifacts path
WunderBart Mar 7, 2023
64e887c
tmp: log out artifacts path
WunderBart Mar 7, 2023
79dc881
tmp: log out node version
WunderBart Mar 7, 2023
2593a77
Pass the variables as args
WunderBart Mar 7, 2023
b3ab0ee
Clean up
WunderBart Mar 7, 2023
335621a
Avoid further path-math and save compiled results json to same folder
WunderBart Mar 7, 2023
ef428f4
Clean up
WunderBart Mar 7, 2023
f2e31bd
Archive perf results for all events
WunderBart Mar 8, 2023
27c4c02
Sort result files by test name rather than branch
WunderBart Mar 8, 2023
f33b7aa
Use existing tests directory path var
WunderBart Mar 8, 2023
23ea28f
Save tmp trace file to the global artifacts folder as well
WunderBart Mar 8, 2023
7f0a37b
Simplify artifact-related utils
WunderBart Mar 9, 2023
5861137
Sort test info logs by suite as well
WunderBart Mar 9, 2023
ad0e335
Remove outdated comment
WunderBart Mar 9, 2023
a844c86
Fix rounds counter info
WunderBart Mar 9, 2023
315ec21
Make file naming even more consistent
WunderBart Mar 9, 2023
c8b652d
Write the env config file with absolute paths instead copying the uti…
WunderBart Mar 10, 2023
4538099
Fix the wp-env config path
WunderBart Mar 10, 2023
7b1b36c
Use `.performance-results.js` suffix
WunderBart Mar 13, 2023
8ac8690
Sanitize branch name to be used as path/filename
WunderBart Mar 13, 2023
7fd97d8
Set the default WP_ARTIFACTS_PATH env variable in test-e2e where othe…
WunderBart Mar 14, 2023
7c86fa4
Fix results path in performance reporter
WunderBart Mar 14, 2023
5751774
Merge remote-tracking branch 'origin' into refactor/perf-test-results…
WunderBart Mar 14, 2023
23b445c
Install testing themes in the correct wp-env context
WunderBart Mar 15, 2023
a53065b
Pass envs to child process instead creating new runner options
WunderBart Mar 15, 2023
1d2cc88
Merge remote-tracking branch 'origin' into refactor/perf-test-results…
WunderBart Mar 16, 2023
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
20 changes: 11 additions & 9 deletions .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
name: Run performance tests
runs-on: ubuntu-latest
if: ${{ github.repository == 'WordPress/gutenberg' }}
env:
WP_ARTIFACTS_PATH: ${{ github.workspace }}/artifacts

steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
Expand All @@ -39,13 +41,6 @@ jobs:
if: github.event_name == 'pull_request'
run: ./bin/plugin/cli.js perf $GITHUB_SHA trunk --tests-branch $GITHUB_SHA

- name: Store performance measurements
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
with:
name: perf-test-results
path: ./__test-results/*.json

- name: Compare performance with current WordPress Core and previous Gutenberg versions
if: github.event_name == 'release'
env:
Expand Down Expand Up @@ -80,6 +75,13 @@ jobs:
run: |
./bin/plugin/cli.js perf $(echo $BRANCHES | tr ',' ' ') --tests-branch $GITHUB_SHA --wp-version "$WP_VERSION"

- name: Archive performance results
if: success()
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
with:
name: performance-results
path: ${{ env.WP_ARTIFACTS_PATH }}/*.performance-results.json

- name: Publish performance results
if: github.event_name == 'push'
env:
Expand All @@ -90,8 +92,8 @@ jobs:

- name: Archive debug artifacts (screenshots, HTML snapshots)
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
if: always()
if: failure()
with:
name: failures-artifacts
path: ./__test-results/artifacts
path: ${{ env.WP_ARTIFACTS_PATH }}
if-no-files-found: ignore
11 changes: 7 additions & 4 deletions bin/log-performance-results.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,25 @@ const [ token, branch, hash, baseHash, timestamp ] = process.argv.slice( 2 );

const resultsFiles = [
{
file: 'post-editor-performance-results.json',
file: 'post-editor.performance-results.json',
metricsPrefix: '',
},
{
file: 'front-end-block-theme-performance-results.json',
file: 'front-end-block-theme.performance-results.json',
metricsPrefix: 'block-theme-',
},
{
file: 'front-end-classic-theme-performance-results.json',
file: 'front-end-classic-theme.performance-results.json',
metricsPrefix: 'classic-theme-',
},
];

const performanceResults = resultsFiles.map( ( { file } ) =>
JSON.parse(
fs.readFileSync( path.join( __dirname, '../' + file ), 'utf8' )
fs.readFileSync(
path.join( process.env.WP_ARTIFACTS_PATH, file ),
'utf8'
)
)
);

Expand Down
113 changes: 66 additions & 47 deletions bin/plugin/commands/performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const {
} = require( '../lib/utils' );
const config = require( '../config' );

const ARTIFACTS_PATH =
process.env.WP_ARTIFACTS_PATH || path.join( process.cwd(), 'artifacts' );

/**
* @typedef WPPerformanceCommandOptions
*
Expand Down Expand Up @@ -193,38 +196,22 @@ function curateResults( testSuite, results ) {
* @return {Promise<WPPerformanceResults>} Performance results for the branch.
*/
async function runTestSuite( testSuite, performanceTestDirectory, runKey ) {
try {
await runShellScript(
`npm run test:performance -- packages/e2e-tests/specs/performance/${ testSuite }.test.js`,
performanceTestDirectory
);
} catch ( error ) {
fs.mkdirSync( './__test-results/artifacts', { recursive: true } );
const artifactsFolder = path.join(
performanceTestDirectory,
'artifacts/'
);
await runShellScript(
'cp -Rv ' + artifactsFolder + ' ' + './__test-results/artifacts/'
);

throw error;
}
const resultsFilename = `${ runKey }.performance-results.json`;

const resultsFile = path.join(
await runShellScript(
`npm run test:performance -- ${ testSuite }`,
performanceTestDirectory,
`packages/e2e-tests/specs/performance/${ testSuite }.test.results.json`
);
fs.mkdirSync( './__test-results', { recursive: true } );
fs.copyFileSync( resultsFile, `./__test-results/${ runKey }.results.json` );
const rawResults = await readJSONFile(
path.join(
performanceTestDirectory,
`packages/e2e-tests/specs/performance/${ testSuite }.test.results.json`
)
{
...process.env,
WP_ARTIFACTS_PATH: ARTIFACTS_PATH,
RESULTS_FILENAME: resultsFilename,
}
);

return curateResults( testSuite, rawResults );
return curateResults(
testSuite,
await readJSONFile( path.join( ARTIFACTS_PATH, resultsFilename ) )
);
}

/**
Expand Down Expand Up @@ -339,15 +326,41 @@ async function runPerformanceTests( branches, options ) {
buildPath
);

await runShellScript(
'cp ' +
path.resolve(
performanceTestDirectory,
'bin/plugin/utils/.wp-env.performance.json'
) +
' ' +
environmentDirectory +
'/.wp-env.json'
// Create the config file for the current env.
fs.writeFileSync(
path.join( environmentDirectory, '.wp-env.json' ),
Copy link
Member

Choose a reason for hiding this comment

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

similar question here about removing performance from the name. when I download these files they lose some inherent linkage to the performance CI job that created them.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was the same before - we were copying the .wp-env.performance.json and renaming it to .wp-env.json, so in this regard nothing has changed. I assumed the default .wp-env.json name is used for the wp-env start script to pick it up without any extra arguments.

JSON.stringify(
{
core: 'WordPress/WordPress',
plugins: [ path.join( environmentDirectory, 'plugin' ) ],
themes: [
path.join(
performanceTestDirectory,
'test/emptytheme'
),
'https://downloads.wordpress.org/theme/twentytwentyone.1.7.zip',
'https://downloads.wordpress.org/theme/twentytwentythree.1.0.zip',
Copy link
Member

Choose a reason for hiding this comment

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

are these things we want to hard-code here in this seemingly independent function? I could easily imagine someone wanting to update the themes and then overlooking these lines…

Copy link
Member Author

@WunderBart WunderBart Mar 21, 2023

Choose a reason for hiding this comment

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

This is only carried over from the .wp-env.performance.json boilerplate file. Hard-coding those here was a solution to an issue described in #49063. In my mind, it was an intermediate solution because those themes should be installed within the tests that use them so that when running tests in isolation (e.g. via npm run test:performance theme-tests), same themes are used as in CI or when we're running locally via the CLI. I would consider this a blocker - I plan to address this in a follow-up PR.

Copy link
Member

Choose a reason for hiding this comment

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

I would consider this a blocker - I plan to address this in a follow-up PR.

if you meant "I would not consider this a blocker" then that sounds good. if not, then I'm confused 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, good catch! Missed the important 'not' there 😅

],
env: {
tests: {
mappings: {
'wp-content/mu-plugins': path.join(
performanceTestDirectory,
'packages/e2e-tests/mu-plugins'
),
'wp-content/plugins/gutenberg-test-plugins':
path.join(
performanceTestDirectory,
'packages/e2e-tests/plugins'
),
},
},
},
},
null,
2
),
'utf8'
);

if ( options.wpVersion ) {
Expand Down Expand Up @@ -404,33 +417,39 @@ async function runPerformanceTests( branches, options ) {

/** @type {Record<string,Record<string, WPPerformanceResults>>} */
const results = {};
const wpEnvPath = path.join(
performanceTestDirectory,
'node_modules/.bin/wp-env'
);

for ( const testSuite of testSuites ) {
results[ testSuite ] = {};
/** @type {Array<Record<string, WPPerformanceResults>>} */
const rawResults = [];
// Alternate three times between branches.
for ( let i = 0; i < TEST_ROUNDS; i++ ) {
const roundInfo = `round ${ i + 1 } of ${ TEST_ROUNDS }`;
log( ` >> Suite: ${ testSuite } (${ roundInfo })` );
rawResults[ i ] = {};
for ( const branch of branches ) {
const sanitizedBranch = sanitizeBranchName( branch );
const runKey = `${ sanitizedBranch }_${ testSuite }_run-${ i }`;
const runKey = `${ testSuite }_${ sanitizedBranch }_run-${ i }`;
// @ts-ignore
const environmentDirectory = branchDirectories[ branch ];
log( ` >> Branch: ${ branch }, Suite: ${ testSuite }` );
log( ' >> Starting the environment.' );
log( ` >> Branch: ${ branch }` );
log( ' >> Starting the environment.' );
await runShellScript(
'../../tests/node_modules/.bin/wp-env start',
`${ wpEnvPath } start`,
environmentDirectory
);
log( ' >> Running the test.' );
log( ' >> Running the test.' );
rawResults[ i ][ branch ] = await runTestSuite(
testSuite,
performanceTestDirectory,
runKey
);
log( ' >> Stopping the environment' );
log( ' >> Stopping the environment' );
await runShellScript(
'../../tests/node_modules/.bin/wp-env stop',
`${ wpEnvPath } stop`,
environmentDirectory
);
}
Expand Down Expand Up @@ -493,9 +512,9 @@ async function runPerformanceTests( branches, options ) {
);
console.table( invertedResult );

const resultsFilename = testSuite + '-performance-results.json';
const resultsFilename = testSuite + '.performance-results.json';
fs.writeFileSync(
path.resolve( __dirname, '../../../', resultsFilename ),
path.join( ARTIFACTS_PATH, resultsFilename ),
JSON.stringify( results[ testSuite ], null, 2 )
);
}
Expand Down
17 changes: 0 additions & 17 deletions bin/plugin/utils/.wp-env.performance.json

This file was deleted.

6 changes: 4 additions & 2 deletions packages/e2e-tests/config/performance-reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ const success = chalk.bold.green;

class PerformanceReporter {
onTestResult( test ) {
const dirname = path.dirname( test.path );
const basename = path.basename( test.path, '.js' );
const filepath = path.join( dirname, basename + '.results.json' );
const filepath = path.join(
process.env.WP_ARTIFACTS_PATH,
basename + '.performance-results.json'
);

if ( ! existsSync( filepath ) ) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/**
* External dependencies
* WordPress dependencies
*/
import { basename, join } from 'path';
import { writeFileSync } from 'fs';
import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';

/**
* WordPress dependencies
* Internal dependencies
*/
import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
import { saveResultsFile } from './utils';

describe( 'Front End Performance', () => {
const results = {
Expand All @@ -22,12 +21,8 @@ describe( 'Front End Performance', () => {
} );

afterAll( async () => {
saveResultsFile( __filename, results );
await activateTheme( 'twentytwentyone' );
const resultsFilename = basename( __filename, '.js' ) + '.results.json';
writeFileSync(
join( __dirname, resultsFilename ),
JSON.stringify( results, null, 2 )
);
} );

it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/**
* External dependencies
* WordPress dependencies
*/
import { basename, join } from 'path';
import { writeFileSync } from 'fs';
import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';

/**
* WordPress dependencies
* Internal dependencies
*/
import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
import { saveResultsFile } from './utils';

describe( 'Front End Performance', () => {
const results = {
Expand All @@ -22,11 +21,7 @@ describe( 'Front End Performance', () => {
} );

afterAll( async () => {
const resultsFilename = basename( __filename, '.js' ) + '.results.json';
writeFileSync(
join( __dirname, resultsFilename ),
JSON.stringify( results, null, 2 )
);
saveResultsFile( __filename, results );
} );

it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
Expand Down
Loading