Title: [249924] trunk/Tools
Revision
249924
Author
jbed...@apple.com
Date
2019-09-16 15:40:50 -0700 (Mon, 16 Sep 2019)

Log Message

results.webkit.org: Configurations should be branch specific
https://bugs.webkit.org/show_bug.cgi?id=201561

Reviewed by Dewei Zhu.

Partition configurations by branch in both Redis and Cassandra.

* resultsdbpy/resultsdbpy/controller/upload_controller.py:
(UploadController.suites): Allow the user to specify branches while listing suites.
* resultsdbpy/resultsdbpy/model/archive_context.py:
(ArchiveContext.register): Register each configuration with a branch.
* resultsdbpy/resultsdbpy/model/configuration_context.py:
(ConfigurationContext.ByPlatform): Index by branch.
(ConfigurationContext.ByPlatformAndVersion): Ditto.
(ConfigurationContext.ByArchitecture): Ditto.
(ConfigurationContext.ByModel): Ditto.
(ConfigurationContext.__init__): Populate Redis cache with branch.
(ConfigurationContext._convert_to_redis_key): Accept branch in Redis key.
(ConfigurationContext._register_in_redis): Register configuration with branch.
(ConfigurationContext.register_configuration): Ditto.
(ConfigurationContext.search_for_configuration): Search for configuration with branch.
(ConfigurationContext.search_for_recent_configuration): Ditto.
(ConfigurationContext.select_from_table_with_configurations): Ditto.
* resultsdbpy/resultsdbpy/model/configuration_context_unittest.py:
(ConfigurationContextTest.register_configurations): Register with branch.
(ConfigurationContextTest.test_repopulate_recent): Construct ConfigurationContext with
CommitContext object.
* resultsdbpy/resultsdbpy/model/upload_context.py:
(UploadContext.SuitesByConfiguration): Index by branch.
(UploadContext.upload_test_results): Register each configuration with a branch.
(UploadContext.find_suites): Pass branch to search for configurations.
* resultsdbpy/resultsdbpy/view/static/js/drawer.js: Check for new configurations when the branch is changed.
* resultsdbpy/resultsdbpy/view/templates/suite_results.html: Add branch to suites query.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (249923 => 249924)


--- trunk/Tools/ChangeLog	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/ChangeLog	2019-09-16 22:40:50 UTC (rev 249924)
@@ -1,3 +1,39 @@
+2019-09-16  Jonathan Bedard  <jbed...@apple.com>
+
+        results.webkit.org: Configurations should be branch specific
+        https://bugs.webkit.org/show_bug.cgi?id=201561
+
+        Reviewed by Dewei Zhu.
+
+        Partition configurations by branch in both Redis and Cassandra.
+
+        * resultsdbpy/resultsdbpy/controller/upload_controller.py:
+        (UploadController.suites): Allow the user to specify branches while listing suites.
+        * resultsdbpy/resultsdbpy/model/archive_context.py:
+        (ArchiveContext.register): Register each configuration with a branch.
+        * resultsdbpy/resultsdbpy/model/configuration_context.py:
+        (ConfigurationContext.ByPlatform): Index by branch.
+        (ConfigurationContext.ByPlatformAndVersion): Ditto.
+        (ConfigurationContext.ByArchitecture): Ditto.
+        (ConfigurationContext.ByModel): Ditto.
+        (ConfigurationContext.__init__): Populate Redis cache with branch.
+        (ConfigurationContext._convert_to_redis_key): Accept branch in Redis key.
+        (ConfigurationContext._register_in_redis): Register configuration with branch.
+        (ConfigurationContext.register_configuration): Ditto.
+        (ConfigurationContext.search_for_configuration): Search for configuration with branch.
+        (ConfigurationContext.search_for_recent_configuration): Ditto.
+        (ConfigurationContext.select_from_table_with_configurations): Ditto.
+        * resultsdbpy/resultsdbpy/model/configuration_context_unittest.py:
+        (ConfigurationContextTest.register_configurations): Register with branch.
+        (ConfigurationContextTest.test_repopulate_recent): Construct ConfigurationContext with
+        CommitContext object.
+        * resultsdbpy/resultsdbpy/model/upload_context.py:
+        (UploadContext.SuitesByConfiguration): Index by branch.
+        (UploadContext.upload_test_results): Register each configuration with a branch.
+        (UploadContext.find_suites): Pass branch to search for configurations.
+        * resultsdbpy/resultsdbpy/view/static/js/drawer.js: Check for new configurations when the branch is changed.
+        * resultsdbpy/resultsdbpy/view/templates/suite_results.html: Add branch to suites query.
+
 2019-09-16  David Kilzer  <ddkil...@apple.com>
 
         check-webkit-style: Fix warning message for std::make_unique<typename[]>

