Title: [223864] trunk/Websites/perf.webkit.org
Revision
223864
Author
[email protected]
Date
2017-10-23 17:22:57 -0700 (Mon, 23 Oct 2017)

Log Message

Update perf dashboard upload logic to support uploading binaries from owned commits.
https://bugs.webkit.org/show_bug.cgi?id=178610

Reviewed by Ryosuke Niwa.

Update build requests to 'completed' only when all commit set items are satisfied.
Extend 'repositoryList' parameter to be able to specified own commit information.
Items in 'repositoryList' can either be a string for top level repository,
or a dictionary with two keys: 'ownerRepository' and 'ownedRepository'.

* public/api/upload-root.php: Extend upload logic for support uploading binaries from owned commits.
* server-tests/api-upload-root-tests.js: Added unit tests.
* server-tests/tools-sync-buildbot-integration-tests.js: Added unit tests.

Modified Paths

Diff

Modified: trunk/Websites/perf.webkit.org/ChangeLog (223863 => 223864)


--- trunk/Websites/perf.webkit.org/ChangeLog	2017-10-24 00:08:40 UTC (rev 223863)
+++ trunk/Websites/perf.webkit.org/ChangeLog	2017-10-24 00:22:57 UTC (rev 223864)
@@ -1,3 +1,19 @@
+2017-10-20  Dewei Zhu  <[email protected]>
+
+        Update perf dashboard upload logic to support uploading binaries from owned commits.
+        https://bugs.webkit.org/show_bug.cgi?id=178610
+
+        Reviewed by Ryosuke Niwa.
+
+        Update build requests to 'completed' only when all commit set items are satisfied.
+        Extend 'repositoryList' parameter to be able to specified own commit information.
+        Items in 'repositoryList' can either be a string for top level repository,
+        or a dictionary with two keys: 'ownerRepository' and 'ownedRepository'.
+
+        * public/api/upload-root.php: Extend upload logic for support uploading binaries from owned commits.
+        * server-tests/api-upload-root-tests.js: Added unit tests.
+        * server-tests/tools-sync-buildbot-integration-tests.js: Added unit tests.
+
 2017-10-05  Dewei Zhu  <[email protected]>
 
         Add try-bot button on perf analysis status page.

Modified: trunk/Websites/perf.webkit.org/public/api/upload-root.php (223863 => 223864)


--- trunk/Websites/perf.webkit.org/public/api/upload-root.php	2017-10-24 00:08:40 UTC (rev 223863)
+++ trunk/Websites/perf.webkit.org/public/api/upload-root.php	2017-10-24 00:22:57 UTC (rev 223864)
@@ -39,8 +39,6 @@
             $build_id = $db->insert_row('builds', 'build', $build_info);
             if (!$build_id)
                 return array('status' => 'FailedToCreateBuild', 'build' => $build_info);
-            if (!$db->update_row('build_requests', 'request', array('id' => $build_request_id), array('status' => 'completed', 'build' => $build_id)))
-                return array('status' => 'FailedToUpdateBuildRequest', 'buildRequest' => $build_request_id);
 
             foreach ($commit_set_items_to_update as $commit_id) {
                 if (!$db->update_row('commit_set_items', 'commitset',
@@ -48,6 +46,10 @@
                     array('commit' => $commit_id, 'root_file' => $root_file_id), '*'))
                     return array('status' => 'FailedToUpdateCommitSet', 'commitSet' => $commit_set_id, 'commit' => $commit_id);
             }
+            if (!all_commit_set_items_are_satisfied($db, $commit_set_id))
+                return NULL;
+            if (!$db->update_row('build_requests', 'request', array('id' => $build_request_id), array('status' => 'completed', 'build' => $build_id)))
+                return array('status' => 'FailedToUpdateBuildRequest', 'buildRequest' => $build_request_id);
             return NULL;
         });
 
@@ -54,30 +56,49 @@
     exit_with_success(array('uploadedFile' => $uploaded_file));
 }
 
