<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[204151] trunk/Websites/perf.webkit.org</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/204151">204151</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-08-04 16:24:14 -0700 (Thu, 04 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Syncing script's configuration duplicates a lot of boilerplate
https://bugs.webkit.org/show_bug.cgi?id=160574

Rubber-stamped by Chris Dumez.

This patch makes each configuration accept an array of platforms and types so that we can write:

{&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookAir&quot;},
{&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookPro&quot;},
{&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookAir&quot;},
{&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookPro&quot;},
{&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookAir&quot;},
{&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookPro&quot;},
{&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookAir&quot;},
{&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookPro&quot;},

more concisely as:

{&quot;builder&quot;: &quot;mba&quot;, &quot;types&quot;: [&quot;speedometer&quot;, &quot;jetstream&quot;],
    &quot;platforms&quot;: [&quot;Trunk El Capitan MacBookAir&quot;, &quot;Trunk Sierra MacBookAir&quot;]},
{&quot;builder&quot;: &quot;mbp&quot;, &quot;types&quot;: [&quot;speedometer&quot;, &quot;jetstream&quot;],
    &quot;platforms&quot;: [&quot;Trunk El Capitan MacBookPro&quot;, &quot;Trunk Sierra MacBookPro&quot;]},

* tools/js/buildbot-syncer.js:
(BuildbotSyncer._loadConfig):
(BuildbotSyncer._expandTypesAndPlatforms): Added. Clones a new configuration entry for each type
and platform.
(BuildbotSyncer._createTestConfiguration): Extracted from _loadConfig.
(BuildbotSyncer._validateAndMergeConfig): Added a new argument that specifies a property that
shouldn't be merged into the configuration. Also added the support for 'types' and 'platforms',
and merged the code for verify an array of strings. Finally, allow the appearance of 'properties'
since this function can now be called on a cloned configuration in which 'arguments' had already
been renamed to 'properties'.

* unit-tests/buildbot-syncer-tests.js: Added a test case to parse a consolidated configuration.
(sampleiOSConfigWithExpansions): Added.

