Skip to content

Commit

Permalink
Added sending notification feature when test group finishes.
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=184340

Reviewed by Ryosuke Niwa.

Added 'testgroup_needs_notification' filed to 'analysis_test_group' table to indicate whether a test group
has a pending notification.
Added 'testgroup_notification_sent_at' to record the last notification sent time.
SQL queries to update existing database are:
    'ALTER TABLE analysis_test_groups ADD COLUMN testgroup_needs_notification boolean NOT NULL DEFAULT FALSE;'
    'ALTER TABLE analysis_test_groups ADD COLUMN testgroup_notification_sent_at timestamp DEFAULT NULL;'
Updated 'run-analysis' script to be able to send notification when test group finishes.
Added 'Notify on completion' checkbox while creating/retrying/bisecting a test group.

* browser-tests/test-group-form-tests.js: Updated existing tests and added a new test.
* browser-tests/test-group-result-page-tests.js: Added unit tests for TestGroupResultPage.
* init-database.sql: Added 'testgroup_needs_notification' filed to 'analysis_test_group' table.
* public/api/test-groups.php: Added '/api/test-groups/ready-for-notification' API to 'test-group' to show all
test groups that need to send notification. Only the ones with 'completed', 'failed' or 'cancelled' status and its
'testgroup_needs_notification' is true will be returned by this API.
* public/include/build-requests-fetcher.php: Added 'fetch_requests_for_groups' to return test groups with given ids.
* public/include/commit-sets-helpers.php: Updated the logic to support setting 'testgroup_needs_notification'
while create an analysis_test_groups.
* public/privileged-api/create-analysis-task.php: Updated the logic to support setting 'testgroup_needs_notification'.
* public/privileged-api/create-test-group.php: Updated the logic to support setting 'testgroup_needs_notification'.
* public/privileged-api/update-test-group.php: Updated the logic to support updating 'testgroup_needs_notification'.
Extended this API to allow authentication both from CSRF token and slave.
* public/v3/components/custom-configuration-test-group-form.js:
(CustomConfigurationTestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
* public/v3/components/customizable-test-group-form.js:
(CustomizableTestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
(CustomizableTestGroupForm.cssTemplate): Added space between 'Notify on completion' checkbox and test group iteration selection list.
* public/v3/components/test-group-form.js:
(TestGroupForm): Added '_notifyOnCompletion' instance variable.
(TestGroupForm.prototype.didConstructShadowTree): Added 'onchange' event for notify on completion checkbox.
(TestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
(TestGroupForm.cssTemplate): Added space between 'Notify on completion' checkbox and test group iteration selection list.
* public/v3/models/analysis-results.js: Export 'AnalysisResults'.
(AnalysisResults.fetch): Update API path to use absolute url.
(AnalysisResults):
* public/v3/models/analysis-task.js:
(AnalysisTask.async.create): Extend this function to take notifyOnCompletion as argument which will be used as
'needsNotification' to send to server.
(AnalysisTask):
* public/v3/models/test-group.js:
(TestGroup): Added '_needsNotification' field.
(TestGroup.prototype.updateSingleton): Added logic to update '_needsNotification' field.
(TestGroup.prototype.needsNotification): Returns '_needsNotification' field.
(TestGroup.prototype.author): Returns author information.
(TestGroup.prototype.async.didSendNotification): API that updates 'testgroup_needs_notification' to true.
(TestGroup.prototype.async.fetchTask): API to fetch the task when it has not been fetched.
(TestGroup.createWithTask): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.createWithCustomConfiguration): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.createAndRefetchTestGroups): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.fetchAllWithNotificationReady): New function that invokes '/api/test-groups/ready-for-notification'.
* public/v3/pages/analysis-task-page.js: Update logic to 'notifyOnCompletion' around
(AnalysisTaskChartPane.prototype.didConstructShadowTree):
(AnalysisTaskResultsPane.prototype.didConstructShadowTree):
(AnalysisTaskTestGroupPane.prototype.didConstructShadowTree):
(AnalysisTaskPage.prototype.didConstructShadowTree):
(AnalysisTaskPage.prototype._retryCurrentTestGroup):
(AnalysisTaskPage.prototype.async._bisectCurrentTestGroup):
(AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList.set const):
(AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList):
(AnalysisTaskPage.prototype._createCustomTestGroup):
* public/v3/pages/chart-pane.js: Added 'Notify on completion' checkbox.
(ChartPane.prototype.didConstructShadowTree):
(ChartPane.prototype.async._analyzeRange):
* public/v3/pages/create-analysis-task-page.js: Adapted API change.
(CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup):
* server-tests/api-test-groups.js: Added tests for '/api/test-groups/ready-for-notification'.
* server-tests/privileged-api-create-analysis-task-tests.js: Updated tests to adapt this change.
Added new tests.
* server-tests/privileged-api-create-test-group-tests.js: Added new tests.
* server-tests/privileged-api-update-test-group-tests.js: Added unit test for 'update-test-group' API.
* server-tests/resources/mock-data.js: addMockData should set 'testgroup_needs_notification' to be true.
* server-tests/tools-sync-buildbot-integration-tests.js: Updated tests to adapt this change.
(async.createTestGroupWihPatch):
(createTestGroupWihOwnedCommit):
* tools/js/analysis-results-notifier.js: Added notifier to send notification for completed test groups.
(AnalysisResultsNotifier):
(AnalysisResultsNotifier.prototype.async.sendNotificationsForTestGroups):
(AnalysisResultsNotifier.prototype._sendNotification): Invoke remote API to send notification.
(AnalysisResultsNotifier.prototype._constructMessageByRules):
(AnalysisResultsNotifier._matchesRule):
(AnalysisResultsNotifier._applyUpdate):
(AnalysisResultsNotifier.async._messageForTestGroup): Build html as message body for a test group.
(AnalysisResultsNotifier._URLForAnalysisTask): Returns URL for an analysis task.
(AnalysisResultsNotifier._instantiateNotificationTemplate):
* tools/js/test-group-result-page.js: Added 'TestGroupResultPage' and 'BarGraph' to show test group result.
(TestGroupResultPage):
(TestGroupResultPage.prototype.async.setTestGroup):
(TestGroupResultPage._urlForAnalysisTask):
(TestGroupResultPage.prototype._URLForAnalysisTask):
(TestGroupResultPage.prototype.constructTables):
(TestGroupResultPage.prototype._constructTableForMetric):
(TestGroupResultPage.):
(TestGroupResultPage.prototype.get pageContent):
(TestGroupResultPage.prototype.get styleTemplate):
(BarGraph):
(BarGraph.prototype.setWidth):
(BarGraph.prototype._constructBarGraph):
(BarGraph.prototype.get pageContent):
(BarGraph.prototype.get styleTemplate):
* tools/js/measurement-set-analyzer.js: Adapted 'AnalysisTask.create' change.
(MeasurementSetAnalyzer.prototype.async._analyzeMeasurementSet):
(MeasurementSetAnalyzer):
* tools/js/v3-models.js:
* tools/run-analysis.js: Added the logic that sends notification for completed test groups.
(main):
(async.analysisLoop):
* unit-tests/analysis-task-tests.js:
* unit-tests/analysis-results-notifier-tests.js: Added a unit test for 'AnalysisResultsNotifier' and 'NotificationService'.
* unit-tests/measurement-set-analyzer-tests.js: Updated unit tests per this change.
* unit-tests/test-groups-tests.js: Added unit tests for 'TestGroup.needsNotification'.
* unit-tests/resources/mock-remote-api.js: Only set 'privilegedAPI' when it exits.