+function all_commit_set_items_are_satisfied($db, $commit_set_id)
+{
+    return !$db->select_first_row('commit_set_items', 'commitset', array('root_file' => NULL, 'requires_build' => TRUE, 'set' => $commit_set_id));
+}
+
 function compute_commit_set_items_to_update($db, $commit_set_id, $repository_name_list)
 {
     if (!is_array($repository_name_list))
         exit_with_error('InvalidRepositoryList', array('repositoryList' => $repository_name_list));
 
-    $commit_repository_rows_in_set = $db->query_and_fetch_all('SELECT * FROM repositories, commits, commit_set_items
-        WHERE repository_id = commit_repository AND commit_id = commitset_commit
+    $commit_repository_rows_in_set = $db->query_and_fetch_all('SELECT commit_set_items.commitset_commit as commitset_commit,
+        owned.repository_name as repository_name, owner.repository_name as owner_repository_name
+        FROM repositories as owned LEFT OUTER JOIN repositories as owner ON owned.repository_owner = owner.repository_id, commits, commit_set_items
+        WHERE owned.repository_id = commit_repository AND commit_id = commitset_commit
             AND commitset_set = $1', array($commit_set_id));
 
     $commit_by_repository_name = array();
+    $commit_by_owner_and_owned_repository_names = array();
     if ($commit_repository_rows_in_set) {
         foreach ($commit_repository_rows_in_set as $row)
-            $commit_by_repository_name[$row['repository_name']] = $row['commitset_commit'];
+            if ($row['owner_repository_name']) {
+                $owned_repositories = &array_ensure_item_has_array($commit_by_owner_and_owned_repository_names, $row['owner_repository_name']);
+                $owned_repositories[$row['repository_name']] = $row['commitset_commit'];
+            } else
+                $commit_by_repository_name[$row['repository_name']] = $row['commitset_commit'];
     }
 
     $commit_set_items_to_update = array();
     foreach ($repository_name_list as $repository_name) {
-        $commit_id = array_get($commit_by_repository_name, $repository_name);
+        $commit_id = NULL;
+        if (is_string($repository_name))
+            $commit_id = array_get($commit_by_repository_name, $repository_name);
+        else if (is_array($repository_name)) {
+            if (!array_key_exists('ownerRepository', $repository_name) || !array_key_exists('ownedRepository', $repository_name))
+                exit_with_error('InvalidKeyForRepository', array('repositoryName' => $repository_name, 'commitSet' => $commit_set_id));
+            $commit_id = array_get(array_get($commit_by_owner_and_owned_repository_names, $repository_name['ownerRepository'], array()), $repository_name['ownedRepository']);
+        }
         if (!$commit_id)
             exit_with_error('InvalidRepository', array('repositoryName' => $repository_name, 'commitSet' => $commit_set_id));
         array_push($commit_set_items_to_update, $commit_id);
     }
     if (!$commit_set_items_to_update)
-        exit_with_error('InvalidRepositoryList', array('repositoryList' => $repository_list));
+        exit_with_error('InvalidRepositoryList', array('repositoryList' => $repository_name_list, 'commitSet' => $commit_set_id));
 
     return $commit_set_items_to_update;
 }

Modified: trunk/Websites/perf.webkit.org/server-tests/api-upload-root-tests.js (223863 => 223864)


--- trunk/Websites/perf.webkit.org/server-tests/api-upload-root-tests.js	2017-10-24 00:08:40 UTC (rev 223863)
+++ trunk/Websites/perf.webkit.org/server-tests/api-upload-root-tests.js	2017-10-24 00:22:57 UTC (rev 223864)
@@ -10,7 +10,7 @@
 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
 
-function makeReport(rootFile, buildRequestId = 1)
+function makeReport(rootFile, buildRequestId = 1, repositoryList = ['WebKit'], buildTime = '2017-05-10T02:54:08.666')
 {
     return {
         slaveName: 'someSlave',
@@ -17,10 +17,10 @@
         slavePassword: 'somePassword',
         builderName: 'someBuilder',
         buildNumber: 123,
-        buildTime: '2017-05-10T02:54:08.666',
+        buildTime: buildTime,
         buildRequest: buildRequestId,
         rootFile: rootFile,
-        repositoryList: '["WebKit"]',
+        repositoryList: JSON.stringify(repositoryList),
     };
 }
 
@@ -73,6 +73,48 @@
     });
 }
 
