Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Unified Diff: test/lib/TestGyp.py

Issue 321953005: [gyp][Android] Implement TestGypAndroid.run_built_executable. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/lib/TestGyp.py
diff --git a/test/lib/TestGyp.py b/test/lib/TestGyp.py
index cde04cac19bf7fa45fc8205249349038cbf6aa52..f50b33726d331a401761a62c3803bcea2968bdfa 100644
--- a/test/lib/TestGyp.py
+++ b/test/lib/TestGyp.py
@@ -406,10 +406,6 @@ class TestGypAndroid(TestGypBase):
"""
Subclass for testing the GYP Android makefile generator. Note that
build/envsetup.sh and lunch must have been run before running tests.
-
- TODO: This is currently an incomplete implementation. We do not support
- run_built_executable(), so we pass only tests which do not use this. As a
- result, support for host targets is not properly tested.
"""
format = 'android'
@@ -452,6 +448,20 @@ class TestGypAndroid(TestGypBase):
os.remove(os.path.join(out_dir, x, d))
super(TestGypAndroid, self).__init__(*args, **kw)
+ self._adb_path = os.path.join(os.environ['ANDROID_HOST_OUT'], 'bin', 'adb')
+ self._device_serial = None
+ adb_devices_out = self._call_adb(['devices'])
+ devices = [l.split()[0] for l in adb_devices_out.splitlines()[1:-1]
+ if l.split()[1] == 'device']
+ if len(devices) == 0:
+ self._device_serial = None
+ else:
+ if len(devices) > 1:
+ self._device_serial = random.choice(devices)
+ else:
+ self._device_serial = devices[0]
+ self._call_adb(['root'])
+ self._to_install = []
def target_name(self, target):
if target == self.ALL:
@@ -462,6 +472,8 @@ class TestGypAndroid(TestGypBase):
return self.ALL
return target
+ _installable_target_regex = re.compile('target Strip:\s*\S+\s+\((\S+)\)')
+
def build(self, gyp_file, target=None, **kw):
"""
Runs a build using the Android makefiles generated from the specified
@@ -476,6 +488,11 @@ class TestGypAndroid(TestGypBase):
makefile = os.path.join(self.workdir, chdir, 'GypAndroid.mk')
os.environ['ONE_SHOT_MAKEFILE'] = makefile
result = self.run(program=self.build_tool, **kw)
+ for l in self.stdout().splitlines():
+ target_result = TestGypAndroid._installable_target_regex.match(l)
+ if target_result:
+ self._to_install.append(os.path.abspath(os.path.join(
+ os.environ['ANDROID_BUILD_TOP'], target_result.group(1))))
del os.environ['ONE_SHOT_MAKEFILE']
return result
@@ -519,23 +536,73 @@ class TestGypAndroid(TestGypBase):
'%s.so' % module_name)
assert False, 'Unhandled type'
+ def _call_adb(self, command):
+ """ Calls the provided adb command.
+
+ If the command fails, the test fails.
+
+ Args:
+ command: The adb command to call.
+ Returns:
+ The command's output.
+ """
+ with tempfile.TemporaryFile(bufsize=0) as adb_out:
+ with tempfile.TemporaryFile(bufsize=0) as adb_err:
+ adb_command = [self._adb_path]
+ if self._device_serial:
+ adb_command += ['-s', self._device_serial]
+ adb_command += command
+ if subprocess.call(adb_command, stdout=adb_out, stderr=adb_err) != 0:
jbudorick 2014/06/11 16:30:22 (tests should fail here for nonzero exit codes)
+ print '%s failed:' % ' '.join(adb_command)
+ print self.banner('STDOUT ')
+ adb_out.seek(0)
+ print adb_out.read()
+ print self.banner('STDERR ')
+ adb_err.seek(0)
+ print adb_err.read()
+ self.fail_test()
+ else:
+ adb_out.seek(0)
+ output = adb_out.read()
+ return output
+
def run_built_executable(self, name, *args, **kw):
"""
Runs an executable program built from a gyp-generated configuration.
-
- This is not correctly implemented for Android. For now, we simply check
- that the executable file exists.
"""
- # Running executables requires a device. Even if we build for target x86,
- # the binary is not built with the correct toolchain options to actually
- # run on the host.
-
- # Copied from TestCommon.run()
match = kw.pop('match', self.match)
- status = None
- if os.path.exists(self.built_file_path(name)):
- status = 1
- self._complete(None, None, None, None, status, match)
+
+ executable_file = self.built_file_path(name, type=self.EXECUTABLE, **kw)
+ if executable_file not in self._to_install:
+ self.fail_test()
+
+ if not self._device_serial:
+ self.skip_test(message='No devices attached.\n')
+
+ storage = self._call_adb(['shell', 'echo', '$ANDROID_DATA']).strip()
+ if not len(storage):
+ self.fail_test()
+
+ installed = []
+ try:
+ for i in self._to_install:
+ a = os.path.abspath(
+ os.path.join(os.environ['ANDROID_BUILD_TOP'], i))
+ dest = '%s/%s' % (storage, os.path.basename(a))
+ self._call_adb(['push', os.path.abspath(a), dest])
+ installed.append(dest)
+ if i == executable_file:
+ device_executable = dest
+ self._call_adb(['shell', 'chmod', '755', device_executable])
+
+ out = self._call_adb(
+ ['shell', 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s' % storage,
+ device_executable])
+ out = out.replace('\r\n', '\n')
+ self._complete(out, kw.pop('stdout', None), None, None, None, match)
Torne 2014/06/11 12:44:18 Is there a way to return the program's exit status
jbudorick 2014/06/11 16:30:22 If a program exits with a nonzero exit code, _call
Torne 2014/06/11 16:41:39 adb does not return the error code of the program
+ finally:
+ if len(installed):
+ self._call_adb(['shell', 'rm'] + installed)
def match_single_line(self, lines = None, expected_line = None):
"""

Powered by Google App Engine
This is Rietveld 408576698