Skip to content

Commit

Permalink
Weight computation improvements, see #88
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanolson committed Jul 8, 2020
1 parent a6f424f commit a5abebe
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 13 deletions.
1 change: 1 addition & 0 deletions js/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module.exports = grunt => {
const server = new ContinuousServer( useRootDir );
server.startServer( port );
server.generateReportLoop();
server.computeWeightsLoop();

if ( snapshot ) {
server.createSnapshotLoop();
Expand Down
48 changes: 37 additions & 11 deletions js/server/ContinuousServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,10 @@ class ContinuousServer {
* @returns {number}
*/
getTestWeight( test ) {
const lastTestedIndex = _.findIndex( this.snapshots, snapshot => {
const snapshotTest = snapshot.findTest( test.names );
return snapshotTest && snapshotTest.results.length > 0;
} );
const lastFailedIndex = _.findIndex( this.snapshots, snapshot => {
const snapshotTest = snapshot.findTest( test.names );
return snapshotTest && _.some( snapshotTest.results, testResult => !testResult.passed );
} );
const snapshotTests = this.snapshots.map( snapshot => snapshot.findTest( test.names ) ).filter( test => !!test );

const lastTestedIndex = _.findIndex( snapshotTests, snapshotTest => snapshotTest.results.length > 0 );
const lastFailedIndex = _.findIndex( snapshotTests, snapshotTest => _.some( snapshotTest.results, testResult => !testResult.passed ) );

let weight = test.priority;

Expand Down Expand Up @@ -387,6 +383,16 @@ class ContinuousServer {
return weight;
}

/**
* Recomputes the desired weights for all recent tests.
* @private
*/
computeRecentTestWeights() {
this.snapshots.slice( 0, 2 ).forEach( snapshot => snapshot.tests.forEach( test => {
test.weight = this.getTestWeight( test );
} ) );
}

/**
* Picks a test based on the tests' relative weights.
* @public
Expand All @@ -397,7 +403,7 @@ class ContinuousServer {
weightedSampleTest( tests ) {
assert( tests.length );

const weights = tests.map( test => this.getTestWeight( test ) );
const weights = tests.map( test => test.weight );
const totalWeight = _.sum( weights );

const cutoffWeight = totalWeight * Math.random();
Expand Down Expand Up @@ -477,6 +483,8 @@ class ContinuousServer {
await snapshot.create( true );

this.snapshots.push( snapshot );

this.computeRecentTestWeights();
}

while ( !this.useRootDir ) {
Expand Down Expand Up @@ -528,6 +536,8 @@ class ContinuousServer {
this.snapshots.pop();
}

this.computeRecentTestWeights();

this.saveToFile();

this.setStatus( 'Removing old snapshot files' );
Expand Down Expand Up @@ -629,9 +639,25 @@ class ContinuousServer {
}
}

/**
* Starts computing weights for tests.
* @public
*/
async computeWeightsLoop() {
while ( true ) { // eslint-disable-line
try {
this.computeRecentTestWeights();
}
catch ( e ) {
this.setError( `weights error: ${e}` );
}

await sleep( 30 * 1000 );
}
}

/**
* Starts generating reports from the available data.
*
* @public
*/
async generateReportLoop() {
Expand Down Expand Up @@ -688,7 +714,7 @@ class ContinuousServer {
for ( const names of testNames ) {
const test = this.snapshots[ 0 ] && this.snapshots[ 0 ].findTest( names );
if ( test ) {
testWeights.push( Math.ceil( this.getTestWeight( test ) * 100 ) / 100 );
testWeights.push( Math.ceil( test.weight * 100 ) / 100 );
}
else {
testWeights.push( 0 );
Expand Down
9 changes: 7 additions & 2 deletions js/server/Snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ class Snapshot {
return new Test( this, description, lastRepoTimestamps[ potentialRepo ] || 0, lastRunnableTimestamps[ potentialRepo ] || 0 );
} );

// @public {Object.<nameString:string,Test>} - ephemeral, we use this.tests for saving things
this.testMap = {};
this.tests.forEach( test => {
this.testMap[ test.nameString ] = test;
} );

this.constructed = true;
}

Expand All @@ -150,8 +156,7 @@ class Snapshot {
* @returns {Test|null}
*/
findTest( names ) {
// TODO: can increase performance with different lookups (e.g. binary?)
return _.find( this.tests, test => _.isEqual( test.names, names ) );
return this.testMap[ Test.namesToNameString( names ) ] || null;
}

/**
Expand Down
17 changes: 17 additions & 0 deletions js/server/Test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class Test {
// @public {Array.<string>}
this.names = description.test;

// @public {string} - Used for faster lookups, single tests, etc. - ephemeral
this.nameString = Test.namesToNameString( this.names );

// @public {string}
this.type = description.type;

Expand All @@ -57,6 +60,9 @@ class Test {
// @public {number}
this.priority = 1;

// @public {number} - ephemeral
this.weight = 1; // a default so things will work in case it isn't immediately set

if ( description.priority ) {
assert( typeof description.priority === 'number', 'priority should be a number' );

Expand Down Expand Up @@ -223,6 +229,17 @@ class Test {
};
}

/**
* Returns a single string from a list of names
* @public
*
* @param {Array.<string>} names
* @returns {string}
*/
static namesToNameString( names ) {
return names.join( '.' );
}

/**
* Creates a pojo-style object for saving/restoring
* @public
Expand Down

0 comments on commit a5abebe

Please sign in to comment.