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

Add test cases for perf-x database #1597

Merged
merged 3 commits into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,19 @@ const rimraf = require('rimraf');
const assetSaver = require('../../../lighthouse-core/lib/asset-saver');

class ExperimentDatabase {
constructor(url, config) {
this._url = url;
this._config = config;

constructor() {
this._fsRoot = fs.mkdtempSync(`${__dirname}/experiment-data-`);
this._timeStamps = {};
}

get url() {
return this._url;
}

get config() {
return this._config;
}

get timeStamps() {
return this._timeStamps;
}

get fsRoot() {
return this._fsRoot;
}

/*
* Save experiment data
* @param {!Object} lhFlags
Expand Down
13 changes: 9 additions & 4 deletions lighthouse-cli/performance-experiment/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const PerfXReportGenerator = require('./report/perf-x-report-generator');

let database;
let fallbackReportId;
let url;
let config;
/**
* Start the server with an arbitrary port and open report page in the default browser.
* @param {!Object} params A JSON contains lighthouse parameters
Expand All @@ -46,7 +48,10 @@ let fallbackReportId;
*/
function hostExperiment(params, results) {
return new Promise(resolve => {
database = new ExperimentDatabase(params.url, params.config);
url = params.url;
config = params.config;

database = new ExperimentDatabase();
const id = database.saveData(params.flags, results);
fallbackReportId = id;

Expand Down Expand Up @@ -101,10 +106,10 @@ function reportRequestHandler(request, response) {

const reportsMetadata = Object.keys(database.timeStamps).map(key => {
const generatedTime = database.timeStamps[key];
return {url: database.url, reportHref: `/?id=${key}`, generatedTime};
return {url, reportHref: `/?id=${key}`, generatedTime};
});
reportsMetadata.sort((metadata1, metadata2) => {
return metadata1.generatedTime - metadata2.generatedTime;
return new Date(metadata1.generatedTime) - new Date(metadata2.generatedTime);
});
const reportsCatalog = {reportsMetadata, selectedReportHref: `/?id=${id}`};

Expand Down Expand Up @@ -137,7 +142,7 @@ function rerunRequestHandler(request, response) {
const additionalFlags = JSON.parse(message);
Object.assign(flags, additionalFlags);

lighthouse(database.url, flags, database.config).then(results => {
lighthouse(url, flags, config).then(results => {
results.artifacts = undefined;
const id = database.saveData(flags, results);
response.writeHead(200);
Expand Down
161 changes: 161 additions & 0 deletions lighthouse-cli/test/cli/performance-experiment/database-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

/* eslint-env mocha */
const assert = require('assert');
const fs = require('fs');

const PerfXDatabase = require('../../../performance-experiment/experiment-database/database');
const sampleResults = require('../../../../lighthouse-core/test/results/sample');

describe('Perf-X Database', function() {
let perfXDatabase;
beforeEach(() => perfXDatabase = new PerfXDatabase());
afterEach(() => perfXDatabase.clear());

it('can store and output experiments data', () => {
const dataSets = [
{
flags: {
'blockedUrlPatterns': ['.woff2', '.jpg'],
'disableNetworkThrottling': false
},
results: sampleResults
},
{
flags: {
'blockedUrlPatterns': ['.woff'],
'disableCpuThrottling': true,
'deepReference': {'anObject': {'anArray': ['anElement', 'anotherElement']}}
},
results: {
generatedTime: new Date(2015, 6, 27, 0, 12, 55, 60).toJSON(),
url: 'http://google.com/',
else: 'someData'
}
},
{
flags: {
'blockedUrlPatterns': ['.woff', 'cat.jpg', '*'],
Copy link
Member

Choose a reason for hiding this comment

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

pretty odd we have this mix of camel casing and not in the flags. Why arent the disable flags in camelcase?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

'disableCpuThrottling': false,
'disableDeviceEmulation': true
},
results: {
'generatedTime': new Date(2014, 5, 1, 23, 56, 54, 99).toJSON(),
'url': 'http://mdn.com/',
'audits': [{'is-on-https': {'score': true}}],
}
}
];

dataSets.forEach(dataSet => {
dataSet.key = perfXDatabase.saveData(dataSet.flags, dataSet.results);
});

dataSets.forEach(dataSet => {
assert.deepStrictEqual(perfXDatabase.getFlags(dataSet.key), dataSet.flags);
assert.deepStrictEqual(perfXDatabase.getResults(dataSet.key), dataSet.results);
});
});

it('prevents data from being changed by reference', () => {
const flags = {
'blockedUrlPatterns': ['.woff', '.jpg', 'random'],
'disableCpuThrottling': false,
'randomFlag': 'randomString'
};
const results = JSON.parse(JSON.stringify(sampleResults));

const key = perfXDatabase.saveData(flags, results);
const flagsBeforeChange = JSON.parse(JSON.stringify(perfXDatabase.getFlags(key)));
const resultsBeforeChange = JSON.parse(JSON.stringify(perfXDatabase.getResults(key)));

// data won't be changed when the flags/results passed to perfXDatabase.saveData is changed
flags.blockedUrlPatterns.push('something');
results.url = undefined;

// data won't be changed when the flags/results returned by perfXDatabase is changed
perfXDatabase.getFlags(key).anotherAttribute = 'random value';
perfXDatabase.getResults(key).aggregations.push('new element');

assert.deepStrictEqual(perfXDatabase.getFlags(key), flagsBeforeChange);
assert.deepStrictEqual(perfXDatabase.getResults(key), resultsBeforeChange);
});

it('returns correct timestamps', () => {
const dataSets = [
{
results: sampleResults
},
{
results: {
generatedTime: new Date(2015, 6, 12, 0, 6, 30, 60).toJSON(),
url: 'http://google.com/',
}
},
{
results: {
'generatedTime': new Date(2014, 2, 21, 11, 12, 33, 46).toJSON(),
'url': 'http://mdn.com/',
}
}
];

dataSets.forEach(dataSet => {
dataSet.key = perfXDatabase.saveData({}, dataSet.results);
});

dataSets.forEach(dataSet => {
assert.strictEqual(perfXDatabase.timeStamps[dataSet.key], dataSet.results.generatedTime);
});

assert.strictEqual(Object.keys(perfXDatabase.timeStamps).length, dataSets.length);
});

it('can delete temp folder on request', () => {
const dataSets = [
{
flags: {
'blockedUrlPatterns': ['.css', '.jpg'],
'disableDeviceEmulation': false
},
results: sampleResults
},
{
flags: {
'blockedUrlPatterns': ['.js', '*'],
'disableCpuThrottling': true,
'disableNetworkThrottling': true
},
results: {
'generatedTime': new Date(2015, 7, 23, 23, 56, 54, 99).toJSON(),
'url': 'http://w3school.com/',
'audits': [{'is-on-https': {'score': true}}],
}
}
];

dataSets.forEach(dataSet => {
dataSet.key = perfXDatabase.saveData({}, dataSet.results);
});
assert.ok(fs.existsSync(perfXDatabase.fsRoot));

perfXDatabase.clear();
assert.ok(!fs.existsSync(perfXDatabase.fsRoot));
});
});