821d01ab34
Also adds default bindings for protractor. Also removes sync web driver adapter for Dart as we don’t have tests for it yet.
369 lines
10 KiB
JavaScript
369 lines
10 KiB
JavaScript
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
|
|
|
import { isBlank, isPresent, BaseException, stringify, Date, DateWrapper } from 'angular2/src/facade/lang';
|
|
import { ListWrapper, List } from 'angular2/src/facade/collection';
|
|
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
|
|
|
|
import {
|
|
Sampler, WebDriverAdapter, WebDriverExtension,
|
|
Validator, Metric, Reporter, Browser,
|
|
bind, Injector, Options, MeasureValues
|
|
} from 'benchpress/common';
|
|
|
|
export function main() {
|
|
var EMPTY_EXECUTE = () => {};
|
|
|
|
describe('sampler', () => {
|
|
var sampler;
|
|
|
|
function createSampler({
|
|
driver,
|
|
driverExtension,
|
|
metric,
|
|
reporter,
|
|
validator,
|
|
forceGc,
|
|
prepare,
|
|
execute
|
|
} = {}) {
|
|
var time = 1000;
|
|
if (isBlank(metric)) {
|
|
metric = new MockMetric([]);
|
|
}
|
|
if (isBlank(reporter)) {
|
|
reporter = new MockReporter([]);
|
|
}
|
|
if (isBlank(driver)) {
|
|
driver = new MockDriverAdapter([]);
|
|
}
|
|
if (isBlank(driverExtension)) {
|
|
driverExtension = new MockDriverExtension([]);
|
|
}
|
|
var bindings = ListWrapper.concat(Sampler.BINDINGS, [
|
|
bind(Metric).toValue(metric),
|
|
bind(Reporter).toValue(reporter),
|
|
bind(WebDriverAdapter).toValue(driver),
|
|
bind(WebDriverExtension).toValue(driverExtension),
|
|
bind(Options.EXECUTE).toValue(execute),
|
|
bind(Validator).toValue(validator),
|
|
bind(Sampler.TIME).toValue( () => DateWrapper.fromMillis(time++) )
|
|
]);
|
|
if (isPresent(prepare)) {
|
|
ListWrapper.push(bindings, bind(Options.PREPARE).toValue(prepare));
|
|
}
|
|
if (isPresent(forceGc)) {
|
|
ListWrapper.push(bindings, bind(Options.FORCE_GC).toValue(forceGc));
|
|
}
|
|
|
|
sampler = new Injector(bindings).get(Sampler);
|
|
}
|
|
|
|
it('should call the prepare and execute callbacks using WebDriverAdapter.waitFor', (done) => {
|
|
var log = [];
|
|
var count = 0;
|
|
var driver = new MockDriverAdapter([], (callback) => {
|
|
var result = callback();
|
|
ListWrapper.push(log, result);
|
|
return PromiseWrapper.resolve(result);
|
|
});
|
|
createSampler({
|
|
driver: driver,
|
|
validator: createCountingValidator(2),
|
|
prepare: () => {
|
|
return count++;
|
|
},
|
|
execute: () => {
|
|
return count++;
|
|
}
|
|
});
|
|
sampler.sample().then( (_) => {
|
|
expect(count).toBe(4);
|
|
expect(log).toEqual([0,1,2,3]);
|
|
done();
|
|
});
|
|
|
|
});
|
|
|
|
it('should call prepare, gc, beginMeasure, execute, gc, endMeasure for every iteration', (done) => {
|
|
var workCount = 0;
|
|
var log = [];
|
|
createSampler({
|
|
forceGc: true,
|
|
metric: createCountingMetric(log),
|
|
driverExtension: new MockDriverExtension(log),
|
|
validator: createCountingValidator(2),
|
|
prepare: () => {
|
|
ListWrapper.push(log, `p${workCount++}`);
|
|
},
|
|
execute: () => {
|
|
ListWrapper.push(log, `w${workCount++}`);
|
|
}
|
|
});
|
|
sampler.sample().then( (_) => {
|
|
expect(log).toEqual([
|
|
['gc'],
|
|
'p0',
|
|
['gc'],
|
|
['beginMeasure'],
|
|
'w1',
|
|
['gc'],
|
|
['endMeasure', false, {'script': 0}],
|
|
'p2',
|
|
['gc'],
|
|
['beginMeasure'],
|
|
'w3',
|
|
['gc'],
|
|
['endMeasure', false, {'script': 1}],
|
|
]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should call execute, gc, endMeasure for every iteration if there is no prepare callback', (done) => {
|
|
var log = [];
|
|
var workCount = 0;
|
|
createSampler({
|
|
forceGc: true,
|
|
metric: createCountingMetric(log),
|
|
driverExtension: new MockDriverExtension(log),
|
|
validator: createCountingValidator(2),
|
|
execute: () => {
|
|
ListWrapper.push(log, `w${workCount++}`);
|
|
},
|
|
prepare: null
|
|
});
|
|
sampler.sample().then( (_) => {
|
|
expect(log).toEqual([
|
|
['gc'],
|
|
['beginMeasure'],
|
|
'w0',
|
|
['gc'],
|
|
['endMeasure', true, {'script': 0}],
|
|
'w1',
|
|
['gc'],
|
|
['endMeasure', true, {'script': 1}],
|
|
]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not gc if the flag is not set', (done) => {
|
|
var log = [];
|
|
createSampler({
|
|
metric: createCountingMetric(),
|
|
driverExtension: new MockDriverExtension(log),
|
|
validator: createCountingValidator(2),
|
|
prepare: EMPTY_EXECUTE,
|
|
execute: EMPTY_EXECUTE
|
|
});
|
|
sampler.sample().then( (_) => {
|
|
expect(log).toEqual([]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should only collect metrics for execute and ignore metrics from prepare', (done) => {
|
|
var scriptTime = 0;
|
|
var iterationCount = 1;
|
|
createSampler({
|
|
validator: createCountingValidator(2),
|
|
metric: new MockMetric([], () => {
|
|
var result = PromiseWrapper.resolve({'script': scriptTime});
|
|
scriptTime = 0;
|
|
return result;
|
|
}),
|
|
prepare: () => {
|
|
scriptTime = 1 * iterationCount;
|
|
},
|
|
execute: () => {
|
|
scriptTime = 10 * iterationCount;
|
|
iterationCount++;
|
|
}
|
|
});
|
|
sampler.sample().then( (state) => {
|
|
expect(state.completeSample.length).toBe(2);
|
|
expect(state.completeSample[0]).toEqual(mv(0, 1000, {'script': 10}));
|
|
expect(state.completeSample[1]).toEqual(mv(1, 1001, {'script': 20}));
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should call the validator for every execution and store the valid sample', (done) => {
|
|
var log = [];
|
|
var validSample = [{}];
|
|
|
|
createSampler({
|
|
metric: createCountingMetric(),
|
|
validator: createCountingValidator(2, validSample, log),
|
|
execute: EMPTY_EXECUTE
|
|
});
|
|
sampler.sample().then( (state) => {
|
|
expect(state.validSample).toBe(validSample);
|
|
// TODO(tbosch): Why does this fail??
|
|
// expect(log).toEqual([
|
|
// ['validate', [{'script': 0}], null],
|
|
// ['validate', [{'script': 0}, {'script': 1}], validSample]
|
|
// ]);
|
|
|
|
expect(log.length).toBe(2);
|
|
expect(log[0]).toEqual(
|
|
['validate', [mv(0, 1000, {'script': 0})], null]
|
|
);
|
|
expect(log[1]).toEqual(
|
|
['validate', [mv(0, 1000, {'script': 0}), mv(1, 1001, {'script': 1})], validSample]
|
|
);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should report the metric values', (done) => {
|
|
var log = [];
|
|
var validSample = [{}];
|
|
createSampler({
|
|
validator: createCountingValidator(2, validSample),
|
|
metric: createCountingMetric(),
|
|
reporter: new MockReporter(log),
|
|
execute: EMPTY_EXECUTE
|
|
});
|
|
sampler.sample().then( (_) => {
|
|
// TODO(tbosch): Why does this fail??
|
|
// expect(log).toEqual([
|
|
// ['reportMeasureValues', 0, {'script': 0}],
|
|
// ['reportMeasureValues', 1, {'script': 1}],
|
|
// ['reportSample', [{'script': 0}, {'script': 1}], validSample]
|
|
// ]);
|
|
expect(log.length).toBe(3);
|
|
expect(log[0]).toEqual(
|
|
['reportMeasureValues', mv(0, 1000, {'script': 0})]
|
|
);
|
|
expect(log[1]).toEqual(
|
|
['reportMeasureValues', mv(1, 1001, {'script': 1})]
|
|
);
|
|
expect(log[2]).toEqual(
|
|
['reportSample', [mv(0, 1000, {'script': 0}), mv(1, 1001, {'script': 1})], validSample]
|
|
);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function mv(runIndex, time, values) {
|
|
return new MeasureValues(runIndex, DateWrapper.fromMillis(time), values);
|
|
}
|
|
|
|
function createCountingValidator(count, validSample = null, log = null) {
|
|
return new MockValidator(log, (completeSample) => {
|
|
count--;
|
|
if (count === 0) {
|
|
return isPresent(validSample) ? validSample : completeSample;
|
|
} else {
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
function createCountingMetric(log = null) {
|
|
var scriptTime = 0;
|
|
return new MockMetric(log, () => {
|
|
return { 'script': scriptTime++ };
|
|
});
|
|
}
|
|
|
|
class MockDriverAdapter extends WebDriverAdapter {
|
|
_log:List;
|
|
_waitFor:Function;
|
|
constructor(log = null, waitFor = null) {
|
|
super();
|
|
if (isBlank(log)) {
|
|
log = [];
|
|
}
|
|
this._log = log;
|
|
this._waitFor = waitFor;
|
|
}
|
|
waitFor(callback:Function):Promise {
|
|
if (isPresent(this._waitFor)) {
|
|
return this._waitFor(callback);
|
|
} else {
|
|
return PromiseWrapper.resolve(callback());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class MockDriverExtension extends WebDriverExtension {
|
|
_log:List;
|
|
constructor(log = null) {
|
|
super();
|
|
if (isBlank(log)) {
|
|
log = [];
|
|
}
|
|
this._log = log;
|
|
}
|
|
gc():Promise {
|
|
ListWrapper.push(this._log, ['gc']);
|
|
return PromiseWrapper.resolve(null);
|
|
}
|
|
}
|
|
|
|
class MockValidator extends Validator {
|
|
_validate:Function;
|
|
_log:List;
|
|
constructor(log = null, validate = null) {
|
|
super();
|
|
this._validate = validate;
|
|
if (isBlank(log)) {
|
|
log = [];
|
|
}
|
|
this._log = log;
|
|
}
|
|
validate(completeSample:List<MeasureValues>):List<MeasureValues> {
|
|
var stableSample = isPresent(this._validate) ? this._validate(completeSample) : completeSample;
|
|
ListWrapper.push(this._log, ['validate', completeSample, stableSample]);
|
|
return stableSample;
|
|
}
|
|
}
|
|
|
|
class MockMetric extends Metric {
|
|
_endMeasure:Function;
|
|
_log:List;
|
|
constructor(log = null, endMeasure = null) {
|
|
super();
|
|
this._endMeasure = endMeasure;
|
|
if (isBlank(log)) {
|
|
log = [];
|
|
}
|
|
this._log = log;
|
|
}
|
|
beginMeasure() {
|
|
ListWrapper.push(this._log, ['beginMeasure']);
|
|
return PromiseWrapper.resolve(null);
|
|
}
|
|
endMeasure(restart) {
|
|
var measureValues = isPresent(this._endMeasure) ? this._endMeasure() : {};
|
|
ListWrapper.push(this._log, ['endMeasure', restart, measureValues]);
|
|
return PromiseWrapper.resolve(measureValues);
|
|
}
|
|
}
|
|
|
|
class MockReporter extends Reporter {
|
|
_log:List;
|
|
constructor(log = null) {
|
|
super();
|
|
if (isBlank(log)) {
|
|
log = [];
|
|
}
|
|
this._log = log;
|
|
}
|
|
reportMeasureValues(values):Promise {
|
|
ListWrapper.push(this._log, ['reportMeasureValues', values]);
|
|
return PromiseWrapper.resolve(null);
|
|
}
|
|
reportSample(completeSample, validSample):Promise {
|
|
ListWrapper.push(this._log, ['reportSample', completeSample, validSample]);
|
|
return PromiseWrapper.resolve(null);
|
|
}
|
|
} |