Bug 1552855 - [mozlog] Add new optional field to test actions for expected intermittents. r=jgraham
authorNikki S <nikkisharpley@gmail.com>
Tue, 21 May 2019 14:17:29 +0000
changeset 474755 1dad417c28ad49a3fb16130ef3b9272dc424e2c9
parent 474754 acd39065fd9fa5f7fe7a4530d5a991f64dcbc9a0
child 474756 f454d7e7502cdade0993677166911085b231963d
push id36046
push useraiakab@mozilla.com
push dateTue, 21 May 2019 21:45:52 +0000
treeherdermozilla-central@257f2c96cef5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgraham
bugs1552855
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1552855 - [mozlog] Add new optional field to test actions for expected intermittents. r=jgraham Added a new optional field on the test_end and test_status actions called expected_intermittents which accepts a List of expected intermittent statuses. The default is None. As it is an optional field, upon landing of D25081, it will only show if there is an expected intermittent. A test was added to check that expected_intermittents are logged. Differential Revision: https://phabricator.services.mozilla.com/D31809
testing/mozbase/mozlog/mozlog/structuredlog.py
testing/mozbase/mozlog/tests/test_structured.py
--- a/testing/mozbase/mozlog/mozlog/structuredlog.py
+++ b/testing/mozbase/mozlog/mozlog/structuredlog.py
@@ -349,17 +349,19 @@ class StructuredLogger(object):
         self._log_data("test_start", data)
 
     @log_action(TestId("test"),
                 Unicode("subtest"),
                 SubStatus("status"),
                 SubStatus("expected", default="PASS"),
                 Unicode("message", default=None, optional=True),
                 Unicode("stack", default=None, optional=True),
-                Dict(Any, "extra", default=None, optional=True))
+                Dict(Any, "extra", default=None, optional=True),
+                List(SubStatus, "expected_intermittent", default=None,
+                     optional=True))
     def test_status(self, data):
         """
         Log a test_status message indicating a subtest result. Tests that
         do not have subtests are not expected to produce test_status messages.
 
         :param test: Identifier of the test that produced the result.
         :param subtest: Name of the subtest.
         :param status: Status string indicating the subtest result
@@ -380,17 +382,19 @@ class StructuredLogger(object):
 
         self._log_data("test_status", data)
 
     @log_action(TestId("test"),
                 Status("status"),
                 Status("expected", default="OK"),
                 Unicode("message", default=None, optional=True),
                 Unicode("stack", default=None, optional=True),
-                Dict(Any, "extra", default=None, optional=True))
+                Dict(Any, "extra", default=None, optional=True),
+                List(Status, "expected_intermittent", default=None,
+                     optional=True))
     def test_end(self, data):
         """
         Log a test_end message indicating that a test completed. For tests
         with subtests this indicates whether the overall test completed without
         errors. For tests without subtests this indicates the test result
         directly.
 
         :param test: Identifier of the test that produced the result.
--- a/testing/mozbase/mozlog/tests/test_structured.py
+++ b/testing/mozbase/mozlog/tests/test_structured.py
@@ -234,16 +234,29 @@ class TestStructuredLog(BaseStructuredTe
                                 "subtest": "subtest name",
                                 "status": "FAIL",
                                 "expected": "PASS",
                                 "test": "test1",
                                 "stack": "many\nlines\nof\nstack"})
         self.logger.test_end("test1", "OK")
         self.logger.suite_end()
 
+    def test_status_expected_intermittent(self):
+        self.logger.suite_start([])
+        self.logger.test_start("test1")
+        self.logger.test_status("test1", "subtest name", "fail", expected_intermittent=["FAIL"])
+        self.assert_log_equals({"action": "test_status",
+                                "subtest": "subtest name",
+                                "status": "FAIL",
+                                "expected": "PASS",
+                                "expected_intermittent": ["FAIL"],
+                                "test": "test1"})
+        self.logger.test_end("test1", "OK")
+        self.logger.suite_end()
+
     def test_status_not_started(self):
         self.logger.test_status("test_UNKNOWN", "subtest", "PASS")
         self.assertTrue(self.pop_last_item()["message"].startswith(
             "test_status for test_UNKNOWN logged while not in progress. Logged with data: {"))
 
     def test_end(self):
         self.logger.suite_start([])
         self.logger.test_start("test1")
@@ -556,17 +569,17 @@ class TestTypeConversions(BaseStructured
         self.logger.process_output(123, "data", "test")
         self.assert_log_equals({"action": "process_output",
                                 "process": "123",
                                 "command": "test",
                                 "data": "data"})
         self.assertRaises(TypeError, self.logger.test_status, subtest="subtest2",
                           status="FAIL", expected="PASS")
         self.assertRaises(TypeError, self.logger.test_status, "test1", "subtest1",
-                          "PASS", "FAIL", "message", "stack", {}, "unexpected")
+                          "PASS", "FAIL", "message", "stack", {}, [], "unexpected")
         self.assertRaises(TypeError, self.logger.test_status,
                           "test1", test="test2")
         self.logger.suite_end()
 
 
 class TestComponentFilter(BaseStructuredTest):
 
     def test_filter_component(self):