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 device_errors
14 from devil
.android
.sdk
import intent
15 from pylib
import constants
16 from pylib
import pexpect
17 from pylib
.gtest
import gtest_test_instance
18 from pylib
.gtest
import local_device_gtest_run
19 from pylib
.gtest
.test_package
import TestPackage
22 class TestPackageApk(TestPackage
):
23 """A helper class for running APK-based native tests."""
25 def __init__(self
, suite_name
):
28 suite_name: Name of the test suite (e.g. base_unittests).
30 TestPackage
.__init
__(self
, suite_name
)
31 self
.suite_path
= os
.path
.join(
32 constants
.GetOutDirectory(), '%s_apk' % suite_name
,
33 '%s-debug.apk' % suite_name
)
34 if suite_name
== 'content_browsertests':
35 self
._package
_info
= constants
.PACKAGE_INFO
['content_browsertests']
36 elif suite_name
== 'components_browsertests':
37 self
._package
_info
= constants
.PACKAGE_INFO
['components_browsertests']
39 self
._package
_info
= constants
.PACKAGE_INFO
['gtest']
41 if suite_name
== 'net_unittests':
42 self
._extras
= {'RunInSubThread': None}
46 def _CreateCommandLineFileOnDevice(self
, device
, options
):
47 device
.WriteFile(self
._package
_info
.cmdline_file
,
48 self
.suite_name
+ ' ' + options
)
51 # The test.fifo path is determined by:
52 # testing/android/native_test/java/src/org/chromium/native_test/
53 # NativeTestActivity.java and
54 # testing/android/native_test_launcher.cc
55 return '/data/data/' + self
._package
_info
.package
+ '/files/test.fifo'
57 def _ClearFifo(self
, device
):
58 device
.RunShellCommand('rm -f ' + self
._GetFifo
())
60 def _WatchFifo(self
, device
, timeout
, logfile
=None):
62 if device
.FileExists(self
._GetFifo
()):
63 logging
.info('Fifo created. Slept for %f secs', i
* 0.5)
67 raise device_errors
.DeviceUnreachableError(
68 'Unable to find fifo on device %s ' % self
._GetFifo
())
69 args
= ['-s', device
.adb
.GetDeviceSerial(), 'shell', 'cat', self
._GetFifo
()]
70 return pexpect
.spawn('adb', args
, timeout
=timeout
, logfile
=logfile
)
72 def _StartActivity(self
, device
, force_stop
=True):
74 intent
.Intent(package
=self
._package
_info
.package
,
75 activity
=self
._package
_info
.activity
,
76 action
='android.intent.action.MAIN',
78 # No wait since the runner waits for FIFO creation anyway.
80 force_stop
=force_stop
)
83 def ClearApplicationState(self
, device
):
84 device
.ClearApplicationState(self
._package
_info
.package
)
85 # Content shell creates a profile on the sdscard which accumulates cache
87 if self
.suite_name
== 'content_browsertests':
89 device
.RunShellCommand(
90 'rm -r %s/content_shell' % device
.GetExternalStoragePath(),
92 except device_errors
.CommandFailedError
:
93 # TODO(jbudorick) Handle this exception appropriately once the
94 # conversions are done.
96 elif self
.suite_name
== 'components_browsertests':
98 device
.RunShellCommand(
99 'rm -r %s/components_shell' % device
.GetExternalStoragePath(),
101 except device_errors
.CommandFailedError
:
102 # TODO(jbudorick) Handle this exception appropriately once the
103 # conversions are done.
107 def CreateCommandLineFileOnDevice(self
, device
, test_filter
, test_arguments
):
108 self
._CreateCommandLineFileOnDevice
(
109 device
, '--gtest_filter=%s %s' % (test_filter
, test_arguments
))
112 def GetAllTests(self
, device
):
113 self
._CreateCommandLineFileOnDevice
(device
, '--gtest_list_tests')
115 self
.tool
.SetupEnvironment()
116 # Clear and start monitoring logcat.
117 self
._ClearFifo
(device
)
118 self
._StartActivity
(device
)
119 # Wait for native test to complete.
120 p
= self
._WatchFifo
(device
, timeout
=30 * self
.tool
.GetTimeoutScale())
121 p
.expect('<<ScopedMainEntryLogger')
124 self
.tool
.CleanUpEnvironment()
125 # We need to strip the trailing newline.
126 content
= [line
.rstrip() for line
in p
.before
.splitlines()]
127 return gtest_test_instance
.ParseGTestListTests(content
)
130 def SpawnTestProcess(self
, device
):
132 self
.tool
.SetupEnvironment()
133 self
._ClearFifo
(device
)
134 # Doesn't need to stop an Activity because ClearApplicationState() is
135 # always called before this call and so it is already stopped at this
137 self
._StartActivity
(device
, force_stop
=False)
139 self
.tool
.CleanUpEnvironment()
140 logfile
= self
._NewLineNormalizer
(sys
.stdout
)
141 return self
._WatchFifo
(device
, timeout
=10, logfile
=logfile
)
143 class _NewLineNormalizer(object):
144 def __init__(self
, output
):
145 self
._output
= output
147 def write(self
, data
):
148 data
= data
.replace('\r\r\n', '\n')
149 self
._output
.write(data
)
155 def Install(self
, device
):
156 self
.tool
.CopyFiles(device
)
157 device
.Install(self
.suite_path
)
160 def PullAppFiles(self
, device
, files
, directory
):
161 local_device_gtest_run
.PullAppFilesImpl(
162 device
, self
._package
_info
.package
, files
, directory
)