Canonical link: https://commits.webkit.org/201783@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232612 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
dewei-zhu committed Jun 8, 2018
1 parent dbfacd5 commit 853907d
Show file tree
Hide file tree
Showing 35 changed files with 1,457 additions and 121 deletions.
125 changes: 125 additions & 0 deletions Websites/perf.webkit.org/ChangeLog
@@ -1,3 +1,128 @@
2018-05-24 Dewei Zhu <dewei_zhu@apple.com>

Added sending notification feature when test group finishes.
https://bugs.webkit.org/show_bug.cgi?id=184340

Reviewed by Ryosuke Niwa.

Added 'testgroup_needs_notification' filed to 'analysis_test_group' table to indicate whether a test group
has a pending notification.
Added 'testgroup_notification_sent_at' to record the last notification sent time.
SQL queries to update existing database are:
'ALTER TABLE analysis_test_groups ADD COLUMN testgroup_needs_notification boolean NOT NULL DEFAULT FALSE;'
'ALTER TABLE analysis_test_groups ADD COLUMN testgroup_notification_sent_at timestamp DEFAULT NULL;'
Updated 'run-analysis' script to be able to send notification when test group finishes.
Added 'Notify on completion' checkbox while creating/retrying/bisecting a test group.

* browser-tests/test-group-form-tests.js: Updated existing tests and added a new test.
* browser-tests/test-group-result-page-tests.js: Added unit tests for TestGroupResultPage.
* init-database.sql: Added 'testgroup_needs_notification' filed to 'analysis_test_group' table.
* public/api/test-groups.php: Added '/api/test-groups/ready-for-notification' API to 'test-group' to show all
test groups that need to send notification. Only the ones with 'completed', 'failed' or 'cancelled' status and its
'testgroup_needs_notification' is true will be returned by this API.
* public/include/build-requests-fetcher.php: Added 'fetch_requests_for_groups' to return test groups with given ids.
* public/include/commit-sets-helpers.php: Updated the logic to support setting 'testgroup_needs_notification'
while create an analysis_test_groups.
* public/privileged-api/create-analysis-task.php: Updated the logic to support setting 'testgroup_needs_notification'.
* public/privileged-api/create-test-group.php: Updated the logic to support setting 'testgroup_needs_notification'.
* public/privileged-api/update-test-group.php: Updated the logic to support updating 'testgroup_needs_notification'.
Extended this API to allow authentication both from CSRF token and slave.
* public/v3/components/custom-configuration-test-group-form.js:
(CustomConfigurationTestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
* public/v3/components/customizable-test-group-form.js:
(CustomizableTestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
(CustomizableTestGroupForm.cssTemplate): Added space between 'Notify on completion' checkbox and test group iteration selection list.
* public/v3/components/test-group-form.js:
(TestGroupForm): Added '_notifyOnCompletion' instance variable.
(TestGroupForm.prototype.didConstructShadowTree): Added 'onchange' event for notify on completion checkbox.
(TestGroupForm.prototype.startTesting): Pass 'notifyOnCompletion' information which represents
'testgroup_needs_notification' from API perspective.
(TestGroupForm.cssTemplate): Added space between 'Notify on completion' checkbox and test group iteration selection list.
* public/v3/models/analysis-results.js: Export 'AnalysisResults'.
(AnalysisResults.fetch): Update API path to use absolute url.
(AnalysisResults):
* public/v3/models/analysis-task.js:
(AnalysisTask.async.create): Extend this function to take notifyOnCompletion as argument which will be used as
'needsNotification' to send to server.
(AnalysisTask):
* public/v3/models/test-group.js:
(TestGroup): Added '_needsNotification' field.
(TestGroup.prototype.updateSingleton): Added logic to update '_needsNotification' field.
(TestGroup.prototype.needsNotification): Returns '_needsNotification' field.
(TestGroup.prototype.author): Returns author information.
(TestGroup.prototype.async.didSendNotification): API that updates 'testgroup_needs_notification' to true.
(TestGroup.prototype.async.fetchTask): API to fetch the task when it has not been fetched.
(TestGroup.createWithTask): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.createWithCustomConfiguration): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.createAndRefetchTestGroups): Updated this function to accept 'notifyOnCompletion' which will be used as
'needsNotification' to send to server.
(TestGroup.fetchAllWithNotificationReady): New function that invokes '/api/test-groups/ready-for-notification'.
* public/v3/pages/analysis-task-page.js: Update logic to 'notifyOnCompletion' around
(AnalysisTaskChartPane.prototype.didConstructShadowTree):
(AnalysisTaskResultsPane.prototype.didConstructShadowTree):
(AnalysisTaskTestGroupPane.prototype.didConstructShadowTree):
(AnalysisTaskPage.prototype.didConstructShadowTree):
(AnalysisTaskPage.prototype._retryCurrentTestGroup):
(AnalysisTaskPage.prototype.async._bisectCurrentTestGroup):
(AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList.set const):
(AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList):
(AnalysisTaskPage.prototype._createCustomTestGroup):
* public/v3/pages/chart-pane.js: Added 'Notify on completion' checkbox.
(ChartPane.prototype.didConstructShadowTree):
(ChartPane.prototype.async._analyzeRange):
* public/v3/pages/create-analysis-task-page.js: Adapted API change.
(CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup):
* server-tests/api-test-groups.js: Added tests for '/api/test-groups/ready-for-notification'.
* server-tests/privileged-api-create-analysis-task-tests.js: Updated tests to adapt this change.
Added new tests.
* server-tests/privileged-api-create-test-group-tests.js: Added new tests.
* server-tests/privileged-api-update-test-group-tests.js: Added unit test for 'update-test-group' API.
* server-tests/resources/mock-data.js: addMockData should set 'testgroup_needs_notification' to be true.
* server-tests/tools-sync-buildbot-integration-tests.js: Updated tests to adapt this change.
(async.createTestGroupWihPatch):
(createTestGroupWihOwnedCommit):
* tools/js/analysis-results-notifier.js: Added notifier to send notification for completed test groups.
(AnalysisResultsNotifier):
(AnalysisResultsNotifier.prototype.async.sendNotificationsForTestGroups):
(AnalysisResultsNotifier.prototype._sendNotification): Invoke remote API to send notification.
(AnalysisResultsNotifier.prototype._constructMessageByRules):
(AnalysisResultsNotifier._matchesRule):
(AnalysisResultsNotifier._applyUpdate):
(AnalysisResultsNotifier.async._messageForTestGroup): Build html as message body for a test group.
(AnalysisResultsNotifier._URLForAnalysisTask): Returns URL for an analysis task.
(AnalysisResultsNotifier._instantiateNotificationTemplate):
* tools/js/test-group-result-page.js: Added 'TestGroupResultPage' and 'BarGraph' to show test group result.
(TestGroupResultPage):
(TestGroupResultPage.prototype.async.setTestGroup):
(TestGroupResultPage._urlForAnalysisTask):
(TestGroupResultPage.prototype._URLForAnalysisTask):
(TestGroupResultPage.prototype.constructTables):
(TestGroupResultPage.prototype._constructTableForMetric):
(TestGroupResultPage.):
(TestGroupResultPage.prototype.get pageContent):
(TestGroupResultPage.prototype.get styleTemplate):
(BarGraph):
(BarGraph.prototype.setWidth):
(BarGraph.prototype._constructBarGraph):
(BarGraph.prototype.get pageContent):
(BarGraph.prototype.get styleTemplate):
* tools/js/measurement-set-analyzer.js: Adapted 'AnalysisTask.create' change.
(MeasurementSetAnalyzer.prototype.async._analyzeMeasurementSet):
(MeasurementSetAnalyzer):
* tools/js/v3-models.js:
* tools/run-analysis.js: Added the logic that sends notification for completed test groups.
(main):
(async.analysisLoop):
* unit-tests/analysis-task-tests.js:
* unit-tests/analysis-results-notifier-tests.js: Added a unit test for 'AnalysisResultsNotifier' and 'NotificationService'.
* unit-tests/measurement-set-analyzer-tests.js: Updated unit tests per this change.
* unit-tests/test-groups-tests.js: Added unit tests for 'TestGroup.needsNotification'.
* unit-tests/resources/mock-remote-api.js: Only set 'privilegedAPI' when it exits.