+function createTestGroupWithPatchAndOwnedCommits()
+{
+    const triggerableConfiguration = {
+        'slaveName': 'sync-slave',
+        'slavePassword': 'password',
+        'triggerable': 'build-webkit',
+        'configurations': [
+            {test: MockData.someTestId(), platform: MockData.somePlatformId()},
+        ],
+        'repositoryGroups': [
+            {name: 'webkit', repositories: [
+                {repository: MockData.webkitRepositoryId(), acceptsPatch: true}
+            ]}
+        ]
+    };
+
+    const db = TestServer.database();
+    return MockData.addMockData(db).then(() => {
+        return Promise.all([TemporaryFile.makeTemporaryFile('patch.dat', 'patch file'), Manifest.fetch()]);
+    }).then((result) => {
+        const patchFile = result[0];
+        return Promise.all([UploadedFile.uploadFile(patchFile), TestServer.remoteAPI().postJSON('/api/update-triggerable/', triggerableConfiguration)]);
+    }).then((result) => {
+        const patchFile = result[0];
+        const someTest = Test.findById(MockData.someTestId());
+        const webkit = Repository.findById(MockData.webkitRepositoryId());
+        const ownedSJC = Repository.findById(MockData.ownedJSCRepositoryId());
+        const set1 = new CustomCommitSet;
+        set1.setRevisionForRepository(webkit, '191622', patchFile);
+        set1.setRevisionForRepository(ownedSJC, 'owned-jsc-6161', null, '191622');
+        const set2 = new CustomCommitSet;
+        set2.setRevisionForRepository(webkit, '192736');
+        set2.setRevisionForRepository(ownedSJC, 'owned-jsc-9191', null, '192736');
+
+        return TestGroup.createWithTask('custom task', Platform.findById(MockData.somePlatformId()), someTest, 'some group', 2, [set1, set2]);
+    }).then((task) => {
+        return TestGroup.findAllByTask(task.id())[0];
+    }).then((group) => {
+        return db.query('UPDATE analysis_test_groups SET testgroup_author = $1', ['someUser']).then(() => group);
+    });
+}
+
 describe('/api/upload-root/', function () {
     prepareServerTest(this);
     TemporaryFile.inject();
@@ -199,6 +241,160 @@
         });
     });
 
