blob: 2e670b0795114eb675525c2df7bea138d338e7c0 [file] [log] [blame]
'use strict';
const assert = require('assert');
require('../tools/js/v3-models.js');
const MockModels = require('./resources/mock-v3-models.js').MockModels;
const MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI;
const BrowserPrivilegedAPI = require('../public/v3/privileged-api.js').PrivilegedAPI;
const NodePrivilegedAPI = require('../tools/js/privileged-api').PrivilegedAPI;
function sampleAnalysisTasks()
{
return {
'analysisTasks': [
{
'author': null,
'bugs': [],
'buildRequestCount': '14',
'finishedBuildRequestCount': '6',
'category': 'identified',
'causes': [
'105975'
],
'createdAt': 1454594330000,
'endRun': '37253448',
'endRunTime': 1454515020303,
'fixes': [],
'id': '1082',
'metric': '2884',
'name': 'Potential 1.2% regression between 2016-02-02 20:20 and 02-03 15:57',
'needed': null,
'platform': '65',
'result': 'regression',
'segmentationStrategy': '1',
'startRun': '37117949',
'startRunTime': 1454444458791,
'testRangeStragegy': '2'
}
],
'bugs': [],
'commits': [
{
'authorEmail': 'commit-queue@webkit.org',
'authorName': 'Commit Queue',
'id': '105975',
'message': 'Commit message',
'order': null,
'previousCommit': null,
'repository': '11',
'revision': '196051',
'time': 1454481246108
}
],
'status': 'OK'
};
}
function measurementCluster()
{
return {
'clusterSize': 5184000000,
'clusterStart': 946684800000,
'configurations': {
'current': [
[
37188161,
124.15015662116,
25,
3103.7539155291,
385398.06003414,
false,
[
[
105978,
10,
'791451',
null,
null,
1454481204649
],
[
105975,
11,
'196051',
null,
null,
1454481246108
],
[
105502,
9,
'10.11 15D21',
null,
1504021,
0
]
],
1454481246108,
227020,
1454492139496,
'3151',
179
],
],
},
'endTime': 1454716800000,
'formatMap': [
'id',
'mean',
'iterationCount',
'sum',
'squareSum',
'markedOutlier',
'revisions',
'commitTime',
'build',
'buildTime',
'buildTag',
'builder'
],
'lastModified': 1455236216153,
'startTime': 1449532800000,
'status': 'OK'
};
}
describe('AnalysisTask', () => {
MockModels.inject();
function makeMockPoints(id, commitSet) {
return {
id,
commitSet: () => commitSet
}
}
describe('fetchById', () => {
const requests = MockRemoteAPI.inject(null, BrowserPrivilegedAPI);
it('should fetch the specified analysis task', () => {
let callCount = 0;
AnalysisTask.fetchById(1).then(() => { callCount++; });
assert.equal(callCount, 0);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks?id=1');
});
it('should not fetch the specified analysis task if all analysis task had been fetched', async () => {
const fetchAll = AnalysisTask.fetchAll();
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks');
requests[0].resolve(sampleAnalysisTasks());
await fetchAll;
AnalysisTask.fetchById(sampleAnalysisTasks().analysisTasks[0].id);
assert.equal(requests.length, 1);
});
it('should fetch the specified analysis task if all analysis task had been fetched but noCache is set to true', async () => {
const fetchAll = AnalysisTask.fetchAll();
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks');
requests[0].resolve(sampleAnalysisTasks());
await fetchAll;
const taskId = sampleAnalysisTasks().analysisTasks[0].id;
AnalysisTask.fetchById(taskId, true);
assert.equal(requests.length, 2);
assert.equal(requests[1].url, `/api/analysis-tasks?id=${taskId}`);
});
})
describe('fetchAll', () => {
const requests = MockRemoteAPI.inject(null, BrowserPrivilegedAPI);
it('should request all analysis tasks', () => {
let callCount = 0;
AnalysisTask.fetchAll().then(() => { callCount++; });
assert.equal(callCount, 0);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks');
});
it('should not request all analysis tasks multiple times', () => {
let callCount = 0;
AnalysisTask.fetchAll().then(() => { callCount++; });
assert.equal(callCount, 0);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks');
AnalysisTask.fetchAll().then(() => { callCount++; });
assert.equal(callCount, 0);
assert.equal(requests.length, 1);
});
it('should resolve the promise when the request is fullfilled', () => {
let callCount = 0;
const promise = AnalysisTask.fetchAll().then(() => { callCount++; });
assert.equal(callCount, 0);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/api/analysis-tasks');
requests[0].resolve(sampleAnalysisTasks());
let anotherCallCount = 0;
return promise.then(() => {
assert.equal(callCount, 1);
AnalysisTask.fetchAll().then(() => { anotherCallCount++; });
}).then(() => {
assert.equal(callCount, 1);
assert.equal(anotherCallCount, 1);
assert.equal(requests.length, 1);
});
});
it('should create AnalysisTask objects', () => {
const promise = AnalysisTask.fetchAll();
requests[0].resolve(sampleAnalysisTasks());
return promise.then(() => {
assert.equal(AnalysisTask.all().length, 1);
var task = AnalysisTask.all()[0];
assert.equal(task.id(), 1082);
assert.equal(task.metric(), MockModels.someMetric);
assert.equal(task.platform(), MockModels.somePlatform);
assert.ok(task.hasResults());
assert.ok(task.hasPendingRequests());
assert.equal(task.requestLabel(), '6 of 14');
assert.equal(task.category(), 'investigated');
assert.equal(task.changeType(), 'regression');
assert.equal(task.startMeasurementId(), 37117949);
assert.equal(task.startTime(), 1454444458791);
assert.equal(task.endMeasurementId(), 37253448);
assert.equal(task.endTime(), 1454515020303);
});
});
it('should create CommitLog objects for `causes`', () => {
const promise = AnalysisTask.fetchAll();
requests[0].resolve(sampleAnalysisTasks());
return promise.then(() => {
assert.equal(AnalysisTask.all().length, 1);
var task = AnalysisTask.all()[0];
assert.equal(task.causes().length, 1);
var commit = task.causes()[0];
assert.equal(commit.revision(), '196051');
assert.equal(commit.repository(), MockModels.webkit);
assert.equal(+commit.time(), 1454481246108);
});
});
it('should find CommitLog objects for `causes` when MeasurementAdaptor created matching objects', () => {
const adaptor = new MeasurementAdaptor(measurementCluster().formatMap);
const adaptedMeasurement = adaptor.applyTo(measurementCluster().configurations.current[0]);
assert.equal(adaptedMeasurement.id, 37188161);
assert.equal(adaptedMeasurement.commitSet().commitForRepository(MockModels.webkit).revision(), '196051');
const promise = AnalysisTask.fetchAll();
requests[0].resolve(sampleAnalysisTasks());
return promise.then(() => {
assert.equal(AnalysisTask.all().length, 1);
var task = AnalysisTask.all()[0];
assert.equal(task.causes().length, 1);
var commit = task.causes()[0];
assert.equal(commit.revision(), '196051');
assert.equal(commit.repository(), MockModels.webkit);
assert.equal(+commit.time(), 1454481246108);
});
});
});
function mockStartAndEndPoints() {
const startPoint = makeMockPoints(1, new MeasurementCommitSet(1, [
[1, MockModels.ios.id(), 'ios-revision-1', null, 0],
[3, MockModels.webkit.id(), 'webkit-revision-1', null, 0]
]));
const endPoint = makeMockPoints(2, new MeasurementCommitSet(2, [
[2, MockModels.ios.id(), 'ios-revision-2', null, 0],
[4, MockModels.webkit.id(), 'webkit-revision-2', null, 0]
]));
return [startPoint, endPoint];
}
describe('create with browser privilege api', () => {
const requests = MockRemoteAPI.inject(null, BrowserPrivilegedAPI);
it('should create analysis task with confirming repetition count zero as default with browser privilege api', async () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
AnalysisTask.create('confirm', startPoint, endPoint);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
requests[0].resolve({
token: 'abc',
expiration: Date.now() + 3600 * 1000,
});
await MockRemoteAPI.waitForRequest();
assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 2);
assert.deepEqual(requests[1].data, {name: 'confirm', startRun: 1, endRun: 2, token: 'abc'});
});
it('should create analysis task with confirming repetition count specified', async () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4, 'alternating', true);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
requests[0].resolve({
token: 'abc',
expiration: Date.now() + 3600 * 1000,
});
await MockRemoteAPI.waitForRequest();
assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 2);
assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4, needsNotification: true, repetitionType: 'alternating',
startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [
{'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
'22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
{'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
'22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
);
});
it('should create analysis task and test groups with "needsNotification" set to false if specified in creation', async () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4, 'alternating', false);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
requests[0].resolve({
token: 'abc',
expiration: Date.now() + 3600 * 1000,
});
await MockRemoteAPI.waitForRequest();
assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 2);
assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4, needsNotification: false, repetitionType: 'alternating',
startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [
{'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
'22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
{'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
'22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
);
});
it('should sync the new analysis task status once it is created', async () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
const creatingPromise = AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4, 'alternating', true);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
requests[0].resolve({
token: 'abc',
expiration: Date.now() + 3600 * 1000,
});
await MockRemoteAPI.waitForRequest();
assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 2);
assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4, needsNotification: true, repetitionType: 'alternating',
startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [
{'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
'22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
{'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
'22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
);
requests[1].resolve({taskId: '5255', status: 'OK'});
await MockRemoteAPI.waitForRequest();
assert.equal(requests.length, 3);
assert.equal(requests[2].url, '/api/analysis-tasks?id=5255');
requests[2].resolve({
analysisTasks: [{
author: null,
bugs: [],
buildRequestCount: 8,
finishedBuildRequestCount: 0,
category: 'identified',
causes: [],
createdAt: 4500,
endRun: 2,
endRunTime: 5000,
fixes: [],
id: 5255,
metric: MockModels.someMetric.id(),
name: 'confirm',
needed: null,
platform: MockModels.somePlatform.id(),
result: 'progression',
segmentationStrategy: 1,
startRun: 1,
startRunTime: 4000,
testRangeStrategy: 2
}],
bugs: [],
commits: [],
status: 'OK'
});
const analysisTask = await creatingPromise;
assert.equal(analysisTask.id(), 5255);
assert.deepEqual(analysisTask.bugs(), []);
assert.equal(analysisTask.author(), '');
assert.equal(analysisTask.platform(), MockModels.somePlatform);
assert.equal(analysisTask.metric(), MockModels.someMetric);
});
it('should return an rejected promise when analysis task creation failed', async () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
const creatingPromise = AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4, 'alternating', true);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
requests[0].resolve({
token: 'abc',
expiration: Date.now() + 3600 * 1000,
});
await MockRemoteAPI.waitForRequest();
assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 2);
assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4, needsNotification: true, repetitionType: 'alternating',
startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [
{'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
'22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
{'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
'22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
);
requests[1].reject('401');
return creatingPromise.then(() => {
assert.ok(false, 'should not be reached');
}, (error) => {
assert.ok(true);
assert.equal(error, '401');
});
});
});
describe('create with node privilege api', () => {
const requests = MockRemoteAPI.inject(null, NodePrivilegedAPI);
beforeEach(() => {
PrivilegedAPI.configure('worker', 'password');
});
it('should create analysis task with confirming repetition count zero as default with browser privilege api', () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
AnalysisTask.create('confirm', startPoint, endPoint);
assert.equal(requests[0].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 1);
assert.deepEqual(requests[0].data, {name: 'confirm', startRun: 1, endRun: 2, workerName: 'worker', workerPassword: 'password'});
});
it('should create analysis task with confirming repetition count specified', () => {
const [startPoint, endPoint] = mockStartAndEndPoints();
AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4, 'alternating', true);
assert.equal(requests[0].url, '/privileged-api/create-analysis-task');
assert.equal(requests.length, 1);
assert.deepEqual(requests[0].data, {name: 'confirm', repetitionCount: 4, needsNotification: true,
startRun: 1, endRun: 2, workerName: 'worker', workerPassword: 'password', repetitionType: 'alternating',
testGroupName: 'Confirm', revisionSets: [
{'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
'22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
{'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
'22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
);
});
});
});