Diff
Modified: trunk/Websites/perf.webkit.org/ChangeLog (215635 => 215636)
--- trunk/Websites/perf.webkit.org/ChangeLog 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/ChangeLog 2017-04-21 21:08:36 UTC (rev 215636)
@@ -1,5 +1,93 @@
2017-04-21 Ryosuke Niwa <[email protected]>
+ Add the support for creating a custom test group in the analysis task page
+
+ Make it possible to create more custom test groups in the analysis task page
+ https://bugs.webkit.org/show_bug.cgi?id=171138
+
+ Rubber-stamped by Chris Dumez.
+
+ Extracted CustomConfigurationTestGroupForm out of CreateAnalysisTaskPage and added it to AnalysisTaskPage inside
+ AnalysisTaskConfiguratorPane. This allows configuration of a new test group within a custom analysis task.
+
+ * public/privileged-api/create-test-group.php:
+ (main): Fixed the bug that the triggerable wasn't resolved when creating a test group in a custom analysis task.
+
+ * public/v3/components/custom-analysis-task-configurator.js:
+ (CustomAnalysisTaskConfigurator.prototype.selectTests): Added. Used by CustomConfigurationTestGroupForm's
+ setConfigurations.
+ (CustomAnalysisTaskConfigurator.prototype.selectPlatform): Ditto.
+ (CustomAnalysisTaskConfigurator.prototype.setCommitSets): Ditto.
+ (CustomAnalysisTaskConfigurator.prototype._setUploadedFilesIfEmpty): Added.
+ (CustomAnalysisTaskConfigurator.prototype._revisionMapFromCommitSet): Added.
+ (CustomAnalysisTaskConfigurator.prototype.render): Update the currently selected platforms and tests now that
+ they can be set externally via selectTests and selectPlatform.
+ (CustomAnalysisTaskConfigurator.prototype._renderTriggerableTests): Return the result of _renderRadioButtonList
+ so that the caller can update the currently selected tests without having to reconstruct the list.
+ (CustomAnalysisTaskConfigurator.prototype._renderTriggerablePlatforms): Ditto.
+ (CustomAnalysisTaskConfigurator.prototype._renderRadioButtonList): Renamed from _buildCheckboxList. Now returns
+ a function which updates the currently selected items. We still pretend that multiple items can be selected to
+ make it future-proof.
+
+ * public/v3/components/custom-configuration-test-group-form.js: Added.
+ (CustomConfigurationTestGroupForm): Added. Inherits from TestGroupForm. Extracted from CreateAnalysisTaskPage.
+ (CustomConfigurationTestGroupForm.prototype.setHasTask): Added.
+ (CustomConfigurationTestGroupForm.prototype.hasCommitSets): Added.
+ (CustomConfigurationTestGroupForm.prototype.setConfigurations): Added. Used by AnalysisTaskConfiguratorPane to
+ set the default configuration to what the latest test group used.
+ (CustomConfigurationTestGroupForm.prototype.startTesting): Added. Dispatches "startTesting" action with
+ platform, test, taskName in addition to what CustomizedTestGroupForm emits.
+ (CustomConfigurationTestGroupForm.prototype.didConstructShadowTree): Added.
+ (CustomConfigurationTestGroupForm.prototype.render): Added.
+ (CustomConfigurationTestGroupForm.prototype._updateTestGroupName): Added.
+ (CustomConfigurationTestGroupForm.cssTemplate): Added.
+ (CustomConfigurationTestGroupForm.htmlTemplate): Added.
+
+ * public/v3/components/test-group-form.js:
+ (TestGroupForm.cssTemplate): Make the form display: block.
+
+ * public/v3/index.html:
+
+ * public/v3/models/test-group.js:
+ (TestGroup.prototype.test): Added.
+ (TestGroup.prototype.platform): Added.
+ (TestGroup.createWithCustomConfiguration): Added. Creates a custom test group with an existing analysis task.
+
+ * public/v3/models/uploaded-file.js:
+ (UploadedFile): Fixed a bug that _deletedAt was set to a Date object even when object.deletedAt is null.
+
+ * public/v3/pages/analysis-task-page.js:
+ (AnalysisTaskConfiguratorPane): Added.
+ (AnalysisTaskConfiguratorPane.prototype.didConstructShadowTree): Added. Dispatch createCustomTestGroup action
+ in turn when receiving startTesting from CustomConfigurationTestGroupForm.
+ (AnalysisTaskConfiguratorPane.prototype.setTestGroups): Added.
+ (AnalysisTaskConfiguratorPane.prototype.render): Added.
+ (AnalysisTaskConfiguratorPane.htmlTemplate): Added. We override this instead of formContent to display the
+ "Start" button at the end instead of at the beginnning.
+ (AnalysisTaskConfiguratorPane.cssTemplate): Added.
+ (AnalysisTaskPage.prototype.didConstructShadowTree): Listen to createCustomTestGroup.
+ (AnalysisTaskPage.prototype.render): Hide AnalysisTaskConfiguratorPane when the analysis task is not custom.
+ (AnalysisTaskPage.prototype._showTestGroup): Let AnalysisTaskConfiguratorPane know of the current test group
+ so that it can update the default configuration if the user hasn't modified yet.
+ (AnalysisTaskPage.prototype._createCustomTestGroup): Added.
+
+ * public/v3/pages/create-analysis-task-page.js:
+ (CreateAnalysisTaskPage.prototype.didConstructShadowTree):
+ (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup):
+ (CreateAnalysisTaskPage.prototype.render):
+ (CreateAnalysisTaskPage.prototype._renderMessage):
+ (CreateAnalysisTaskPage.htmlTemplate):
+ (CreateAnalysisTaskPage.cssTemplate):
+
+ * server-tests/privileged-api-create-test-group-tests.js: Added a test case for creating a custom test group for
+ an existing analysis task.
+
+ * server-tests/resources/mock-data.js:
+ (MockData.otherPlatformId): Added.
+ (MockData.addMockData): Added a test configuration for otherPlatformId.
+
+2017-04-21 Ryosuke Niwa <[email protected]>
+
Make it possible to view results for sub tests and metrics in A/B testing
https://bugs.webkit.org/show_bug.cgi?id=170975
Modified: trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php 2017-04-21 21:08:36 UTC (rev 215636)
@@ -59,7 +59,8 @@
exit_with_error('InconsistentTest', array('groupTest' => $test_id, 'taskTest' => $triggerable['test']));
}
}
- } else if ($platform_id && $test_id) {
+ }
+ if (!$triggerable_id && $platform_id && $test_id) {
$triggerable_configuration = $db->select_first_row('triggerable_configurations', 'trigconfig',
array('test' => $test_id, 'platform' => $platform_id));
if ($triggerable_configuration)
Modified: trunk/Websites/perf.webkit.org/public/v3/components/custom-analysis-task-configurator.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/components/custom-analysis-task-configurator.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/components/custom-analysis-task-configurator.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -32,6 +32,69 @@
return [map['Baseline'], map['Comparison']];
}
+ selectTests(selectedTests)
+ {
+ this._selectedTests = selectedTests;
+
+ this._triggerablePlatforms = Triggerable.triggerablePlatformsForTests(this._selectedTests);
+ if (this._selectedTests.length && !this._triggerablePlatforms.includes(this._selectedPlatform))
+ this._selectedPlatform = null;
+
+ this.enqueueToRender();
+ }
+
+ selectPlatform(selectedPlatform)
+ {
+ this._selectedPlatform = selectedPlatform;
+
+ const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
+ this._updateRepositoryGroups(triggerable);
+ this._updateCommitSetMap();
+
+ this.enqueueToRender();
+ }
+
+ setCommitSets(baselineCommitSet, comparisonCommitSet)
+ {
+ const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
+
+ if (!triggerable)
+ return;
+
+ const baselineRepositoryGroup = triggerable.repositoryGroups().find((repositoryGroup) => repositoryGroup.accepts(baselineCommitSet));
+ if (baselineRepositoryGroup) {
+ this._repositoryGroupByConfiguration['Baseline'] = baselineRepositoryGroup;
+ this._setUploadedFilesIfEmpty(this._fileUploaders['Baseline'], baselineCommitSet);
+ this._specifiedRevisions['Baseline'] = this._revisionMapFromCommitSet(baselineCommitSet);
+ }
+
+ const comparisonRepositoryGroup = triggerable.repositoryGroups().find((repositoryGroup) => repositoryGroup.accepts(baselineCommitSet));
+ if (comparisonRepositoryGroup) {
+ this._repositoryGroupByConfiguration['Comparison'] = comparisonRepositoryGroup;
+ this._setUploadedFilesIfEmpty(this._fileUploaders['Comparison'], comparisonCommitSet);
+ this._specifiedRevisions['Comparison'] = this._revisionMapFromCommitSet(comparisonCommitSet);
+ }
+
+ this._showComparison = true;
+ this._updateCommitSetMap();
+ }
+
+ _setUploadedFilesIfEmpty(uploader, commitSet)
+ {
+ if (uploader.hasFileToUpload() || uploader.uploadedFiles().length)
+ return;
+ for (const uploadedFile of commitSet.customRoots())
+ uploader.addUploadedFile(uploadedFile);
+ }
+
+ _revisionMapFromCommitSet(commitSet)
+ {
+ const revisionMap = new Map;
+ for (const repository of commitSet.repositories())
+ revisionMap.set(repository, commitSet.revisionForRepository(repository));
+ return revisionMap;
+ }
+
didConstructShadowTree()
{
this.content('specify-comparison-button')._onclick_ = this.createEventHandler(() => this._configureComparison());
@@ -68,8 +131,11 @@
{
super.render();
- this._renderTriggerableTestsLazily.evaluate();
- this._renderTriggerablePlatformsLazily.evaluate(this._selectedTests, this._triggerablePlatforms);
+ const updateSelectedTestsLazily = this._renderTriggerableTestsLazily.evaluate();
+ updateSelectedTestsLazily.evaluate(...this._selectedTests);
+ const updateSelectedPlatformsLazily = this._renderTriggerablePlatformsLazily.evaluate(this._selectedTests, this._triggerablePlatforms);
+ if (updateSelectedPlatformsLazily)
+ updateSelectedPlatformsLazily.evaluate(this._selectedPlatform);
const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
@@ -81,13 +147,7 @@
const enabledTriggerables = Triggerable.all().filter((triggerable) => !triggerable.isDisabled());
let tests = Test.topLevelTests().filter((test) => test.metrics().length && enabledTriggerables.some((triggerable) => triggerable.acceptsTest(test)));
- this.renderReplace(this.content('test-list'), this._buildCheckboxList('test', tests, (selectedTests) => {
- this._selectedTests = selectedTests;
-
- this._triggerablePlatforms = Triggerable.triggerablePlatformsForTests(this._selectedTests);
- if (this._selectedTests.length && !this._triggerablePlatforms.includes(this._selectedPlatform))
- this._selectedPlatform = null;
- }));
+ return this._renderRadioButtonList(this.content('test-list'), 'test', tests, this.selectTests.bind(this));
}
_renderTriggerablePlatforms(selectedTests, triggerablePlatforms)
@@ -94,39 +154,47 @@
{
if (!selectedTests.length) {
this.content('platform-pane').style.display = 'none';
- return;
+ return null;
}
this.content('platform-pane').style.display = null;
- this.renderReplace(this.content('platform-list'), this._buildCheckboxList('platform', triggerablePlatforms, (selectedPlatforms) => {
- this._selectedPlatform = selectedPlatforms.length ? selectedPlatforms[0] : null;
-
- const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
- this._updateRepositoryGroups(triggerable);
- this._updateCommitSetMap();
-
- this.enqueueToRender();
- }));
+ return this._renderRadioButtonList(this.content('platform-list'), 'platform', triggerablePlatforms, (selectedPlatforms) => {
+ this.selectPlatform(selectedPlatforms.length ? selectedPlatforms[0] : null);
+ });
}
- _buildCheckboxList(name, objects, callback)
+ _renderRadioButtonList(listContainer, name, objects, callback)
{
const listItems = [];
let selectedListItems = [];
+ const checkSelectedRadioButtons = (newSelectedListItems) => {
+ selectedListItems.forEach((item) => {
+ item.label.classList.remove('selected');
+ item.radioButton.checked = false;
+ });
+ selectedListItems = newSelectedListItems;
+ selectedListItems.forEach((item) => {
+ item.label.classList.add('selected');
+ item.radioButton.checked = true;
+ });
+ }
+
const element = ComponentBase.createElement;
- return objects.map((object) => {
- const checkbox = element('input', {type: 'radio', name: name, onchange: () => {
- selectedListItems.forEach((item) => item.label.classList.remove('selected'));
- selectedListItems = listItems.filter((item) => item.checkbox.checked);
- selectedListItems.forEach((item) => item.label.classList.add('selected'));
-
+ this.renderReplace(listContainer, objects.map((object) => {
+ const radioButton = element('input', {type: 'radio', name: name, onchange: () => {
+ checkSelectedRadioButtons(listItems.filter((item) => item.radioButton.checked));
callback(selectedListItems.map((item) => item.object));
this.enqueueToRender();
}});
- const label = element('label', [checkbox, object.label()]);
- listItems.push({checkbox, label, object});
+ const label = element('label', [radioButton, object.label()]);
+ listItems.push({radioButton, label, object});
return element('li', label);
- })
+ }));
+
+ return new LazilyEvaluatedFunction((...selectedObjects) => {
+ const objects = new Set(selectedObjects);
+ checkSelectedRadioButtons(listItems.filter((item) => objects.has(item.object)));
+ });
}
_updateTriggerable(tests, platform)
Added: trunk/Websites/perf.webkit.org/public/v3/components/custom-configuration-test-group-form.js (0 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/components/custom-configuration-test-group-form.js (rev 0)
+++ trunk/Websites/perf.webkit.org/public/v3/components/custom-configuration-test-group-form.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -0,0 +1,110 @@
+
+class CustomConfigurationTestGroupForm extends TestGroupForm {
+
+ constructor()
+ {
+ super('custom-configuration-test-group-form');
+ this._hasTask = false;
+ this._updateTestGroupNameLazily = new LazilyEvaluatedFunction(this._updateTestGroupName.bind(this));
+ }
+
+ setHasTask(hasTask)
+ {
+ this._hasTask = hasTask;
+ this.enqueueToRender();
+ }
+
+ hasCommitSets()
+ {
+ return !!this.part('configurator').commitSets();
+ }
+
+ setConfigurations(test, platform, repetitionCount, commitSets)
+ {
+ const configurator = this.part('configurator');
+ configurator.selectTests([test]);
+ configurator.selectPlatform(platform);
+ if (commitSets.length == 2)
+ configurator.setCommitSets(commitSets[0], commitSets[1]);
+ this.setRepetitionCount(repetitionCount);
+ this.enqueueToRender();
+ }
+
+ startTesting()
+ {
+ const taskName = this.content('task-name').value;
+ const testGroupName = this.content('group-name').value;
+ const configurator = this.part('configurator');
+ const commitSets = configurator.commitSets();
+ const platform = configurator.platform();
+ const test = configurator.tests()[0]; // FIXME: Add the support for specifying multiple tests.
+ this.dispatchAction('startTesting', this._repetitionCount, testGroupName, commitSets, platform, test, taskName);
+ }
+
+ didConstructShadowTree()
+ {
+ super.didConstructShadowTree();
+
+ this.part('configurator').listenToAction('commitSetChange', () => this.enqueueToRender());
+
+ this.content('task-name')._oninput_ = () => this.enqueueToRender();
+ this.content('group-name')._oninput_ = () => this.enqueueToRender();
+ }
+
+ render()
+ {
+ super.render();
+ const configurator = this.part('configurator');
+ this._updateTestGroupNameLazily.evaluate(configurator.tests(), configurator.platform());
+
+ const needsTaskName = !this._hasTask && !this.content('task-name').value;
+ this.content('iteration-start-pane').style.display = !!configurator.commitSets() ? null : 'none';
+ this.content('task-name').style.display = this._hasTask ? 'none' : null;
+ this.content('start-button').disabled = needsTaskName || !this.content('group-name').value;
+ }
+
+ _updateTestGroupName(tests, platform)
+ {
+ if (!platform || !tests.length)
+ return;
+ this.content('group-name').value = `${tests.map((test) => test.name()).join(', ')} on ${platform.name()}`;
+ }
+
+ static cssTemplate()
+ {
+ return super.cssTemplate() + `
+ input {
+ width: 30%;
+ min-width: 10rem;
+ font-size: 1rem;
+ font-weight: inherit;
+ }
+
+ #form > * {
+ margin-bottom: 1rem;
+ }
+
+ #start-button {
+ display: block;
+ margin-top: 0.5rem;
+ font-size: 1.2rem;
+ font-weight: inherit;
+ }
+ `;
+ }
+
+ static htmlTemplate()
+ {
+ return `<form id="form">
+ <input id="task-name" type="text" placeholder="Name this task">
+ <custom-analysis-task-configurator id="configurator"></custom-analysis-task-configurator>
+ <div id="iteration-start-pane">
+ <input id="group-name" type="text" placeholder="Test group name">
+ ${super.formContent()}
+ <button id="start-button">Start</button>
+ </div>
+ </form>`;
+ }
+}
+
+ComponentBase.defineElement('custom-configuration-test-group-form', CustomConfigurationTestGroupForm);
Modified: trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/components/test-group-form.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -32,6 +32,15 @@
return `<form id="form"><button id="start-button" type="submit"><slot>Start A/B testing</slot></button>${this.formContent()}</form>`;
}
+ static cssTemplate()
+ {
+ return `
+ :host {
+ display: block;
+ }
+ `;
+ }
+
static formContent()
{
return `
Modified: trunk/Websites/perf.webkit.org/public/v3/index.html (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/index.html 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/index.html 2017-04-21 21:08:36 UTC (rev 215636)
@@ -96,6 +96,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
Modified: trunk/Websites/perf.webkit.org/public/v3/models/test-group.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/models/test-group.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/models/test-group.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -40,6 +40,20 @@
this._commitSetToLabel.clear();
}
+ test()
+ {
+ if (!this._buildRequests.length)
+ return null;
+ return this._buildRequests[0].test();
+ }
+
+ platform()
+ {
+ if (!this._buildRequests.length)
+ return null;
+ return this._buildRequests[0].platform();
+ }
+
repetitionCount()
{
if (!this._buildRequests.length)
@@ -188,6 +202,16 @@
});
}
+ static createWithCustomConfiguration(task, platform, test, groupName, repetitionCount, commitSets)
+ {
+ console.assert(commitSets.length == 2);
+ const revisionSets = this._revisionSetsFromCommitSets(commitSets);
+ const params = {task: task.id(), name: groupName, platform: platform.id(), test: test.id(), repetitionCount, revisionSets};
+ return PrivilegedAPI.sendRequest('create-test-group', params).then((data) => {
+ return this._fetchTestGroupsForTask(task.id());
+ });
+ }
+
static createAndRefetchTestGroups(task, name, repetitionCount, commitSets)
{
console.assert(commitSets.length == 2);
Modified: trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -5,7 +5,7 @@
{
super(id, object);
this._createdAt = new Date(object.createdAt);
- this._deletedAt = new Date(object.deletedAt);
+ this._deletedAt = object.deletedAt ? new Date(object.deletedAt) : null;
this._filename = object.filename;
this._author = object.author;
this._size = object.size;
Modified: trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -133,6 +133,53 @@
ComponentBase.defineElement('analysis-task-results-pane', AnalysisTaskResultsPane);
+class AnalysisTaskConfiguratorPane extends ComponentBase {
+ constructor()
+ {
+ super('analysis-task-configurator-pane');
+ this._currentGroup = null;
+ }
+
+ didConstructShadowTree()
+ {
+ const form = this.part('form');
+ form.setHasTask(true);
+ form.listenToAction('startTesting', (...args) => {
+ this.dispatchAction('createCustomTestGroup', ...args);
+ });
+ }
+
+ setTestGroups(testGroups, currentGroup)
+ {
+ this._currentGroup = currentGroup;
+ const form = this.part('form');
+ if (!form.hasCommitSets())
+ form.setConfigurations(currentGroup.test(), currentGroup.platform(), currentGroup.repetitionCount(), currentGroup.requestedCommitSets());
+ this.enqueueToRender();
+ }
+
+ render()
+ {
+ super.render();
+ }
+
+ static htmlTemplate()
+ {
+ return `<custom-configuration-test-group-form id="form"></custom-configuration-test-group-form>`;
+ }
+
+ static cssTemplate()
+ {
+ return `
+ #form {
+ margin: 1rem;
+ }
+ `;
+ }
+};
+
+ComponentBase.defineElement('analysis-task-configurator-pane', AnalysisTaskConfiguratorPane);
+
class AnalysisTaskTestGroupPane extends ComponentBase {
constructor()
@@ -389,6 +436,8 @@
resultsPane.listenToAction('showTestGroup', (testGroup) => this._showTestGroup(testGroup));
resultsPane.listenToAction('newTestGroup', this._createTestGroupAfterVerifyingCommitSetList.bind(this));
+ this.part('configurator-pane').listenToAction('createCustomTestGroup', this._createCustomTestGroup.bind(this));
+
const groupPane = this.part('group-pane');
groupPane.listenToAction('showTestGroup', (testGroup) => this._showTestGroup(testGroup));
groupPane.listenToAction('showHiddenTestGroups', () => this._showAllTestGroups());
@@ -524,6 +573,8 @@
this.content('results-pane').style.display = this._task && !this._task.isCustom() ? null : 'none';
this.part('results-pane').setShowForm(!!this._triggerable);
+ this.content('configurator-pane').style.display = this._task && this._task.isCustom() ? null : 'none';
+
Instrumentation.endMeasuringTime('AnalysisTaskPage', 'render');
}
@@ -583,6 +634,7 @@
_showTestGroup(testGroup)
{
this._currentTestGroup = testGroup;
+ this.part('configurator-pane').setTestGroups(this._filteredTestGroups, this._currentTestGroup);
this.part('results-pane').setTestGroups(this._filteredTestGroups, this._currentTestGroup);
const groupsInReverseChronology = this._filteredTestGroups.slice(0).reverse();
const showHiddenGroups = !this._testGroups.some((group) => group.isHidden()) || this._showHiddenTestGroups;
@@ -711,6 +763,20 @@
});
}
+ _createCustomTestGroup(repetitionCount, testGroupName, commitSets, platform, test)
+ {
+ console.assert(this._task.isCustom());
+ if (this._hasDuplicateTestGroupName(testGroupName)) {
+ alert(`There is already a test group named "${testGroupName}"`);
+ return;
+ }
+
+ TestGroup.createWithCustomConfiguration(this._task, platform, test, testGroupName, repetitionCount, commitSets)
+ .then(this._didFetchTestGroups.bind(this), function (error) {
+ alert('Failed to create a new test group: ' + error);
+ });
+ }
+
_createRetryNameForTestGroup(name)
{
var nameWithNumberMatch = name.match(/(.+?)\s*\(\s*(\d+)\s*\)\s*$/);
@@ -777,6 +843,7 @@
</div>
<analysis-task-chart-pane id="chart-pane"></analysis-task-chart-pane>
<analysis-task-results-pane id="results-pane"></analysis-task-results-pane>
+ <analysis-task-configurator-pane id="configurator-pane"></analysis-task-configurator-pane>
<analysis-task-test-group-pane id="group-pane"></analysis-task-test-group-pane>
</div>
`;
Modified: trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -19,32 +19,12 @@
didConstructShadowTree()
{
- this.part('configurator').listenToAction('commitSetChange', () => this.enqueueToRender());
- this.content('start-button')._onclick_ = this.createEventHandler(() => this._createAnalysisTaskWithGroup());
+ this.part('form').listenToAction('startTesting', this._createAnalysisTaskWithGroup.bind(this));
}
- _createAnalysisTaskWithGroup()
+ _createAnalysisTaskWithGroup(repetitionCount, testGroupName, commitSets, platform, test, taskName)
{
- const taskNameInput = this.content('task-name');
- if (!taskNameInput.reportValidity())
- return;
-
- const testGroupInput = this.content('test-group-name');
- if (!testGroupInput.reportValidity())
- return;
-
- const configurator = this.part('configurator');
- const tests = configurator.tests();
- if (tests.length != 1)
- return alert('Exactly one test must be selected');
-
- const taskName = taskNameInput.value;
- const testGroupName = testGroupInput.value;
- const iterationCount = this.content('iteration-count').value;
- const platform = configurator.platform();
- const commitSets = configurator.commitSets();
-
- TestGroup.createWithTask(taskName, platform, tests[0], testGroupName, iterationCount, commitSets).then((task) => {
+ TestGroup.createWithTask(taskName, platform, test, testGroupName, repetitionCount, commitSets).then((task) => {
const url = ""
location.href = ""
}, (error) => {
@@ -55,19 +35,16 @@
render()
{
super.render();
- const configurator = this.part('configurator');
- this._renderMessageLazily.evaluate(this._message, !!configurator.commitSets(), configurator.tests(), configurator.platform());
+ this._renderMessageLazily.evaluate(this._message);
}
- _renderMessage(message, hasValidCommitSets, tests, platform)
+ _renderMessage(message)
{
const messageContainer = this.content('message');
messageContainer.textContent = this._message;
messageContainer.style.display = this._message ? null : 'none';
- this.content('new-task').style.display = this._message ? 'none' : null;
- if (platform)
- this.content('test-group-name').value = `${tests.map((test) => test.name()).join(', ')} on ${platform.name()}`;
- this.content('iteration-start-pane').style.display = !this._message && hasValidCommitSets ? null : 'none';
+ this.content('form').style.display = this._message ? 'none' : null;
+
}
static htmlTemplate()
@@ -74,22 +51,7 @@
{
return `
<p id="message"></p>
- <div id="new-task">
- <input id="task-name" type="text" placeholder="Name this task" required>
- <custom-analysis-task-configurator id="configurator"></custom-analysis-task-configurator>
- <div id="iteration-start-pane">
- <input id="test-group-name" placeholder="Name this test group" required>
- <label><select id="iteration-count">
- <option>1</option>
- <option>2</option>
- <option>3</option>
- <option selected>4</option>
- <option>5</option>
- <option>6</option>
- </select> iterations per configuration</label>
- <button id="start-button">Start</button>
- </div>
- </div>`;
+ <custom-configuration-test-group-form id="form"></custom-configuration-test-group-form>`;
}
static cssTemplate()
@@ -98,25 +60,9 @@
#message {
text-align: center;
}
-
- #new-task > * {
- display: block;
+ #form {
margin: 1rem;
}
-
- #new-task input {
- width: 30%;
- min-width: 10rem;
- font-size: 1rem;
- font-weight: inherit;
- }
-
- #start-button {
- display: block;
- margin-top: 0.5rem;
- font-size: 1.2rem;
- font-weight: inherit;
- }
`;
}
}
Modified: trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -99,7 +99,8 @@
'slavePassword': 'anotherPassword',
'triggerable': 'build-webkit',
'configurations': [
- {test: MockData.someTestId(), platform: MockData.somePlatformId()}
+ {test: MockData.someTestId(), platform: MockData.somePlatformId()},
+ {test: MockData.someTestId(), platform: MockData.otherPlatformId()},
],
'repositoryGroups': [
{name: 'webkit-only', repositories: [MockData.webkitRepositoryId()]},
@@ -524,4 +525,61 @@
});
});
+ it('should create a custom test group for an existing custom analysis task', () => {
+ let firstResult;
+ let secondResult;
+ let webkit;
+ let test = MockData.someTestId();
+ return addTriggerableAndCreateTask('some task').then(() => {
+ webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
+ const revisionSets = [{[webkit.id()]: '191622'}, {[webkit.id()]: '191623'}];
+ return PrivilegedAPI.sendRequest('create-test-group',
+ {name: 'test1', taskName: 'other task', platform: MockData.somePlatformId(), test, revisionSets});
+ }).then((result) => {
+ firstResult = result;
+ const revisionSets = [{[webkit.id()]: '191622'}, {[webkit.id()]: '192736'}];
+ return PrivilegedAPI.sendRequest('create-test-group',
+ {name: 'test2', task: result['taskId'], platform: MockData.otherPlatformId(), test, revisionSets, repetitionCount: 2});
+ }).then((result) => {
+ secondResult = result;
+ assert.equal(firstResult['taskId'], secondResult['taskId']);
+ return Promise.all([AnalysisTask.fetchById(result['taskId']), TestGroup.fetchByTask(result['taskId'])]);
+ }).then((result) => {
+ const [analysisTask, testGroups] = result;
+
+ assert.equal(analysisTask.name(), 'other task');
+
+ assert.equal(testGroups.length, 2);
+ TestGroup.sortByName(testGroups);
+
+ assert.equal(testGroups[0].name(), 'test1');
+ assert.equal(testGroups[0].repetitionCount(), 1);
+ let requests = testGroups[0].buildRequests();
+ assert.equal(requests.length, 2);
+ let set0 = requests[0].commitSet();
+ let set1 = requests[1].commitSet();
+ assert.deepEqual(set0.repositories(), [webkit]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(set1.repositories(), [webkit]);
+ assert.deepEqual(set1.customRoots(), []);
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '191623');
+
+ assert.equal(testGroups[1].name(), 'test2');
+ assert.equal(testGroups[1].repetitionCount(), 2);
+ requests = testGroups[1].buildRequests();
+ assert.equal(requests.length, 4);
+ set0 = requests[0].commitSet();
+ set1 = requests[1].commitSet();
+ assert.deepEqual(requests[2].commitSet(), set0);
+ assert.deepEqual(requests[3].commitSet(), set1);
+ assert.deepEqual(set0.repositories(), [webkit]);
+ assert.deepEqual(set0.customRoots(), []);
+ assert.deepEqual(set1.repositories(), [webkit]);
+ assert.deepEqual(set1.customRoots(), []);
+ assert.equal(set0.revisionForRepository(webkit), '191622');
+ assert.equal(set1.revisionForRepository(webkit), '192736');
+ });
+ });
+
});
Modified: trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js (215635 => 215636)
--- trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js 2017-04-21 20:56:04 UTC (rev 215635)
+++ trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js 2017-04-21 21:08:36 UTC (rev 215636)
@@ -21,6 +21,7 @@
emptyTriggeragbleId() { return 1001; },
someTestId() { return 200; },
somePlatformId() { return 65; },
+ otherPlatformId() { return 101; },
macosRepositoryId() { return 9; },
webkitRepositoryId() { return 11; },
gitWebkitRepositoryId() { return 111; },
@@ -41,9 +42,11 @@
db.insert('commits', {id: 96336, repository: this.webkitRepositoryId(), revision: '192736', time: (new Date(1448225325650)).toISOString()}),
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('tests', {id: MockData.someTestId(), name: 'some test'}),
db.insert('test_metrics', {id: 300, test: 200, name: 'some metric'}),
- db.insert('test_configurations', {id: 301, metric: 300, platform: 65, type: 'current'}),
+ db.insert('test_configurations', {id: 301, metric: 300, platform: MockData.somePlatformId(), type: 'current'}),
+ db.insert('test_configurations', {id: 302, metric: 300, platform: MockData.otherPlatformId(), type: 'current'}),
db.insert('test_runs', {id: 801, config: 301, build: 901, mean_cache: 100}),
db.insert('commit_sets', {id: 401}),
db.insert('commit_set_relationships', {set: 401, commit: 87832}),