Repository: google/clusterfuzz

Issue:
Update OS labels based on the variant task results
would be quite useful, issue https://bugs.chromium.org/p/chromium/issues/detail?id=1019779 is a good example

not sure if this is a duplicate of #1177, looks different to me, but feel free to merge two together


Discussion:

Resolving patch:
diff --git a/src/appengine/handlers/cron/cleanup.py b/src/appengine/handlers/cron/cleanup.py
--- a/src/appengine/handlers/cron/cleanup.py
+++ b/src/appengine/handlers/cron/cleanup.py
@@ -252,9 +252,21 @@ def _get_crash_occurrence_platforms_from_crash_parameters(
   platforms = set()
   for row in rows:
     for group in row['groups']:
-      platform = group['name'].split(':')[0].capitalize()
-      platforms.add(platform)
-  return list(platforms)
+      platform = group['name'].split(':')[0]
+      platforms.add(platform.lower())
+  return platforms
+
+
+def get_platforms_from_testcase_variants(testcase):
+  """Get platforms from crash stats based on crash parameters."""
+  variant_query = data_types.TestcaseVariant.query(
+      data_types.TestcaseVariant.testcase_id == testcase.key.id())
+  platforms = {
+      variant.platform
+      for variant in variant_query
+      if variant.is_similar and variant.platform
+  }
+  return platforms
 
 
 def get_crash_occurrence_platforms(testcase, lookbehind_days=1):
@@ -876,12 +888,13 @@ def update_os_labels(policy, testcase, issue):
     return
 
   platforms = get_crash_occurrence_platforms(testcase)
+  platforms = platforms.union(get_platforms_from_testcase_variants(testcase))
   logs.log(
       'Found %d platforms for the testcase %d.' % (len(platforms),
                                                    testcase.key.id()),
       platforms=platforms)
   for platform in platforms:
-    label = os_label.replace('%PLATFORM%', platform)
+    label = os_label.replace('%PLATFORM%', platform.capitalize())
     if not issue_tracker_utils.was_label_added(issue, label):
       issue.labels.add(label)
 
diff --git a/src/python/bot/tasks/variant_task.py b/src/python/bot/tasks/variant_task.py
--- a/src/python/bot/tasks/variant_task.py
+++ b/src/python/bot/tasks/variant_task.py
@@ -152,6 +152,7 @@ def execute_task(testcase_id, job_type):
     variant.crash_state = crash_state
     variant.security_flag = security_flag
     variant.is_similar = is_similar
+    variant.platform = environment.platform().lower()
     # Explicitly skipping crash stacktrace for now as it make entities larger
     # and we plan to use only crash paramaters in UI.
     variant.put()
diff --git a/src/python/datastore/data_types.py b/src/python/datastore/data_types.py
--- a/src/python/datastore/data_types.py
+++ b/src/python/datastore/data_types.py
@@ -1461,3 +1461,6 @@ class TestcaseVariant(Model):
   # Similar testcase reproducer key (optional). This is set in case we notice a
   # similar crash on another platform.
   reproducer_key = ndb.StringProperty()
+
+  # Platform (e.g. windows, linux, android).
+  platform = ndb.StringProperty()


Test patch:
diff --git a/src/python/tests/appengine/handlers/cron/cleanup_test.py b/src/python/tests/appengine/handlers/cron/cleanup_test.py
--- a/src/python/tests/appengine/handlers/cron/cleanup_test.py
+++ b/src/python/tests/appengine/handlers/cron/cleanup_test.py
@@ -887,6 +887,13 @@ def test_labels_added(self):
         project_name='project')
     testcase.put()
 
+    testcase_variant = data_types.TestcaseVariant(
+        testcase_id=testcase.key.id(),
+        job_type='mac_job',
+        is_similar=True,
+        platform='mac')
+    testcase_variant.put()
+
     history = data_types.BuildCrashStatsJobHistory(end_time_in_hours=10000)
     history.put()
 
@@ -895,8 +902,6 @@ def test_labels_added(self):
             'name': 'windows'
         }, {
             'name': 'linux'
-        }, {
-            'name': 'mac'
         }, {
             'name': 'android:test'
         }, {