2018-06-07 Ryosuke Niwa <rniwa@webkit.org>

Add the basic support for writing components in node.js
Expand Down
1 change: 1 addition & 0 deletions Websites/perf.webkit.org/browser-tests/index.html
Expand Up @@ -28,6 +28,7 @@
<script src="commit-log-viewer-tests.js"></script>
<script src="test-group-form-tests.js"></script>
<script src="markup-page-tests.js"></script>
<script src="test-group-result-page-tests.js"></script>
<script>

afterEach(() => {
Expand Down
31 changes: 25 additions & 6 deletions Websites/perf.webkit.org/browser-tests/test-group-form-tests.js
Expand Up @@ -18,7 +18,7 @@ describe('TestGroupFormTests', () => {
testGroupForm.listenToAction('startTesting', (...args) => calls.push(args));
expect(calls).to.eql({});
testGroupForm.content('start-button').click();
expect(calls).to.eql([[4]]);
expect(calls).to.eql([[4, true]]);
});
});

Expand All @@ -29,12 +29,31 @@ describe('TestGroupFormTests', () => {
testGroupForm.listenToAction('startTesting', (...args) => calls.push(args));
expect(calls).to.eql({});
testGroupForm.content('start-button').click();
expect(calls).to.eql([[4]]);
expect(calls).to.eql([[4, true]]);
const countForm = testGroupForm.content('repetition-count');
countForm.value = '6';
countForm.dispatchEvent(new Event('change'));
countForm.dispatchEvent(new Event('change'));
testGroupForm.content('start-button').click();
expect(calls).to.eql([[4], [6]]);
expect(calls).to.eql([[4, true], [6, true]]);
});
});

