Auto merge of #29317 - delan:structured-subtest-results, r=mrobinson

wpt: retain raw results for unexpected tests and subtests

ServoHandler currently processes the raw results for unexpected tests and subtests on the fly, discarding the test_end (test) or test_status (subtest) event data once it has generated output for the events.

This patch retains that event data in ServoHandler.test_failures and ServoHandler.subtest_failures, allowing servowpt.py to send structured data about unexpected tests and subtests to the dashboard (servo/intermittent-tracker#5), e.g.

```diff
diff --git a/tests/wpt/servowpt.py b/tests/wpt/servowpt.py
index fee6dcf2df..ac3e46e36d 100644
--- a/tests/wpt/servowpt.py
+++ b/tests/wpt/servowpt.py
@@ -27,6 +27,7 @@ import update  # noqa: F401,E402

 TRACKER_API = "https://build.servo.org/intermittent-tracker"
 TRACKER_API_ENV_VAR = "INTERMITTENT_TRACKER_API"
+TRACKER_DASHBOARD_SECRET_ENV_VAR = "INTERMITTENT_TRACKER_DASHBOARD_SECRET"
 GITHUB_API_TOKEN_ENV_VAR = "INTERMITTENT_TRACKER_GITHUB_API_TOKEN"

@@ -145,6 +146,48 @@ def run_tests(**kwargs):
     logger.add_handler(handler)

     wptrunner.run_tests(**kwargs)
+
+    if TRACKER_DASHBOARD_SECRET_ENV_VAR in os.environ:
+        body = []
+        for failure in handler.test_failures:
+            # print(f'>>> {repr(failure)}')
+            body.append({
+                'path': failure['test'],
+                'subtest': None,
+                'expected': failure['expected'],
+                'actual': failure['status'],
+                'time': failure['time'] // 1000,
+                'message': failure.get('message'),
+                'stack': failure.get('stack'),
+                'branch': os.environ.get('SERVO_BRANCH'),
+                'build_url': os.environ.get('SERVO_BUILD_URL'),
+                'pull_url': os.environ.get('SERVO_PULL_URL'),
+            })
+        for (path, failures) in handler.subtest_failures.items():
+            for failure in failures:
+                # print(f'>>> {repr(failure)}')
+                body.append({
+                    'path': path,
+                    'subtest': failure['subtest'],
+                    'expected': failure['expected'],
+                    'actual': failure['status'],
+                    'time': failure['time'] // 1000,
+                    'message': failure.get('message'),
+                    'stack': failure.get('stack'),
+                    'branch': os.environ.get('SERVO_BRANCH'),
+                    'build_url': os.environ.get('SERVO_BUILD_URL'),
+                    'pull_url': os.environ.get('SERVO_PULL_URL'),
+                })
+        request = urllib.request.Request(
+            f'{os.environ.get(TRACKER_API_ENV_VAR, TRACKER_API)}/dashboard/attempts',
+            method='POST',
+            data=json.dumps(body).encode('utf-8'),
+            headers={
+                'Authorization': f'Bearer {os.environ[TRACKER_DASHBOARD_SECRET_ENV_VAR]}',
+                'Content-Type': 'application/json',
+            })
+        urllib.request.urlopen(request)
+
     if handler.unexpected_results and filter_intermittents_output:
         all_filtered = filter_intermittents(
             handler.unexpected_results,
```

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [ ] ~~`./mach build -d` does not report any errors~~
- [ ] ~~`./mach test-tidy` does not report any errors~~
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___
This commit is contained in:
bors-servo 2023-02-01 17:35:52 +01:00 committed by GitHub
commit 69b272b4e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -34,6 +34,7 @@ class ServoHandler(mozlog.reader.LogHandler):
self.need_to_erase_last_line = False
self.running_tests: Dict[str, str] = {}
self.test_output = collections.defaultdict(str)
self.test_failures = []
self.subtest_failures = collections.defaultdict(list)
self.tests_with_failing_subtests = []
self.unexpected_results: List[UnexpectedResult] = []
@ -144,7 +145,7 @@ class ServoHandler(mozlog.reader.LogHandler):
test_status = data["status"]
test_name = data["test"]
had_unexpected_test_result = "expected" in data
subtest_failures = self.subtest_failures.pop(test_name, [])
subtest_failures = self.subtest_failures.get(test_name, [])
del self.running_tests[data['thread']]
@ -162,6 +163,7 @@ class ServoHandler(mozlog.reader.LogHandler):
output = ""
if had_unexpected_test_result:
self.test_failures.append(data)
self.unexpected_tests[test_status].append(data)
lines = self.get_lines_for_unexpected_result(
test_name,