14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import logging
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import os
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)import unittest
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)from telemetry.core import bitmap
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)from telemetry.core import util
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)from telemetry.core.platform import android_platform_backend
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)from telemetry.unittest import system_stub
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class MockAdbCommands(object):
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def __init__(self, mock_content):
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.mock_content = mock_content
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def CanAccessProtectedFileContents(self):
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return True
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  # pylint: disable=W0613
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def GetProtectedFileContents(self, file_name, log_result):
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return self.mock_content
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class AndroidPlatformBackendTest(unittest.TestCase):
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def setUp(self):
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self._stubs = system_stub.Override(android_platform_backend,
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       ['perf_control', 'thermal_throttle'])
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def tearDown(self):
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self._stubs.Restore()
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def testGetCpuStats(self):
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    proc_stat_content = [
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        '7702 (.android.chrome) S 167 167 0 0 -1 1077936448 '
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        '3247 0 0 0 4 1 0 0 20 0 9 0 5603962 337379328 5867 '
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        '4294967295 1074458624 1074463824 3197495984 3197494152 '
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        '1074767676 0 4612 0 38136 4294967295 0 0 17 0 0 0 0 0 0 '
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        '1074470376 1074470912 1102155776']
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    adb_valid_proc_content = MockAdbCommands(proc_stat_content)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    backend = android_platform_backend.AndroidPlatformBackend(
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        adb_valid_proc_content, False)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cpu_stats = backend.GetCpuStats('7702')
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertEquals(cpu_stats, {'CpuProcessTime': 5.0})
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  def testGetCpuStatsInvalidPID(self):
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    # Mock an empty /proc/pid/stat.
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    adb_empty_proc_stat = MockAdbCommands([])
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    backend = android_platform_backend.AndroidPlatformBackend(
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        adb_empty_proc_stat, False)
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    cpu_stats = backend.GetCpuStats('7702')
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertEquals(cpu_stats, {})
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  def testFramesFromMp4(self):
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    mock_adb = MockAdbCommands([])
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    backend = android_platform_backend.AndroidPlatformBackend(mock_adb, False)
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    try:
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      backend.InstallApplication('avconv')
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    finally:
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if not backend.CanLaunchApplication('avconv'):
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        logging.warning('Test not supported on this platform')
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        return  # pylint: disable=W0150
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    vid = os.path.join(util.GetUnittestDataDir(), 'vid.mp4')
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    expected_timestamps = [
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      0,
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      763,
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      783,
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      940,
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      1715,
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      1732,
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      1842,
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      1926,
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ]
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    # pylint: disable=W0212
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for i, timestamp_bitmap in enumerate(backend._FramesFromMp4(vid)):
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      timestamp, bmp = timestamp_bitmap
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      self.assertEquals(timestamp, expected_timestamps[i])
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      expected_bitmap = bitmap.Bitmap.FromPngFile(os.path.join(
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          util.GetUnittestDataDir(), 'frame%d.png' % i))
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      self.assertTrue(expected_bitmap.IsEqual(bmp))
86