• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from typing import Final
6
7from crossbench.benchmarks.loading.page.live import LivePage
8from crossbench.probes.v8.rcs import V8RCSProbe
9from tests import test_helper
10from tests.crossbench.probes.helper import GenericProbeTestCase
11
12EXAMPLE_RCS_DATA: Final[str] = """
13                      Runtime Function/C++ Builtin        Time             Count
14========================================================================================
15                                  FunctionCallback     94.96ms  38.47%     65908  29.19%
16                                      JS_Execution     19.37ms   7.85%       976   0.43%
17          PreParseBackgroundWithVariableResolution     14.49ms   5.87%      5175   2.29%
18                              ParseFunctionLiteral     10.25ms   4.15%      2209   0.98%
19                                   CompileIgnition      9.30ms   3.77%      2236   0.99%
20"""
21
22
23class V8RCSProbeTestCase(GenericProbeTestCase):
24
25  def test_simple_loading_case(self):
26    probe = V8RCSProbe()
27    stories = [
28        LivePage("google", "https://google.com"),
29        LivePage("amazon", "https://amazon.com")
30    ]
31    repetitions = 2
32    runner = self.create_runner(
33        stories,
34        js_side_effects=[EXAMPLE_RCS_DATA],
35        repetitions=repetitions,
36        separate=True,
37        throw=True)
38    runner.attach_probe(probe)
39    runner.run()
40    self.assertTrue(runner.is_success)
41
42    for run in runner.runs:
43      self.assertIn("--runtime-call-stats", run.browser.js_flags)
44
45    # One file per story repetition
46    result_count = len(self.browsers) * len(stories) * repetitions
47    # One merged result per story
48    result_count += len(self.browsers) * len(stories)
49    # One merged results per browser
50    result_count += len(self.browsers)
51    # Symlinked summary files:
52    rcs_result_files = list(runner.out_dir.glob(f"**/{probe.name}.txt"))
53    self.assertEqual(len(rcs_result_files), result_count)
54    # Cache-temperatures files
55    rcs_result_files = list(runner.out_dir.glob(f"**/{probe.name}/*.rcs.txt"))
56    self.assertEqual(len(rcs_result_files), result_count)
57
58    (story_data, reps_data, stories_data, _) = self.get_non_empty_results_str(
59        runner, probe, "txt", has_browsers_data=False)
60
61    self.assertEqual(story_data.count(EXAMPLE_RCS_DATA), 1)
62    self.assertEqual(reps_data.count(EXAMPLE_RCS_DATA), repetitions)
63    self.assertEqual(
64        stories_data.count(EXAMPLE_RCS_DATA),
65        len(stories) * repetitions)
66
67    self.assertEqual(story_data.count("== Page: "), 0)
68    self.assertEqual(reps_data.count("== Page: "), 1)
69    self.assertEqual(stories_data.count("== Page: "), len(stories))
70
71  def validate_cache_temperatures_files(self, probe, group, cache_temperatures):
72    rcs_result_files = list(group.path.glob(f"{probe.name}/*.rcs.txt"))
73    self.assertEqual(len(rcs_result_files), len(cache_temperatures) + 1)
74    self.assertTrue((group.path / f"{probe.name}.txt").is_file())
75    for index, cache_temperature in enumerate(cache_temperatures):
76      path = group.path / probe.name / f"{index}_{cache_temperature}.rcs.txt"
77      self.assertTrue(path.is_file(), f"{path} does not exist")
78
79  def test_simple_loading_case_cache_temperatures(self):
80    probe = V8RCSProbe()
81    stories = [
82        LivePage("google", "https://google.com"),
83        LivePage("amazon", "https://amazon.com")
84    ]
85    repetitions = 2
86    cache_temperatures = ("cold", "warm")
87    runner = self.create_runner(
88        stories,
89        js_side_effects=[EXAMPLE_RCS_DATA, EXAMPLE_RCS_DATA],
90        repetitions=repetitions,
91        cache_temperatures=cache_temperatures,
92        separate=True,
93        throw=True)
94    runner.attach_probe(probe)
95    runner.run()
96    self.assertTrue(runner.is_success)
97
98    repetition_group = runner.repetitions_groups[0]
99    self.validate_cache_temperatures_files(probe, repetition_group,
100                                           cache_temperatures)
101    story_group = runner.story_groups[0]
102    self.validate_cache_temperatures_files(probe, story_group,
103                                           cache_temperatures)
104
105    rcs_result_files = list(runner.out_dir.glob(f"**/{probe.name}.txt"))
106    # One merged file for each story and cache temp + all.rcs.txt:
107    result_count = len(self.browsers) * len(stories) * (
108        len(cache_temperatures) + 1)
109    # One merged results per browser and cache temp + all.rcs.txt
110    result_count += len(self.browsers) * (len(cache_temperatures) + 1)
111    # One merged results per browser
112    result_count += len(self.browsers)
113    # Without symlinked summary files:
114    rcs_result_files = list(runner.out_dir.glob(f"**/{probe.name}/*.rcs.txt"))
115    self.assertEqual(len(rcs_result_files), result_count)
116
117    top_level_rcs_files = list((runner.out_dir / probe.name).iterdir())
118    self.assertEqual(len(top_level_rcs_files), len(self.browsers))
119
120    with self.assertLogs() as cm:
121      probe.log_browsers_result(runner.browser_group)
122    log_output = "\n".join(cm.output)
123    for top_level_rcs_file in top_level_rcs_files:
124      self.assertIn(str(top_level_rcs_file), log_output)
125
126
127if __name__ == "__main__":
128  test_helper.run_pytest(__file__)
129