-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Kamil Śliwak <[email protected]>
- Loading branch information
Showing
3 changed files
with
192 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import subprocess | ||
|
||
def run_cmd(command: str, env: dict = None, logfile: str = None) -> int: | ||
""" | ||
Args: | ||
command: command to run | ||
logfile: log file name | ||
env: dictionary holding key-value pairs for bash environment variables | ||
Returns: | ||
int: The exit status of the command. Exit status codes are: | ||
0 -> Success | ||
1-255 -> Failure | ||
""" | ||
if logfile is None: | ||
logfile = os.devnull | ||
if env is None: | ||
env = os.environ.copy() | ||
with open( | ||
file=logfile, | ||
mode='w', | ||
encoding='utf8' | ||
) as log: | ||
ret = subprocess.run( | ||
command, | ||
shell=True, | ||
check=True, | ||
executable='/bin/bash', | ||
env=env, | ||
stdout=log if not logfile else None, | ||
stderr=None | ||
) | ||
return ret.returncode |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# ------------------------------------------------------------------------------ | ||
# This file is part of solidity. | ||
# | ||
# solidity is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# solidity is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with solidity. If not, see <http://www.gnu.org/licenses/> | ||
# | ||
# (c) 2023 solidity contributors. | ||
# ------------------------------------------------------------------------------ | ||
|
||
from argparse import ArgumentParser, Namespace | ||
import os | ||
from pathlib import Path | ||
import sys | ||
|
||
# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it | ||
# pragma pylint: disable=import-error,wrong-import-position | ||
SCRIPTS_DIR = Path(__file__).parents[1] / "scripts" | ||
sys.path.insert(0, str(SCRIPTS_DIR)) | ||
|
||
from common.shell_command import run_cmd | ||
|
||
EXTERNAL_TESTS_DIR = Path(__file__).parent / "externalTests" | ||
|
||
|
||
class ExternalTestNotFound(Exception): | ||
pass | ||
|
||
|
||
def detect_external_tests() -> dict: | ||
# TODO: Remove `file_path.stem != "common"` when we complete the migration | ||
# of the external tests to python, since there will be no more | ||
# common.sh script in the externalTests folder. | ||
return { | ||
file_path.stem: file_path | ||
for file_path in Path(EXTERNAL_TESTS_DIR).iterdir() | ||
if file_path.is_file() and file_path.suffix == ".sh" and file_path.stem != "common" | ||
} | ||
|
||
|
||
def display_available_external_tests(_) -> int: | ||
print("Available external tests:") | ||
print(*detect_external_tests().keys()) | ||
|
||
|
||
def run_test_scripts(solc_binary_type: str, solc_binary_path: Path, tests: dict) -> int: | ||
for test_name, test_script_path in tests.items(): | ||
print(f"Running {test_name} external test...") | ||
subprocess.run( | ||
[test_script_path, solc_binary_type, solc_binary_path], | ||
check=True | ||
) | ||
|
||
|
||
def run_external_tests(args: dict) -> int: | ||
solc_binary_type = args["solc_binary_type"] | ||
solc_binary_path = args["solc_binary_path"] | ||
|
||
all_test_scripts = detect_external_tests() | ||
if args["run_all"]: | ||
return run_test_scripts(solc_binary_type, solc_binary_path, all_test_scripts) | ||
else: | ||
selected_tests = args["selected_tests"] | ||
if selected_tests: | ||
unrecognized_tests = set(selected_tests) - set(all_test_scripts.keys()) | ||
if unrecognized_tests != set(): | ||
raise ExternalTestNotFound( | ||
f"External test(s) not found: {', '.join(unrecognized_tests)}" | ||
) | ||
return run_test_scripts( | ||
solc_binary_type, | ||
solc_binary_path, | ||
{k: all_test_scripts[k] for k in selected_tests}, | ||
) | ||
raise ExternalTestNotFound( | ||
"External test was not selected. Please use --run or --run-all option" | ||
) | ||
|
||
|
||
def parse_commandline() -> Namespace: | ||
script_description = "Script to run external Solidity tests." | ||
|
||
parser = ArgumentParser(description=script_description) | ||
subparser = parser.add_subparsers() | ||
list_command = subparser.add_parser( | ||
"list", | ||
help="List all available external tests.", | ||
) | ||
list_command.set_defaults(cmd=display_available_external_tests) | ||
|
||
run_command = subparser.add_parser( | ||
"test", | ||
help="Run external tests.", | ||
) | ||
run_command.set_defaults(cmd=run_external_tests) | ||
|
||
run_command.add_argument( | ||
"--solc-binary-type", | ||
dest="solc_binary_type", | ||
type=str, | ||
required=True, | ||
choices=["native", "solcjs"], | ||
help="Type of the solidity compiler binary to be used.", | ||
) | ||
run_command.add_argument( | ||
"--solc-binary-path", | ||
dest="solc_binary_path", | ||
type=Path, | ||
required=True, | ||
help="Path to the solidity compiler binary.", | ||
) | ||
|
||
running_mode = run_command.add_mutually_exclusive_group() | ||
running_mode.add_argument( | ||
"--run", | ||
metavar="TEST_NAME", | ||
dest="selected_tests", | ||
nargs="+", | ||
default=[], | ||
help="List of one or more external tests to run (separated by sapce).", | ||
) | ||
running_mode.add_argument( | ||
"--run-all", | ||
dest="run_all", | ||
default=False, | ||
action="store_true", | ||
help="Run all available external tests.", | ||
) | ||
|
||
return parser.parse_args() | ||
|
||
|
||
def main(): | ||
try: | ||
args = parse_commandline() | ||
args.cmd(vars(args)) | ||
return os.EX_OK | ||
except ExternalTestNotFound as exception: | ||
print(f"Error: {exception}", file=sys.stderr) | ||
return os.EX_NOINPUT | ||
except RuntimeError as exception: | ||
print(f"Error: {exception}", file=sys.stderr) | ||
return 1 | ||
|
||
|
||
if __name__ == "__main__": | ||
sys.exit(main()) |