+2017-09-12 Dewei Zhu <dewei_zhu@apple.com>
+
+ Performance Dashboard backend should support A/B testing for owned components.
+ https://bugs.webkit.org/show_bug.cgi?id=175978
+
+ Reviewed by Ryosuke Niwa.
+
+ Add backend change for Performance Dashboard to support A/B testing for owned components.
+ Added 'commitset_commit_owner' and 'commitset_requires_build' columns to 'commit_set_items' table.
+ 'commitset_commit_owner' referrs to determine a commit with owner.
+ 'commitset_requires_build' indicates whether a root build is required.
+ This will be set true whenever commit_set_item specifies a patch file,
+ or commit_set_item is commit with owner commit,
+ or any other commit from same repository and in same build-request group requires build.
+ SQL for updating existing database:
+ 'BEGIN;
+ ALTER TABLE commit_set_items ADD COLUMN commitset_commit_owner integer REFERENCES commits DEFAULT NULL, ADD COLUMN commitset_requires_build boolean DEFAULT FALSE;
+ UPDATE commit_set_items SET commitset_requires_build = TRUE WHERE commitset_patch_file IS NOT NULL;
+ UPDATE commit_set_items SET commitset_requires_build = TRUE WHERE commitset_set IN (SELECT requests1.request_commit_set FROM build_requests as requests1 JOIN build_requests as requests2 ON requests1.request_group = requests2.request_group JOIN commit_set_items as item ON item.commitset_set = requests2.request_commit_set WHERE item.commitset_patch_file IS NOT NULL);
+ ALTER TABLE commit_set_items ADD CONSTRAINT commitset_item_with_patch_must_requires_build CHECK (commitset_patch_file IS NULL OR commitset_requires_build = TRUE),
+ ADD CONSTRAINT commitset_item_with_owned_commit_must_requires_build CHECK (commitset_commit_owner IS NULL OR commitset_requires_build = TRUE);
+ END;'
+
+ * init-database.sql: Updated 'commit_set_items' table.
+ * public/admin/triggerables.php: Only top level repository should show on triggerables page.
+ * public/include/build-requests-fetcher.php: Added 'commitOwner' and 'requireBuild' to 'revision_items'. Added 'commitOwner' field to a commit.
+ * public/include/db.php: Should be able to insert boolean value to database without explicted convert to 't' or 'f'.
+ * public/privileged-api/create-test-group.php:
+ Added logic to process 'commitOwner' and 'requireBuild' in 'commit_set_items'.
+ Removed a 'FIXME' that has been addressed before this commit.
+ * public/v3/models/build-request.js:
+ (BuildRequest.constructBuildRequestsFromData): Set 'commitOwner' field for a commit set item.
+ * public/v3/models/commit-set.js:
+ (CommitSet): Added maps for repository to commit owner and whether a repository requires builds.
+ (CommitSet.prototype.updateSingleton):
+ (CommitSet.prototype._updateFromObject):
+ (CommitSet.prototype.ownerRevisionForRepository): Returns owner revision for a given repository in current commit set.
+ (CommitSet.prototype.requiresBuildForRepository): Returns whether a repository need to build.
+ (CommitSet.prototype.equals): Equality check should include 2 new maps.
+ (CustomCommitSet): CustomCommitSet should be able to store commit with an owner commit.
+ (CustomCommitSet.prototype.setRevisionForRepository): Added each revision list entry should have 'ownerRevision'(null by default).
+ (CustomCommitSet.prototype.equals): Equality check should also check the equality of 'ownerRevision'.
+ (CustomCommitSet.prototype.ownerRevisionForRepository): Returns a owner revision for a given repository.
+ * public/v3/models/repository.js:
+ (Repository.prototype.findOwnedRepositoryByName): Return an repository owned by current repository with a given name.
+ * public/v3/models/test-group.js: Added 'ownerRevision' field in each entry of revisionSet.
+ * server-tests/api-build-requests-tests.js: Added tests.
+ * server-tests/privileged-api-create-test-group-tests.js: Added tests.
+ * server-tests/privileged-api-upload-file-tests.js: Fix unit tests by setting'requires_build' field to be true when updating commit_set_item which has a patch..
+ * server-tests/resources/mock-data.js: Added mock build requests with commit sets contain owned commits.
+ (MockData.jscRepositoryId): Returns id for JavaScriptsCore repository.
+ (MockData.addMockConfiguration): Added mock JavaScriptCore and owned JavaScriptCore repositories and commits associated with them.
+ (MockData.ownedJSCRepositoryId): Added a JavaScriptCore repository with WebKit as owner.
+ (MockData.addMockConfiguration): Added mock data for test cases those require a commit with a owner commit.
+ (MockData.addTestGroupWithOwnedCommits): Added mock data for analysis tasks, the build requires of which contains owned commits.
+ (MockData.set addAnotherTriggerable): Added another triggerable which has mac, webkit and javascript core repositories as triggerable repository group.
+ (MockData.set addAnotherMockTestGroup): Added another mock test group.
+ * tools/js/v3-models.js: Import CustomCommitSet.
+ * unit-tests/resources/mock-v3-models.js: Added an owned webkit repository.
+ * unit-tests/commit-set-tests.js: Added unit tests CustomCommitSet.
+
2017-09-15 Dewei Zhu <dewei_zhu@apple.com>
Should not mark a platform as missing in summary page if all expecting metrics are exlucded.
CREATE TABLE commit_set_items (
commitset_set integer REFERENCES commit_sets NOT NULL,
commitset_commit integer REFERENCES commits,
+ commitset_commit_owner integer REFERENCES commits DEFAULT NULL,
commitset_patch_file integer REFERENCES uploaded_files,
commitset_root_file integer REFERENCES uploaded_files,
+ commitset_requires_build boolean DEFAULT FALSE,
CONSTRAINT commitset_must_have_commit_or_root CHECK (commitset_commit IS NOT NULL OR commitset_root_file IS NOT NULL),
- CONSTRAINT commitset_with_patch_must_have_commit CHECK (commitset_patch_file IS NULL OR commitset_commit IS NOT NULL));
+ CONSTRAINT commitset_with_patch_must_have_commit CHECK (commitset_patch_file IS NULL OR commitset_commit IS NOT NULL),
+ CONSTRAINT commitset_item_with_patch_must_requires_build CHECK (commitset_patch_file IS NULL OR commitset_requires_build = TRUE),
+ CONSTRAINT commitset_item_with_owned_commit_must_requires_build CHECK (commitset_commit_owner IS NULL OR commitset_requires_build = TRUE));
CREATE TYPE build_request_status_type as ENUM ('pending', 'scheduled', 'running', 'failed', 'completed', 'canceled');
CREATE TABLE build_requests (
}
}
- $repository_rows = $db->fetch_table('repositories', 'repository_name');
+ $repository_rows = $db->select_rows('repositories', 'repository', array('owner' => NULL), 'name');
$page = new AdministrativePage($db, 'build_triggerables', 'triggerable', array(
'name' => array('editing_mode' => 'string'),
if ($root_file_id)
$this->add_uploaded_file($root_file_id);
- array_push($revision_items, array('commit' => $row['commit_id'], 'patch' => $patch_file_id, 'rootFile' => $root_file_id));
+ array_push($revision_items, array(
+ 'commit' => $row['commit_id'],
+ 'patch' => $patch_file_id,
+ 'rootFile' => $root_file_id,
+ 'commitOwner' => $row['commitset_commit_owner'],
+ 'requiresBuild' => Database::is_true($row['commitset_requires_build'])));
if (array_key_exists($commit_id, $this->commits_by_id))
continue;
array_push($this->commits, array(
'id' => $commit_id,
'repository' => $repository_id,
+ 'commitOwner' => $row['commitset_commit_owner'],
'revision' => $revision,
'time' => Database::to_js_time($commit_time)));
assert(ctype_alnum_underscore($name));
array_push($column_names, $name);
array_push($placeholders, '$' . $i);
+ if (is_bool($current_value))
+ $current_value = $this->to_database_boolean($current_value);
array_push($values, $current_value);
$i++;
}
if ($duplicate_test_group)
exit_with_error('DuplicateTestGroupName', array('task' => $task_id, 'testGroup' => $duplicate_test_group['testgroup_id']));
- // FIXME: Add a check for duplicate test group name.
$triggerable = find_triggerable_for_task($db, $task_id);
if ($triggerable) {
$triggerable_id = $triggerable['id'];
$need_to_build = FALSE;
foreach ($commit_list['set'] as $commit_row) {
$commit_row['set'] = $commit_set_id;
- $need_to_build = $need_to_build || $commit_row['patch_file'];
+ $requires_build = $commit_row['requires_build'];
+ assert(is_bool($requires_build));
+ $need_to_build = $need_to_build || $requires_build;
$db->insert_row('commit_set_items', 'commitset', $commit_row, 'commit');
}
$repository_group = $commit_list['repository_group'];
'order' => $order,
'commit_set' => $config['commit_set']));
$order++;
- }
+ }
}
$order = 0;
$finder = new RepositoryGroupFinder($db, $triggerable_id);
$commit_set_list = array();
+ $repository_owner_list = array();
+ $repositories_require_build = array();
+ $commit_set_items_by_repository = array();
foreach ($revision_set_list as $revision_set) {
if (!count($revision_set))
exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list));
$commit_set = array();
$repository_list = array();
$repository_with_patch = array();
+ $required_owner_commits = array();
+ $owner_commits_in_set = array();
foreach ($revision_set as $repository_id => $data) {
if ($repository_id == 'customRoots') {
$file_id_list = $data;
foreach ($file_id_list as $file_id) {
if (!is_numeric($file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $file_id)))
exit_with_error('InvalidUploadedFile', array('file' => $file_id));
- array_push($commit_set, array('root_file' => $file_id, 'patch_file' => NULL));
+ array_push($commit_set, array('root_file' => $file_id, 'patch_file' => NULL, 'requires_build' => FALSE, 'commit_owner' => NULL));
}
continue;
}
exit_with_error('InvalidRevision', array('repository' => $repository_id, 'data' => $data));
$commit_id = CommitLogFetcher::find_commit_id_by_revision($db, $repository_id, $revision);
if ($commit_id < 0)
- exit_with_error('AmbigiousRevision', array('repository' => $repository_id, 'revision' => $revision));
+ exit_with_error('AmbiguousRevision', array('repository' => $repository_id, 'revision' => $revision));
if (!$commit_id)
exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision));
+ $owner_revision = array_get($data, 'ownerRevision');
$patch_file_id = array_get($data, 'patch');
if ($patch_file_id) {
if (!is_numeric($patch_file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $patch_file_id)))
exit_with_error('InvalidPatchFile', array('patch' => $patch_file_id));
array_push($repository_with_patch, $repository_id);
+ $repositories_require_build[$repository_id] = TRUE;
}
- array_push($commit_set, array('commit' => $commit_id, 'patch_file' => $patch_file_id));
+ $repository = NULL;
+ $owner_commit_id = NULL;
+ if ($owner_revision) {
+ $repository = $db->select_first_row('repositories', 'repository', array('id' => intval($repository_id)));
+ if (!$repository)
+ exit_with_error('RepositoryNotFound', array('repository' => $repository_id));
+ $owner_commit = $db->select_first_row('commits', 'commit', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision));
+ if (!$owner_commit)
+ exit_with_error('InvalidOwnerRevision', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision));
+ if (!$db->select_first_row('commit_ownerships', 'commit', array('owned' => $commit_id, 'owner' => $owner_commit['commit_id'])))
+ exit_with_error('InvalidCommitOwnership', array('commitOwner' => $owner_commit['commit_id'], 'commitOwned' => $commit_id));
+ $repositories_require_build[$repository_id] = TRUE;
+ $owner_commit_id = $owner_commit['commit_id'];
+ $required_owner_commits[$owner_commit_id] = $commit_id;
+ } else
+ $owner_commits_in_set[$commit_id] = TRUE;
+
+ array_push($commit_set, array('commit' => $commit_id, 'patch_file' => $patch_file_id, 'requires_build' => FALSE, 'commit_owner' => $owner_commit_id));
+
+ array_ensure_item_has_array($commit_set_items_by_repository, $repository_id);
+ $commit_set_items_by_repository[$repository_id][] = &$commit_set[count($commit_set) - 1];
+
+ if ($owner_commit_id)
+ continue;
array_push($repository_list, $repository_id);
}
-
$repository_group_id = $finder->find_by_repositories($repository_list);
if (!$repository_group_id)
- exit_with_error('NoMatchingRepositoryGroup', array('repositoris' => $repository_list));
+ exit_with_error('NoMatchingRepositoryGroup', array('repositories' => $repository_list));
foreach ($repository_with_patch as $repository_id) {
if (!$finder->accepts_patch($repository_group_id, $repository_id))
exit_with_error('PatchNotAccepted', array('repository' => $repository_id, 'repositoryGroup' => $repository_group_id));
}
+ foreach($required_owner_commits as $required_owner_commit => $owned_commit) {
+ if (!array_get($owner_commits_in_set, $required_owner_commit, FALSE))
+ exit_with_error('CommitOwnerMustExistInCommitSet', array('owner_commit' => $required_owner_commit, 'owned_commit' => $owned_commit));
+ }
array_push($commit_set_list, array('repository_group' => $repository_group_id, 'set' => $commit_set));
}
+ foreach (array_keys($repositories_require_build) as $repository_id) {
+ foreach($commit_set_items_by_repository[$repository_id] as &$commit_set_item)
+ $commit_set_item['requires_build'] = TRUE;
+ }
return $commit_set_list;
}
if (!$commit)
exit_with_error('RevisionNotFound', array('repository' => $repository_name, 'revision' => $revision));
array_set_default($commit_sets, $i, array('set' => array()));
- array_push($commit_sets[$i]['set'], array('commit' => $commit['commit_id'], 'patch_file' => NULL));
+ array_push($commit_sets[$i]['set'], array('commit' => $commit['commit_id'], 'patch_file' => NULL, 'requires_build' => FALSE, 'commit_owner' => NULL));
}
}
$finder = new RepositoryGroupFinder($db, $triggerable_id);
$repository_group_id = $finder->find_by_repositories($repository_list);
if (!$repository_group_id)
- exit_with_error('NoMatchingRepositoryGroup', array('repositoris' => $repository_list));
+ exit_with_error('NoMatchingRepositoryGroup', array('repositories' => $repository_list));
if (count($commit_sets) < 2)
exit_with_error('InvalidCommitSets', array('commitSets' => $commit_sets_info));
item.commit = CommitLog.findById(item.commit);
item.patch = item.patch ? UploadedFile.findById(item.patch) : null;
item.rootFile = item.rootFile ? UploadedFile.findById(item.rootFile) : null;
+ item.commitOwner = item.commitOwner ? CommitLog.findById(item.commitOwner) : null;
}
rawData.customRoots = rawData.customRoots.map((fileId) => UploadedFile.findById(fileId));
return CommitSet.ensureSingleton(rawData.id, rawData);
this._repositoryToCommitMap = new Map;
this._repositoryToPatchMap = new Map;
this._repositoryToRootMap = new Map;
+ this._repositoryToCommitOwnerMap = new Map;
+ this._repositoryRequiresBuildMap = new Map;
this._latestCommitTime = null;
this._customRoots = [];
this._allRootFiles = [];
this._repositoryToCommitMap.clear();
this._repositoryToPatchMap.clear();
this._repositoryToRootMap.clear();
+ this._repositoryToCommitOwnerMap.clear();
+ this._repositoryRequiresBuildMap.clear();
this._repositories = [];
this._updateFromObject(object);
}
console.assert(commit instanceof CommitLog);
console.assert(!item.patch || item.patch instanceof UploadedFile);
console.assert(!item.rootFile || item.rootFile instanceof UploadedFile);
+ console.assert(!item.commitOwner || item.commitOwner instanceof CommitLog);
const repository = commit.repository();
this._repositoryToCommitMap.set(repository, commit);
this._repositoryToPatchMap.set(repository, item.patch);
+ this._repositoryToCommitOwnerMap.set(repository, item.commitOwner);
+ this._repositoryRequiresBuildMap.set(repository, item.requiresBuild);
this._repositoryToRootMap.set(repository, item.rootFile);
if (item.rootFile)
rootFiles.add(item.rootFile);
return commit ? commit.revision() : null;
}
+ ownerRevisionForRepository(repository)
+ {
+ const commit = this._repositoryToCommitOwnerMap.get(repository);
+ return commit ? commit.revision() : null;
+ }
+
patchForRepository(repository) { return this._repositoryToPatchMap.get(repository); }
rootForRepository(repository) { return this._repositoryToRootMap.get(repository); }
+ requiresBuildForRepository(repository) { return this._repositoryRequiresBuildMap.get(repository); }
// FIXME: This should return a Date object.
latestCommitTime()
return false;
if (this._repositoryToRootMap.get(repository) != other._repositoryToRootMap.get(repository))
return false;
+ if (this._repositoryToCommitOwnerMap.get(repository) != other._repositoryToCommitMap.get(repository))
+ return false;
+ if (this._repositoryRequiresBuildMap.get(repository) != other._repositoryRequiresBuildMap.get(repository))
+ return false;
}
return CommitSet.areCustomRootsEqual(this._customRoots, other._customRoots);
}
}
// Use CommitSet's static maps because MeasurementCommitSet and CommitSet are logically of the same type.
- // FIXME: Idaelly, DataModel should take care of this but traversing prototype chain is expensive.
+ // FIXME: Ideally, DataModel should take care of this but traversing prototype chain is expensive.
namedStaticMap(name) { return CommitSet.namedStaticMap(name); }
ensureNamedStaticMap(name) { return CommitSet.ensureNamedStaticMap(name); }
static namedStaticMap(name) { return CommitSet.namedStaticMap(name); }
this._customRoots = [];
}
- setRevisionForRepository(repository, revision, patch = null)
+ setRevisionForRepository(repository, revision, patch = null, ownerRevision = null)
{
console.assert(repository instanceof Repository);
console.assert(!patch || patch instanceof UploadedFile);
- this._revisionListByRepository.set(repository, {revision, patch});
+ this._revisionListByRepository.set(repository, {revision, patch, ownerRevision});
}
equals(other)
console.assert(other instanceof CustomCommitSet);
if (this._revisionListByRepository.size != other._revisionListByRepository.size)
return false;
- for (let repository of this._revisionListByRepository.keys()) {
- const thisRevision = this._revisionListByRepository.get(repository);
+
+ for (const [repository, thisRevision] of this._revisionListByRepository) {
const otherRevision = other._revisionListByRepository.get(repository);
if (!thisRevision != !otherRevision)
return false;
if (thisRevision && (thisRevision.revision != otherRevision.revision
- || thisRevision.patch != otherRevision.patch))
+ || thisRevision.patch != otherRevision.patch
+ || thisRevision.ownerRevision != otherRevision.ownerRevision))
return false;
}
return CommitSet.areCustomRootsEqual(this._customRoots, other._customRoots);
return null;
return entry.patch;
}
+ ownerRevisionForRepository(repository)
+ {
+ const entry = this._revisionListByRepository.get(repository);
+ if (!entry)
+ return null;
+ return entry.ownerRevision;
+ }
customRoots() { return this._customRoots; }
addCustomRoot(uploadedFile)
const patchFile = commitSet.patchForRepository(repository);
revisionSet[repository.id()] = {
revision: commitSet.revisionForRepository(repository),
+ ownerRevision: commitSet.ownerRevisionForRepository(repository),
patch: patchFile ? patchFile.id() : null,
};
}
});
});
- it('should return build requets associated with a given triggerable with appropriate commits and commitSets', () => {
+ it('should return build requests associated with a given triggerable with appropriate commits and commitSets with owned components', () => {
+ return MockData.addTestGroupWithOwnedCommits(TestServer.database()).then(() => {
+ return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit');
+ }).then((content) => {
+ assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
+
+ assert.equal(content['commitSets'].length, 2);
+ assert.equal(content['commitSets'][0].id, 403);
+ assert.deepEqual(content['commitSets'][0].revisionItems,
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null},
+ {commit: '93116', commitOwner: null, patch: null, requiresBuild: false, rootFile: null},
+ {commit: '1797', commitOwner: "93116", patch: null, requiresBuild: true, rootFile: null}]);
+ assert.equal(content['commitSets'][1].id, 404);
+ assert.deepEqual(content['commitSets'][1].revisionItems,
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null},
+ {commit: '96336', commitOwner: null, patch: null, requiresBuild: false, rootFile: null},
+ {commit: '2017', commitOwner: "96336", patch: null, requiresBuild: true, rootFile: null}]);
+
+ assert.equal(content['commits'].length, 5);
+ assert.deepEqual(content['commits'][0], {commitOwner: null, id: 87832, repository: '9', revision: '10.11 15A284', time: 0});
+ assert.deepEqual(content['commits'][1], {commitOwner: null, id: 93116, repository: '11', revision: '191622', time: 1445945816878})
+ assert.deepEqual(content['commits'][2], {commitOwner: '93116', id: '1797', repository: '213', revision: 'owned-jsc-6161', time: 1456960795300})
+ assert.deepEqual(content['commits'][3], {commitOwner: null, id: 96336, repository: '11', revision: '192736', time: 1448225325650})
+ assert.deepEqual(content['commits'][4], {commitOwner: '96336', id: 2017, repository: '213', revision: 'owned-jsc-9191', time: 1462230837100})
+
+ assert.equal(content['buildRequests'].length, 4);
+ content['buildRequests'][0]['createdAt'] = 0;
+ content['buildRequests'][1]['createdAt'] = 0;
+ content['buildRequests'][2]['createdAt'] = 0;
+ content['buildRequests'][3]['createdAt'] = 0;
+ assert.deepEqual(content['buildRequests'][0], {id: '704', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '0', commitSet: '403', status: 'pending', url: null, build: null, createdAt: 0});
+ assert.deepEqual(content['buildRequests'][1], {id: '705', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '1', commitSet: '404', status: 'pending', url: null, build: null, createdAt: 0});
+ assert.deepEqual(content['buildRequests'][2], {id: '706', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '2', commitSet: '403', status: 'pending', url: null, build: null, createdAt: 0});
+ assert.deepEqual(content['buildRequests'][3], {id: '707', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '3', commitSet: '404', status: 'pending', url: null, build: null, createdAt: 0});
+ });
+ });
+
+ it('should return build requests associated with a given triggerable with appropriate commits and commitSets', () => {
return MockData.addMockData(TestServer.database()).then(() => {
return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit');
}).then((content) => {
assert.equal(content['commitSets'].length, 2);
assert.equal(content['commitSets'][0].id, 401);
assert.deepEqual(content['commitSets'][0].revisionItems,
- [{commit: '87832', patch: null, rootFile: null}, {commit: '93116', patch: null, rootFile: null}]);
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}, {commit: '93116', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}]);
assert.equal(content['commitSets'][1].id, 402);
assert.deepEqual(content['commitSets'][1].revisionItems,
- [{commit: '87832', patch: null, rootFile: null}, {commit: '96336', patch: null, rootFile: null}]);
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}, {commit: '96336', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}]);
assert.equal(content['commits'].length, 3);
assert.equal(content['commits'][0].id, 87832);
assert.equal(content['commitSets'].length, 2);
assert.equal(content['commitSets'][0].id, 401);
assert.deepEqual(content['commitSets'][0].revisionItems,
- [{commit: '87832', patch: null, rootFile: null}, {commit: '93116', patch: null, rootFile: null}]);
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}, {commit: '93116', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}]);
assert.equal(content['commitSets'][1].id, 402);
assert.deepEqual(content['commitSets'][1].revisionItems,
- [{commit: '87832', patch: null, rootFile: null}, {commit: '96336', patch: null, rootFile: null}]);
+ [{commit: '87832', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}, {commit: '96336', commitOwner: null, patch: null, requiresBuild: false, rootFile: null}]);
assert.equal(content['commits'].length, 3);
assert.equal(content['commits'][0].id, 87832);
});
});
+ it('should be fetchable by BuildRequest.fetchForTriggerable for commitSets with owned commits', () => {
+ return MockData.addTestGroupWithOwnedCommits(TestServer.database()).then(() => {
+ return Manifest.fetch();
+ }).then(() => {
+ return BuildRequest.fetchForTriggerable('build-webkit');
+ }).then((buildRequests) => {
+ assert.equal(buildRequests.length, 4);
+
+ let test = Test.findById(200);
+ assert(test);
+
+ let platform = Platform.findById(65);
+ assert(platform);
+
+ assert.equal(buildRequests[0].id(), 704);
+ assert.equal(buildRequests[0].testGroupId(), 900);
+ assert.equal(buildRequests[0].test(), test);
+ assert.equal(buildRequests[0].platform(), platform);
+ assert.equal(buildRequests[0].order(), 0);
+ assert.ok(buildRequests[0].commitSet() instanceof CommitSet);
+ assert.ok(!buildRequests[0].hasFinished());
+ assert.ok(!buildRequests[0].hasStarted());
+ assert.ok(buildRequests[0].isPending());
+ assert.equal(buildRequests[0].statusLabel(), 'Waiting');
+
+ assert.equal(buildRequests[1].id(), 705);
+ assert.equal(buildRequests[1].testGroupId(), 900);
+ assert.equal(buildRequests[1].test(), test);
+ assert.equal(buildRequests[1].platform(), platform);
+ assert.equal(buildRequests[1].order(), 1);
+ assert.ok(buildRequests[1].commitSet() instanceof CommitSet);
+ assert.ok(!buildRequests[1].hasFinished());
+ assert.ok(!buildRequests[1].hasStarted());
+ assert.ok(buildRequests[1].isPending());
+ assert.equal(buildRequests[1].statusLabel(), 'Waiting');
+
+ assert.equal(buildRequests[2].id(), 706);
+ assert.equal(buildRequests[2].testGroupId(), 900);
+ assert.equal(buildRequests[2].test(), test);
+ assert.equal(buildRequests[2].platform(), platform);
+ assert.equal(buildRequests[2].order(), 2);
+ assert.ok(buildRequests[2].commitSet() instanceof CommitSet);
+ assert.ok(!buildRequests[2].hasFinished());
+ assert.ok(!buildRequests[2].hasStarted());
+ assert.ok(buildRequests[2].isPending());
+ assert.equal(buildRequests[2].statusLabel(), 'Waiting');
+
+ assert.equal(buildRequests[3].id(), 707);
+ assert.equal(buildRequests[3].testGroupId(), 900);
+ assert.equal(buildRequests[3].test(), test);
+ assert.equal(buildRequests[3].platform(), platform);
+ assert.equal(buildRequests[3].order(), 3);
+ assert.ok(buildRequests[3].commitSet() instanceof CommitSet);
+ assert.ok(!buildRequests[3].hasFinished());
+ assert.ok(!buildRequests[3].hasStarted());
+ assert.ok(buildRequests[3].isPending());
+ assert.equal(buildRequests[3].statusLabel(), 'Waiting');
+
+ const osx = Repository.findById(9);
+ assert.equal(osx.name(), 'macOS');
+
+ const webkit = Repository.findById(11);
+ assert.equal(webkit.name(), 'WebKit');
+
+ const jsc = Repository.findById(213);
+ assert.equal(jsc.name(), 'JavaScriptCore');
+
+ const firstCommitSet = buildRequests[0].commitSet();
+ assert.equal(buildRequests[2].commitSet(), firstCommitSet);
+
+ const secondCommitSet = buildRequests[1].commitSet();
+ assert.equal(buildRequests[3].commitSet(), secondCommitSet);
+
+ assert.equal(firstCommitSet.revisionForRepository(osx), '10.11 15A284');
+ assert.equal(firstCommitSet.revisionForRepository(webkit), '191622');
+ assert.equal(firstCommitSet.revisionForRepository(jsc), 'owned-jsc-6161');
+ assert.equal(firstCommitSet.ownerRevisionForRepository(jsc), '191622');
+
+ assert.equal(secondCommitSet.revisionForRepository(osx), '10.11 15A284');
+ assert.equal(secondCommitSet.revisionForRepository(webkit), '192736');
+ assert.equal(secondCommitSet.revisionForRepository(jsc), 'owned-jsc-9191');
+ assert.equal(secondCommitSet.ownerRevisionForRepository(jsc), '192736');
+
+ const osxCommit = firstCommitSet.commitForRepository(osx);
+ assert.equal(osxCommit.revision(), '10.11 15A284');
+ assert.equal(osxCommit, secondCommitSet.commitForRepository(osx));
+
+ const firstWebKitCommit = firstCommitSet.commitForRepository(webkit);
+ assert.equal(firstWebKitCommit.revision(), '191622');
+ assert.equal(+firstWebKitCommit.time(), 1445945816878);
+
+ const secondWebKitCommit = secondCommitSet.commitForRepository(webkit);
+ assert.equal(secondWebKitCommit.revision(), '192736');
+ assert.equal(+secondWebKitCommit.time(), 1448225325650);
+
+ const firstSJCCommit = firstCommitSet.commitForRepository(jsc);
+ assert.equal(firstSJCCommit.revision(), 'owned-jsc-6161');
+ assert.equal(+firstSJCCommit.time(), 1456960795300);
+
+ const secondSJCCommit = secondCommitSet.commitForRepository(jsc);
+ assert.equal(secondSJCCommit.revision(), 'owned-jsc-9191');
+ assert.equal(+secondSJCCommit.time(), 1462230837100)
+ });
+ });
+
it('should be fetchable by BuildRequest.fetchForTriggerable', () => {
return MockData.addMockData(TestServer.database()).then(() => {
return Manifest.fetch();
{repository: MockData.macosRepositoryId(), acceptsPatch: false},
{repository: MockData.webkitRepositoryId(), acceptsPatch: true}
]},
+ {name: 'system-webkit-sjc', acceptsRoot: true, repositories: [
+ {repository: MockData.macosRepositoryId(), acceptsPatch: false},
+ {repository: MockData.jscRepositoryId(), acceptsPatch: false},
+ {repository: MockData.webkitRepositoryId(), acceptsPatch: true}
+ ]},
]
};
return MockData.addMockData(TestServer.database()).then(() => {
});
});
- it('should return "AmbigiousRevision" when there are multiple commits that match the specified revision string', () => {
+ it('should return "AmbiguousRevision" when there are multiple commits that match the specified revision string', () => {
return addTriggerableAndCreateTask('some task', ['2ceda45d3cd63cde58d0dbf5767714e03d902e43', '2c71a8ddc1f661663ccfd1a29c633ba57e879533']).then((taskId) => {
const webkit = Repository.all().find((repository) => repository.name() == 'WebKit');
const revisionSets = [{[webkit.id()]: {revision: '2ceda'}}, {[webkit.id()]: {revision: '2c'}}];
return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, revisionSets}).then((content) => {
assert(false, 'should never be reached');
}, (error) => {
- assert.equal(error, 'AmbigiousRevision');
+ assert.equal(error, 'AmbiguousRevision');
});
});
});
});
});
+ it('should return "InvalidOwnerRevision" when commit ownership is not valid', () => {
+ let taskId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ const webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ const macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ const jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191621'}},
+ {[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '191622'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then(() => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 'InvalidOwnerRevision');
+ });
+ });
+
+ it('should return "InvalidCommitOwnership" when commit ownership is not valid', () => {
+ let taskId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ const webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ const macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ const jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '191622'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then(() => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 'InvalidCommitOwnership');
+ });
+ });
+
+ it('should return "CommitOwnerMustExistInCommitSet" when owner of a commit is missing in the commit set', () => {
+ let taskId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ const webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ const macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ const jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then(() => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 'CommitOwnerMustExistInCommitSet');
+ });
+ });
+
+ it('should return "CommitOwnerMustExistInCommitSet" when repository of owner commit is not specified at all', () => {
+ let taskId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ const webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ const macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ const jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then(() => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 'CommitOwnerMustExistInCommitSet');
+ });
+ });
+
it('should create a test group from commitSets with the repetition count of one when repetitionCount is omitted', () => {
return addTriggerableAndCreateTask('some task').then((taskId) => {
let insertedGroupId;
});
});
- it('should create a test group with a patch', () => {
+ it('should create a build test group with a patch', () => {
let taskId;
let webkit;
let macos;
});
});
+ it('should create a build test group with a owned commits even when one of group does not contain an owned commit', () => {
+ let taskId;
+ let webkit;
+ let jsc;
+ let macos;
+ let insertedGroupId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}},
+ {[webkit.id()]: {revision: '192736'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then((content) => {
+ insertedGroupId = content['testGroupId'];
+ return TestGroup.fetchForTask(taskId, true);
+ }).then((testGroups) => {
+ assert.equal(testGroups.length, 1);
+ const group = testGroups[0];
+ assert.equal(group.id(), insertedGroupId);
+ assert.equal(group.repetitionCount(), 2);
+ assert.equal(group.test(), Test.findById(MockData.someTestId()));
+ assert.equal(group.platform(), Platform.findById(MockData.somePlatformId()));
+ const requests = group.buildRequests();
+ assert.equal(requests.length, 6);
+
+ assert.equal(requests[0].isBuild(), true);
+ assert.equal(requests[1].isBuild(), true);
+ assert.equal(requests[2].isBuild(), false);
+ assert.equal(requests[3].isBuild(), false);
+ assert.equal(requests[4].isBuild(), false);
+ assert.equal(requests[5].isBuild(), false);
+
+ assert.equal(requests[0].isTest(), false);
+ assert.equal(requests[1].isTest(), false);
+ assert.equal(requests[2].isTest(), true);
+ assert.equal(requests[3].isTest(), true);
+ assert.equal(requests[4].isTest(), true);
+ assert.equal(requests[5].isTest(), true);
+
+ const set0 = requests[0].commitSet();
+ const set1 = requests[1].commitSet();
+ assert.equal(requests[2].commitSet(), set0);
+ assert.equal(requests[3].commitSet(), set1);
+ assert.equal(requests[4].commitSet(), set0);
+ assert.equal(requests[5].commitSet(), set1);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set0.repositories()), [webkit, macos]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set1.repositories()), [jsc, webkit, macos]);
+ assert.deepEqual(set1.customRoots(), []);
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '192736');
+ assert.equal(set0.patchForRepository(webkit), null);
+ assert.equal(set1.patchForRepository(webkit), null);
+ assert.equal(set0.requiresBuildForRepository(webkit), false);
+ assert.equal(set1.requiresBuildForRepository(webkit), false);
+ assert.equal(set0.revisionForRepository(macos), '15A284');
+ assert.equal(set0.revisionForRepository(macos), set1.revisionForRepository(macos));
+ assert.equal(set0.commitForRepository(macos), set1.commitForRepository(macos));
+ assert.equal(set0.patchForRepository(macos), null);
+ assert.equal(set1.patchForRepository(macos), null);
+ assert.equal(set0.requiresBuildForRepository(macos), false);
+ assert.equal(set1.requiresBuildForRepository(macos), false);
+ assert.equal(set0.revisionForRepository(jsc), null);
+ assert.equal(set1.revisionForRepository(jsc), 'owned-jsc-9191');
+ assert.equal(set0.patchForRepository(jsc), null);
+ assert.equal(set1.patchForRepository(jsc), null);
+ assert.equal(set0.ownerRevisionForRepository(jsc), null);
+ assert.equal(set1.ownerRevisionForRepository(jsc), '192736');
+ assert.equal(set1.requiresBuildForRepository(jsc), true);
+ assert(!set0.equals(set1));
+ });
+ });
+
+ it('should create a test group with a owned commits even when no patch is specified', () => {
+ let taskId;
+ let webkit;
+ let jsc;
+ let macos;
+ let insertedGroupId;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[webkit.id()]: {revision: '192736'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then((content) => {
+ insertedGroupId = content['testGroupId'];
+ return TestGroup.fetchForTask(taskId, true);
+ }).then((testGroups) => {
+ assert.equal(testGroups.length, 1);
+ const group = testGroups[0];
+ assert.equal(group.id(), insertedGroupId);
+ assert.equal(group.repetitionCount(), 2);
+ assert.equal(group.test(), Test.findById(MockData.someTestId()));
+ assert.equal(group.platform(), Platform.findById(MockData.somePlatformId()));
+ const requests = group.buildRequests();
+ assert.equal(requests.length, 6);
+
+ assert.equal(requests[0].isBuild(), true);
+ assert.equal(requests[1].isBuild(), true);
+ assert.equal(requests[2].isBuild(), false);
+ assert.equal(requests[3].isBuild(), false);
+ assert.equal(requests[4].isBuild(), false);
+ assert.equal(requests[5].isBuild(), false);
+
+ assert.equal(requests[0].isTest(), false);
+ assert.equal(requests[1].isTest(), false);
+ assert.equal(requests[2].isTest(), true);
+ assert.equal(requests[3].isTest(), true);
+ assert.equal(requests[4].isTest(), true);
+ assert.equal(requests[5].isTest(), true);
+
+ const set0 = requests[0].commitSet();
+ const set1 = requests[1].commitSet();
+ assert.equal(requests[2].commitSet(), set0);
+ assert.equal(requests[3].commitSet(), set1);
+ assert.equal(requests[4].commitSet(), set0);
+ assert.equal(requests[5].commitSet(), set1);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set0.repositories()), [jsc, webkit, macos]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set1.repositories()), [jsc, webkit, macos]);
+ assert.deepEqual(set1.customRoots(), []);
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '192736');
+ assert.equal(set0.patchForRepository(webkit), null);
+ assert.equal(set1.patchForRepository(webkit), null);
+ assert.equal(set0.requiresBuildForRepository(webkit), false);
+ assert.equal(set1.requiresBuildForRepository(webkit), false);
+ assert.equal(set0.revisionForRepository(macos), '15A284');
+ assert.equal(set0.revisionForRepository(macos), set1.revisionForRepository(macos));
+ assert.equal(set0.commitForRepository(macos), set1.commitForRepository(macos));
+ assert.equal(set0.patchForRepository(macos), null);
+ assert.equal(set1.patchForRepository(macos), null);
+ assert.equal(set0.requiresBuildForRepository(macos), false);
+ assert.equal(set1.requiresBuildForRepository(macos), false);
+ assert.equal(set0.revisionForRepository(jsc), 'owned-jsc-6161');
+ assert.equal(set1.revisionForRepository(jsc), 'owned-jsc-9191');
+ assert.equal(set0.patchForRepository(jsc), null);
+ assert.equal(set1.patchForRepository(jsc), null);
+ assert.equal(set0.ownerRevisionForRepository(jsc), '191622');
+ assert.equal(set1.ownerRevisionForRepository(jsc), '192736');
+ assert.equal(set0.requiresBuildForRepository(jsc), true);
+ assert.equal(set1.requiresBuildForRepository(jsc), true);
+ assert(!set0.equals(set1));
+ });
+ });
+
+ it('should create a test group with a owned commits and a patch', () => {
+ let taskId;
+ let webkit;
+ let macos;
+ let jsc;
+ let insertedGroupId;
+ let uploadedFile;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore')[0];
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content');
+ }).then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const rawFile = response['uploadedFile'];
+ uploadedFile = UploadedFile.ensureSingleton(rawFile.id, rawFile);
+ const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[webkit.id()]: {revision: '192736', patch: uploadedFile.id()}, [macos.id()]: {revision: '15A284'}, [jsc.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then((content) => {
+ insertedGroupId = content['testGroupId'];
+ return TestGroup.fetchForTask(taskId, true);
+ }).then((testGroups) => {
+ assert.equal(testGroups.length, 1);
+ const group = testGroups[0];
+ assert.equal(group.id(), insertedGroupId);
+ assert.equal(group.repetitionCount(), 2);
+ assert.equal(group.test(), Test.findById(MockData.someTestId()));
+ assert.equal(group.platform(), Platform.findById(MockData.somePlatformId()));
+ const requests = group.buildRequests();
+ assert.equal(requests.length, 6);
+
+ assert.equal(requests[0].isBuild(), true);
+ assert.equal(requests[1].isBuild(), true);
+ assert.equal(requests[2].isBuild(), false);
+ assert.equal(requests[3].isBuild(), false);
+ assert.equal(requests[4].isBuild(), false);
+ assert.equal(requests[5].isBuild(), false);
+
+ assert.equal(requests[0].isTest(), false);
+ assert.equal(requests[1].isTest(), false);
+ assert.equal(requests[2].isTest(), true);
+ assert.equal(requests[3].isTest(), true);
+ assert.equal(requests[4].isTest(), true);
+ assert.equal(requests[5].isTest(), true);
+
+ const set0 = requests[0].commitSet();
+ const set1 = requests[1].commitSet();
+ assert.equal(requests[2].commitSet(), set0);
+ assert.equal(requests[3].commitSet(), set1);
+ assert.equal(requests[4].commitSet(), set0);
+ assert.equal(requests[5].commitSet(), set1);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set0.repositories()), [jsc, webkit, macos]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set1.repositories()), [jsc, webkit, macos]);
+ assert.deepEqual(set1.customRoots(), []);
+
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '192736');
+ assert.equal(set0.patchForRepository(webkit), null);
+ assert.equal(set1.patchForRepository(webkit), uploadedFile);
+ assert.equal(set0.ownerRevisionForRepository(webkit), null);
+ assert.equal(set1.ownerRevisionForRepository(webkit), null);
+ assert.equal(set0.requiresBuildForRepository(webkit), true);
+ assert.equal(set1.requiresBuildForRepository(webkit), true);
+
+ assert.equal(set0.revisionForRepository(macos), '15A284');
+ assert.equal(set0.revisionForRepository(macos), set1.revisionForRepository(macos));
+ assert.equal(set0.commitForRepository(macos), set1.commitForRepository(macos));
+ assert.equal(set0.patchForRepository(macos), null);
+ assert.equal(set1.patchForRepository(macos), null);
+ assert.equal(set0.ownerRevisionForRepository(macos), null);
+ assert.equal(set1.ownerRevisionForRepository(macos), null);
+ assert.equal(set0.requiresBuildForRepository(macos), false);
+ assert.equal(set1.requiresBuildForRepository(macos), false);
+
+ assert.equal(set0.revisionForRepository(jsc), 'owned-jsc-6161');
+ assert.equal(set1.revisionForRepository(jsc), 'owned-jsc-9191');
+ assert.equal(set0.patchForRepository(jsc), null);
+ assert.equal(set1.patchForRepository(jsc), null);
+ assert.equal(set0.ownerRevisionForRepository(jsc), '191622');
+ assert.equal(set1.ownerRevisionForRepository(jsc), '192736');
+ assert.equal(set0.requiresBuildForRepository(jsc), true);
+ assert.equal(set1.requiresBuildForRepository(jsc), true);
+ assert(!set0.equals(set1));
+ });
+ });
+
+ it('should still work even if components with same name but one is owned, one is not', () => {
+ let taskId;
+ let webkit;
+ let macos;
+ let jsc;
+ let ownedJSC;
+ let insertedGroupId;
+ let uploadedFile;
+ return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
+ return MockData.addAnotherTriggerable(TestServer.database());
+ }).then(() => {
+ webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
+ jsc = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore' && !repository.ownerId())[0];
+ ownedJSC = Repository.all().filter((repository) => repository.name() == 'JavaScriptCore' && repository.ownerId())[0];
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content');
+ }).then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const rawFile = response['uploadedFile'];
+ uploadedFile = UploadedFile.ensureSingleton(rawFile.id, rawFile);
+ const revisionSets = [{[jsc.id()]: {revision: 'jsc-6161'}, [webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}, [ownedJSC.id()]: {revision: 'owned-jsc-6161', ownerRevision: '191622'}},
+ {[jsc.id()]: {revision: 'jsc-9191'}, [webkit.id()]: {revision: '192736', patch: uploadedFile.id()}, [macos.id()]: {revision: '15A284'}, [ownedJSC.id()]: {revision: 'owned-jsc-9191', ownerRevision: '192736'}}];
+ return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
+ }).then((content) => {
+ insertedGroupId = content['testGroupId'];
+ return TestGroup.fetchForTask(taskId, true);
+ }).then((testGroups) => {
+ assert.equal(testGroups.length, 1);
+ const group = testGroups[0];
+ assert.equal(group.id(), insertedGroupId);
+ assert.equal(group.repetitionCount(), 2);
+ assert.equal(group.test(), Test.findById(MockData.someTestId()));
+ assert.equal(group.platform(), Platform.findById(MockData.somePlatformId()));
+ const requests = group.buildRequests();
+ assert.equal(requests.length, 6);
+
+ assert.equal(requests[0].isBuild(), true);
+ assert.equal(requests[1].isBuild(), true);
+ assert.equal(requests[2].isBuild(), false);
+ assert.equal(requests[3].isBuild(), false);
+ assert.equal(requests[4].isBuild(), false);
+ assert.equal(requests[5].isBuild(), false);
+
+ assert.equal(requests[0].isTest(), false);
+ assert.equal(requests[1].isTest(), false);
+ assert.equal(requests[2].isTest(), true);
+ assert.equal(requests[3].isTest(), true);
+ assert.equal(requests[4].isTest(), true);
+ assert.equal(requests[5].isTest(), true);
+
+ const set0 = requests[0].commitSet();
+ const set1 = requests[1].commitSet();
+ assert.equal(requests[2].commitSet(), set0);
+ assert.equal(requests[3].commitSet(), set1);
+ assert.equal(requests[4].commitSet(), set0);
+ assert.equal(requests[5].commitSet(), set1);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set0.repositories()), [jsc, ownedJSC, webkit, macos]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set1.repositories()), [jsc, ownedJSC, webkit, macos]);
+ assert.deepEqual(set1.customRoots(), []);
+
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '192736');
+ assert.equal(set0.patchForRepository(webkit), null);
+ assert.equal(set1.patchForRepository(webkit), uploadedFile);
+ assert.equal(set0.ownerRevisionForRepository(webkit), null);
+ assert.equal(set1.ownerRevisionForRepository(webkit), null);
+ assert.equal(set0.requiresBuildForRepository(webkit), true);
+ assert.equal(set1.requiresBuildForRepository(webkit), true);
+
+ assert.equal(set0.revisionForRepository(macos), '15A284');
+ assert.equal(set0.revisionForRepository(macos), set1.revisionForRepository(macos));
+ assert.equal(set0.commitForRepository(macos), set1.commitForRepository(macos));
+ assert.equal(set0.patchForRepository(macos), null);
+ assert.equal(set1.patchForRepository(macos), null);
+ assert.equal(set0.ownerRevisionForRepository(macos), null);
+ assert.equal(set1.ownerRevisionForRepository(macos), null);
+ assert.equal(set0.requiresBuildForRepository(macos), false);
+ assert.equal(set1.requiresBuildForRepository(macos), false);
+
+ assert.equal(set0.revisionForRepository(ownedJSC), 'owned-jsc-6161');
+ assert.equal(set1.revisionForRepository(ownedJSC), 'owned-jsc-9191');
+ assert.equal(set0.patchForRepository(ownedJSC), null);
+ assert.equal(set1.patchForRepository(ownedJSC), null);
+ assert.equal(set0.ownerRevisionForRepository(ownedJSC), '191622');
+ assert.equal(set1.ownerRevisionForRepository(ownedJSC), '192736');
+ assert.equal(set0.requiresBuildForRepository(ownedJSC), true);
+ assert.equal(set1.requiresBuildForRepository(ownedJSC), true);
+
+ assert.equal(set0.revisionForRepository(jsc), 'jsc-6161');
+ assert.equal(set1.revisionForRepository(jsc), 'jsc-9191');
+ assert.equal(set0.patchForRepository(jsc), null);
+ assert.equal(set1.patchForRepository(jsc), null);
+ assert.equal(set0.ownerRevisionForRepository(jsc), null);
+ assert.equal(set1.ownerRevisionForRepository(jsc), null);
+ assert.equal(set0.requiresBuildForRepository(jsc), false);
+ assert.equal(set1.requiresBuildForRepository(jsc), false);
+ assert(!set0.equals(set1));
+ });
+ });
+
it('should not create a build request to build a patch when the commit set does not have a patch', () => {
let taskId;
let webkit;
let taskId;
let webkit;
let macos;
- let insertedGroupId;
let uploadedFile;
return addTriggerableAndCreateTask('some task').then((id) => taskId = id).then(() => {
webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
const rawFile = response['uploadedFile'];
uploadedFile = UploadedFile.ensureSingleton(rawFile.id, rawFile);
const revisionSets = [{[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284', patch: uploadedFile.id()}},
- {[webkit.id()]: {revision: '191622'}, [macos.id()]: {revision: '15A284'}}];
+ {[webkit.id()]: {revision: '192736'}, [macos.id()]: {revision: '15A284'}}];
return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets});
}).then(() => {
assert(false, 'should never be reached');
}).then((result) => {
const fileB = result.uploadedFile;
return Promise.all([
- db.query('UPDATE commit_set_items SET commitset_patch_file = $1 WHERE commitset_set = 402 AND commitset_commit = 87832', [fileA.id]),
- db.query('UPDATE commit_set_items SET commitset_patch_file = $1 WHERE commitset_set = 402 AND commitset_commit = 96336', [fileB.id])
+ db.query('UPDATE commit_set_items SET (commitset_patch_file, commitset_requires_build) = ($1, TRUE) WHERE commitset_set = 402 AND commitset_commit = 87832', [fileA.id]),
+ db.query('UPDATE commit_set_items SET (commitset_patch_file, commitset_requires_build) = ($1, TRUE) WHERE commitset_set = 402 AND commitset_commit = 96336', [fileB.id])
]);
}).then(() => {
return TemporaryFile.makeTemporaryFileOfSizeInMB('other.dat', limitInMB, 'c');
}).then((result) => {
const fileB = result.uploadedFile;
return Promise.all([
- db.query('UPDATE commit_set_items SET commitset_patch_file = $1 WHERE commitset_set = 402 AND commitset_commit = 87832', [fileA.id]),
- db.query('UPDATE commit_set_items SET commitset_patch_file = $1 WHERE commitset_set = 402 AND commitset_commit = 96336', [fileB.id])
+ db.query('UPDATE commit_set_items SET (commitset_patch_file, commitset_requires_build) = ($1, TRUE) WHERE commitset_set = 402 AND commitset_commit = 87832', [fileA.id]),
+ db.query('UPDATE commit_set_items SET (commitset_patch_file, commitset_requires_build) = ($1, TRUE) WHERE commitset_set = 402 AND commitset_commit = 96336', [fileB.id])
]);
}).then(() => {
return TemporaryFile.makeTemporaryFileOfSizeInMB('another.dat', limitInMB, 'c');
return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
}).then((result) => {
const fileB = result.uploadedFile;
- return db.query(`UPDATE commit_set_items SET (commitset_patch_file, commitset_root_file) = ($1, $2)
+ return db.query(`UPDATE commit_set_items SET (commitset_patch_file, commitset_root_file, commitset_requires_build) = ($1, $2, TRUE)
WHERE commitset_set = 402 AND commitset_commit = 87832`, [fileA.id, fileB.id]);
}).then(() => {
return TemporaryFile.makeTemporaryFileOfSizeInMB('another.dat', limitInMB, 'c');
otherPlatformId() { return 101; },
macosRepositoryId() { return 9; },
webkitRepositoryId() { return 11; },
+ ownedJSCRepositoryId() { return 213; },
+ jscRepositoryId() { return 222; },
gitWebkitRepositoryId() { return 111; },
sharedRepositoryId() { return 14; },
addMockConfiguration: function (db)
db.insert('repositories', {id: this.macosRepositoryId(), name: 'macOS'}),
db.insert('repositories', {id: this.webkitRepositoryId(), name: 'WebKit'}),
db.insert('repositories', {id: this.sharedRepositoryId(), name: 'Shared'}),
+ db.insert('repositories', {id: this.ownedJSCRepositoryId(), owner: this.webkitRepositoryId(), name: 'JavaScriptCore'}),
+ db.insert('repositories', {id: this.jscRepositoryId(), name: 'JavaScriptCore'}),
db.insert('triggerable_repository_groups', {id: 2001, name: 'webkit-svn', triggerable: 1000}),
db.insert('triggerable_repositories', {repository: this.macosRepositoryId(), group: 2001}),
db.insert('triggerable_repositories', {repository: this.webkitRepositoryId(), group: 2001}),
db.insert('commits', {id: 96336, repository: this.webkitRepositoryId(), revision: '192736', time: (new Date(1448225325650)).toISOString()}),
db.insert('commits', {id: 111168, repository: this.sharedRepositoryId(), revision: '80229', time: '2016-03-02T23:17:54.3Z'}),
db.insert('commits', {id: 111169, repository: this.sharedRepositoryId(), revision: '80230', time: '2016-03-02T23:37:18.0Z'}),
+ db.insert('commits', {id: 11797, repository: this.jscRepositoryId(), revision: 'jsc-6161', time: '2016-03-02T23:19:55.3Z'}),
+ db.insert('commits', {id: 12017, repository: this.jscRepositoryId(), revision: 'jsc-9191', time: '2016-05-02T23:13:57.1Z'}),
+ db.insert('commits', {id: 1797, repository: this.ownedJSCRepositoryId(), revision: 'owned-jsc-6161', time: '2016-03-02T23:19:55.3Z'}),
+ db.insert('commits', {id: 2017, repository: this.ownedJSCRepositoryId(), revision: 'owned-jsc-9191', time: '2016-05-02T23:13:57.1Z'}),
+ db.insert('commit_ownerships', {owner: 93116, owned: 1797}),
+ db.insert('commit_ownerships', {owner: 96336, owned: 2017}),
db.insert('builds', {id: 901, number: '901', time: '2015-10-27T12:05:27.1Z'}),
db.insert('platforms', {id: MockData.somePlatformId(), name: 'some platform'}),
db.insert('platforms', {id: MockData.otherPlatformId(), name: 'other platform'}),
db.insert('build_requests', {id: 703, status: statusList[3], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 600, order: 3, commit_set: 402}),
]);
},
+ addAnotherTriggerable(db) {
+ return Promise.all([
+ db.insert('build_triggerables', {id: 2345, name: 'build-webkit-jsc'}),
+ db.insert('triggerable_repository_groups', {id: 4002, name: 'mac-svnwebkit-jsc', triggerable: 2345}),
+ db.insert('triggerable_repositories', {repository: this.macosRepositoryId(), group: 4002}),
+ db.insert('triggerable_repositories', {repository: this.webkitRepositoryId(), group: 4002}),
+ db.insert('triggerable_repositories', {repository: this.jscRepositoryId(), group: 4002}),
+ ]);
+ },
addEmptyTriggerable(db)
{
return Promise.all([
db.insert('build_requests', {id: 711, status: statusList[1], triggerable, repository_group, platform, test, group: 601, order: 1, commit_set: 402}),
]);
},
+ addTestGroupWithOwnedCommits(db, statusList)
+ {
+
+ if (!statusList)
+ statusList = ['pending', 'pending', 'pending', 'pending'];
+ return Promise.all([
+ this.addMockConfiguration(db),
+ this.addAnotherTriggerable(db),
+ db.insert('analysis_tasks', {id: 1080, platform: 65, metric: 300, name: 'some task with component test',
+ start_run: 801, start_run_time: '2015-10-27T12:05:27.1Z',
+ end_run: 801, end_run_time: '2015-10-27T12:05:27.1Z'}),
+ db.insert('analysis_test_groups', {id: 900, task: 1080, name: 'some test group with component test'}),
+ db.insert('commit_sets', {id: 403}),
+ db.insert('commit_set_items', {set: 403, commit: 87832}),
+ db.insert('commit_set_items', {set: 403, commit: 93116}),
+ db.insert('commit_set_items', {set: 403, commit: 1797, commit_owner: 93116, requires_build: true}),
+ db.insert('commit_sets', {id: 404}),
+ db.insert('commit_set_items', {set: 404, commit: 87832}),
+ db.insert('commit_set_items', {set: 404, commit: 96336}),
+ db.insert('commit_set_items', {set: 404, commit: 2017, commit_owner: 96336, requires_build: true}),
+ db.insert('build_requests', {id: 704, status: statusList[0], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 900, order: 0, commit_set: 403}),
+ db.insert('build_requests', {id: 705, status: statusList[1], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 900, order: 1, commit_set: 404}),
+ db.insert('build_requests', {id: 706, status: statusList[2], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 900, order: 2, commit_set: 403}),
+ db.insert('build_requests', {id: 707, status: statusList[3], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 900, order: 3, commit_set: 404}),
+ ]);
+ },
mockTestSyncConfigWithSingleBuilder: function ()
{
return {
importFromV3('models/builder.js', 'Build');
importFromV3('models/builder.js', 'Builder');
importFromV3('models/commit-log.js', 'CommitLog');
+importFromV3('models/commit-set.js', 'CustomCommitSet')
importFromV3('models/manifest.js', 'Manifest');
importFromV3('models/measurement-adaptor.js', 'MeasurementAdaptor');
importFromV3('models/measurement-cluster.js', 'MeasurementCluster');
--- /dev/null
+"use strict";
+
+const assert = require('assert');
+require('../tools/js/v3-models.js');
+const MockModels = require('./resources/mock-v3-models.js').MockModels;
+
+function createPatch()
+{
+ return new UploadedFile(453, {'createdAt': new Date('2017-05-01T19:16:53Z'), 'filename': 'patch.dat', 'extension': '.dat', 'author': 'some user',
+ size: 534637, sha256: '169463c8125e07c577110fe144ecd63942eb9472d438fc0014f474245e5df8a1'});
+}
+
+function createRoot()
+{
+ return new UploadedFile(456, {'createdAt': new Date('2017-05-01T21:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user',
+ size: 16452234, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4d6c175809ba968f78f656d58d'});
+}
+
+function customCommitSetWithoutOwnedCommit()
+{
+ const customCommitSet = new CustomCommitSet;
+ customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
+ customCommitSet.setRevisionForRepository(MockModels.webkit, '200805');
+ return customCommitSet;
+}
+
+function customCommitSetWithOwnedCommit()
+{
+ const customCommitSet = new CustomCommitSet;
+ customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
+ customCommitSet.setRevisionForRepository(MockModels.ownerRepository, 'OwnerRepository-r0');
+ customCommitSet.setRevisionForRepository(MockModels.ownedRepository, 'OwnedRepository-r0', null, 'OwnerRepository-r0');
+ return customCommitSet;
+}
+
+function customCommitSetWithPatch()
+{
+ const customCommitSet = new CustomCommitSet;
+ const patch = createPatch();
+ customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
+ customCommitSet.setRevisionForRepository(MockModels.webkit, '200805', patch);
+ return customCommitSet;
+}
+
+function customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository()
+{
+ const customCommitSet = new CustomCommitSet;
+ customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
+ customCommitSet.setRevisionForRepository(MockModels.webkit, '200805');
+ customCommitSet.setRevisionForRepository(MockModels.ownedWebkit, 'owned-200805', null, '10.11.4 15E65');
+ return customCommitSet;
+}
+
+describe('CustomCommitSet', () => {
+ MockModels.inject();
+
+ describe('Test custom commit set without owned commit', () => {
+ it('should have right revision for a given repository', () => {
+ const commitSet = customCommitSetWithoutOwnedCommit();
+ assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
+ assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
+ });
+
+ it('should have no patch for any repository', () => {
+ const commitSet = customCommitSetWithoutOwnedCommit();
+ assert.equal(commitSet.patchForRepository(MockModels.osx), null);
+ assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
+ });
+
+ it('should have no owner revision for a given repository', () => {
+ const commitSet = customCommitSetWithoutOwnedCommit();
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
+ });
+
+ it('should return all repositories in it', () => {
+ const commitSet = customCommitSetWithoutOwnedCommit();
+ assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
+ });
+ });
+
+ describe('Test custom commit set with owned commit', () => {
+ it('should have right revision for a given repository', () => {
+ const commitSet = customCommitSetWithOwnedCommit();
+ assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
+ assert.equal(commitSet.revisionForRepository(MockModels.ownerRepository), 'OwnerRepository-r0');
+ assert.equal(commitSet.revisionForRepository(MockModels.ownedRepository), 'OwnedRepository-r0');
+ });
+
+ it('should have no patch for any repository', () => {
+ const commitSet = customCommitSetWithOwnedCommit();
+ assert.equal(commitSet.patchForRepository(MockModels.osx), null);
+ assert.equal(commitSet.patchForRepository(MockModels.ownerRepository), null);
+ assert.equal(commitSet.patchForRepository(MockModels.ownedRepository), null);
+ });
+
+ it('should have right owner revision for an owned repository', () => {
+ const commitSet = customCommitSetWithOwnedCommit();
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownerRepository), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedRepository), 'OwnerRepository-r0');
+ });
+
+ it('should return all repositories in it', () => {
+ const commitSet = customCommitSetWithOwnedCommit();
+ assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.ownerRepository, MockModels.ownedRepository]);
+ });
+ });
+
+ describe('Test custom commit set with patch', () => {
+ it('should have right revision for a given repository', () => {
+ const commitSet = customCommitSetWithPatch();
+ assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
+ assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
+ });
+
+ it('should have a patch for a repository with patch specified', () => {
+ const commitSet = customCommitSetWithPatch();
+ assert.equal(commitSet.patchForRepository(MockModels.osx), null);
+ assert.deepEqual(commitSet.patchForRepository(MockModels.webkit), createPatch());
+ });
+
+ it('should have no owner revision for a given repository', () => {
+ const commitSet = customCommitSetWithPatch();
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
+ });
+
+ it('should return all repositories in it', () => {
+ const commitSet = customCommitSetWithPatch();
+ assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
+ });
+ });
+
+ describe('Test custom commit set with owned repository has same name as non-owned repository', () => {
+ it('should have right revision for a given repository', () => {
+ const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
+ assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
+ assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
+ assert.equal(commitSet.revisionForRepository(MockModels.ownedWebkit), 'owned-200805');
+ });
+
+ it('should have no patch for any repository', () => {
+ const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
+ assert.equal(commitSet.patchForRepository(MockModels.osx), null);
+ assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
+ assert.equal(commitSet.patchForRepository(MockModels.ownedWebkit), null);
+ });
+
+ it('should have right owner revision for an owned repository', () => {
+ const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
+ assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedWebkit), '10.11.4 15E65');
+ });
+
+ it('should return all repositories in it', () => {
+ const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
+ assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit, MockModels.ownedWebkit]);
+ });
+ });
+
+ describe('Test custom commit set equality function', () => {
+ it('should be equal to same custom commit set', () => {
+ assert.deepEqual(customCommitSetWithoutOwnedCommit(), customCommitSetWithoutOwnedCommit());
+ assert.deepEqual(customCommitSetWithOwnedCommit(), customCommitSetWithOwnedCommit());
+ assert.deepEqual(customCommitSetWithPatch(), customCommitSetWithPatch());
+ assert.deepEqual(customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository(),
+ customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository());
+ });
+
+ it('should not be equal even if non-owned revisions are the same', () => {
+ const commitSet0 = customCommitSetWithoutOwnedCommit();
+ const commitSet1 = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
+ assert.equal(commitSet0.equals(commitSet1), false);
+ });
+ });
+
+ describe('Test custom commit set custom root operations', () => {
+ it('should return empty custom roots if no custom root specified', () => {
+ assert.deepEqual(customCommitSetWithoutOwnedCommit().customRoots(), []);
+ });
+
+ it('should return root if root is added into commit set', () => {
+ const commitSet = customCommitSetWithoutOwnedCommit();
+ commitSet.addCustomRoot(createRoot());
+ assert.deepEqual(commitSet.customRoots(), [createRoot()]);
+ });
+ });
+});
MockModels.osx = Repository.ensureSingleton(9, {name: 'OS X'});
MockModels.ios = Repository.ensureSingleton(22, {name: 'iOS'});
MockModels.webkit = Repository.ensureSingleton(11, {name: 'WebKit', url: 'http://trac.webkit.org/changeset/$1'});
+ MockModels.ownedWebkit = Repository.ensureSingleton(191, {name: 'WebKit', url: 'http://trac.webkit.org/changeset/$1', owner: 9});
MockModels.sharedRepository = Repository.ensureSingleton(16, {name: 'Shared'});
MockModels.ownerRepository = Repository.ensureSingleton(111, {name: 'Owner Repository'});
MockModels.ownedRepository = Repository.ensureSingleton(112, {name: 'Owned Repository', owner: 111});