Skip to content

Commit 049c437

Browse files
committed
[libcxx] Introduce LinuxRemoteTI for remote testing
Summary: This patch adds a new target info object called LinuxRemoteTI. Unlike LinuxLocalTI, which asks the host system about various things like available locales, distribution name etc. which don't make sense if we're testing on a remote board, LinuxRemoteTI uses SSHExecutor to get information from the target system. Reviewers: jroelofs, ldionne, bcraig, EricWF, danalbert, mclow.lists Reviewed By: jroelofs Subscribers: christof, dexonsmith, libcxx-commits Tags: #libc Differential Revision: https://reviews.llvm.org/D72847
1 parent a93aa53 commit 049c437

File tree

3 files changed

+62
-46
lines changed

3 files changed

+62
-46
lines changed

libcxx/utils/libcxx/test/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def configure_executor(self):
202202
te = ValgrindExecutor(self.lit_config.valgrindArgs, te)
203203

204204
te.target_info = self.target_info
205+
self.target_info.executor = te
205206

206207
self.executor = te
207208

libcxx/utils/libcxx/test/executor.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def _copy_in_file(self, src, dst):
133133

134134
def delete_remote(self, remote):
135135
try:
136-
self._execute_command_remote(['rm', '-rf', remote])
136+
self.execute_command_remote(['rm', '-rf', remote])
137137
except OSError:
138138
# TODO: Log failure to delete?
139139
pass
@@ -172,14 +172,14 @@ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):
172172
# TODO(jroelofs): capture the copy_in and delete_remote commands,
173173
# and conjugate them with '&&'s around the first tuple element
174174
# returned here:
175-
return self._execute_command_remote(chmod_cmd + ['&&'] + cmd,
176-
target_cwd,
177-
env)
175+
return self.execute_command_remote(chmod_cmd + ['&&'] + cmd,
176+
target_cwd,
177+
env)
178178
finally:
179179
if target_cwd:
180180
self.delete_remote(target_cwd)
181181

182-
def _execute_command_remote(self, cmd, remote_work_dir='.', env=None):
182+
def execute_command_remote(self, cmd, remote_work_dir='.', env=None):
183183
raise NotImplementedError()
184184

185185

@@ -206,7 +206,7 @@ def _remote_temp(self, is_dir):
206206
# Not sure how to do suffix on osx yet
207207
dir_arg = '-d' if is_dir else ''
208208
cmd = 'mktemp -q {} /tmp/libcxx.XXXXXXXXXX'.format(dir_arg)
209-
_, temp_path, err, exitCode = self._execute_command_remote([cmd])
209+
_, temp_path, err, exitCode = self.execute_command_remote([cmd])
210210
temp_path = temp_path.strip()
211211
if exitCode != 0:
212212
raise RuntimeError(err)
@@ -238,7 +238,7 @@ def _export_command(self, env):
238238

239239
return export_cmd
240240

241-
def _execute_command_remote(self, cmd, remote_work_dir='.', env=None):
241+
def execute_command_remote(self, cmd, remote_work_dir='.', env=None):
242242
remote = self.user_prefix + self.host
243243
ssh_cmd = [self.ssh_command, '-oBatchMode=yes', remote]
244244
export_cmd = self._export_command(env)

libcxx/utils/libcxx/test/target_info.py

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
class DefaultTargetInfo(object):
2020
def __init__(self, full_config):
2121
self.full_config = full_config
22+
self.executor = None
2223

2324
def platform(self):
2425
return sys.platform.lower().strip()
@@ -50,39 +51,37 @@ def add_path(self, dest_env, new_path):
5051
dest_env['PATH'] = '%s%s%s' % (new_path, split_char,
5152
dest_env['PATH'])
5253