* unit-tests/resources/mock-v3-models.js:
(MockModels.inject): Added a few more mock models for the newly added test.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgtoolsjsbuildbotsyncerjs">trunk/Websites/perf.webkit.org/tools/js/buildbot-syncer.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsbuildbotsyncertestsjs">trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsresourcesmockv3modelsjs">trunk/Websites/perf.webkit.org/unit-tests/resources/mock-v3-models.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (204150 => 204151)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2016-08-04 22:43:50 UTC (rev 204150)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2016-08-04 23:24:14 UTC (rev 204151)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2016-08-04  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Syncing script's configuration duplicates a lot of boilerplate
+        https://bugs.webkit.org/show_bug.cgi?id=160574
+
+        Rubber-stamped by Chris Dumez.
+
+        This patch makes each configuration accept an array of platforms and types so that we can write:
+
+        {&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookAir&quot;},
+        {&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookPro&quot;},
+        {&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookAir&quot;},
+        {&quot;type&quot;: &quot;speedometer&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookPro&quot;},
+        {&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookAir&quot;},
+        {&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk El Capitan MacBookPro&quot;},
+        {&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mba&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookAir&quot;},
+        {&quot;type&quot;: &quot;jetstream&quot;, &quot;builder&quot;: &quot;mbp&quot;, &quot;platform&quot;: &quot;Trunk Sierra MacBookPro&quot;},
+
+        more concisely as:
+
+        {&quot;builder&quot;: &quot;mba&quot;, &quot;types&quot;: [&quot;speedometer&quot;, &quot;jetstream&quot;],
+            &quot;platforms&quot;: [&quot;Trunk El Capitan MacBookAir&quot;, &quot;Trunk Sierra MacBookAir&quot;]},
+        {&quot;builder&quot;: &quot;mbp&quot;, &quot;types&quot;: [&quot;speedometer&quot;, &quot;jetstream&quot;],
+            &quot;platforms&quot;: [&quot;Trunk El Capitan MacBookPro&quot;, &quot;Trunk Sierra MacBookPro&quot;]},
+
+        * tools/js/buildbot-syncer.js:
+        (BuildbotSyncer._loadConfig):
+        (BuildbotSyncer._expandTypesAndPlatforms): Added. Clones a new configuration entry for each type
+        and platform.
+        (BuildbotSyncer._createTestConfiguration): Extracted from _loadConfig.
+        (BuildbotSyncer._validateAndMergeConfig): Added a new argument that specifies a property that
+        shouldn't be merged into the configuration. Also added the support for 'types' and 'platforms',
+        and merged the code for verify an array of strings. Finally, allow the appearance of 'properties'
+        since this function can now be called on a cloned configuration in which 'arguments' had already
+        been renamed to 'properties'.
+
+        * unit-tests/buildbot-syncer-tests.js: Added a test case to parse a consolidated configuration.
+        (sampleiOSConfigWithExpansions): Added.
+
+        * unit-tests/resources/mock-v3-models.js:
+        (MockModels.inject): Added a few more mock models for the newly added test.
+
</ins><span class="cx"> 2016-07-26  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION: Tooltip for analysis tasks doesn't show up on charts
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgtoolsjsbuildbotsyncerjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/tools/js/buildbot-syncer.js (204150 => 204151)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/tools/js/buildbot-syncer.js        2016-08-04 22:43:50 UTC (rev 204150)
+++ trunk/Websites/perf.webkit.org/tools/js/buildbot-syncer.js        2016-08-04 23:24:14 UTC (rev 204151)
</span><span class="lines">@@ -262,47 +262,79 @@
</span><span class="cx">         for (let entry of config['configurations']) {
</span><span class="cx">             let newConfig = {};
</span><span class="cx">             this._validateAndMergeConfig(newConfig, shared);
</span><del>-
</del><span class="cx">             this._validateAndMergeConfig(newConfig, entry);
</span><span class="cx"> 
</span><del>-            let type = entry['type'];
-            if (type) {
-                assert(types[type]);
-                this._validateAndMergeConfig(newConfig, types[type]);
-            }
</del><ins>+            let expandedConfigurations = this._expandTypesAndPlatforms(newConfig);
+            for (let config of expandedConfigurations) {
+                if ('type' in config) {
+                    let type = config['type'];
+                    assert(type, `${type} is not a valid type in the configuration`);
+                    this._validateAndMergeConfig(config, types[type]);
+                }
</ins><span class="cx"> 
</span><del>-            let builder = entry['builder'];
-            if (builders[builder])
-                this._validateAndMergeConfig(newConfig, builders[builder]);
</del><ins>+                let builder = entry['builder'];
+                if (builders[builder])
+                    this._validateAndMergeConfig(config, builders[builder]);
</ins><span class="cx"> 
</span><del>-            assert('platform' in newConfig, 'configuration must specify a platform');
-            assert('test' in newConfig, 'configuration must specify a test');
-            assert('builder' in newConfig, 'configuration must specify a builder');
-            assert('properties' in newConfig, 'configuration must specify arguments to post on a builder');
-            assert('buildRequestArgument' in newConfig, 'configuration must specify buildRequestArgument');
</del><ins>+                this._createTestConfiguration(remote, syncerByBuilder, config);
+            }
+        }
</ins><span class="cx"> 
</span><del>-            let test = Test.findByPath(newConfig.test);
-            assert(test, `${newConfig.test} is not a valid test path`);
</del><ins>+        return Array.from(syncerByBuilder.values());
+    }
</ins><span class="cx"> 
</span><del>-            let platform = Platform.findByName(newConfig.platform);
-            assert(platform, `${newConfig.platform} is not a valid platform name`);
</del><ins>+    static _expandTypesAndPlatforms(unresolvedConfig)
+    {
+        let typeExpanded = [];
+        if ('types' in unresolvedConfig) {
+            for (let type of unresolvedConfig['types'])
+                typeExpanded.push(this._validateAndMergeConfig({'type': type}, unresolvedConfig, 'types'));
+        } else
+            typeExpanded.push(unresolvedConfig);
</ins><span class="cx"> 
</span><del>-            let syncer = syncerByBuilder.get(newConfig.builder);
-            if (!syncer) {
-                syncer = new BuildbotSyncer(remote, newConfig);
-                syncerByBuilder.set(newConfig.builder, syncer);
-            }
-            syncer.addTestConfiguration(test, platform, newConfig.properties);
</del><ins>+        let configurations = [];
+        for (let config of typeExpanded) {
+            if ('platforms' in config) {
+                for (let platform of config['platforms'])
+                    configurations.push(this._validateAndMergeConfig({'platform': platform}, config, 'platforms'));
+            } else
+                configurations.push(config);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return Array.from(syncerByBuilder.values());
</del><ins>+        return configurations;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static _validateAndMergeConfig(config, valuesToMerge)
</del><ins>+    static _createTestConfiguration(remote, syncerByBuilder, newConfig)
</ins><span class="cx">     {
</span><ins>+        assert('platform' in newConfig, 'configuration must specify a platform');
+        assert('test' in newConfig, 'configuration must specify a test');
+        assert('builder' in newConfig, 'configuration must specify a builder');
+        assert('properties' in newConfig, 'configuration must specify arguments to post on a builder');
+        assert('buildRequestArgument' in newConfig, 'configuration must specify buildRequestArgument');
+
+        let test = Test.findByPath(newConfig.test);
+        assert(test, `${newConfig.test} is not a valid test path`);
+
+        let platform = Platform.findByName(newConfig.platform);
+        assert(platform, `${newConfig.platform} is not a valid platform name`);
+
+        let syncer = syncerByBuilder.get(newConfig.builder);
+        if (!syncer) {
+            syncer = new BuildbotSyncer(remote, newConfig);
+            syncerByBuilder.set(newConfig.builder, syncer);
+        }
+        syncer.addTestConfiguration(test, platform, newConfig.properties);
+    }
+
+    static _validateAndMergeConfig(config, valuesToMerge, excludedProperty)
+    {
</ins><span class="cx">         for (let name in valuesToMerge) {
</span><span class="cx">             let value = valuesToMerge[name];
</span><ins>+            if (name == excludedProperty)
+                continue;
+
</ins><span class="cx">             switch (name) {
</span><ins>+            case 'properties': // fallthrough
</ins><span class="cx">             case 'arguments':
</span><span class="cx">                 assert.equal(typeof(value), 'object', 'arguments should be a dictionary');
</span><span class="cx">                 if (!config['properties'])
</span><span class="lines">@@ -309,16 +341,14 @@
</span><span class="cx">                     config['properties'] = {};
</span><span class="cx">                 this._validateAndMergeProperties(config['properties'], value);
</span><span class="cx">                 break;
</span><del>-            case 'test':
-                assert(value instanceof Array, 'test should be an array');
-                assert(value.every(function (part) { return typeof part == 'string'; }), 'test should be an array of strings');
</del><ins>+            case 'test': // fallthrough
+            case 'slaveList': // fallthrough
+            case 'platforms':
+            case 'types':
+                assert(value instanceof Array, `${name} should be an array`);
+                assert(value.every(function (part) { return typeof part == 'string'; }), `${name} should be an array of strings`);
</ins><span class="cx">                 config[name] = value.slice();
</span><span class="cx">                 break;
</span><del>-            case 'slaveList':
-                assert(value instanceof Array, 'slaveList should be an array');
-                assert(value.every(function (part) { return typeof part == 'string'; }), 'slaveList should be an array of strings');
-                config[name] = value;
-                break;
</del><span class="cx">             case 'type': // fallthrough
</span><span class="cx">             case 'builder': // fallthrough
</span><span class="cx">             case 'platform': // fallthrough
</span><span class="lines">@@ -331,6 +361,7 @@
</span><span class="cx">                 assert(false, `Unrecognized parameter ${name}`);
</span><span class="cx">             }
</span><span class="cx">         }
</span><ins>+        return config;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static _validateAndMergeProperties(properties, configArguments)
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsbuildbotsyncertestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js (204150 => 204151)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js        2016-08-04 22:43:50 UTC (rev 204150)
+++ trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js        2016-08-04 23:24:14 UTC (rev 204151)
</span><span class="lines">@@ -58,6 +58,58 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function sampleiOSConfigWithExpansions()
+{
+    return {
+        &quot;triggerableName&quot;: &quot;build-webkit-ios&quot;,
+        &quot;shared&quot;:
+            {
+                &quot;arguments&quot;: {
+                    &quot;webkit-revision&quot;: {&quot;root&quot;: &quot;WebKit&quot;},
+                    &quot;os-version&quot;: {&quot;root&quot;: &quot;iOS&quot;}
+                },
+                &quot;buildRequestArgument&quot;: &quot;build-request-id&quot;
+            },
+        &quot;types&quot;: {
+            &quot;iphone-plt&quot;: {
+                &quot;test&quot;: [&quot;PLT-iPhone&quot;],
+                &quot;arguments&quot;: {&quot;test_name&quot;: &quot;plt&quot;}
+            },
+            &quot;ipad-plt&quot;: {
+                &quot;test&quot;: [&quot;PLT-iPad&quot;],
+                &quot;arguments&quot;: {&quot;test_name&quot;: &quot;plt&quot;}
+            },
+            &quot;speedometer&quot;: {
+                &quot;test&quot;: [&quot;Speedometer&quot;],
+                &quot;arguments&quot;: {&quot;tests&quot;: &quot;speedometer&quot;}
+            },
+        },
+        &quot;builders&quot;: {
+            &quot;iphone&quot;: {
+                &quot;builder&quot;: &quot;iPhone AB Tests&quot;,
+                &quot;arguments&quot;: {&quot;forcescheduler&quot;: &quot;force-iphone-ab-tests&quot;}
+            },
+            &quot;ipad&quot;: {
+                &quot;builder&quot;: &quot;iPad AB Tests&quot;,
+                &quot;arguments&quot;: {&quot;forcescheduler&quot;: &quot;force-ipad-ab-tests&quot;}
+            },
+        },
+        &quot;configurations&quot;: [
+            {
+                &quot;builder&quot;: &quot;iphone&quot;,
+                &quot;platforms&quot;: [&quot;iPhone&quot;, &quot;iOS 10 iPhone&quot;],
+                &quot;types&quot;: [&quot;iphone-plt&quot;, &quot;speedometer&quot;],
+            },
+            {
+                &quot;builder&quot;: &quot;ipad&quot;,
+                &quot;platforms&quot;: [&quot;iPad&quot;],
+                &quot;types&quot;: [&quot;ipad-plt&quot;, &quot;speedometer&quot;],
+            },
+        ]
+    }
+    
+}
+
</ins><span class="cx"> let sampleRootSetData = {
</span><span class="cx">     'WebKit': {
</span><span class="cx">         'id': '111127',
</span><span class="lines">@@ -482,6 +534,30 @@
</span><span class="cx">             assert.equal(configurations[1].platform, MockModels.ipad);
</span><span class="cx">             assert.equal(configurations[1].test, MockModels.jetstream);
</span><span class="cx">         });
</span><ins>+
+        it('should parse test configurations with types and platforms expansions correctly', function () {
+            let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfigWithExpansions());
+
+            assert.equal(syncers.length, 2);
+
+            let configurations = syncers[0].testConfigurations();
+            assert.equal(configurations.length, 4);
+            assert.equal(configurations[0].platform, MockModels.iphone);
+            assert.equal(configurations[0].test, MockModels.iPhonePLT);
+            assert.equal(configurations[1].platform, MockModels.iOS10iPhone);
+            assert.equal(configurations[1].test, MockModels.iPhonePLT);
+            assert.equal(configurations[2].platform, MockModels.iphone);
+            assert.equal(configurations[2].test, MockModels.speedometer);
+            assert.equal(configurations[3].platform, MockModels.iOS10iPhone);
+            assert.equal(configurations[3].test, MockModels.speedometer);
+
+            configurations = syncers[1].testConfigurations();
+            assert.equal(configurations.length, 2);
+            assert.equal(configurations[0].platform, MockModels.ipad);
+            assert.equal(configurations[0].test, MockModels.iPadPLT);
+            assert.equal(configurations[1].platform, MockModels.ipad);
+            assert.equal(configurations[1].test, MockModels.speedometer);
+        });
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     describe('_propertiesForBuildRequest', function () {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsresourcesmockv3modelsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/resources/mock-v3-models.js (204150 => 204151)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/resources/mock-v3-models.js        2016-08-04 22:43:50 UTC (rev 204150)
+++ trunk/Websites/perf.webkit.org/unit-tests/resources/mock-v3-models.js        2016-08-04 23:24:14 UTC (rev 204151)
</span><span class="lines">@@ -31,8 +31,11 @@
</span><span class="cx"> 
</span><span class="cx">             MockModels.iphone = Platform.ensureSingleton(12, {name: 'iPhone', metrics: []});
</span><span class="cx">             MockModels.ipad = Platform.ensureSingleton(13, {name: 'iPad', metrics: []});
</span><ins>+            MockModels.iOS10iPhone = Platform.ensureSingleton(14, {name: 'iOS 10 iPhone', metrics: []});
</ins><span class="cx"> 
</span><span class="cx">             MockModels.plt = Test.ensureSingleton(844, {name: 'Page Load Test'});
</span><ins>+            MockModels.iPadPLT = Test.ensureSingleton(1444, {name: 'PLT-iPad'});
+            MockModels.iPhonePLT = Test.ensureSingleton(1500, {name: 'PLT-iPhone'});
</ins><span class="cx">             MockModels.pltMean = Metric.ensureSingleton(1158, {name: 'Time', aggregator: 'Arithmetic', test: MockModels.plt});
</span><span class="cx">             MockModels.elCapitan = Platform.ensureSingleton(31, {name: 'El Capitan', metrics: [MockModels.pltMean]});
</span><span class="cx">         });
</span></span></pre>
</div>
</div>

</body>
</html>