1 # Copyright (c) 2012 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.
5 """Defines TestPackageApk to help run APK-based native tests."""
6 # pylint: disable=W0212
13 from devil
.android
import apk_helper
14 from devil
.android
import device_errors
15 from devil
.android
.sdk
import intent
16 from pylib
import constants
17 from pylib
import pexpect
18 from pylib
.gtest
import gtest_test_instance
19 from pylib
.gtest
.test_package
import TestPackage
20 from pylib
.local
.device
import local_device_gtest_run
23 class TestPackageApk(TestPackage
):
24 """A helper class for running APK-based native tests."""
26 def __init__(self
, suite_name
):
29 suite_name: Name of the test suite (e.g. base_unittests).
31 TestPackage
.__init
__(self
, suite_name
)
32 self
.suite_path
= os
.path
.join(
33 constants
.GetOutDirectory(), '%s_apk' % suite_name
,
34 '%s-debug.apk' % suite_name
)
35 if suite_name
== 'content_browsertests':
36 self
._package
_info
= constants
.PACKAGE_INFO
['content_browsertests']
37 elif suite_name
== 'components_browsertests':
38 self
._package
_info
= constants
.PACKAGE_INFO
['components_browsertests']
40 self
._package
_info
= constants
.PACKAGE_INFO
['gtest']
42 if suite_name
== 'net_unittests':
44 'org.chromium.native_test.NativeTestActivity.RunInSubThread': None
49 def _CreateCommandLineFileOnDevice(self
, device
, options
):
50 device
.WriteFile(self
._package
_info
.cmdline_file
,
51 self
.suite_name
+ ' ' + options
)
54 # The test.fifo path is determined by:
55 # testing/android/native_test/java/src/org/chromium/native_test/
56 # NativeTestActivity.java and
57 # testing/android/native_test_launcher.cc
58 return '/data/data/' + self
._package
_info
.package
+ '/files/test.fifo'
60 def _ClearFifo(self
, device
):
61 device
.RunShellCommand('rm -f ' + self
._GetFifo
())
63 def _WatchFifo(self
, device
, timeout
, logfile
=None):
65 if device
.FileExists(self
._GetFifo
()):
66 logging
.info('Fifo created. Slept for %f secs', i
* 0.5)
70 raise device_errors
.DeviceUnreachableError(
71 'Unable to find fifo on device %s ' % self
._GetFifo
())
72 args
= ['-s', device
.adb
.GetDeviceSerial(), 'shell', 'cat', self
._GetFifo
()]
73 return pexpect
.spawn('adb', args
, timeout
=timeout
, logfile
=logfile
)
75 def _StartActivity(self
, device
, force_stop
=True):
77 intent
.Intent(package
=self
._package
_info
.package
,
78 activity
=self
._package
_info
.activity
,
79 action
='android.intent.action.MAIN',
81 # No wait since the runner waits for FIFO creation anyway.
83 force_stop
=force_stop
)
86 def ClearApplicationState(self
, device
):
87 device
.ClearApplicationState(self
._package
_info
.package
)
88 # Content shell creates a profile on the sdscard which accumulates cache
90 if self
.suite_name
== 'content_browsertests':
92 device
.RunShellCommand(
93 'rm -r %s/content_shell' % device
.GetExternalStoragePath(),
95 except device_errors
.CommandFailedError
:
96 # TODO(jbudorick) Handle this exception appropriately once the
97 # conversions are done.
99 elif self
.suite_name
== 'components_browsertests':
101 device
.RunShellCommand(
102 'rm -r %s/components_shell' % device
.GetExternalStoragePath(),
104 except device_errors
.CommandFailedError
:
105 # TODO(jbudorick) Handle this exception appropriately once the
106 # conversions are done.
110 def CreateCommandLineFileOnDevice(self
, device
, test_filter
, test_arguments
):
111 self
._CreateCommandLineFileOnDevice
(
112 device
, '--gtest_filter=%s %s' % (test_filter
, test_arguments
))
115 def GetAllTests(self
, device
):
116 self
._CreateCommandLineFileOnDevice
(device
, '--gtest_list_tests')
118 self
.tool
.SetupEnvironment()
119 # Clear and start monitoring logcat.
120 self
._ClearFifo
(device
)
121 self
._StartActivity
(device
)
122 # Wait for native test to complete.
123 p
= self
._WatchFifo
(device
, timeout
=30 * self
.tool
.GetTimeoutScale())
124 p
.expect('<<ScopedMainEntryLogger')
127 self
.tool
.CleanUpEnvironment()
128 # We need to strip the trailing newline.
129 content
= [line
.rstrip() for line
in p
.before
.splitlines()]
130 return gtest_test_instance
.ParseGTestListTests(content
)
133 def SpawnTestProcess(self
, device
):
135 self
.tool
.SetupEnvironment()
136 self
._ClearFifo
(device
)
137 # Doesn't need to stop an Activity because ClearApplicationState() is
138 # always called before this call and so it is already stopped at this
140 self
._StartActivity
(device
, force_stop
=False)
142 self
.tool
.CleanUpEnvironment()
143 logfile
= self
._NewLineNormalizer
(sys
.stdout
)
144 return self
._WatchFifo
(device
, timeout
=10, logfile
=logfile
)
146 class _NewLineNormalizer(object):
147 def __init__(self
, output
):
148 self
._output
= output
150 def write(self
, data
):
151 data
= data
.replace('\r\r\n', '\n')
152 self
._output
.write(data
)
158 def Install(self
, device
):
159 self
.tool
.CopyFiles(device
)
160 device
.Install(self
.suite_path
)
163 def PullAppFiles(self
, device
, files
, directory
):
164 local_device_gtest_run
.PullAppFilesImpl(
165 device
, self
._package
_info
.package
, files
, directory
)
168 def SetPermissions(self
, device
):
169 permissions
= apk_helper
.ApkHelper(self
.suite_path
).GetPermissions()
170 device
.GrantPermissions(
171 apk_helper
.GetPackageName(self
.suite_path
), permissions
)