53-
54-
def test_locale(loc):
55-
assert loc is not None
56-
default_locale = locale.setlocale(locale.LC_ALL)
57-
try:
58-
locale.setlocale(locale.LC_ALL, loc)
59-
return True
60-
except locale.Error:
61-
return False
62-
finally:
63-
locale.setlocale(locale.LC_ALL, default_locale)
64-
65-
66-
def add_common_locales(features, lit_config, is_windows=False):
67-
# A list of locales needed by the test-suite.
68-
# The list uses the canonical name for the locale used in the test-suite
69-
# TODO: On Linux ISO8859 *may* needs to hyphenated.
70-
locales = [
71-
('en_US.UTF-8', 'English_United States.1252'),
72-
('fr_FR.UTF-8', 'French_France.1252'),
73-
('ru_RU.UTF-8', 'Russian_Russia.1251'),
74-
('zh_CN.UTF-8', 'Chinese_China.936'),
75-
('fr_CA.ISO8859-1', 'French_Canada.1252'),
76-
('cs_CZ.ISO8859-2', 'Czech_Czech Republic.1250')
77-
]
78-
for loc_id, windows_loc_name in locales:
79-
loc_name = windows_loc_name if is_windows else loc_id
80-
if test_locale(loc_name):
81-
features.add('locale.{0}'.format(loc_id))
82-
else:
83-
lit_config.warning('The locale {0} is not supported by '
84-
'your platform. Some tests will be '
85-
'unsupported.'.format(loc_name))
54+
def _test_locale(self, loc):
55+
assert loc is not None
56+
default_locale = locale.setlocale(locale.LC_ALL)
57+
try:
58+
locale.setlocale(locale.LC_ALL, loc)
59+
return True
60+
except locale.Error:
61+
return False
62+
finally:
63+
locale.setlocale(locale.LC_ALL, default_locale)
64+
65+
def add_common_locales(self, features, is_windows=False):
66+
# A list of locales needed by the test-suite.
67+
# The list uses the canonical name for the locale used in the test-suite
68+
# TODO: On Linux ISO8859 *may* needs to hyphenated.
69+
locales = [
70+
('en_US.UTF-8', 'English_United States.1252'),
71+
('fr_FR.UTF-8', 'French_France.1252'),
72+
('ru_RU.UTF-8', 'Russian_Russia.1251'),
73+
('zh_CN.UTF-8', 'Chinese_China.936'),
74+
('fr_CA.ISO8859-1', 'French_Canada.1252'),
75+
('cs_CZ.ISO8859-2', 'Czech_Czech Republic.1250')
76+
]
77+
for loc_id, windows_loc_name in locales:
78+
loc_name = windows_loc_name if is_windows else loc_id
79+
if self._test_locale(loc_name):
80+
features.add('locale.{0}'.format(loc_id))
81+
else:
82+
self.full_config.lit_config.warning('The locale {0} is not supported by '
83+
'your platform. Some tests will be '
84+
'unsupported.'.format(loc_name))
8685

8786

8887
class DarwinLocalTI(DefaultTargetInfo):
@@ -136,7 +135,7 @@ def get_platform(self):
136135
return (True, name, version)
137136

138137
def add_locale_features(self, features):
139-
add_common_locales(features, self.full_config.lit_config)
138+
self.add_common_locales(features)
140139

141140
def add_cxx_compile_flags(self, flags):
142141
if self.full_config.use_deployment:
@@ -182,7 +181,7 @@ def __init__(self, full_config):
182181
super(FreeBSDLocalTI, self).__init__(full_config)
183182

184183
def add_locale_features(self, features):
185-
add_common_locales(features, self.full_config.lit_config)
184+
self.add_common_locales(features)
186185

187186
def add_cxx_link_flags(self, flags):
188187
flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
@@ -193,7 +192,7 @@ def __init__(self, full_config):
193192
super(NetBSDLocalTI, self).__init__(full_config)
194193

195194
def add_locale_features(self, features):
196-
add_common_locales(features, self.full_config.lit_config)
195+
self.add_common_locales(features)
197196

198197
def add_cxx_link_flags(self, flags):
199198
flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lc++abi',
@@ -220,7 +219,7 @@ def platform_ver(self):
220219
return ver # Permitted to be None.
221220

222221
def add_locale_features(self, features):
223-
add_common_locales(features, self.full_config.lit_config)
222+
self.add_common_locales(features)
224223
# Some linux distributions have different locale data than others.
225224
# Insert the distributions name and name-version into the available
226225
# features to allow tests to XFAIL on them.
@@ -268,14 +267,30 @@ def add_cxx_link_flags(self, flags):
268267
# clang/lib/Driver/Tools.cpp
269268
flags += ['-lpthread', '-lrt', '-lm', '-ldl']
270269

270+
class LinuxRemoteTI(LinuxLocalTI):
271+
def __init__(self, full_config):
272+
super(LinuxRemoteTI, self).__init__(full_config)
273+
self.__cached_locales = None
274+
275+
def _test_locale(self, loc):
276+
if self.__cached_locales is None:
277+
self.full_config.lit_config.note('asking the remote host for supported locales...')
278+
_, out, err, exit_code = self.executor.execute_command_remote(['locale', '-a'])
279+
if exit_code != 0:
280+
raise RuntimeError(err)
281+
self.__cached_locales = out.splitlines()
282+
283+
# It is possible that the output will use 'en_US.utf8' instead of 'en_US.UTF-8',
284+
# so we check both variants.
285+
return loc in self.__cached_locales or \
286+
loc.replace('UTF-8', 'utf8') in self.__cached_locales
271287

272288
class WindowsLocalTI(DefaultTargetInfo):
273289
def __init__(self, full_config):
274290
super(WindowsLocalTI, self).__init__(full_config)
275291

276292
def add_locale_features(self, features):
277-
add_common_locales(features, self.full_config.lit_config,
278-
is_windows=True)
293+
self.add_common_locales(features, is_windows=True)
279294

280295
def use_lit_shell_default(self):
281296
# Default to the internal shell on Windows, as bash on Windows is

0 commit comments

Comments
 (0)