it('must update "notify on completion" when it is unchecked', () => {
const context = new BrowsingContext();
return createTestGroupFormWithContext(context).then((testGroupForm) => {
const calls = [];
testGroupForm.listenToAction('startTesting', (...args) => calls.push(args));
expect(calls).to.eql({});
testGroupForm.content('start-button').click();
expect(calls).to.eql([[4, true]]);
const countForm = testGroupForm.content('repetition-count');
countForm.value = '6';
countForm.dispatchEvent(new Event('change'));
const notifyOnCompletionCheckbox = testGroupForm.content('notify-on-completion-checkbox');
notifyOnCompletionCheckbox.checked = false;
notifyOnCompletionCheckbox.dispatchEvent(new Event('change'));
testGroupForm.content('start-button').click();
expect(calls).to.eql([[4, true], [6, false]]);
});
});

Expand All @@ -57,10 +76,10 @@ describe('TestGroupFormTests', () => {
testGroupForm.listenToAction('startTesting', (...args) => calls.push(args));
expect(calls).to.eql({});
testGroupForm.content().querySelector('button').click();
expect(calls).to.eql([[4]]);
expect(calls).to.eql([[4, true]]);
testGroupForm.setRepetitionCount(8);
testGroupForm.content().querySelector('button').click();
expect(calls).to.eql([[4], [8]]);
expect(calls).to.eql([[4, true], [8, true]]);
});
});
});
Expand Down
@@ -0,0 +1,80 @@
describe('TestGroupResultPage', () => {

async function importMarkupComponent(context)
{
return await context.importScripts(['lazily-evaluated-function.js', '../shared/common-component-base.js', '../../tools/js/markup-component.js', '../../tools/js/test-group-result-page.js',
'models/data-model.js', 'models/metric.js', '../shared/statistics.js',], 'TestGroupResultPage', 'Metric');
}

async function prepareTestGroupResultPage(context, resultA, resultB)
{
const [TestGroupResultPage, Metric] = await importMarkupComponent(context);

const mockAnalysisTask = {
metric: () => ({
makeFormatter: (sigFig, alwaysShowSign) => Metric.makeFormatter('MB', sigFig, alwaysShowSign),
aggregatorLabel: () => 'Arithmetic mean'
}),
name: () => 'mock-analysis-task'
};

const mockTestGroup = {
requestedCommitSets: () => ['A', 'B'],
test: () => ({test: () => 'speeodmeter-2', name: () => 'speedometer-2'}),
labelForCommitSet: (commitSet) => commitSet,
requestsForCommitSet: (commitSet) => ({'A': resultA, 'B': resultB}[commitSet]),
compareTestResults: (...args) => ({isStatisticallySignificant: true, changeType: 'worse'}),
name: () => 'mock-test-group',
};

const mockAnalysisResults = {
viewForMetric: (metric) => ({resultForRequest: (buildRequest) => (buildRequest === null ? null : {value: buildRequest})})
};

const page = new TestGroupResultPage('test');
page._testGroup = mockTestGroup;
page._analysisTask = mockAnalysisTask;
page._analysisResults = mockAnalysisResults;
page._analysisURL = 'http://localhost';

return page;
}

it('should render failed test group with empty bar', async () => {
const context = new BrowsingContext();
const page = await prepareTestGroupResultPage(context, [null, 3, 5], [2, 4, 6]);
await page.enqueueToRender();
const document = context.document;
document.open();
document.write(page.generateMarkup());
document.close();

expect(context.global.getComputedStyle(context.document.querySelector('.bar-graph-placeholder')).width).to.be('0px');
});

it('should render right ratio based on test group result', async () => {
const context = new BrowsingContext();
const resultA = [1, 3, 5];
const resultB = [2, 4, 6];
const page = await prepareTestGroupResultPage(context, resultA, resultB);
page.enqueueToRender();
const document = context.document;
document.open();
document.write(page.generateMarkup());
document.close();

const min = 0.5;
const max = 6.5;
const expectedPercentages = [...resultA, ...resultB].map((result) => (result - min) / (max - min));
const barNodes = context.document.querySelectorAll('.bar-graph-placeholder');
expect(barNodes.length).to.be(6);

const almostEqual = (a, b) => Math.abs(a - b) < 0.001;
let previousNodeWidth = parseFloat(context.global.getComputedStyle(barNodes[0]).width);
for (let i = 1; i < 6; ++ i) {
const currentNodeWidth = parseFloat(context.global.getComputedStyle(barNodes[i]).width);
expect(almostEqual(currentNodeWidth / previousNodeWidth, expectedPercentages[i] / expectedPercentages[i - 1])).to.be(true);
previousNodeWidth = currentNodeWidth;
}
});
});
2 changes: 2 additions & 0 deletions Websites/perf.webkit.org/init-database.sql
Expand Up @@ -279,6 +279,8 @@ CREATE TABLE analysis_test_groups (
testgroup_author varchar(256),
testgroup_created_at timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
testgroup_hidden boolean NOT NULL DEFAULT FALSE,
testgroup_needs_notification boolean NOT NULL DEFAULT FALSE,
testgroup_notification_sent_at timestamp DEFAULT NULL,
CONSTRAINT testgroup_name_must_be_unique_for_each_task UNIQUE(testgroup_task, testgroup_name));
CREATE INDEX testgroup_task_index ON analysis_test_groups(testgroup_task);