+    it('should reject when using invalid key to specify an owned repository', () => {
+        let webkit;
+        let webkitPatch;
+        let ownedJSC;
+        let testGroup;
+        let buildRequest;
+        let otherBuildRequest;
+        let uploadedRoot;
+        return createTestGroupWithPatchAndOwnedCommits().then((group) => {
+            webkit = Repository.findById(MockData.webkitRepositoryId());
+            ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+
+            testGroup = group;
+            buildRequest = testGroup.buildRequests()[0];
+            assert.equal(testGroup.buildRequests().length, 6);
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert(!buildRequest.hasFinished());
+            assert(buildRequest.isPending());
+            assert.equal(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            webkitPatch = commitSet.patchForRepository(webkit);
+            assert(webkitPatch instanceof UploadedFile);
+            assert.equal(webkitPatch.filename(), 'patch.dat');
+            assert.equal(commitSet.rootForRepository(webkit), null);
+            assert.equal(commitSet.revisionForRepository(ownedJSC), 'owned-jsc-6161');
+            assert.equal(commitSet.patchForRepository(ownedJSC), null);
+            assert.equal(commitSet.rootForRepository(ownedJSC), null);
+            assert.deepEqual(commitSet.allRootFiles(), []);
+
+            otherBuildRequest = testGroup.buildRequests()[1];
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.revisionForRepository(ownedJSC), 'owned-jsc-9191');
+            assert.equal(otherCommitSet.patchForRepository(ownedJSC), null);
+            assert.equal(otherCommitSet.rootForRepository(ownedJSC), null);
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            return addSlaveAndCreateRootFile();
+        }).then((rootFile) => {
+            const report = makeReport(rootFile, buildRequest.id(), ['WebKit']);
+            return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
+        }).then((response) => {
+            assert.equal(response['status'], 'OK');
+            const uploadedRootRawData = response['uploadedFile'];
+            uploadedRoot = UploadedFile.ensureSingleton(uploadedRootRawData.id, uploadedRootRawData);
+            assert.equal(uploadedRoot.filename(), 'some.dat');
+            return TestGroup.fetchForTask(buildRequest.testGroup().task().id(), true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const group = testGroups[0];
+            assert.equal(group, testGroup);
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const updatedBuildRequest = testGroup.buildRequests()[0];
+            assert.equal(updatedBuildRequest, buildRequest);
+
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert(!buildRequest.hasFinished());
+            assert.equal(buildRequest.buildId(), null);
+
+            assert.deepEqual(buildRequest.commitSet().allRootFiles(), [uploadedRoot]);
+            assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
+            return TemporaryFile.makeTemporaryFile('_javascript_Core-Root.dat', '_javascript_ Content 0');
+        }).then((rootFile) => {
+            const report = makeReport(rootFile, buildRequest.id(), [{ownerRepositoryWrongKey: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666');
+            return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
+        }).then((response) => {
+            assert.equal(response['status'], 'InvalidKeyForRepository');
+        });
+    });
+
+    it('should reject when reporting an invalid owned repository', () => {
+        let webkit;
+        let webkitPatch;
+        let ownedJSC;
+        let testGroup;
+        let buildRequest;
+        let otherBuildRequest;
+        let uploadedRoot;
+        return createTestGroupWithPatchAndOwnedCommits().then((group) => {
+            webkit = Repository.findById(MockData.webkitRepositoryId());
+            ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+
+            testGroup = group;
+            buildRequest = testGroup.buildRequests()[0];
+            assert.equal(testGroup.buildRequests().length, 6);
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert(!buildRequest.hasFinished());
+            assert(buildRequest.isPending());
+            assert.equal(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            webkitPatch = commitSet.patchForRepository(webkit);
+            assert(webkitPatch instanceof UploadedFile);
+            assert.equal(webkitPatch.filename(), 'patch.dat');
+            assert.equal(commitSet.rootForRepository(webkit), null);
+            assert.equal(commitSet.revisionForRepository(ownedJSC), 'owned-jsc-6161');
+            assert.equal(commitSet.patchForRepository(ownedJSC), null);
+            assert.equal(commitSet.rootForRepository(ownedJSC), null);
+            assert.deepEqual(commitSet.allRootFiles(), []);
+
+            otherBuildRequest = testGroup.buildRequests()[1];
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.revisionForRepository(ownedJSC), 'owned-jsc-9191');
+            assert.equal(otherCommitSet.patchForRepository(ownedJSC), null);
+            assert.equal(otherCommitSet.rootForRepository(ownedJSC), null);
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            return addSlaveAndCreateRootFile();
+        }).then((rootFile) => {
+            const report = makeReport(rootFile, buildRequest.id(), ['WebKit']);
+            return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
+        }).then((response) => {
+            assert.equal(response['status'], 'OK');
+            const uploadedRootRawData = response['uploadedFile'];
+            uploadedRoot = UploadedFile.ensureSingleton(uploadedRootRawData.id, uploadedRootRawData);
+            assert.equal(uploadedRoot.filename(), 'some.dat');
+            return TestGroup.fetchForTask(buildRequest.testGroup().task().id(), true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const group = testGroups[0];
+            assert.equal(group, testGroup);
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const updatedBuildRequest = testGroup.buildRequests()[0];
+            assert.equal(updatedBuildRequest, buildRequest);
+
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert(!buildRequest.hasFinished());
+            assert.equal(buildRequest.buildId(), null);
+
+            assert.deepEqual(buildRequest.commitSet().allRootFiles(), [uploadedRoot]);
+            assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
+            return TemporaryFile.makeTemporaryFile('_javascript_Core-Root.dat', '_javascript_ Content 0');
+        }).then((rootFile) => {
+            const report = makeReport(rootFile, buildRequest.id(), [{ownerRepository: 'WebKit2', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666');
+            return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
+        }).then((response) => {
+            assert.equal(response['status'], 'InvalidRepository');
+        });
+    });
+
     it('should accept when build request exists', () => {
         let webkit;
         let webkitPatch;
@@ -424,17 +620,18 @@
         });
     });
 
-    it('should update all commit set items in the repository listed', () => {
+    it('should only set build requests as complete when all roots are built', () => {
         let webkit;
         let webkitPatch;
-        let shared;
+        let ownedJSC;
         let testGroup;
         let buildRequest;
         let otherBuildRequest;
         let uploadedRoot;
-        return createTestGroupWihPatch().then((group) => {
+        let jscRoot;
+        return createTestGroupWithPatchAndOwnedCommits().then((group) => {
             webkit = Repository.findById(MockData.webkitRepositoryId());
-            shared = Repository.findById(MockData.sharedRepositoryId());
+            ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
 
             testGroup = group;
             buildRequest = testGroup.buildRequests()[0];
@@ -442,7 +639,7 @@
             assert(buildRequest.isBuild());
             assert(!buildRequest.isTest());
             assert(!buildRequest.hasFinished());
-            assert(buildRequest.isPending()); 
+            assert(buildRequest.isPending());
             assert.equal(buildRequest.buildId(), null);
 
             const commitSet = buildRequest.commitSet();
@@ -451,25 +648,24 @@
             assert(webkitPatch instanceof UploadedFile);
             assert.equal(webkitPatch.filename(), 'patch.dat');
             assert.equal(commitSet.rootForRepository(webkit), null);
-            assert.equal(commitSet.revisionForRepository(shared), '80229');
-            assert.equal(commitSet.patchForRepository(shared), null);
-            assert.equal(commitSet.rootForRepository(shared), null);
+            assert.equal(commitSet.revisionForRepository(ownedJSC), 'owned-jsc-6161');
+            assert.equal(commitSet.patchForRepository(ownedJSC), null);
+            assert.equal(commitSet.rootForRepository(ownedJSC), null);
             assert.deepEqual(commitSet.allRootFiles(), []);
 
             otherBuildRequest = testGroup.buildRequests()[1];
             const otherCommitSet = otherBuildRequest.commitSet();
-            assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
             assert.equal(otherCommitSet.patchForRepository(webkit), null);
             assert.equal(otherCommitSet.rootForRepository(webkit), null);
-            assert.equal(otherCommitSet.revisionForRepository(shared), '80229');
-            assert.equal(otherCommitSet.patchForRepository(shared), null);
-            assert.equal(otherCommitSet.rootForRepository(shared), null);
+            assert.equal(otherCommitSet.revisionForRepository(ownedJSC), 'owned-jsc-9191');
+            assert.equal(otherCommitSet.patchForRepository(ownedJSC), null);
+            assert.equal(otherCommitSet.rootForRepository(ownedJSC), null);
             assert.deepEqual(otherCommitSet.allRootFiles(), []);
 
             return addSlaveAndCreateRootFile();
         }).then((rootFile) => {
-            const report = makeReport(rootFile, buildRequest.id());
-            report.repositoryList = '["WebKit", "Shared"]';
+            const report = makeReport(rootFile, buildRequest.id(), ['WebKit']);
             return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
         }).then((response) => {
             assert.equal(response['status'], 'OK');
@@ -488,13 +684,38 @@
 
             assert(buildRequest.isBuild());
             assert(!buildRequest.isTest());
+            assert(!buildRequest.hasFinished());
+            assert.equal(buildRequest.buildId(), null);
+
+            assert.deepEqual(buildRequest.commitSet().allRootFiles(), [uploadedRoot]);
+            assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
+            return TemporaryFile.makeTemporaryFile('_javascript_Core-Root.dat', '_javascript_ Content 0');
+        }).then((rootFile) => {
+            const report = makeReport(rootFile, buildRequest.id(), [{ownerRepository: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666');
+            return TestServer.remoteAPI().postFormData('/api/upload-root/', report);
+        }).then((response) => {
+            assert.equal(response['status'], 'OK');
+            const uploadedRootRawData = response['uploadedFile'];
+            jscRoot = UploadedFile.ensureSingleton(uploadedRootRawData.id, uploadedRootRawData);
+            assert.equal(jscRoot.filename(), '_javascript_Core-Root.dat');
+            return TestGroup.fetchForTask(buildRequest.testGroup().task().id(), true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const group = testGroups[0];
+            assert.equal(group, testGroup);
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const updatedBuildRequest = testGroup.buildRequests()[0];
+            assert.equal(updatedBuildRequest, buildRequest);
+
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
             assert(buildRequest.hasFinished());
-            assert(!buildRequest.isPending()); 
+            assert(!buildRequest.isPending());
             assert.notEqual(buildRequest.buildId(), null);
 
-            assert.deepEqual(buildRequest.commitSet().allRootFiles(), [uploadedRoot]);
+            assert.deepEqual(buildRequest.commitSet().allRootFiles(), [uploadedRoot, jscRoot]);
             assert.deepEqual(otherBuildRequest.commitSet().allRootFiles(), []);
         });
     });
-
 });

Modified: trunk/Websites/perf.webkit.org/server-tests/tools-sync-buildbot-integration-tests.js (223863 => 223864)


--- trunk/Websites/perf.webkit.org/server-tests/tools-sync-buildbot-integration-tests.js	2017-10-24 00:08:40 UTC (rev 223863)
+++ trunk/Websites/perf.webkit.org/server-tests/tools-sync-buildbot-integration-tests.js	2017-10-24 00:22:57 UTC (rev 223864)
@@ -102,18 +102,18 @@
     });
 }
 
-function uploadRoot(buildRequestId, buildNumber)
+function uploadRoot(buildRequestId, buildNumber, repositoryList = ["WebKit"], buildTime = '2017-05-10T02:54:08.666')
 {
-    return TemporaryFile.makeTemporaryFile(`root${buildNumber}.dat`, `root for build ${buildNumber}`).then((rootFile) => {
+    return TemporaryFile.makeTemporaryFile(`root${buildNumber}.dat`, `root for build ${buildNumber} and repository list at ${buildTime}`).then((rootFile) => {
         return TestServer.remoteAPI().postFormData('/api/upload-root/', {
             slaveName: 'sync-slave',
             slavePassword: 'password',
             builderName: 'some builder',
             buildNumber: buildNumber,
-            buildTime: '2017-05-10T02:54:08.666',
+            buildTime: buildTime,
             buildRequest: buildRequestId,
             rootFile,
-            repositoryList: '["WebKit"]',
+            repositoryList: JSON.stringify(repositoryList),
         });
     });
 }
@@ -793,7 +793,7 @@
             assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
             assert.deepEqual(otherCommitSet.allRootFiles(), []);
 
-            return uploadRoot(buildRequest.id(), 123);
+            return uploadRoot(buildRequest.id(), 123).then(() => uploadRoot(buildRequest.id(), 123, [{ownerRepository: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666'));
         }).then(() => {
             return TestGroup.fetchForTask(taskId, true);
         }).then((testGroups) => {
@@ -818,7 +818,10 @@
             const webkitRoot = commitSet.rootForRepository(webkit);
             assert(webkitRoot instanceof UploadedFile);
             assert.equal(webkitRoot.filename(), 'root123.dat');
-            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
 
             const otherBuildRequest = testGroup.buildRequests()[1];
             assert(otherBuildRequest.isBuild());
@@ -896,11 +899,350 @@
             const webkitRoot = commitSet.rootForRepository(webkit);
             assert(webkitRoot instanceof UploadedFile);
             assert.equal(webkitRoot.filename(), 'root123.dat');
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Running');
+            assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            return uploadRoot(otherBuildRequest.id(), 124).then(() => uploadRoot(otherBuildRequest.id(), 124, [{ownerRepository: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666'));
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Completed');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.notEqual(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            const webkitRoot = commitSet.rootForRepository(webkit);
+            assert(webkitRoot instanceof UploadedFile);
+            assert.equal(webkitRoot.filename(), 'root123.dat');
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Completed');
+            assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.notEqual(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
+            assert(otherWebkitRoot instanceof UploadedFile);
+            assert.equal(otherWebkitRoot.filename(), 'root124.dat');
+            const otherJSCRoot = otherCommitSet.rootForRepository(ownedJSC);
+            assert(otherJSCRoot instanceof UploadedFile);
+            assert.equal(otherJSCRoot.filename(), 'root124.dat');
+            assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot, otherJSCRoot]);
+        });
+    });
+
+    it('should not update a build request to "completed" until all roots needed in the commit set are uploaded', () => {
+        const requests = MockRemoteAPI.requests;
+        let triggerable;
+        let taskId = null;
+        let syncPromise;
+        return createTriggerable().then((newTriggerable) => {
+            triggerable = newTriggerable;
+            return createTestGroupWihOwnedCommit();
+        }).then((testGroup) => {
+            taskId = testGroup.task().id();
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Waiting');
+            assert.equal(buildRequest.statusUrl(), null);
+            assert.equal(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.rootForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            assert.deepEqual(commitSet.allRootFiles(), []);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
+            assert.equal(otherBuildRequest.statusUrl(), null);
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 3);
+            assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
+            assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
+            assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 6);
+            assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
+            assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {});
+            assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 7);
+            assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
+            assert.deepEqual(requests[6].data, {'wk': '191622', 'build-request-id': '1', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-6161","repository":"_javascript_Core","ownerRevision":"191622"}]}`});
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 10);
+            assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
+            assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds',
+                [MockData.pendingBuild({builder: 'some builder', buildRequestId: 1})]);
+            assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 13);
+            assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
+            assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
+                [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 1})
+            });
+            assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
+            return syncPromise;
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Running');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.equal(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.rootForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            assert.deepEqual(commitSet.allRootFiles(), []);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
+            assert.equal(otherBuildRequest.statusUrl(), null);
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            return uploadRoot(buildRequest.id(), 123);
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Running');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.equal(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            const webkitRoot = commitSet.rootForRepository(webkit);
+            assert(webkitRoot instanceof UploadedFile);
+            assert.equal(webkitRoot.filename(), 'root123.dat');
             assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
 
             const otherBuildRequest = testGroup.buildRequests()[1];
             assert(otherBuildRequest.isBuild());
             assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
+            assert.equal(otherBuildRequest.statusUrl(), null);
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+            return uploadRoot(buildRequest.id(), 123, [{ownerRepository: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666');
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Completed');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.notEqual(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            const webkitRoot = commitSet.rootForRepository(webkit);
+            assert(webkitRoot instanceof UploadedFile);
+            assert.equal(webkitRoot.filename(), 'root123.dat');
+            const jscRoot = commitSet.rootForRepository((ownedJSC));
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
+            assert.equal(otherBuildRequest.statusUrl(), null);
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.rootForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            assert.deepEqual(otherCommitSet.allRootFiles(), []);
+
+            MockRemoteAPI.reset();
+            syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 3);
+            assertAndResolveRequest(requests[0], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
+            assertAndResolveRequest(requests[1], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
+            assertAndResolveRequest(requests[2], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 6);
+            assertAndResolveRequest(requests[3], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
+            assertAndResolveRequest(requests[4], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
+                [-1]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1})
+            });
+            assertAndResolveRequest(requests[5], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 7);
+            assertAndResolveRequest(requests[6], 'POST', '/builders/some%20builder/force', 'OK');
+            assert.deepEqual(requests[6].data, {'wk': '192736', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'owned-commits': `{"WebKit":[{"revision":"owned-jsc-9191","repository":"_javascript_Core","ownerRevision":"192736"}]}`});
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 10);
+            assertAndResolveRequest(requests[7], 'GET', '/json/builders/some%20tester/pendingBuilds', []);
+            assertAndResolveRequest(requests[8], 'GET', '/json/builders/some%20builder/pendingBuilds', []);
+            assertAndResolveRequest(requests[9], 'GET', '/json/builders/other%20builder/pendingBuilds', []);
+            return MockRemoteAPI.waitForRequest();
+        }).then(() => {
+            assert.equal(requests.length, 13);
+            assertAndResolveRequest(requests[10], 'GET', '/json/builders/some%20tester/builds/?select=-1&select=-2', {});
+            assertAndResolveRequest(requests[11], 'GET', '/json/builders/some%20builder/builds/?select=-1&select=-2', {
+                [-1]: MockData.runningBuild({builder: 'some builder', buildRequestId: 2}),
+                [-2]: MockData.finishedBuild({builder: 'some builder', buildRequestId: 1}),
+            });
+            assertAndResolveRequest(requests[12], 'GET', '/json/builders/other%20builder/builds/?select=-1&select=-2', {});
+            return syncPromise;
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Completed');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.notEqual(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            const webkitRoot = commitSet.rootForRepository(webkit);
+            assert(webkitRoot instanceof UploadedFile);
+            assert.equal(webkitRoot.filename(), 'root123.dat');
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
             assert.equal(otherBuildRequest.statusLabel(), 'Running');
             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
             assert.equal(otherBuildRequest.buildId(), null);
@@ -938,11 +1280,60 @@
             const webkitRoot = commitSet.rootForRepository(webkit);
             assert(webkitRoot instanceof UploadedFile);
             assert.equal(webkitRoot.filename(), 'root123.dat');
-            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
 
             const otherBuildRequest = testGroup.buildRequests()[1];
             assert(otherBuildRequest.isBuild());
             assert(!otherBuildRequest.isTest());
+            assert.equal(otherBuildRequest.statusLabel(), 'Running');
+            assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.equal(otherBuildRequest.buildId(), null);
+
+            const otherCommitSet = otherBuildRequest.commitSet();
+            assert.equal(otherCommitSet.revisionForRepository(webkit), '192736');
+            assert.equal(otherCommitSet.patchForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(otherCommitSet.ownerRevisionForRepository(ownedJSC), otherCommitSet.revisionForRepository(webkit));
+            const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
+            assert(otherWebkitRoot instanceof UploadedFile);
+            assert.equal(otherWebkitRoot.filename(), 'root124.dat');
+            assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
+            return uploadRoot(otherBuildRequest.id(), 124, [{ownerRepository: 'WebKit', ownedRepository: '_javascript_Core'}], '2017-05-10T02:54:09.666');
+        }).then(() => {
+            return TestGroup.fetchForTask(taskId, true);
+        }).then((testGroups) => {
+            assert.equal(testGroups.length, 1);
+            const testGroup = testGroups[0];
+            const webkit = Repository.findById(MockData.webkitRepositoryId());
+            const ownedJSC = Repository.findById(MockData.ownedJSCRepositoryId());
+            assert.equal(testGroup.buildRequests().length, 6);
+
+            const buildRequest = testGroup.buildRequests()[0];
+            assert(buildRequest.isBuild());
+            assert(!buildRequest.isTest());
+            assert.equal(buildRequest.statusLabel(), 'Completed');
+            assert.equal(buildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
+            assert.notEqual(buildRequest.buildId(), null);
+
+            const commitSet = buildRequest.commitSet();
+            assert.equal(commitSet.revisionForRepository(webkit), '191622');
+            assert.equal(commitSet.patchForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(webkit), null);
+            assert.equal(commitSet.ownerRevisionForRepository(ownedJSC), commitSet.revisionForRepository(webkit));
+            const webkitRoot = commitSet.rootForRepository(webkit);
+            assert(webkitRoot instanceof UploadedFile);
+            assert.equal(webkitRoot.filename(), 'root123.dat');
+            const jscRoot = commitSet.rootForRepository(ownedJSC);
+            assert(jscRoot instanceof UploadedFile);
+            assert.equal(jscRoot.filename(), 'root123.dat');
+            assert.deepEqual(commitSet.allRootFiles(), [webkitRoot, jscRoot]);
+
+            const otherBuildRequest = testGroup.buildRequests()[1];
+            assert(otherBuildRequest.isBuild());
+            assert(!otherBuildRequest.isTest());
             assert.equal(otherBuildRequest.statusLabel(), 'Completed');
             assert.equal(otherBuildRequest.statusUrl(), 'http://build.webkit.org/builders/some%20builder/builds/124');
             assert.notEqual(otherBuildRequest.buildId(), null);
@@ -955,7 +1346,10 @@
             const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
             assert(otherWebkitRoot instanceof UploadedFile);
             assert.equal(otherWebkitRoot.filename(), 'root124.dat');
-            assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
+            const otherJSCRoot = otherCommitSet.rootForRepository(ownedJSC);
+            assert(otherJSCRoot instanceof UploadedFile);
+            assert.equal(otherJSCRoot.filename(), 'root124.dat');
+            assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot, otherJSCRoot]);
         });
     });
 });
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to