Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@

import argparse
import atexit
import datetime
import fnmatch
import glob
import logging
import math
import operator
import os
import random
import re
import subprocess
import sys
import time
import unittest
Expand All @@ -44,7 +47,7 @@
from common import errlog
from single_line_runner import SingleLineTestRunner

from tools import colored_logger, config, shared, utils
from tools import building, colored_logger, config, shared, utils

logger = logging.getLogger("runner")

Expand Down Expand Up @@ -506,6 +509,7 @@ def parse_args():
'Useful when combined with --failfast')
parser.add_argument('--force64', action='store_true')
parser.add_argument('--crossplatform-only', action='store_true')
parser.add_argument('--log-test-environment', action='store_true', help='Prints out detailed information about the current environment. Useful for adding more info to CI test runs.')
parser.add_argument('--force-browser-process-termination', action='store_true', help='If true, a fail-safe method is used to ensure that all browser processes are terminated before and after the test suite run. Note that this option will terminate all browser processes, not just those launched by the harness, so will result in loss of all open browsing sessions.')
parser.add_argument('--repeat', type=int, default=1,
help='Repeat each test N times (default: 1).')
Expand Down Expand Up @@ -563,6 +567,95 @@ def cleanup_emscripten_temp():
pass


def print_repository_info(directory, repository_name):
current_commit = utils.run_process(['git', 'show', '--no-patch'], cwd=directory, stdout=subprocess.PIPE, text=True).stdout.strip()
print(f'\n{repository_name} {current_commit}\n')
local_changes = utils.run_process(['git', 'diff'], cwd=directory, stdout=subprocess.PIPE, text=True).stdout.strip()
if local_changes:
print(f'\n{local_changes}\n')


def log_test_environment():
"""Print detailed information about the current test environment. Useful for
logging test run configuration in a CI."""
print('======================== Test Setup ========================')
print(f'Test time: {datetime.datetime.now(datetime.timezone.utc).strftime("%A, %B %d, %Y %H:%M:%S %Z")}')
print(f'Python: "{sys.executable}". Version: {sys.version}')
print(f'Emscripten test runner path: "{os.path.realpath(__file__)}"')

if os.path.isdir(os.path.join(__rootpath__, '.git')):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utils.path_from_root('.git')

print(f'\nEmscripten repository: "{__rootpath__}"')

emscripten_version = utils.path_from_root('emscripten-version.txt')
if os.path.isfile(emscripten_version):
print(f'emscripten-version.txt: {utils.EMSCRIPTEN_VERSION}')

if os.path.isdir(os.path.join(__rootpath__, '.git')):
print_repository_info(__rootpath__, 'Emscripten')

print(f'EM_CONFIG: "{config.EM_CONFIG}"')
if os.path.isfile(config.EM_CONFIG):
print(f'\n{utils.read_file(config.EM_CONFIG).strip()}\n')

node_js_version = utils.run_process(config.NODE_JS + ['--version'], stdout=subprocess.PIPE, text=True).stdout.strip()
print(f'NODE_JS: {config.NODE_JS}. Version: {node_js_version}')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have this available via utils.get_node_version()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's shared.get_node_version(), but that parses the output. I think it's better in this case to output the raw version string as emitted by NODE_JS --version.


print(f'BINARYEN_ROOT: {config.BINARYEN_ROOT}')
wasm_opt_version = building.get_binaryen_version(building.get_binaryen_bin()).strip()
print(f'wasm-opt version: {wasm_opt_version}')

binaryen_git_dir = config.BINARYEN_ROOT
# Detect emsdk directory structure (build root vs source root)
if re.match(r'main_.*_64bit_binaryen', os.path.basename(binaryen_git_dir)):
binaryen_git_dir = os.path.realpath(os.path.join(binaryen_git_dir, '..', 'main'))
if os.path.isdir(os.path.join(binaryen_git_dir, '.git')):
print(f'Binaryen git directory: "{binaryen_git_dir}"')
print_repository_info(binaryen_git_dir, 'Binaryen')

print(f'LLVM_ROOT: {config.LLVM_ROOT}')

# Find LLVM git directory in emsdk aware fashion
def find_llvm_git_root(dir):
while True:
if os.path.isdir(os.path.join(dir, ".git")):
return dir
if os.path.isdir(os.path.join(dir, "src", ".git")):
return os.path.join(dir, "src")
if os.path.dirname(dir) == dir:
return None
dir = os.path.dirname(dir)

llvm_git_root = find_llvm_git_root(config.LLVM_ROOT)
if llvm_git_root:
print(f'LLVM git directory: "{llvm_git_root}"')
print_repository_info(llvm_git_root, 'LLVM')

clang_version = utils.run_process([shared.CLANG_CC, '--version'], stdout=subprocess.PIPE, text=True).stdout.strip()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need text=True here, or above

print(f'Clang: "{shared.CLANG_CC}"\n{clang_version}\n')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have shared.get_clang_version() for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That too parses the output - it would be preferable to print the raw output here.


print(f'EMTEST_BROWSER: {browser_common.EMTEST_BROWSER}')
if browser_common.is_firefox():
print(f'Firefox version: {browser_common.get_firefox_version()}')
else:
print('Not detected as a Firefox browser')
if browser_common.is_safari():
print(f'Safari version: {browser_common.get_safari_version()}')
else:
print('Not detected as a Safari browser')
if browser_common.is_chrome():
print(f'Browser is Chrome.')
else:
print('Not detected as a Chrome browser')

emsdk_dir = os.getenv('EMSDK')
print(f'\nEMSDK: "{emsdk_dir}"')
if emsdk_dir:
if os.path.isdir(os.path.join(emsdk_dir, '.git')):
print_repository_info(emsdk_dir, 'Emsdk')

print('==================== End of Test Setup =====================')


def main():
options = parse_args()

Expand Down Expand Up @@ -606,6 +699,9 @@ def set_env(name, option_value):

browser_common.init(options.force_browser_process_termination)

if options.log_test_environment:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we should probably print all this into in circle CI too. The best way to do that is probably to add or os.getenv('CI').

log_test_environment()

def prepend_default(arg):
if arg.startswith('test_'):
return default_core_test_mode + '.' + arg
Expand Down
8 changes: 6 additions & 2 deletions tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -1189,14 +1189,18 @@ def get_binaryen_feature_flags():
return ['--detect-features']


def check_binaryen(bindir):
def get_binaryen_version(bindir):
opt = os.path.join(bindir, utils.exe_suffix('wasm-opt'))
if not os.path.exists(opt):
exit_with_error('binaryen executable not found (%s). Please check your binaryen installation' % opt)
try:
output = run_process([opt, '--version'], stdout=PIPE).stdout
return run_process([opt, '--version'], stdout=PIPE).stdout
except subprocess.CalledProcessError:
exit_with_error('error running binaryen executable (%s). Please check your binaryen installation' % opt)


def check_binaryen(bindir):
output = get_binaryen_version(bindir)
if output:
output = output.splitlines()[0]
try:
Expand Down