Skip to content

Commit f1857f4

Browse files
committed
Revise tools scripts to be python3 compatible on win32
We introduce setup_stdio function to setup stdout/stderr properly. For python <-> python pipe, we always use 'utf8'/'ignore' encoding for not lost characters. For tty <-> python, we using native encoding with xmlcharrefreplace to encode, to preserve maximal information. For python <-> native program, we use naive encoding with 'ignore' to not cause error update_exclude_list with binary mode so that on win32 would not generate \r\n run-test-suite.py: Handling skiplist properly on win32 Fixes jerryscript-project#4854 Fixes test262-harness.py complain cannot use a string pattern on a bytes-like object with running test262 with python3 For reading/writing to file, we use 'utf8' /'ignore' encoding for not lost characters. For decoding from process stdout, using native encoding with decoding error ignored for not lost data. Execute commands also ignore errors Fixes jerryscript-project#4853 Fixes running test262-esnext failed with installed python3.9 on win32 with space in path Fixes jerryscript-project#4852 JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo [email protected]
1 parent 42e4229 commit f1857f4

File tree

6 files changed

+31
-8
lines changed

6 files changed

+31
-8
lines changed

tools/run-tests.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ def create_binary(job, options):
251251
subprocess.check_output(build_cmd)
252252
ret = 0
253253
except subprocess.CalledProcessError as err:
254-
print(err.output.decode("utf8"))
254+
# For python <-> native program, we use default encoding with error='ignore' to not lost data
255+
print(err.output.decode(errors="ignore"))
255256
ret = err.returncode
256257

257258
BINARY_CACHE[binary_key] = (ret, build_dir_path)
@@ -445,6 +446,7 @@ def run_buildoption_test(options):
445446
Check = collections.namedtuple('Check', ['enabled', 'runner', 'arg'])
446447

447448
def main(options):
449+
util.setup_stdio()
448450
checks = [
449451
Check(options.check_signed_off, run_check, [settings.SIGNED_OFF_SCRIPT]
450452
+ {'tolerant': ['--tolerant'], 'gh-actions': ['--gh-actions']}.get(options.check_signed_off, [])),

tools/runners/run-test-suite-test262.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ def update_exclude_list(args):
9191
# Tests pass in strict-mode but fail in non-strict-mode (or vice versa) should be considered as failures
9292
passing_tests = passing_tests - failing_tests
9393

94-
with open(args.excludelist_path, 'r+', encoding='utf8') as exclude_file:
94+
with open(args.excludelist_path, 'rb+') as exclude_file:
9595
lines = exclude_file.readlines()
9696
exclude_file.seek(0)
9797
exclude_file.truncate()
9898

9999
# Skip the last line "</excludeList>" to be able to insert new failing tests.
100100
for line in lines[:-1]:
101-
match = re.match(r" <test id=\"(\S*)\">", line)
101+
match = re.match(r" <test id=\"(\S*)\">", line.decode('utf-8', 'ignore'))
102102
if match:
103103
test = match.group(1)
104104
if test in failing_tests:
@@ -114,11 +114,12 @@ def update_exclude_list(args):
114114
if failing_tests:
115115
print("New failing tests added to the excludelist")
116116
for test in sorted(failing_tests):
117-
exclude_file.write(' <test id="' + test + '"><reason></reason></test>\n')
117+
line_added = ' <test id="' + test + '"><reason></reason></test>\n'
118+
exclude_file.write(line_added.encode('utf-8'))
118119
print(" " + test)
119120
print("")
120121

121-
exclude_file.write('</excludeList>\n')
122+
exclude_file.write('</excludeList>\n'.encode('utf-8'))
122123

123124
if new_passing_tests:
124125
print("New passing tests removed from the excludelist")
@@ -135,6 +136,7 @@ def update_exclude_list(args):
135136

136137

137138
def main(args):
139+
util.setup_stdio()
138140
return_code = prepare_test262_test_suite(args)
139141
if return_code:
140142
return return_code

tools/runners/run-test-suite.py

+3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def get_tests(test_dir, test_list, skip_list):
6666
tests.sort()
6767

6868
def filter_tests(test):
69+
test = test.replace('\\', '/')
6970
for skipped in skip_list:
7071
if skipped in test:
7172
return False
@@ -78,13 +79,15 @@ def execute_test_command(test_cmd):
7879
kwargs = {}
7980
if sys.version_info.major >= 3:
8081
kwargs['encoding'] = 'unicode_escape'
82+
kwargs['errors'] = 'ignore'
8183
with subprocess.Popen(test_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
8284
universal_newlines=True, **kwargs) as process:
8385
stdout, _ = process.communicate()
8486
return process.returncode, stdout
8587

8688

8789
def main(args):
90+
util.setup_stdio()
8891
tests = get_tests(args.test_dir, args.test_list, args.skip_list)
8992
total = len(tests)
9093
if total == 0:

tools/runners/run-unittests.py

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def get_unittests(path):
4949

5050

5151
def main(args):
52+
util.setup_stdio()
5253
unittests = get_unittests(args.path)
5354
total = len(unittests)
5455
if total == 0:

tools/runners/test262-harness.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
import signal
5656
import multiprocessing
5757

58+
import util
59+
5860
#######################################################################
5961
# based on _monkeyYaml.py
6062
#######################################################################
@@ -490,8 +492,8 @@ def __init__(self, suite, name, full_path, strict_mode, command_template, module
490492
self.name = name
491493
self.full_path = full_path
492494
self.strict_mode = strict_mode
493-
with open(self.full_path, "r", newline='', encoding='utf8') as file_desc:
494-
self.contents = file_desc.read()
495+
with open(self.full_path, "rb") as file_desc:
496+
self.contents = file_desc.read().decode("utf8", "ignore")
495497
test_record = parse_test_record(self.contents, name)
496498
self.test = test_record["test"]
497499
del test_record["test"]
@@ -901,6 +903,7 @@ def list_includes(self, tests):
901903

902904

903905
def main():
906+
util.setup_stdio()
904907
code = 0
905908
parser = build_options()
906909
options = parser.parse_args()

tools/runners/util.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import codecs
1516
import signal
1617
import subprocess
1718
import sys
@@ -42,6 +43,17 @@ def set_sighdl_to_reset_timezone(timezone):
4243
signal.signal(signal.SIGINT, lambda signal, frame: set_timezone_and_exit(timezone))
4344

4445

46+
def setup_stdio():
47+
(out_stream, err_stream) = (sys.stdout, sys.stderr)
48+
if sys.version_info.major >= 3:
49+
(out_stream, err_stream) = (sys.stdout.buffer, sys.stderr.buffer)
50+
# For tty using native encoding, otherwise (pipe) use 'utf-8'
51+
encoding = sys.stdout.encoding if sys.stdout.isatty() else 'utf-8'
52+
# Always override it to anvoid encode error
53+
sys.stdout = codecs.getwriter(encoding)(out_stream, 'xmlcharrefreplace')
54+
sys.stderr = codecs.getwriter(encoding)(err_stream, 'xmlcharrefreplace')
55+
56+
4557
def print_test_summary(summary_string, total, passed, failed):
4658
print(f"\n[summary] {summary_string}\n")
4759
print(f"TOTAL: {total}")
@@ -72,4 +84,4 @@ def get_platform_cmd_prefix():
7284

7385
def get_python_cmd_prefix():
7486
# python script doesn't have execute permission on github actions windows runner
75-
return get_platform_cmd_prefix() + [sys.executable or 'python']
87+
return [sys.executable or 'python']

0 commit comments

Comments
 (0)