Modified: trunk/Tools/resultsdbpy/resultsdbpy/controller/upload_controller.py (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/controller/upload_controller.py	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/controller/upload_controller.py	2019-09-16 22:40:50 UTC (rev 249924)
@@ -159,13 +159,16 @@
 
     @query_as_kwargs()
     @configuration_for_query()
-    def suites(self, configurations=None, recent=None, suite=None, **kwargs):
+    def suites(self, configurations=None, recent=None, suite=None, branch=None, **kwargs):
         AssertRequest.is_type(['GET'])
         AssertRequest.query_kwargs_empty(**kwargs)
 
         with self.upload_context:
-            suites_by_config = self.upload_context.find_suites(configurations=configurations,
-                                                               recent=boolean_query(*recent)[0] if recent else True)
+            suites_by_config = self.upload_context.find_suites(
+                configurations=configurations,
+                recent=boolean_query(*recent)[0] if recent else True,
+                branch=branch[0] if branch else None,
+            )
             result = []
             for config, candidate_suites in suites_by_config.items():
                 suites_for_config = [s for s in candidate_suites if not suite or s in suite]

Modified: trunk/Tools/resultsdbpy/resultsdbpy/model/archive_context.py (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/model/archive_context.py	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/model/archive_context.py	2019-09-16 22:40:50 UTC (rev 249924)
@@ -98,11 +98,11 @@
             uuid = self.commit_context.uuid_for_commits(commits)
             ttl = int((uuid // Commit.TIMESTAMP_TO_UUID_MULTIPLIER) + self.ttl_seconds - time.time()) if self.ttl_seconds else None
 
-            self.configuration_context.register_configuration(configuration, timestamp=timestamp)
+            for branch in self.commit_context.branch_keys_for_commits(commits):
+                self.configuration_context.register_configuration(configuration, branch=branch, timestamp=timestamp)
 
-            for branch in self.commit_context.branch_keys_for_commits(commits):
                 self.configuration_context.insert_row_with_configuration(
-                    UploadContext.SuitesByConfiguration.__table_name__, configuration, suite=suite, ttl=ttl,
+                    UploadContext.SuitesByConfiguration.__table_name__, configuration, suite=suite, branch=branch, ttl=ttl,
                 )
                 self.configuration_context.insert_row_with_configuration(
                     self.ArchivesByCommit.__table_name__, configuration=configuration, suite=suite,

Modified: trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context.py (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context.py	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context.py	2019-09-16 22:40:50 UTC (rev 249924)
@@ -29,6 +29,7 @@
 from collections import Iterable, OrderedDict
 from datetime import datetime
 from resultsdbpy.controller.configuration import Configuration
+from resultsdbpy.model.commit_context import CommitContext
 
 
 class ClusteredByConfiguration(Model):
@@ -64,7 +65,7 @@
             )
 
     class ByPlatform(Model, ConfigurationModel):
-        __table_name__ = 'configurations_by_platform'
+        __table_name__ = 'configs_by_platform_with_branch'
         platform = columns.Text(partition_key=True, required=True)
         style = columns.Text(primary_key=True, required=False)
         flavor = columns.Text(primary_key=True, required=False)
@@ -72,11 +73,12 @@
         model = columns.Text(primary_key=True, required=False)
         is_simulator = columns.Boolean(primary_key=True, required=True)
         version = columns.Integer(primary_key=True, required=True)
+        branch = columns.Text(primary_key=True, required=True)
         version_name = columns.Text(primary_key=True, required=False)
         last_run = columns.DateTime(required=True)
 
     class ByPlatformAndVersion(Model, ConfigurationModel):
-        __table_name__ = 'configurations_by_platform_and_version'
+        __table_name__ = 'configs_by_platform_and_version_with_branch'
         platform = columns.Text(partition_key=True, required=True)
         version = columns.Integer(partition_key=True, required=True)
         style = columns.Text(primary_key=True, required=False)
@@ -84,11 +86,12 @@
         architecture = columns.Text(primary_key=True, required=True)
         model = columns.Text(primary_key=True, required=False)
         is_simulator = columns.Boolean(primary_key=True, required=True)
+        branch = columns.Text(primary_key=True, required=True)
         version_name = columns.Text(primary_key=True, required=False)
         last_run = columns.DateTime(required=True)
 
     class ByArchitecture(Model, ConfigurationModel):
-        __table_name__ = 'configurations_by_architecture'
+        __table_name__ = 'configs_by_architecture_with_branch'
         architecture = columns.Text(partition_key=True, required=True)
         style = columns.Text(primary_key=True, required=False)
         platform = columns.Text(primary_key=True, required=True)
@@ -96,11 +99,12 @@
         model = columns.Text(primary_key=True, required=False)
         flavor = columns.Text(primary_key=True, required=False)
         is_simulator = columns.Boolean(primary_key=True, required=True)
+        branch = columns.Text(primary_key=True, required=True)
         version_name = columns.Text(primary_key=True, required=False)
         last_run = columns.DateTime(required=True)
 
     class ByModel(Model, ConfigurationModel):
-        __table_name__ = 'configurations_by_model'
+        __table_name__ = 'configs_by_model_with_branch'
         model = columns.Text(partition_key=True, required=True)
         version = columns.Integer(primary_key=True, required=True)
         style = columns.Text(primary_key=True, required=False)
@@ -108,6 +112,7 @@
         flavor = columns.Text(primary_key=True, required=False)
         architecture = columns.Text(primary_key=True, required=True)
         is_simulator = columns.Boolean(primary_key=True, required=True)
+        branch = columns.Text(primary_key=True, required=True)
         version_name = columns.Text(primary_key=True, required=False)
         last_run = columns.DateTime(required=True)
 
@@ -117,7 +122,6 @@
 
         self.redis = redis
         self.cassandra = cassandra
-        self.repositories = {}
         self.cache_timeout = cache_timeout
 
         with self:
@@ -128,7 +132,7 @@
 
             for configuration in self.cassandra.select_from_table(self.ByPlatform.__table_name__):
                 if configuration.last_run >= datetime.utcfromtimestamp(int(time.time() - cache_timeout)):
-                    self._register_in_redis(configuration.to_configuration(), configuration.last_run)
+                    self._register_in_redis(configuration.to_configuration(), configuration.branch, configuration.last_run)
 
     def __enter__(self):
         self.cassandra.__enter__()
@@ -137,16 +141,17 @@
         self.cassandra.__exit__(*args, **kwargs)
 
     @classmethod
-    def _convert_to_redis_key(cls, configuration):
-        return 'configurations:{}:{}:{}:{}:{}:{}:{}:{}'.format(
+    def _convert_to_redis_key(cls, configuration, branch):
+        return 'configs_with_branch:{}:{}:{}:{}:{}:{}:{}:{}:{}'.format(
             configuration.platform or '*', '*' if configuration.is_simulator is None else (1 if configuration.is_simulator else 0),
             '*' if configuration.version is None else Configuration.integer_to_version(configuration.version),
             configuration.version_name or '*',
             configuration.architecture or '*', configuration.model or '*',
             configuration.style or '*', configuration.flavor or '*',
+            branch,
         )
 
-    def _register_in_redis(self, configuration, timestamp):
+    def _register_in_redis(self, configuration, branch, timestamp):
         if isinstance(timestamp, datetime):
             timestamp = calendar.timegm(timestamp.timetuple())
         expiration = int(self.cache_timeout - (time.time() - int(timestamp)))
@@ -154,11 +159,11 @@
             sdk = configuration.sdk
             try:
                 configuration.sdk = None
-                self.redis.set(self._convert_to_redis_key(configuration), configuration.to_json(), ex=expiration)
+                self.redis.set(self._convert_to_redis_key(configuration, branch), configuration.to_json(), ex=expiration)
             finally:
                 configuration.sdk = sdk
 
-    def register_configuration(self, configuration, timestamp=time.time()):
+    def register_configuration(self, configuration, branch=None, timestamp=time.time()):
         if not isinstance(configuration, Configuration):
             raise TypeError(f'Expected type {Configuration}, got {type(configuration)}')
         if not configuration.is_complete():
@@ -166,6 +171,8 @@
         if not isinstance(timestamp, datetime):
             timestamp = datetime.utcfromtimestamp(int(timestamp))
 
+        branch = branch or CommitContext.DEFAULT_BRANCH_KEY
+
         with self:
             tables_to_insert_to = [self.ByPlatform.__table_name__, self.ByPlatformAndVersion.__table_name__, self.ByArchitecture.__table_name__]
             if configuration.model is not None:
@@ -172,7 +179,7 @@
                 tables_to_insert_to.append(self.ByModel.__table_name__)
             for table in tables_to_insert_to:
                 self.cassandra.insert_row(
-                    table,
+                    table, branch=branch,
                     platform=configuration.platform, is_simulator=configuration.is_simulator,
                     version=configuration.version, version_name=configuration.version_name or '',
                     architecture=configuration.architecture, model=configuration.model or '',
@@ -180,13 +187,13 @@
                     last_run=timestamp,
                 )
 
-        self._register_in_redis(configuration, timestamp)
+        self._register_in_redis(configuration, branch, timestamp)
 
-    def search_for_configuration(self, configuration):
+    def search_for_configuration(self, configuration, branch=None):
         if not isinstance(configuration, Configuration):
             raise TypeError(f'Expected type {Configuration}, got {type(configuration)}')
 
-        kwargs = {}
+        kwargs = dict(branch=branch or CommitContext.DEFAULT_BRANCH_KEY)
         for member in Configuration.REQUIRED_MEMBERS + Configuration.OPTIONAL_MEMBERS:
             if getattr(configuration, member):
                 kwargs[member] = getattr(configuration, member)
@@ -205,12 +212,12 @@
         with self:
             return [model.to_configuration() for model in self.cassandra.select_from_table(table.__table_name__, **kwargs)]
 
-    def search_for_recent_configuration(self, configuration=Configuration()):
+    def search_for_recent_configuration(self, configuration=Configuration(), branch=None):
         if not isinstance(configuration, Configuration):
             raise TypeError(f'Expected type {Configuration}, got {type(configuration)}')
 
         configurations = []
-        for key in self.redis.scan_iter(self._convert_to_redis_key(configuration)):
+        for key in self.redis.scan_iter(self._convert_to_redis_key(configuration, branch or CommitContext.DEFAULT_BRANCH_KEY)):
             candidate = Configuration.from_json(self.redis.get(key.decode('utf-8')).decode('utf-8'))
             if candidate == configuration:
                 configurations.append(candidate)
@@ -236,7 +243,7 @@
                 attributes=json.dumps(attributes_dict),
                 **kwargs)
 
-    def select_from_table_with_configurations(self, table_name, configurations=None, recent=True, limit=100, **kwargs):
+    def select_from_table_with_configurations(self, table_name, configurations=None, branch=None, recent=True, limit=100, **kwargs):
         if not isinstance(configurations, Iterable):
             raise TypeError('Expected configurations to be iterable')
         if not configurations:
@@ -250,9 +257,9 @@
                 if config.is_complete():
                     complete_configurations.add(config)
                 elif recent:
-                    [complete_configurations.add(element) for element in self.search_for_recent_configuration(config)]
+                    [complete_configurations.add(element) for element in self.search_for_recent_configuration(config, branch=branch)]
                 else:
-                    [complete_configurations.add(element) for element in self.search_for_configuration(config)]
+                    [complete_configurations.add(element) for element in self.search_for_configuration(config, branch=branch)]
 
             results = {}
             for configuration in complete_configurations:
@@ -268,6 +275,7 @@
                     architecture=configuration.architecture,
                     attributes=json.dumps(attributes_dict),
                     limit=limit,
+                    branch=branch or CommitContext.DEFAULT_BRANCH_KEY,
                     **kwargs)
                 if len(rows) == 0:
                     continue

Modified: trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context_unittest.py (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context_unittest.py	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/model/configuration_context_unittest.py	2019-09-16 22:40:50 UTC (rev 249924)
@@ -27,6 +27,7 @@
 from fakeredis import FakeStrictRedis
 from redis import StrictRedis
 from resultsdbpy.model.cassandra_context import CassandraContext
+from resultsdbpy.model.commit_context import CommitContext
 from resultsdbpy.model.configuration_context import ConfigurationContext, ClusteredByConfiguration
 from resultsdbpy.model.mock_cassandra_context import MockCassandraContext
 from resultsdbpy.model.wait_for_docker_test_case import WaitForDockerTestCase
@@ -75,9 +76,9 @@
         for configuration in self.CONFIGURATIONS:
             if (configuration.platform == 'Mac' and configuration.version <= Configuration.version_to_integer('10.13')) \
                or (configuration.platform == 'iOS' and configuration.version <= Configuration.version_to_integer('11')):
-                self.database.register_configuration(configuration, old)
+                self.database.register_configuration(configuration, branch=None, timestamp=old)
             else:
-                self.database.register_configuration(configuration, current)
+                self.database.register_configuration(configuration, branch=None, timestamp=current)
 
     @WaitForDockerTestCase.mock_if_no_docker(mock_redis=FakeStrictRedis, mock_cassandra=MockCassandraContext)
     def test_invalid_configuration(self, redis=StrictRedis, cassandra=CassandraContext):

Modified: trunk/Tools/resultsdbpy/resultsdbpy/model/upload_context.py (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/model/upload_context.py	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/model/upload_context.py	2019-09-16 22:40:50 UTC (rev 249924)
@@ -43,8 +43,9 @@
     MAX_TASKS_IN_SCAN = 10
 
     class SuitesByConfiguration(ClusteredByConfiguration):
-        __table_name__ = 'suites_by_configuration'
+        __table_name__ = 'suites_by_configuration_and_branch'
         suite = columns.Text(primary_key=True, required=True)
+        branch = columns.Text(primary_key=True, required=True)
 
     class UploadsByConfiguration(ClusteredByConfiguration):
         __table_name__ = 'uploads_by_configuration_01'
@@ -227,11 +228,11 @@
         branches = self.commit_context.branch_keys_for_commits(commits)
 
         with self:
-            self.configuration_context.register_configuration(configuration, timestamp=timestamp)
+            for branch in branches:
+                self.configuration_context.register_configuration(configuration, branch=branch, timestamp=timestamp)
 
-            for branch in branches:
                 self.configuration_context.insert_row_with_configuration(
-                    self.SuitesByConfiguration.__table_name__, configuration, suite=suite,
+                    self.SuitesByConfiguration.__table_name__, configuration, suite=suite, branch=branch,
                     ttl=int((uuid // Commit.TIMESTAMP_TO_UUID_MULTIPLIER) + self.ttl_seconds - time.time()) if self.ttl_seconds else None,
                 )
                 self.configuration_context.insert_row_with_configuration(
@@ -258,11 +259,11 @@
                 ).items()})
             return result
 
-    def find_suites(self, configurations, recent=True, limit=100):
+    def find_suites(self, configurations, branch=None, recent=True, limit=100):
         with self:
             return {
                 config: [row.suite for row in rows] for config, rows in self.configuration_context.select_from_table_with_configurations(
-                    self.SuitesByConfiguration.__table_name__, configurations=configurations, recent=recent, limit=limit,
+                    self.SuitesByConfiguration.__table_name__, configurations=configurations, branch=branch, recent=recent, limit=limit,
                 ).items()
             }
 

Modified: trunk/Tools/resultsdbpy/resultsdbpy/view/static/js/drawer.js (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/view/static/js/drawer.js	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/view/static/js/drawer.js	2019-09-16 22:40:50 UTC (rev 249924)
@@ -22,7 +22,7 @@
 // THE POSSIBILITY OF SUCH DAMAGE.
 
 import {DOM, REF} from '/library/js/Ref.js';
-import {QueryModifier} from '/assets/js/common.js';
+import {queryToParams, paramsToQuery, QueryModifier, } from '/assets/js/common.js';
 import {Configuration} from '/assets/js/configuration.js'
 
 function setEnableRecursive(element, state) {
@@ -116,6 +116,26 @@
         </div>`;
 }
 
+let configurations = []
+let configurationsDefinedCallbacks = [];
+function refreshConfigurations() {
+    let params = queryToParams(document.URL.split('?')[1]);
+    let queryParams = {};
+    if (params.branch)
+        queryParams.branch = params.branch;
+
+    const query = paramsToQuery(queryParams);
+    fetch(query ? 'api/suites?' + query: 'api/suites').then(response => {
+        response.json().then(json => {
+            configurations = json.map(pair => new Configuration(pair[0]));
+            configurationsDefinedCallbacks.forEach(callback => callback());
+        });
+    }).catch(error => {
+        // If the load fails, log the error and continue
+        console.error(JSON.stringify(error, null, 4));
+    });
+}
+
 function BranchSelector(callback) {
     const defaultBranches = new Set(['trunk', 'master']);
     const defaultBranchKey = [...defaultBranches].sort().join('/');
@@ -130,6 +150,7 @@
                     branchModifier.remove();
                 else
                     branchModifier.replace(branch);
+                refreshConfigurations();
                 callback();
             }
         },
@@ -209,21 +230,7 @@
 }
 
 function ConfigurationSelectors(callback) {
-    let configurations = []
-    let configurationsDefinedCallbacks = [];
-    fetch('api/suites').then(response => {
-        response.json().then(json => {
-            json.forEach(pair => {
-                const config = new Configuration(pair[0]);
-                configurations.push(config);
-            });
-            configurationsDefinedCallbacks.forEach(callback => {callback();});
-        });
-    }).catch(error => {
-        // If the load fails, log the error and continue
-        console.error(JSON.stringify(error, null, 4));
-    });
-
+    refreshConfigurations();
     const elements = [
         {'query': 'platform', 'name': 'Platform'},
         {'query': 'version_name', 'name': 'Version Name'},

Modified: trunk/Tools/resultsdbpy/resultsdbpy/view/templates/suite_results.html (249923 => 249924)


--- trunk/Tools/resultsdbpy/resultsdbpy/view/templates/suite_results.html	2019-09-16 21:52:05 UTC (rev 249923)
+++ trunk/Tools/resultsdbpy/resultsdbpy/view/templates/suite_results.html	2019-09-16 22:40:50 UTC (rev 249924)
@@ -120,6 +120,8 @@
             if (params[member])
                 suiteParams[member] = params[member];
         });
+        if (params.branch)
+            suiteParams.branch = params.branch;
         let query = paramsToQuery(suiteParams);
         fetch(query ? 'api/suites?' + query: 'api/suites').then(response => {
             response.json().then(json => {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to