Skip to content

Commit

Permalink
synchronously wait 20 seconds before testing, #152
Browse files Browse the repository at this point in the history
  • Loading branch information
zepumph committed Nov 2, 2022
1 parent a8ad8b6 commit 06cfefd
Showing 1 changed file with 120 additions and 110 deletions.
230 changes: 120 additions & 110 deletions js/server/QuickServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ class QuickServer {
this.errorMessages = [];
}

// @private
async getStaleReposFrom( reposToCheck ) {
const staleRepos = [];
await Promise.all( reposToCheck.map( async repo => {
if ( await isStale( repo ) ) {
staleRepos.push( repo );
winston.info( `QuickServer: ${repo} stale` );
}
} ) );
return staleRepos;
}

/**
* @public
*/
Expand Down Expand Up @@ -102,141 +114,139 @@ class QuickServer {

try {
const reposToCheck = getRepoList( 'active-repos' ).filter( repo => repo !== 'aqua' );
const staleRepos = [];

// wait 20 seconds before checking for stale repos to give multi-repo pushes a chance to make it in this round
setTimeout( async () => {
winston.info( 'QuickServer: checking stale' );
await Promise.all( reposToCheck.map( async repo => {
if ( await isStale( repo ) ) {
staleRepos.push( repo );
winston.info( `QuickServer: ${repo} stale` );
}
} ) );

const timestamp = Date.now();
let staleRepos = await this.getStaleReposFrom( reposToCheck );

if ( staleRepos.length || forceTests ) {
forceTests = this.isTestMode;
const timestamp = Date.now();

winston.info( `QuickServer: stale repos: ${staleRepos}` );
if ( staleRepos.length || forceTests ) {
forceTests = this.isTestMode;

for ( const repo of staleRepos ) {
winston.info( `QuickServer: pulling ${repo}` );
await gitPull( repo );
}
// don't hold for 20 seconds when forcing.
if ( !forceTests ) {

winston.info( 'QuickServer: cloning missing repos' );
const clonedRepos = await cloneMissingRepos();
// wait 20 seconds before checking for stale repos to give multi-repo pushes a chance to make it in this round
await new Promise( resolve => setTimeout( resolve, 20000 ) );
staleRepos = await this.getStaleReposFrom( reposToCheck );
}

for ( const repo of [ ...staleRepos, ...clonedRepos ] ) {
if ( [ 'chipper', 'perennial', 'perennial-alias' ].includes( repo ) ) {
winston.info( `QuickServer: npm update ${repo}` );
await npmUpdate( repo );
}
}
winston.info( `QuickServer: stale repos: ${staleRepos}` );

winston.info( 'QuickServer: checking SHAs' );
const shas = {};
for ( const repo of reposToCheck ) {
shas[ repo ] = await gitRevParse( repo, 'master' );
}
for ( const repo of staleRepos ) {
winston.info( `QuickServer: pulling ${repo}` );
await gitPull( repo );
}

winston.info( 'QuickServer: linting' );
const lintResult = await execute( gruntCommand, [ 'lint-everything', '--hide-progress-bar' ], `${this.rootDir}/perennial`, { errors: 'resolve' } );
winston.info( 'QuickServer: cloning missing repos' );
const clonedRepos = await cloneMissingRepos();

// Periodically clean chipper/dist, but not on the first time for easier local testing
if ( count++ % 10 === 2 ) {
await deleteDirectory( `${this.rootDir}/chipper/dist` );
for ( const repo of [ ...staleRepos, ...clonedRepos ] ) {
if ( [ 'chipper', 'perennial', 'perennial-alias' ].includes( repo ) ) {
winston.info( `QuickServer: npm update ${repo}` );
await npmUpdate( repo );
}
}

winston.info( 'QuickServer: tsc' );
const tscResult = await execute( '../../node_modules/typescript/bin/tsc', [], `${this.rootDir}/chipper/tsconfig/all`, { errors: 'resolve' } );
winston.info( 'QuickServer: checking SHAs' );
const shas = {};
for ( const repo of reposToCheck ) {
shas[ repo ] = await gitRevParse( repo, 'master' );
}

winston.info( 'QuickServer: transpiling' );
const transpileResult = await execute( 'node', [ 'js/scripts/transpile.js' ], `${this.rootDir}/chipper`, { errors: 'resolve' } );
winston.info( 'QuickServer: linting' );
const lintResult = await execute( gruntCommand, [ 'lint-everything', '--hide-progress-bar' ], `${this.rootDir}/perennial`, { errors: 'resolve' } );

winston.info( 'QuickServer: sim fuzz' );
// Periodically clean chipper/dist, but not on the first time for easier local testing
if ( count++ % 10 === 2 ) {
await deleteDirectory( `${this.rootDir}/chipper/dist` );
}

let simFuzz = null;
try {
await withServer( async port => {
const url = `http://localhost:${port}/natural-selection/natural-selection_en.html?brand=phet&ea&debugger&fuzz`;
const error = await puppeteerLoad( url, puppeteerOptions );
if ( error ) {
simFuzz = error;
}
} );
}
catch( e ) {
simFuzz = e;
}
winston.info( 'QuickServer: tsc' );
const tscResult = await execute( '../../node_modules/typescript/bin/tsc', [], `${this.rootDir}/chipper/tsconfig/all`, { errors: 'resolve' } );

winston.info( 'QuickServer: studio fuzz' );
let studioFuzz = null;
try {
await withServer( async port => {
const url = `http://localhost:${port}/studio/index.html?sim=states-of-matter&phetioElementsDisplay=all&fuzz`;
const error = await puppeteerLoad( url, puppeteerOptions );
if ( error ) {
studioFuzz = error;
}
} );
}
catch( e ) {
studioFuzz = e;
}

const executeResultToOutput = ( result, name ) => {
return {
passed: result.code === 0,
winston.info( 'QuickServer: transpiling' );
const transpileResult = await execute( 'node', [ 'js/scripts/transpile.js' ], `${this.rootDir}/chipper`, { errors: 'resolve' } );

// full length message, used when someone clicks on a quickNode in CT for error details
message: `code: ${result.code}\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`,
winston.info( 'QuickServer: sim fuzz' );

// trimmed down and separated error messages, used to track the state of individual errors and show
// abbreviated errors for the Slack CT Notifier
errorMessages: result.code === 0 ? [] : this.parseErrors( result.stdout, name )
};
};
const fuzzResultToOutput = ( result, name ) => {
if ( result === null ) {
return { passed: true, message: '', errorMessages: [] };
}
else {
return { passed: false, message: '' + result, errorMessages: this.parseErrors( result, name ) };
let simFuzz = null;
try {
await withServer( async port => {
const url = `http://localhost:${port}/natural-selection/natural-selection_en.html?brand=phet&ea&debugger&fuzz`;
const error = await puppeteerLoad( url, puppeteerOptions );
if ( error ) {
simFuzz = error;
}
};
} );
}
catch( e ) {
simFuzz = e;
}

// This would take up too much space
transpileResult.stdout = '';

this.testingState = {
lint: executeResultToOutput( lintResult, ctqType.LINT ),
tsc: executeResultToOutput( tscResult, ctqType.TSC ),
transpile: executeResultToOutput( transpileResult, ctqType.TRANSPILE ),
simFuzz: fuzzResultToOutput( simFuzz, ctqType.SIM_FUZZ ),
studioFuzz: fuzzResultToOutput( studioFuzz, ctqType.STUDIO_FUZZ ),
shas: shas,
timestamp: timestamp
};
winston.info( 'QuickServer: studio fuzz' );
let studioFuzz = null;
try {
await withServer( async port => {
const url = `http://localhost:${port}/studio/index.html?sim=states-of-matter&phetioElementsDisplay=all&fuzz`;
const error = await puppeteerLoad( url, puppeteerOptions );
if ( error ) {
studioFuzz = error;
}
} );
}
catch( e ) {
studioFuzz = e;
}

try {
const broken = !this.testingState.lint.passed ||
!this.testingState.tsc.passed ||
!this.testingState.transpile.passed ||
!this.testingState.simFuzz.passed ||
!this.testingState.studioFuzz.passed;
const executeResultToOutput = ( result, name ) => {
return {
passed: result.code === 0,

await this.reportErrorStatus( broken, lastBroken );
// full length message, used when someone clicks on a quickNode in CT for error details
message: `code: ${result.code}\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`,

lastBroken = broken;
// trimmed down and separated error messages, used to track the state of individual errors and show
// abbreviated errors for the Slack CT Notifier
errorMessages: result.code === 0 ? [] : this.parseErrors( result.stdout, name )
};
};
const fuzzResultToOutput = ( result, name ) => {
if ( result === null ) {
return { passed: true, message: '', errorMessages: [] };
}
catch( e ) {
winston.info( `Slack error: ${e}` );
else {
return { passed: false, message: '' + result, errorMessages: this.parseErrors( result, name ) };
}
};

// This would take up too much space
transpileResult.stdout = '';

this.testingState = {
lint: executeResultToOutput( lintResult, ctqType.LINT ),
tsc: executeResultToOutput( tscResult, ctqType.TSC ),
transpile: executeResultToOutput( transpileResult, ctqType.TRANSPILE ),
simFuzz: fuzzResultToOutput( simFuzz, ctqType.SIM_FUZZ ),
studioFuzz: fuzzResultToOutput( studioFuzz, ctqType.STUDIO_FUZZ ),
shas: shas,
timestamp: timestamp
};

try {
const broken = !this.testingState.lint.passed ||
!this.testingState.tsc.passed ||
!this.testingState.transpile.passed ||
!this.testingState.simFuzz.passed ||
!this.testingState.studioFuzz.passed;

await this.reportErrorStatus( broken, lastBroken );

lastBroken = broken;
}
catch( e ) {
winston.info( `Slack error: ${e}` );
}
}, 20000 );
}
}
catch( e ) {
winston.info( `QuickServer error: ${e}` );
Expand Down

0 comments on commit 06cfefd

Please sign in to comment.