| 'use strict'; |
| |
| const assert = require('assert'); |
| |
| require('../tools/js/v3-models.js'); |
| const BrowserPrivilegedAPI = require('../public/v3/privileged-api.js').PrivilegedAPI; |
| const MockModels = require('./resources/mock-v3-models.js').MockModels; |
| const MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI; |
| |
| describe('CommitSetRangeBisector', () => { |
| |
| function makeCommit(id, repository, revision, time, order) |
| { |
| return CommitLog.ensureSingleton(id, { |
| id, |
| repository, |
| revision, |
| ownsCommits: false, |
| time, |
| order |
| }); |
| } |
| |
| function sortedCommitSets() |
| { |
| return [ |
| CommitSet.ensureSingleton(1, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(2, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(3, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(4, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(5, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function sortedCommitSetsWithoutTimeOrOrder() |
| { |
| return [ |
| CommitSet.ensureSingleton(6, { |
| revisionItems: [ |
| { commit: makeCommit(101, MockModels.webkit, 'webkit-commit-101', 0), requiresBuild: false }, |
| { commit: makeCommit(111, MockModels.osx, 'osx-commit-111', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(7, { |
| revisionItems: [ |
| { commit: makeCommit(101, MockModels.webkit, 'webkit-commit-101', 0), requiresBuild: false }, |
| { commit: makeCommit(112, MockModels.osx, 'osx-commit-112', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(8, { |
| revisionItems: [ |
| { commit: makeCommit(102, MockModels.webkit, 'webkit-commit-102', 0), requiresBuild: false }, |
| { commit: makeCommit(112, MockModels.osx, 'osx-commit-112', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(9, { |
| revisionItems: [ |
| { commit: makeCommit(103, MockModels.webkit, 'webkit-commit-103', 0), requiresBuild: false }, |
| { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(10, { |
| revisionItems: [ |
| { commit: makeCommit(106, MockModels.webkit, 'webkit-commit-106', 0), requiresBuild: false }, |
| { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetsWithSomeCommitsOnlyHaveOrder() |
| { |
| return [ |
| CommitSet.ensureSingleton(11, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false }, |
| { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(12, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(13, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(14, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(15, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(16, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetsWitCommitRollback() |
| { |
| return [ |
| CommitSet.ensureSingleton(11, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false }, |
| { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(12, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(13, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(14, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(15, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(17, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetsWithSomeHaveOwnedCommits() |
| { |
| return [ |
| CommitSet.ensureSingleton(11, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false }, |
| { commit: makeCommit(201, MockModels.ownerRepository, 'owner-commit-1', 0, 1), requiresBuild: false }, |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(12, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(13, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 21), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(14, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(202, MockModels.ownerRepository, 'owner-commit-2', 0, 2), requiresBuild: false }, |
| { commit: makeCommit(302, MockModels.ownedRepository, 'owned-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(15, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(16, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 31), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.ownerRepository, 'owner-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetsWithSomeCommitsNotMonotonicallyIncrease() |
| { |
| return [ |
| CommitSet.ensureSingleton(17, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(18, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(19, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(20, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-2', 20), requiresBuild: false }, |
| { commit: makeCommit(12, MockModels.osx, 'osx-commit-2', 0, 2), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(21, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(13, MockModels.osx, 'osx-commit-3', 0, 3), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(22, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 0, 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetWithOnlySomeCommitsHaveOrdering() |
| { |
| return [ |
| CommitSet.ensureSingleton(23, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(111, MockModels.osx, 'osx-commit-111', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(24, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(112, MockModels.osx, 'osx-commit-112', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(25, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(26, { |
| revisionItems: [ |
| { commit: makeCommit(3, MockModels.webkit, 'webkit-commit-3', 30), requiresBuild: false }, |
| { commit: makeCommit(114, MockModels.osx, 'osx-commit-114', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(27, { |
| revisionItems: [ |
| { commit: makeCommit(6, MockModels.webkit, 'webkit-commit-6', 60), requiresBuild: false }, |
| { commit: makeCommit(113, MockModels.osx, 'osx-commit-113', 0), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function commitSetsWithTime() |
| { |
| return [ |
| CommitSet.ensureSingleton(28, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(201, MockModels.osx, 'osx-commit-201', 8), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(29, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(203, MockModels.osx, 'osx-commit-203', 11), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(30, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(204, MockModels.osx, 'osx-commit-204', 12), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(31, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 10), requiresBuild: false }, |
| { commit: makeCommit(205, MockModels.osx, 'osx-commit-205', 13), requiresBuild: false } |
| ], |
| customRoots: []}), |
| ]; |
| } |
| |
| function createRoot() |
| { |
| return UploadedFile.ensureSingleton(456, {'createdAt': new Date('2017-05-01T21:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user', |
| size: 16452234, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4d6c175809ba968f78f656d58d'}); |
| } |
| |
| function commitSetWithRoot() |
| { |
| return CommitSet.ensureSingleton(15, { |
| revisionItems: [{ commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }], |
| customRoots: [createRoot()] |
| }); |
| } |
| |
| function commitSet() |
| { |
| return CommitSet.ensureSingleton(16, { |
| revisionItems: [{ commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }], |
| customRoots: [] |
| }); |
| } |
| |
| function commitSetsWithNoCommonRepository() { |
| return [ |
| CommitSet.ensureSingleton(1, { |
| revisionItems: [ |
| { commit: makeCommit(1, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }, |
| { commit: makeCommit(11, MockModels.osx, 'osx-commit-1', 1), requiresBuild: false } |
| ], |
| customRoots: []}), |
| CommitSet.ensureSingleton(2, { |
| revisionItems: [ |
| { commit: makeCommit(2, MockModels.webkit, 'webkit-commit-1', 1), requiresBuild: false }, |
| { commit: makeCommit(31, MockModels.ios, 'ios-commit-1', 1), requiresBuild: false }, |
| ], |
| customRoots: []}) |
| ]; |
| } |
| |
| describe('commitSetClosestToMiddleOfAllCommits', () => { |
| MockModels.inject(); |
| const requests = MockRemoteAPI.inject(null, BrowserPrivilegedAPI); |
| |
| it('should return "null" if no common repository found', async () => { |
| const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits(commitSetsWithNoCommonRepository().splice(0, 2)); |
| assert.equal(middleCommitSet, null); |
| }); |
| |
| it('should return "null" to bisect commit set with root', async () => { |
| const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([commitSet(), commitSetWithRoot()], [commitSet(), commitSetWithRoot()]); |
| assert.equal(middleCommitSet, null); |
| }); |
| |
| it('should return "null" if no repository with time or order is found', async () => { |
| const allCommitSets = sortedCommitSetsWithoutTimeOrOrder(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const middleCommitSet = await CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| assert.equal(middleCommitSet, null); |
| }); |
| |
| it('should throw exception when failed to fetch commit log', async () => { |
| const allCommitSets = sortedCommitSets(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const rejectReason = '404'; |
| requests[0].reject(rejectReason); |
| let exceptionRaised = false; |
| try { |
| await promise; |
| } catch (error) { |
| exceptionRaised = true; |
| assert.equal(error, rejectReason); |
| } |
| assert.ok(exceptionRaised); |
| }); |
| |
| it('should return "null" if no commit set is found other than the commit sets that define the range', async () => { |
| const allCommitSets = sortedCommitSets(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], [startCommitSet, endCommitSet]); |
| assert.equal(requests.length, 2); |
| assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3'); |
| assert.equal(requests[1].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| |
| assert.equal(await promise, null); |
| }); |
| |
| it('should return bisecting commit set point closest to the middle of revision range', async () => { |
| const allCommitSets = sortedCommitSets(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| assert.equal(requests.length, 2); |
| const osxFetchRequest = requests.find((fetch_request) => fetch_request.url === '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3'); |
| const webkitFetchRequest = requests.find((fetch_request) => fetch_request.url === '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| webkitFetchRequest.resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| osxFetchRequest.resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| |
| assert.equal(await promise, allCommitSets[3]); |
| }); |
| |
| it('should return same bisection point even when two commit sets from original commit set have reverse order', async () => { |
| const allCommitSets = sortedCommitSets(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([endCommitSet, startCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| |
| assert.equal(await promise, allCommitSets[3]); |
| }); |
| |
| it('should use commits with order as fallback when multiple commit sets found for the commit that is closest to the middle of commits with time', async () => { |
| const allCommitSets = commitSetsWithSomeCommitsOnlyHaveOrder(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| const ownerRepositoryId = MockModels.ownerRepository.id(); |
| |
| assert.equal(requests.length, 3); |
| assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3'); |
| assert.equal(requests[1].url, '/api/commits/111/?precedingRevision=owner-commit-1&lastRevision=owner-commit-3'); |
| assert.equal(requests[2].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: ownerRepositoryId, |
| id: 202, |
| revision: 'owner-commit-2', |
| ownsCommits: false, |
| time: 0, |
| order: 2 |
| }, |
| { |
| repository: ownerRepositoryId, |
| id: 203, |
| revision: 'owner-commit-3', |
| ownsCommits: false, |
| time: 0, |
| order: 3 |
| } |
| ] |
| }); |
| |
| requests[2].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| assert.equal(await promise, allCommitSets[3]); |
| }); |
| |
| it('should still check the repository revision even the repository has no change in the range', async () => { |
| const allCommitSets = commitSetsWitCommitRollback(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| |
| assert.equal(requests.length, 2); |
| assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3'); |
| assert.equal(requests[1].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| assert.equal(await promise, null); |
| }); |
| |
| it('should filter out commit set with owned commit', async () => { |
| const allCommitSets = commitSetsWithSomeHaveOwnedCommits(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| const ownerRepositoryId = MockModels.ownerRepository.id(); |
| |
| assert.equal(requests.length, 3); |
| assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-3'); |
| assert.equal(requests[1].url, '/api/commits/111/?precedingRevision=owner-commit-1&lastRevision=owner-commit-3'); |
| assert.equal(requests[2].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 21 |
| }, |
| { |
| repository: osxId, |
| id: 13, |
| revision: 'osx-commit-3', |
| ownsCommits: false, |
| time: 31 |
| } |
| ] |
| }); |
| |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: ownerRepositoryId, |
| id: 202, |
| revision: 'owner-commit-2', |
| ownsCommits: true, |
| time: 0, |
| order: 2 |
| }, |
| { |
| repository: ownerRepositoryId, |
| id: 203, |
| revision: 'owner-commit-3', |
| ownsCommits: true, |
| time: 0, |
| order: 3 |
| } |
| ] |
| }); |
| |
| requests[2].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| assert.equal(await promise, allCommitSets[4]); |
| }); |
| |
| it('should filter out commits those are not in any commit sets for commit without ordering', async () => { |
| const allCommitSets = commitSetWithOnlySomeCommitsHaveOrdering(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| |
| assert.equal(requests.length, 1); |
| assert.equal(requests[0].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| assert.equal(await promise, allCommitSets[2]); |
| }); |
| |
| it('should still work even some commits do not monotonically increasing', async () => { |
| const allCommitSets = commitSetsWithSomeCommitsNotMonotonicallyIncrease(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| const webkitId = MockModels.webkit.id(); |
| const osxId = MockModels.osx.id(); |
| |
| assert.equal(requests.length, 2); |
| assert.equal(requests[0].url, '/api/commits/9/?precedingRevision=osx-commit-1&lastRevision=osx-commit-2'); |
| assert.equal(requests[1].url, '/api/commits/11/?precedingRevision=webkit-commit-1&lastRevision=webkit-commit-6'); |
| |
| requests[0].resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 12, |
| revision: 'osx-commit-2', |
| ownsCommits: false, |
| time: 0, |
| order: 2 |
| } |
| ] |
| }); |
| requests[1].resolve({ |
| 'commits': [ |
| { |
| repository: webkitId, |
| id: 2, |
| revision: 'webkit-commit-2', |
| ownsCommits: false, |
| time: 20 |
| }, |
| { |
| repository: webkitId, |
| id: 3, |
| revision: 'webkit-commit-3', |
| ownsCommits: false, |
| time: 30 |
| }, |
| { |
| repository: webkitId, |
| id: 4, |
| revision: 'webkit-commit-4', |
| ownsCommits: false, |
| time: 40 |
| }, |
| { |
| repository: webkitId, |
| id: 5, |
| revision: 'webkit-commit-5', |
| ownsCommits: false, |
| time: 50 |
| }, |
| { |
| repository: webkitId, |
| id: 6, |
| revision: 'webkit-commit-6', |
| ownsCommits: false, |
| time: 60 |
| }, |
| ] |
| }); |
| |
| assert.equal(await promise, allCommitSets[3]); |
| }); |
| |
| it('should not double count a commit if start and end commits are the same', async () => { |
| const allCommitSets = commitSetsWithTime(); |
| const startCommitSet = allCommitSets[0]; |
| const endCommitSet = allCommitSets[allCommitSets.length - 1]; |
| const promise = CommitSetRangeBisector.commitSetClosestToMiddleOfAllCommits([startCommitSet, endCommitSet], allCommitSets); |
| assert.equal(requests.length, 1); |
| const osxFetchRequest = requests[0]; |
| assert.equal(osxFetchRequest.url, '/api/commits/9/?precedingRevision=osx-commit-201&lastRevision=osx-commit-205'); |
| const osxId = MockModels.osx.id(); |
| osxFetchRequest.resolve({ |
| 'commits': [ |
| { |
| repository: osxId, |
| id: 202, |
| revision: 'osx-commit-202', |
| ownsCommits: false, |
| time: 9 |
| }, |
| { |
| repository: osxId, |
| id: 203, |
| revision: 'osx-commit-203', |
| ownsCommits: false, |
| time: 11 |
| }, |
| { |
| repository: osxId, |
| id: 204, |
| revision: 'osx-commit-204', |
| ownsCommits: false, |
| time: 12 |
| }, |
| { |
| repository: osxId, |
| id: 205, |
| revision: 'osx-commit-205', |
| ownsCommits: false, |
| time: 13 |
| } |
| ] |
| }); |
| |
| assert.equal(await promise, allCommitSets[1]); |
| }); |
| }); |
| |
| describe('_orderCommitSetsByTimeAndOrderThenDeduplicate', () => { |
| it('should sort by alphabetically for commits without ordering', () => { |
| const oneCommitSet = CommitSet.ensureSingleton(100, { |
| revisionItems: [ |
| { commit: makeCommit(1001, MockModels.webkit, 'webkit-commit-1001'), requiresBuild: false} |
| ], |
| customRoots: [] |
| }); |
| |
| const anotherCommitSet = CommitSet.ensureSingleton(101, { |
| revisionItems: [ |
| { commit: makeCommit(1002, MockModels.webkit, 'webkit-commit-1002'), requiresBuild: false} |
| ], |
| customRoots: [] |
| }); |
| |
| const [commitSet0, commitSet1] = CommitSetRangeBisector._orderCommitSetsByTimeAndOrderThenDeduplicate([anotherCommitSet, oneCommitSet], [], [], [MockModels.webkit]); |
| assert.equal(oneCommitSet, commitSet0); |
| assert.equal(anotherCommitSet, commitSet1); |
| }) |
| }) |
| }); |