• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from telemetry.testing import test_page_test_results
8from telemetry.timeline import slice as slice_module
9from telemetry.timeline import model as model_module
10from telemetry.web_perf import timeline_interaction_record as tir_module
11
12from telemetry.web_perf.metrics import v8_execution
13
14RENDERER_PROCESS = 'Renderer'
15OTHER_PROCESS = 'Other'
16INTERACTION_RECORDS = [tir_module.TimelineInteractionRecord("test-record",
17                                                            0,
18                                                            float('inf'))]
19
20STATS = ('v8_execution_time_total', 'v8_execution_time_self',
21         'v8_parse_lazy_total', 'v8_compile_fullcode_total',
22         'v8_recompile_total', 'v8_recompile_synchronous_total',
23         'v8_recompile_concurrent_total', 'v8_optimize_code_total',
24         'v8_deoptimize_code_total',)
25
26
27class SliceContext(object):
28  """
29  Context object for easily adding subslices/subevents.
30  """
31  def __init__(self, test, record):
32    self.test = test
33    self.record = record
34
35  def __enter__(self):
36    self.test.parent_slice = self.record
37
38  def __exit__(self, exc_type, exc_value, exc_traceback):
39    self.test.parent_slice = self.record.parent_slice
40
41
42class V8ExecutionTests(unittest.TestCase):
43
44  def setUp(self):
45    self.model = model_module.TimelineModel()
46    self.renderer_process = self.model.GetOrCreateProcess(1)
47    self.renderer_process.name = RENDERER_PROCESS
48    self.renderer_thread = self.renderer_process.GetOrCreateThread(tid=11)
49    self.other_process = self.model.GetOrCreateProcess(2)
50    self.other_process.name = OTHER_PROCESS
51    self.other_thread = self.other_process.GetOrCreateThread(tid=12)
52    self.metric = v8_execution.V8ExecutionMetric()
53    self.results = None
54    self.parent_slice = None
55
56  def GetThreadForProcessName(self, process_name):
57    if process_name is RENDERER_PROCESS:
58      return self.renderer_thread
59    elif process_name is OTHER_PROCESS:
60      return self.other_thread
61    else:
62      raise
63
64  def AddResults(self):
65    self.results = test_page_test_results.TestPageTestResults(self)
66    self.metric.AddResults(self.model, self.renderer_thread,
67                           INTERACTION_RECORDS, self.results)
68
69  def AddEvent(self, process_name, event_category, event_name,
70               start, duration, thread_start=None, thread_duration=None):
71    thread = self.GetThreadForProcessName(process_name)
72    record = slice_module.Slice(thread, event_category, event_name,
73                start, duration,
74                start if thread_start is None else thread_start,
75                duration if thread_duration is None else thread_duration)
76    thread.PushSlice(record)
77    if self.parent_slice is not None:
78      record.parent_slice = self.parent_slice
79      self.parent_slice.AddSubSlice(record)
80    return SliceContext(self, record)
81
82  def AssertResultValues(self, name, value, count, average):
83    self.results.AssertHasPageSpecificScalarValue('%s' % name, 'ms', value)
84    self.results.AssertHasPageSpecificScalarValue('%s_count' % name, 'count',
85                                                  count)
86    self.results.AssertHasPageSpecificScalarValue('%s_average' % name, 'ms',
87                                                  average)
88
89  def testWithNoTraceEvents(self):
90    self.AddResults()
91    for name in STATS:
92      self.AssertResultValues(name, value=0, count=0, average=0)
93
94  def testExecutionTime(self):
95    self.AddEvent(RENDERER_PROCESS, '', 'V8.Execute', 0, 10)
96    with self.AddEvent(RENDERER_PROCESS, '', 'V8.Execute', 10, 20):
97      self.AddEvent(RENDERER_PROCESS, '', 'other', 10, 12)
98    self.AddResults()
99    self.AssertResultValues('v8_execution_time_total', value=30, count=2,
100                            average=15)
101    self.AssertResultValues('v8_execution_time_self', value=18, count=2,
102                            average=9)
103
104  def testOptimizeParseLazy(self):
105    self.AddEvent(RENDERER_PROCESS, '', 'V8.ParseLazy', 0, 10)
106    self.AddResults()
107    self.AssertResultValues('v8_parse_lazy_total', value=10, count=1,
108                            average=10)
109    self.AssertResultValues('v8_optimize_code_total', value=0, count=0,
110                            average=0)
111    self.AssertResultValues('v8_optimize_parse_lazy_total', value=0, count=0,
112                            average=0)
113
114    with self.AddEvent(RENDERER_PROCESS, '', 'V8.OptimizeCode', 10, 20):
115      self.AddEvent(RENDERER_PROCESS, '', 'V8.ParseLazy', 20, 8)
116    self.AddResults()
117    self.AssertResultValues('v8_parse_lazy_total', value=18, count=2, average=9)
118    self.AssertResultValues('v8_optimize_code_total', value=20, count=1,
119                            average=20)
120    self.AssertResultValues('v8_optimize_parse_lazy_total', value=8, count=1,
121                            average=8)
122
123  def testRecompile(self):
124    self.AddEvent(RENDERER_PROCESS, '', 'V8.RecompileSynchronous', 0, 10)
125    self.AddResults()
126    self.AssertResultValues('v8_recompile_synchronous_total', value=10, count=1,
127                            average=10)
128    self.AssertResultValues('v8_recompile_concurrent_total', value=0, count=0,
129                            average=0)
130    self.AssertResultValues('v8_recompile_total', value=10, count=1, average=10)
131
132    self.AddEvent(RENDERER_PROCESS, '', 'V8.RecompileConcurrent', 10, 8)
133    self.AddResults()
134    self.AssertResultValues('v8_recompile_synchronous_total', value=10, count=1,
135                            average=10)
136    self.AssertResultValues('v8_recompile_concurrent_total', value=8, count=1,
137                            average=8)
138    self.AssertResultValues('v8_recompile_total', value=18, count=2, average=9)
139