Expand Down
35 changes: 26 additions & 9 deletions Websites/perf.webkit.org/public/api/test-groups.php
Expand Up @@ -13,14 +13,7 @@ function main($path) {

$build_requests_fetcher = new BuildRequestsFetcher($db);

if (count($path) > 0 && $path[0]) {
$group_id = intval($path[0]);
$group = $db->select_first_row('analysis_test_groups', 'testgroup', array('id' => $group_id));
if (!$group)
exit_with_error('GroupNotFound', array('id' => $group_id));
$test_groups = array($group);
$build_requests_fetcher->fetch_for_group($group['testgroup_task'], $group_id);
} else {
if (!count($path)) {
$task_id = array_get($_GET, 'task');
if (!$task_id)
exit_with_error('TaskIdNotSpecified');
Expand All @@ -29,6 +22,28 @@ function main($path) {
if (!is_array($test_groups))
exit_with_error('FailedToFetchTestGroups');
$build_requests_fetcher->fetch_for_task($task_id);
} elseif ($path[0] == 'ready-for-notification') {
$test_groups = $db->query_and_fetch_all("SELECT * FROM analysis_test_groups
WHERE EXISTS(SELECT 1 FROM build_requests
WHERE request_group = testgroup_id
AND request_status IN ('pending', 'scheduled', 'running', 'canceled')) IS FALSE
AND testgroup_needs_notification IS TRUE AND testgroup_hidden IS FALSE");

if (!count($test_groups)) {
exit_with_success(array('testGroups' => array(),
'buildRequests' => array(),
'commitSets' => array(),
'commits' => array(),
'uploadedFiles' => array()));
}
$build_requests_fetcher->fetch_requests_for_groups($test_groups);
} else {
$group_id = intval($path[0]);
$group = $db->select_first_row('analysis_test_groups', 'testgroup', array('id' => $group_id));
if (!$group)
exit_with_error('GroupNotFound', array('id' => $group_id));
$test_groups = array($group);
$build_requests_fetcher->fetch_for_group($group['testgroup_task'], $group_id);
}
if (!$build_requests_fetcher->has_results())
exit_with_error('FailedToFetchBuildRequests');
Expand Down Expand Up @@ -63,8 +78,10 @@ function format_test_group($group_row) {
'task' => $group_row['testgroup_task'],
'name' => $group_row['testgroup_name'],
'author' => $group_row['testgroup_author'],
'createdAt' => strtotime($group_row['testgroup_created_at']) * 1000,
'createdAt' => Database::to_js_time($group_row['testgroup_created_at']),
'notificationSentAt' => Database::to_js_time($group_row['testgroup_notification_sent_at']),
'hidden' => Database::is_true($group_row['testgroup_hidden']),
'needsNotification' => Database::is_true($group_row['testgroup_needs_notification']),
'buildRequests' => array(),
'commitSets' => array(),
);
Expand Down

0 comments on commit 853907d

Please sign in to comment.