2015-04-02 19:07:55 +08:00
|
|
|
""" This module contains functions used by the test cases to hide the
|
|
|
|
architecture and/or the platform dependent nature of the tests. """
|
|
|
|
|
Python 3 - Turn on absolute imports, and fix existing imports.
Absolute imports were introduced in Python 2.5 as a feature
(e.g. from __future__ import absolute_import), and made default
in Python 3.
When absolute imports are enabled, the import system changes in
a couple of ways:
1) The `import foo` syntax will *only* search sys.path. If `foo`
isn't in sys.path, it won't be found. Period. Without absolute
imports, the import system will also search the same directory
that the importing file resides in, so that you can easily
import from the same folder.
2) From inside a package, you can use a dot syntax to refer to higher
levels of the current package. For example, if you are in the
package lldbsuite.test.utility, then ..foo refers to
lldbsuite.test.foo. You can use this notation with the
`from X import Y` syntax to write intra-package references. For
example, using the previous locationa s a starting point, writing
`from ..support import seven` would import lldbsuite.support.seven
Since this is now the default behavior in Python 3, this means that
importing from the same directory with `import foo` *no longer works*.
As a result, the only way to have portable code is to force absolute
imports for all versions of Python.
See PEP 0328 [https://www.python.org/dev/peps/pep-0328/] for more
information about absolute and relative imports.
Differential Revision: http://reviews.llvm.org/D14342
Reviewed By: Todd Fiala
llvm-svn: 252191
2015-11-06 03:22:28 +08:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
|
|
|
# System modules
|
2016-02-19 02:50:02 +08:00
|
|
|
import itertools
|
2016-02-04 03:12:30 +08:00
|
|
|
import re
|
|
|
|
import subprocess
|
2016-02-05 02:03:01 +08:00
|
|
|
import sys
|
2017-07-06 00:29:36 +08:00
|
|
|
import os
|
Python 3 - Turn on absolute imports, and fix existing imports.
Absolute imports were introduced in Python 2.5 as a feature
(e.g. from __future__ import absolute_import), and made default
in Python 3.
When absolute imports are enabled, the import system changes in
a couple of ways:
1) The `import foo` syntax will *only* search sys.path. If `foo`
isn't in sys.path, it won't be found. Period. Without absolute
imports, the import system will also search the same directory
that the importing file resides in, so that you can easily
import from the same folder.
2) From inside a package, you can use a dot syntax to refer to higher
levels of the current package. For example, if you are in the
package lldbsuite.test.utility, then ..foo refers to
lldbsuite.test.foo. You can use this notation with the
`from X import Y` syntax to write intra-package references. For
example, using the previous locationa s a starting point, writing
`from ..support import seven` would import lldbsuite.support.seven
Since this is now the default behavior in Python 3, this means that
importing from the same directory with `import foo` *no longer works*.
As a result, the only way to have portable code is to force absolute
imports for all versions of Python.
See PEP 0328 [https://www.python.org/dev/peps/pep-0328/] for more
information about absolute and relative imports.
Differential Revision: http://reviews.llvm.org/D14342
Reviewed By: Todd Fiala
llvm-svn: 252191
2015-11-06 03:22:28 +08:00
|
|
|
|
|
|
|
# Third-party modules
|
2016-02-19 02:50:02 +08:00
|
|
|
import six
|
2016-02-04 03:12:30 +08:00
|
|
|
from six.moves.urllib import parse as urlparse
|
Python 3 - Turn on absolute imports, and fix existing imports.
Absolute imports were introduced in Python 2.5 as a feature
(e.g. from __future__ import absolute_import), and made default
in Python 3.
When absolute imports are enabled, the import system changes in
a couple of ways:
1) The `import foo` syntax will *only* search sys.path. If `foo`
isn't in sys.path, it won't be found. Period. Without absolute
imports, the import system will also search the same directory
that the importing file resides in, so that you can easily
import from the same folder.
2) From inside a package, you can use a dot syntax to refer to higher
levels of the current package. For example, if you are in the
package lldbsuite.test.utility, then ..foo refers to
lldbsuite.test.foo. You can use this notation with the
`from X import Y` syntax to write intra-package references. For
example, using the previous locationa s a starting point, writing
`from ..support import seven` would import lldbsuite.support.seven
Since this is now the default behavior in Python 3, this means that
importing from the same directory with `import foo` *no longer works*.
As a result, the only way to have portable code is to force absolute
imports for all versions of Python.
See PEP 0328 [https://www.python.org/dev/peps/pep-0328/] for more
information about absolute and relative imports.
Differential Revision: http://reviews.llvm.org/D14342
Reviewed By: Todd Fiala
llvm-svn: 252191
2015-11-06 03:22:28 +08:00
|
|
|
|
|
|
|
# LLDB modules
|
2016-02-04 03:12:30 +08:00
|
|
|
from . import configuration
|
|
|
|
import lldb
|
2019-10-10 07:52:31 +08:00
|
|
|
import lldbsuite.test.lldbplatform as lldbplatform
|
2015-11-19 19:01:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-04-02 19:07:55 +08:00
|
|
|
def check_first_register_readable(test_case):
|
2015-11-19 19:01:21 +08:00
|
|
|
arch = test_case.getArchitecture()
|
|
|
|
|
|
|
|
if arch in ['x86_64', 'i386']:
|
2015-04-02 19:07:55 +08:00
|
|
|
test_case.expect("register read eax", substrs=['eax = 0x'])
|
2019-11-13 08:30:25 +08:00
|
|
|
elif arch in ['arm', 'armv7', 'armv7k', 'armv8l', 'armv7l']:
|
2015-04-17 17:37:06 +08:00
|
|
|
test_case.expect("register read r0", substrs=['r0 = 0x'])
|
2019-10-17 03:14:49 +08:00
|
|
|
elif arch in ['aarch64', 'arm64', 'arm64e', 'arm64_32']:
|
2015-04-02 19:07:55 +08:00
|
|
|
test_case.expect("register read x0", substrs=['x0 = 0x'])
|
2015-11-19 19:01:21 +08:00
|
|
|
elif re.match("mips", arch):
|
|
|
|
test_case.expect("register read zero", substrs=['zero = 0x'])
|
2016-04-14 22:28:34 +08:00
|
|
|
elif arch in ['s390x']:
|
|
|
|
test_case.expect("register read r0", substrs=['r0 = 0x'])
|
2018-03-01 04:57:26 +08:00
|
|
|
elif arch in ['powerpc64le']:
|
|
|
|
test_case.expect("register read r0", substrs=['r0 = 0x'])
|
2015-04-02 19:07:55 +08:00
|
|
|
else:
|
|
|
|
# TODO: Add check for other architectures
|
|
|
|
test_case.fail(
|
|
|
|
"Unsupported architecture for test case (arch: %s)" %
|
|
|
|
test_case.getArchitecture())
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-04 03:12:30 +08:00
|
|
|
|
|
|
|
def _run_adb_command(cmd, device_id):
|
|
|
|
device_id_args = []
|
|
|
|
if device_id:
|
|
|
|
device_id_args = ["-s", device_id]
|
|
|
|
full_cmd = ["adb"] + device_id_args + cmd
|
2016-02-04 06:53:18 +08:00
|
|
|
p = subprocess.Popen(
|
|
|
|
full_cmd,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE)
|
2016-02-04 03:12:30 +08:00
|
|
|
stdout, stderr = p.communicate()
|
|
|
|
return p.returncode, stdout, stderr
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Centralize libc++ test skipping logic
Summary:
This aims to replace the different decorators we've had on each libc++
test with a single solution. Each libc++ will be assigned to the
"libc++" category and a single central piece of code will decide whether
we are actually able to run libc++ test in the given configuration by
enabling or disabling the category (while giving the user the
opportunity to override this).
I started this effort because I wanted to get libc++ tests running on
android, and none of the existing decorators worked for this use case:
- skipIfGcc - incorrect, we can build libc++ executables on android
with gcc (in fact, after this, we can now do it on linux as well)
- lldbutil.skip_if_library_missing - this checks whether libc++.so is
loaded in the proces, which fails in case of a statically linked
libc++ (this makes copying executables to the remote target easier to
manage).
To make this work I needed to split out the pseudo_barrier code from the
force-included file, as libc++'s atomic does not play well with gcc on
linux, and this made every test fail, even though we need the code only
in the threading tests.
So far, I am only annotating one of the tests with this category. If
this does not break anything, I'll proceed to update the rest.
Reviewers: jingham, zturner, EricWF
Subscribers: srhines, lldb-commits
Differential Revision: https://reviews.llvm.org/D30984
llvm-svn: 299028
2017-03-30 05:01:14 +08:00
|
|
|
def target_is_android():
|
|
|
|
if not hasattr(target_is_android, 'result'):
|
2016-02-04 03:12:30 +08:00
|
|
|
triple = lldb.DBG.GetSelectedPlatform().GetTriple()
|
|
|
|
match = re.match(".*-.*-.*-android", triple)
|
Centralize libc++ test skipping logic
Summary:
This aims to replace the different decorators we've had on each libc++
test with a single solution. Each libc++ will be assigned to the
"libc++" category and a single central piece of code will decide whether
we are actually able to run libc++ test in the given configuration by
enabling or disabling the category (while giving the user the
opportunity to override this).
I started this effort because I wanted to get libc++ tests running on
android, and none of the existing decorators worked for this use case:
- skipIfGcc - incorrect, we can build libc++ executables on android
with gcc (in fact, after this, we can now do it on linux as well)
- lldbutil.skip_if_library_missing - this checks whether libc++.so is
loaded in the proces, which fails in case of a statically linked
libc++ (this makes copying executables to the remote target easier to
manage).
To make this work I needed to split out the pseudo_barrier code from the
force-included file, as libc++'s atomic does not play well with gcc on
linux, and this made every test fail, even though we need the code only
in the threading tests.
So far, I am only annotating one of the tests with this category. If
this does not break anything, I'll proceed to update the rest.
Reviewers: jingham, zturner, EricWF
Subscribers: srhines, lldb-commits
Differential Revision: https://reviews.llvm.org/D30984
llvm-svn: 299028
2017-03-30 05:01:14 +08:00
|
|
|
target_is_android.result = match is not None
|
|
|
|
return target_is_android.result
|
2016-02-04 03:12:30 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-04 03:12:30 +08:00
|
|
|
def android_device_api():
|
|
|
|
if not hasattr(android_device_api, 'result'):
|
|
|
|
assert configuration.lldb_platform_url is not None
|
|
|
|
device_id = None
|
|
|
|
parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
|
|
|
|
host_name = parsed_url.netloc.split(":")[0]
|
|
|
|
if host_name != 'localhost':
|
|
|
|
device_id = host_name
|
|
|
|
if device_id.startswith('[') and device_id.endswith(']'):
|
|
|
|
device_id = device_id[1:-1]
|
|
|
|
retcode, stdout, stderr = _run_adb_command(
|
|
|
|
["shell", "getprop", "ro.build.version.sdk"], device_id)
|
|
|
|
if retcode == 0:
|
|
|
|
android_device_api.result = int(stdout)
|
|
|
|
else:
|
|
|
|
raise LookupError(
|
|
|
|
">>> Unable to determine the API level of the Android device.\n"
|
|
|
|
">>> stdout:\n%s\n"
|
|
|
|
">>> stderr:\n%s\n" %
|
|
|
|
(stdout, stderr))
|
|
|
|
return android_device_api.result
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-04 03:12:30 +08:00
|
|
|
def match_android_device(device_arch, valid_archs=None, valid_api_levels=None):
|
Centralize libc++ test skipping logic
Summary:
This aims to replace the different decorators we've had on each libc++
test with a single solution. Each libc++ will be assigned to the
"libc++" category and a single central piece of code will decide whether
we are actually able to run libc++ test in the given configuration by
enabling or disabling the category (while giving the user the
opportunity to override this).
I started this effort because I wanted to get libc++ tests running on
android, and none of the existing decorators worked for this use case:
- skipIfGcc - incorrect, we can build libc++ executables on android
with gcc (in fact, after this, we can now do it on linux as well)
- lldbutil.skip_if_library_missing - this checks whether libc++.so is
loaded in the proces, which fails in case of a statically linked
libc++ (this makes copying executables to the remote target easier to
manage).
To make this work I needed to split out the pseudo_barrier code from the
force-included file, as libc++'s atomic does not play well with gcc on
linux, and this made every test fail, even though we need the code only
in the threading tests.
So far, I am only annotating one of the tests with this category. If
this does not break anything, I'll proceed to update the rest.
Reviewers: jingham, zturner, EricWF
Subscribers: srhines, lldb-commits
Differential Revision: https://reviews.llvm.org/D30984
llvm-svn: 299028
2017-03-30 05:01:14 +08:00
|
|
|
if not target_is_android():
|
2016-02-04 03:12:30 +08:00
|
|
|
return False
|
|
|
|
if valid_archs is not None and device_arch not in valid_archs:
|
|
|
|
return False
|
|
|
|
if valid_api_levels is not None and android_device_api() not in valid_api_levels:
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-04 03:12:30 +08:00
|
|
|
def finalize_build_dictionary(dictionary):
|
Centralize libc++ test skipping logic
Summary:
This aims to replace the different decorators we've had on each libc++
test with a single solution. Each libc++ will be assigned to the
"libc++" category and a single central piece of code will decide whether
we are actually able to run libc++ test in the given configuration by
enabling or disabling the category (while giving the user the
opportunity to override this).
I started this effort because I wanted to get libc++ tests running on
android, and none of the existing decorators worked for this use case:
- skipIfGcc - incorrect, we can build libc++ executables on android
with gcc (in fact, after this, we can now do it on linux as well)
- lldbutil.skip_if_library_missing - this checks whether libc++.so is
loaded in the proces, which fails in case of a statically linked
libc++ (this makes copying executables to the remote target easier to
manage).
To make this work I needed to split out the pseudo_barrier code from the
force-included file, as libc++'s atomic does not play well with gcc on
linux, and this made every test fail, even though we need the code only
in the threading tests.
So far, I am only annotating one of the tests with this category. If
this does not break anything, I'll proceed to update the rest.
Reviewers: jingham, zturner, EricWF
Subscribers: srhines, lldb-commits
Differential Revision: https://reviews.llvm.org/D30984
llvm-svn: 299028
2017-03-30 05:01:14 +08:00
|
|
|
if target_is_android():
|
2016-02-04 03:12:30 +08:00
|
|
|
if dictionary is None:
|
|
|
|
dictionary = {}
|
|
|
|
dictionary["OS"] = "Android"
|
2017-11-07 18:36:42 +08:00
|
|
|
dictionary["PIE"] = 1
|
2016-02-04 03:12:30 +08:00
|
|
|
return dictionary
|
2016-02-05 02:03:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-05 02:03:01 +08:00
|
|
|
def getHostPlatform():
|
|
|
|
"""Returns the host platform running the test suite."""
|
|
|
|
# Attempts to return a platform name matching a target Triple platform.
|
|
|
|
if sys.platform.startswith('linux'):
|
|
|
|
return 'linux'
|
2018-02-08 11:05:47 +08:00
|
|
|
elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
|
2016-02-05 02:03:01 +08:00
|
|
|
return 'windows'
|
|
|
|
elif sys.platform.startswith('darwin'):
|
|
|
|
return 'darwin'
|
|
|
|
elif sys.platform.startswith('freebsd'):
|
|
|
|
return 'freebsd'
|
|
|
|
elif sys.platform.startswith('netbsd'):
|
|
|
|
return 'netbsd'
|
|
|
|
else:
|
|
|
|
return sys.platform
|
2016-02-05 07:04:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
def getDarwinOSTriples():
|
2017-09-26 02:19:39 +08:00
|
|
|
return ['darwin', 'macosx', 'ios', 'watchos', 'tvos', 'bridgeos']
|
2016-02-05 07:04:17 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-05 07:04:17 +08:00
|
|
|
def getPlatform():
|
|
|
|
"""Returns the target platform which the tests are running on."""
|
|
|
|
platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
|
|
|
|
if platform.startswith('freebsd'):
|
|
|
|
platform = 'freebsd'
|
|
|
|
elif platform.startswith('netbsd'):
|
|
|
|
platform = 'netbsd'
|
|
|
|
return platform
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-05 07:04:17 +08:00
|
|
|
def platformIsDarwin():
|
|
|
|
"""Returns true if the OS triple for the selected platform is any valid apple OS"""
|
|
|
|
return getPlatform() in getDarwinOSTriples()
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2017-07-06 00:29:36 +08:00
|
|
|
def findMainThreadCheckerDylib():
|
|
|
|
if not platformIsDarwin():
|
|
|
|
return ""
|
|
|
|
|
2019-10-10 07:52:31 +08:00
|
|
|
if getPlatform() in lldbplatform.translate(lldbplatform.darwin_embedded):
|
|
|
|
return "/Developer/usr/lib/libMainThreadChecker.dylib"
|
|
|
|
|
2017-07-06 00:29:36 +08:00
|
|
|
with os.popen('xcode-select -p') as output:
|
|
|
|
xcode_developer_path = output.read().strip()
|
|
|
|
mtc_dylib_path = '%s/usr/lib/libMainThreadChecker.dylib' % xcode_developer_path
|
|
|
|
if os.path.isfile(mtc_dylib_path):
|
|
|
|
return mtc_dylib_path
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
2016-02-05 07:04:17 +08:00
|
|
|
class _PlatformContext(object):
|
|
|
|
"""Value object class which contains platform-specific options."""
|
|
|
|
|
|
|
|
def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
|
|
|
|
self.shlib_environment_var = shlib_environment_var
|
|
|
|
self.shlib_prefix = shlib_prefix
|
|
|
|
self.shlib_extension = shlib_extension
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-05 07:04:17 +08:00
|
|
|
def createPlatformContext():
|
|
|
|
if platformIsDarwin():
|
|
|
|
return _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
|
|
|
|
elif getPlatform() in ("freebsd", "linux", "netbsd"):
|
|
|
|
return _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
|
|
|
|
else:
|
|
|
|
return None
|
2016-04-14 23:52:53 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-04-14 23:52:53 +08:00
|
|
|
def hasChattyStderr(test_case):
|
|
|
|
"""Some targets produce garbage on the standard error output. This utility function
|
|
|
|
determines whether the tests can be strict about the expected stderr contents."""
|
2017-11-27 21:47:14 +08:00
|
|
|
if match_android_device(test_case.getArchitecture(), ['aarch64'], range(22, 25+1)):
|
2016-04-14 23:52:53 +08:00
|
|
|
return True # The dynamic linker on the device will complain about unknown DT entries
|
|
|
|
return False
|