graphics_WebGLAquarium.py revision e96b8f8d31f21f30028d7d544c82d3817295c8f5
1ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# Use of this source code is governed by a BSD-style license that can be
3ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang# found in the LICENSE file.
4ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
5ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang"""This is a client side WebGL aquarium test."""
6ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
7ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport logging
8ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport os
9ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport threading
10ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport time
11ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
12ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangimport sampler
13ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangfrom autotest_lib.client.bin import test, utils
14ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangfrom autotest_lib.client.common_lib.cros import chrome
1567eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedelfrom autotest_lib.client.cros.graphics import graphics_utils
16e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasanafrom autotest_lib.client.cros import power_status, power_utils
17e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasanafrom autotest_lib.client.cros import service_stopper
18e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
19e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
20e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Minimum battery charge percentage to run the test
21e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaBATTERY_INITIAL_CHARGED_MIN = 10
22e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
23e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Measurement duration in seconds.
24e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaMEASUREMENT_DURATION = 30
25e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
26e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaPOWER_DESCRIPTION = 'avg_energy_rate_1000_fishes'
27e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
28e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana# Time to exclude from calculation after playing a webgl demo [seconds].
29e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit MakasanaSTABILIZATION_DURATION = 10
30ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
31ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
32ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liangclass graphics_WebGLAquarium(test.test):
33ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    """WebGL aquarium graphics test."""
34ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    version = 1
3567eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel    GSC = None
36ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
37ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def setup(self):
38ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tarball_path = os.path.join(self.bindir,
39ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                    'webgl_aquarium_static.tar.bz2')
40ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        utils.extract_tarball_to_dir(tarball_path, self.srcdir)
41ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
42ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def initialize(self):
43e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._test_power = False
44e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._backlight = None
45e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._service_stopper = None
4667eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel        self.GSC = graphics_utils.GraphicsStateChecker()
47ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.test_settings = {
48ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                50: ('setSetting2', 2),
49ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                1000: ('setSetting6', 6),
50ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        }
51ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.perf_keyval = {}
52ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.flip_stats = {}
53ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.active_tab = None
54ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.sampler_lock = threading.Lock()
55ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if utils.get_board().lower() in ['daisy', 'daisy_spring']:
56ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # Enable ExynosSampler on Exynos platforms.  The sampler looks for
57ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # exynos-drm page flip states: 'wait_kds', 'rendered', 'prepared',
58ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # and 'flipped' in kernel debugfs.
59ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
60ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # Sample 3-second durtaion for every 5 seconds.
61ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler = sampler.ExynosSampler(period=5, duration=3)
62ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.sampler_callback = self.exynos_sampler_callback
63ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.output_flip_stats = (
64ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    self.exynos_output_flip_stats)
65ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        else:
66ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            # TODO: Create samplers for other platforms (e.g. x86).
67ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler = None
68ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
6967eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel    def cleanup(self):
70e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        if self._backlight:
71e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            self._backlight.restore()
7267eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel        if self.GSC:
7367eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel            keyvals = self.GSC.get_memory_keyvals()
74e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            if not self._test_power:
75e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                for key, val in keyvals.iteritems():
76e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    self.output_perf_value(description=key, value=val,
77e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                                           units='bytes',
78e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                                           higher_is_better=False)
7967eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel            self.GSC.finalize()
8067eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel            self.write_perf_keyval(keyvals)
8167eac4d97a9e69f3fbe52c78b4d7f7fa35cfe562Ilja H. Friedel
82e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana    def run_fish_test(self, browser, test_url, num_fishes, perf_log=True):
83ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Run the test with the given number of fishes.
84ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
85ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param browser: The Browser object to run the test with.
86ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_url: The URL to the aquarium test site.
87ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param num_fishes: The number of fishes to run the test with.
88e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param perf_log: Report perf data only if it's set to True.
89ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
90ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # Create tab and load page. Set the number of fishes when page is fully
91ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # loaded.
92ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab = browser.tabs.New()
93ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab.Navigate(test_url)
94ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        tab.Activate()
95ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.active_tab = tab
96ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
97ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # Set the number of fishes when document finishes loading.  Also reset
98ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # our own FPS counter and start recording FPS and rendering time.
99ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        utils.wait_for_value(lambda: tab.EvaluateJavaScript(
100ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                'if (document.readyState === "complete") {'
101ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '  setSetting(document.getElementById("%s"), %d);'
102ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '  g_crosFpsCounter.reset();'
103ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '  true;'
104ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '} else {'
105ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '  false;'
106ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                '}' % self.test_settings[num_fishes]),
107ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                expected_value=True, timeout_sec=30)
108ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
109ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if self.kernel_sampler:
110ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.start_sampling_thread()
111ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        time.sleep(self.test_duration_secs)
112ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if self.kernel_sampler:
113ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.stop_sampling_thread()
114ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.kernel_sampler.output_flip_stats(
115ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    'flip_stats_%d' % num_fishes)
116ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.flip_stats = {}
117ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
118e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        if perf_log:
119e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            # Get average FPS and rendering time, then close the tab.
120e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            avg_fps = tab.EvaluateJavaScript('g_crosFpsCounter.getAvgFps();')
121e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            avg_render_time = tab.EvaluateJavaScript(
122e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    'g_crosFpsCounter.getAvgRenderTime();')
123e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            self.perf_keyval['avg_fps_%04d_fishes' % num_fishes] = avg_fps
124e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            self.perf_keyval['avg_render_time_%04d_fishes' % num_fishes] = (
125e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    avg_render_time)
126e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            self.output_perf_value(description='avg_fps_%04d_fishes' %
127e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                                   num_fishes, value=avg_fps, units='fps',
128e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                                   higher_is_better=True)
129e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            logging.info('%d fish(es): Average FPS = %f, '
130e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                         'average render time = %f',
131e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                         num_fishes, avg_fps, avg_render_time)
132e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
133e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana    def run_power_test(self, browser, test_url):
134e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        """
135e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        Runs the webgl power consumption test and reports the perf results.
136e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
137e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param browser: The Browser object to run the test with.
138e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        @param test_url: The URL to the aquarium test site.
139e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        """
140e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
141e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._backlight = power_utils.Backlight()
142e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._backlight.set_default()
143e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
144e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._service_stopper = service_stopper.ServiceStopper(
145e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
146e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._service_stopper.stop_services()
147e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
148e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._power_status = power_status.get_status()
149e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        # Verify that we are running on battery and the battery is sufficiently
150e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        # charged.
151e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN)
152e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
153e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        measurements = [power_status.SystemPower(
154e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                self._power_status.battery_path)]
155e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
156e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        def get_power():
157e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger = power_status.PowerLogger(measurements)
158e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger.start()
159e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            time.sleep(STABILIZATION_DURATION)
160e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            start_time = time.time()
161e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            time.sleep(MEASUREMENT_DURATION)
162e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            power_logger.checkpoint('result', start_time)
163e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            keyval = power_logger.calc()
164e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            logging.info('Power output %s', keyval)
165e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            return keyval['result_' + measurements[0].domain + '_pwr']
166e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
167e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self.run_fish_test(browser, test_url, 1000, perf_log=False)
168e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        energy_rate = get_power()
169e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        # This is a power specific test so we are not capturing
170e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        # avg_fps and avg_render_time in this test.
171e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self.perf_keyval[POWER_DESCRIPTION] = energy_rate
172e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana        self.output_perf_value(description=POWER_DESCRIPTION,
173e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                               value=energy_rate, units='W',
174e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                               higher_is_better=False)
175e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana
176ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
177ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def exynos_sampler_callback(self, sampler_obj):
178ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Sampler callback function for ExynosSampler.
179ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
180ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param sampler_obj: The ExynosSampler object that invokes this callback
181ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                function.
182ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
183ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        if sampler_obj.stopped:
184ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            return
185ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
186ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        with self.sampler_lock:
187ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            now = time.time()
188ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results = {}
189ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            info_str = ['\nfb_id wait_kds flipped']
190ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            for value in sampler_obj.frame_buffers.itervalues():
191ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                results[value.fb] = {}
192ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for state, stats in value.states.iteritems():
193ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    results[value.fb][state] = (stats.avg, stats.stdev)
194ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                info_str.append('%s: %s %s' % (
195ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                        value.fb, results[value.fb]['wait_kds'][0],
196ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                        results[value.fb]['flipped'][0]))
197ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results['avg_fps'] = self.active_tab.EvaluateJavaScript(
198ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    'g_crosFpsCounter.getAvgFps();')
199ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            results['avg_render_time'] = self.active_tab.EvaluateJavaScript(
200ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    'g_crosFpsCounter.getAvgRenderTime();')
201ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.active_tab.ExecuteJavaScript('g_crosFpsCounter.reset();')
202ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            info_str.append('avg_fps: %s, avg_render_time: %s' %
203ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                            (results['avg_fps'], results['avg_render_time']))
204ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            self.flip_stats[now] = results
205ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            logging.info('\n'.join(info_str))
206ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
207ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def exynos_output_flip_stats(self, file_name):
208ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Pageflip statistics output function for ExynosSampler.
209ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
210ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param file_name: The output file name.
211ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
212ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # output format:
213ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # time fb_id avg_rendered avg_prepared avg_wait_kds avg_flipped
214ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        # std_rendered std_prepared std_wait_kds std_flipped
215ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        with open(file_name, 'w') as f:
216ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            for t in sorted(self.flip_stats.keys()):
217ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                if ('avg_fps' in self.flip_stats[t] and
218ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    'avg_render_time' in self.flip_stats[t]):
219ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s %s\n' % (
220ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                            t, self.flip_stats[t]['avg_fps'],
221ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                            self.flip_stats[t]['avg_render_time']))
222ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for fb, stats in self.flip_stats[t].iteritems():
223ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    if not isinstance(fb, int):
224ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                        continue
225ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s ' % (t, fb))
226ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s %s %s ' % (stats['rendered'][0],
227ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['prepared'][0],
228ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['wait_kds'][0],
229ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                              stats['flipped'][0]))
230ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                    f.write('%s %s %s %s\n' % (stats['rendered'][1],
231ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['prepared'][1],
232ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['wait_kds'][1],
233ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                                               stats['flipped'][1]))
234ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
235ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang    def run_once(self, test_duration_secs=30,
236e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                 test_setting_num_fishes=(50, 1000), power_test=False):
237ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """Find a brower with telemetry, and run the test.
238ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
239ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_duration_secs: The duration in seconds to run each scenario
240ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                for.
241ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        @param test_setting_num_fishes: A list of the numbers of fishes to
242ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                enable in the test.
243ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        """
244ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.test_duration_secs = test_duration_secs
245ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.test_setting_num_fishes = test_setting_num_fishes
246ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang
2472d4a164e8e583d365bb5fff12defd56687238ee7Ilja Friedel        with chrome.Chrome(logged_in=False) as cr:
248ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            cr.browser.SetHTTPServerDirectories(self.srcdir)
249ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang            test_url = cr.browser.http_server.UrlOf(
250ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang                os.path.join(self.srcdir, 'aquarium.html'))
251e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            if not utils.wait_for_cool_machine():
252e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                raise error.TestFail('Could not get cold machine.')
253e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            if power_test:
254e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                self._test_power = True
255e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                self.run_power_test(cr.browser, test_url)
256e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                with self.sampler_lock:
257e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    self.active_tab.Close()
258e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    self.active_tab = None
259e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana            else:
260e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                for n in self.test_setting_num_fishes:
261e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    self.run_fish_test(cr.browser, test_url, n)
262e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    # Do not close the tab when the sampler_callback is doing
263e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    # his work.
264e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                    with self.sampler_lock:
265e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                        self.active_tab.Close()
266e96b8f8d31f21f30028d7d544c82d3817295c8f5Rohit Makasana                        self.active_tab = None
267ab19e9793140c5bab16a2b865c796f0789c17446Ricky Liang        self.write_perf_keyval(self.perf_keyval)
268