1import json
2import time
3from io import StringIO
4
5from mozlog import handlers, structuredlog
6
7from ..formatters.wptscreenshot import WptscreenshotFormatter
8from ..formatters.wptreport import WptreportFormatter
9
10
11def test_wptreport_runtime(capfd):
12    # setup the logger
13    output = StringIO()
14    logger = structuredlog.StructuredLogger("test_a")
15    logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
16
17    # output a bunch of stuff
18    logger.suite_start(["test-id-1"], run_info={})
19    logger.test_start("test-id-1")
20    time.sleep(0.125)
21    logger.test_end("test-id-1", "PASS")
22    logger.suite_end()
23
24    # check nothing got output to stdout/stderr
25    # (note that mozlog outputs exceptions during handling to stderr!)
26    captured = capfd.readouterr()
27    assert captured.out == ""
28    assert captured.err == ""
29
30    # check the actual output of the formatter
31    output.seek(0)
32    output_obj = json.load(output)
33    # be relatively lax in case of low resolution timers
34    # 62 is 0.125s = 125ms / 2 = 62ms (assuming int maths)
35    # this provides a margin of 62ms, sufficient for even DOS (55ms timer)
36    assert output_obj["results"][0]["duration"] >= 62
37
38
39def test_wptreport_run_info_optional(capfd):
40    """per the mozlog docs, run_info is optional; check we work without it"""
41    # setup the logger
42    output = StringIO()
43    logger = structuredlog.StructuredLogger("test_a")
44    logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
45
46    # output a bunch of stuff
47    logger.suite_start(["test-id-1"])  # no run_info arg!
48    logger.test_start("test-id-1")
49    logger.test_end("test-id-1", "PASS")
50    logger.suite_end()
51
52    # check nothing got output to stdout/stderr
53    # (note that mozlog outputs exceptions during handling to stderr!)
54    captured = capfd.readouterr()
55    assert captured.out == ""
56    assert captured.err == ""
57
58    # check the actual output of the formatter
59    output.seek(0)
60    output_obj = json.load(output)
61    assert "run_info" not in output_obj or output_obj["run_info"] == {}
62
63
64def test_wptreport_lone_surrogate(capfd):
65    output = StringIO()
66    logger = structuredlog.StructuredLogger("test_a")
67    logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
68
69    # output a bunch of stuff
70    logger.suite_start(["test-id-1"])  # no run_info arg!
71    logger.test_start("test-id-1")
72    logger.test_status("test-id-1",
73                       subtest=u"Name with surrogate\uD800",
74                       status="FAIL",
75                       message=u"\U0001F601 \uDE0A\uD83D")
76    logger.test_end("test-id-1",
77                    status="PASS",
78                    message=u"\uDE0A\uD83D \U0001F601")
79    logger.suite_end()
80
81    # check nothing got output to stdout/stderr
82    # (note that mozlog outputs exceptions during handling to stderr!)
83    captured = capfd.readouterr()
84    assert captured.out == ""
85    assert captured.err == ""
86
87    # check the actual output of the formatter
88    output.seek(0)
89    output_obj = json.load(output)
90    test = output_obj["results"][0]
91    assert test["message"] == u"U+de0aU+d83d \U0001F601"
92    subtest = test["subtests"][0]
93    assert subtest["name"] == u"Name with surrogateU+d800"
94    assert subtest["message"] == u"\U0001F601 U+de0aU+d83d"
95
96
97def test_wptreport_known_intermittent(capfd):
98    output = StringIO()
99    logger = structuredlog.StructuredLogger("test_a")
100    logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
101
102    # output a bunch of stuff
103    logger.suite_start(["test-id-1"])  # no run_info arg!
104    logger.test_start("test-id-1")
105    logger.test_status("test-id-1",
106                       "a-subtest",
107                       status="FAIL",
108                       expected="PASS",
109                       known_intermittent=["FAIL"])
110    logger.test_end("test-id-1",
111                    status="OK",)
112    logger.suite_end()
113
114    # check nothing got output to stdout/stderr
115    # (note that mozlog outputs exceptions during handling to stderr!)
116    captured = capfd.readouterr()
117    assert captured.out == ""
118    assert captured.err == ""
119
120    # check the actual output of the formatter
121    output.seek(0)
122    output_obj = json.load(output)
123    test = output_obj["results"][0]
124    assert test["status"] == u"OK"
125    subtest = test["subtests"][0]
126    assert subtest["expected"] == u"PASS"
127    assert subtest["known_intermittent"] == [u'FAIL']
128
129
130def test_wptscreenshot_test_end(capfd):
131    formatter = WptscreenshotFormatter()
132
133    # Empty
134    data = {}
135    assert formatter.test_end(data) is None
136
137    # No items
138    data['extra'] = {"reftest_screenshots": []}
139    assert formatter.test_end(data) is None
140
141    # Invalid item
142    data['extra']['reftest_screenshots'] = ["no dict item"]
143    assert formatter.test_end(data) is None
144
145    # Random hash
146    data['extra']['reftest_screenshots'] = [{"hash": "HASH", "screenshot": "DATA"}]
147    assert 'data:image/png;base64,DATA\n' == formatter.test_end(data)
148
149    # Already cached hash
150    assert formatter.test_end(data) is None
151