Skip to content

Commit

Permalink
Merge pull request #411 from multiversx/contract-test-using-sc-meta
Browse files Browse the repository at this point in the history
Modify contract test command to use sc-meta
  • Loading branch information
andreibancioiu authored Sep 16, 2024
2 parents a63926c + 587bac1 commit 689fba6
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-13, macos-13-xlarge]
python-version: [3.11]

steps:
Expand Down
23 changes: 9 additions & 14 deletions multiversx_sdk_cli/cli_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ def setup_parser(args: List[str], subparsers: Any) -> Any:
sub.add_argument("--path", default=os.getcwd(), help="the project directory (default: current directory)")
sub.set_defaults(func=clean)

sub = cli_shared.add_command_subparser(subparsers, "contract", "test", "Run scenarios (tests).")
_add_project_arg(sub)
sub.add_argument("--directory", default="scenarios",
help="🗀 the directory containing the tests (default: %(default)s)")
sub.add_argument("--wildcard", required=False, help="wildcard to match only specific test files")
_add_recursive_arg(sub)
sub = cli_shared.add_command_subparser(subparsers, "contract", "test", "Run tests.")
sub.add_argument("--path", default=os.getcwd(),
help="the directory of the contract (default: %(default)s)")
sub.add_argument("--go", action="store_true",
help="this arg runs rust and go tests (default: false)")
sub.add_argument("--scen", action="store_true", help="this arg runs scenarios (default: false). If `--scen` and `--go` are both specified, scen overrides the go argument")
sub.add_argument("--nocapture", action="store_true", help="this arg prints the entire output of the vm (default: false)")
sub.set_defaults(func=run_tests)

sub = cli_shared.add_command_subparser(subparsers, "contract", "report", "Print a detailed report of the smart contracts.")
Expand Down Expand Up @@ -176,7 +177,7 @@ def setup_parser(args: List[str], subparsers: Any) -> Any:

def _add_project_arg(sub: Any):
sub.add_argument("project", nargs='?', default=os.getcwd(),
help="🗀 the project directory (default: current directory)")
help="the project directory (default: current directory)")


def _add_build_options_sc_meta(sub: Any):
Expand Down Expand Up @@ -217,10 +218,6 @@ def _add_build_options_args(sub: Any):
help="for rust projects, optionally specify the suffix of the wasm bytecode output file")


def _add_recursive_arg(sub: Any):
sub.add_argument("-r", "--recursive", dest="recursive", action="store_true", help="locate projects recursively")


def _add_bytecode_arg(sub: Any):
sub.add_argument("--bytecode", type=str, required=True,
help="the file containing the WASM bytecode")
Expand Down Expand Up @@ -312,9 +309,7 @@ def do_report(args: Any):

def run_tests(args: Any):
check_if_rust_is_installed()
project_paths = get_project_paths(args)
for project in project_paths:
projects.run_tests(project, args)
projects.run_tests(args)


def deploy(args: Any):
Expand Down
2 changes: 1 addition & 1 deletion multiversx_sdk_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MetaChainSystemSCsCost:
def get_dependency_resolution(key: str) -> str:
try:
return get_value(f"dependencies.{key}.resolution")
except:
except Exception:
return ""


Expand Down
4 changes: 1 addition & 3 deletions multiversx_sdk_cli/dependencies/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from multiversx_sdk_cli import config, errors
from multiversx_sdk_cli.dependencies.modules import (DependencyModule,
GolangModule, Rust,
TestWalletsModule,
VMToolsModule)
TestWalletsModule)

logger = logging.getLogger("install")

Expand Down Expand Up @@ -51,7 +50,6 @@ def get_all_deps() -> List[DependencyModule]:
return [
Rust(key="rust"),
GolangModule(key="golang"),
VMToolsModule(key="vmtools"),
TestWalletsModule(key="testwallets")
]

Expand Down
73 changes: 18 additions & 55 deletions multiversx_sdk_cli/dependencies/modules.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import os
import platform
import shutil
from os import path
from pathlib import Path
Expand Down Expand Up @@ -135,59 +136,6 @@ def _get_archive_path(self, tag: str) -> Path:
return archive


class VMToolsModule(StandaloneModule):
def __init__(self, key: str, aliases: List[str] = []):
super().__init__(key, aliases)
self.repo_name = 'mx-chain-vm-go'
self.organisation = 'multiversx'

def _post_install(self, tag: str):
dependencies.install_module('golang')

self.build_binary(tag, 'test')
self.make_binary_symlink_in_parent_folder(tag, 'test', 'run-scenarios')
self.copy_libwasmer_in_parent_directory(tag)

def build_binary(self, tag: str, binary_name: str):
source_folder = self.binary_source_folder(tag, binary_name)
golang = dependencies.get_module_by_key("golang")
golang_env = golang.get_env()
myprocess.run_process(['go', 'build'], cwd=source_folder, env=golang_env)

def binary_source_folder(self, tag: str, binary_name: str):
directory = self.get_source_directory(tag)
return directory / 'cmd' / binary_name

def make_binary_symlink_in_parent_folder(self, tag: str, binary_name: str, symlink_name: str):
source_folder = self.binary_source_folder(tag, binary_name)
binary = source_folder / binary_name

parent = self.get_parent_directory()
symlink = parent / symlink_name

symlink.unlink(missing_ok=True)
symlink.symlink_to(binary)

def copy_libwasmer_in_parent_directory(self, tag: str):
libwasmer_directory = self.get_source_directory(tag) / 'wasmer'
cmd_test_directory = self.get_source_directory(tag) / 'cmd' / 'test'
parent_directory = self.get_parent_directory()
for f in libwasmer_directory.iterdir():
if f.suffix in ['.dylib', '.so', '.dll']:
# Copy the dynamic library near the "run-scenarios" symlink
shutil.copy(f, parent_directory)
# Though, also copy the dynamic library near the target executable (seems to be necessary on MacOS)
shutil.copy(f, cmd_test_directory)

def get_env(self) -> Dict[str, str]:
return dict()

def get_source_directory(self, tag: str) -> Path:
directory = self.get_directory(tag)
first_subdirectory = next(directory.iterdir())
return first_subdirectory


class GolangModule(StandaloneModule):
def _post_install(self, tag: str):
parent_directory = self.get_parent_directory()
Expand Down Expand Up @@ -244,11 +192,13 @@ def is_installed(self, tag: str) -> bool:
which_rustc = shutil.which("rustc")
which_cargo = shutil.which("cargo")
which_sc_meta = shutil.which("sc-meta")
which_mx_scenario_go = shutil.which("mx-scenario-go")
which_wasm_opt = shutil.which("wasm-opt")
which_twiggy = shutil.which("twiggy")
logger.info(f"which rustc: {which_rustc}")
logger.info(f"which cargo: {which_cargo}")
logger.info(f"which sc-meta: {which_sc_meta}")
logger.info(f"which mx-scenario-go: {which_mx_scenario_go}")
logger.info(f"which wasm-opt: {which_wasm_opt}")
logger.info(f"which twiggy: {which_twiggy}")

Expand Down Expand Up @@ -291,6 +241,7 @@ def install(self, overwrite: bool) -> None:
self._install_sc_meta()
self._install_wasm_opt()
self._install_twiggy()
self._install_sc_meta_deps()

def _check_install_env(self, apply_correction: bool = True):
"""
Expand All @@ -304,15 +255,15 @@ def _check_install_env(self, apply_correction: bool = True):
This may cause problems with the installation.""")

if apply_correction:
show_warning(f"CARGO_HOME will be temporarily unset.")
show_warning("CARGO_HOME will be temporarily unset.")
os.environ["CARGO_HOME"] = ""

if current_rustup_home:
show_warning(f"""RUSTUP_HOME variable is set to: {current_rustup_home}.
This may cause problems with the installation of rust.""")

if apply_correction:
show_warning(f"RUSTUP_HOME will be temporarily unset.")
show_warning("RUSTUP_HOME will be temporarily unset.")
os.environ["RUSTUP_HOME"] = ""

def _install_rust(self, tag: str) -> None:
Expand Down Expand Up @@ -359,6 +310,18 @@ def _install_twiggy(self):

myprocess.run_process(args, env=self.get_cargo_env())

def _install_sc_meta_deps(self):
# this is needed for sc-meta to run the tests
# if os is Windows skip installation
os = platform.system().lower()
if os == "windows":
logger.warning("`sc-meta install all` command is not supported on windows")
return

logger.info("Installing sc-meta dependencies.")
args = ["sc-meta", "install", "all"]
myprocess.run_process(args)

def _get_installer_url(self) -> str:
if workstation.is_windows():
return "https://win.rustup.rs"
Expand Down
17 changes: 7 additions & 10 deletions multiversx_sdk_cli/projects/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path
from typing import Any, List

from multiversx_sdk_cli import dependencies, errors, guards
from multiversx_sdk_cli import errors, guards
from multiversx_sdk_cli.projects import shared
from multiversx_sdk_cli.projects.constants import (OLD_PROJECT_CONFIG_FILENAME,
PROJECT_CONFIG_FILENAME)
Expand Down Expand Up @@ -42,17 +42,14 @@ def clean_project(directory: Path):
logger.info("Project cleaned.")


def run_tests(project_path: Path, args: Any):
directory = Path(args.directory)
wildcard = args.wildcard
def run_tests(args: Any):
directory = Path(args.path)

logger.info("run_tests.project: %s", project_path)
logger.info("run_tests.project: %s", directory)

dependencies.install_module("vmtools")

guards.is_directory(project_path)
project = load_project(project_path)
project.run_tests(directory, wildcard)
guards.is_directory(directory)
project = load_project(directory)
project.run_tests(args)


def get_project_paths_recursively(base_path: Path) -> List[Path]:
Expand Down
37 changes: 17 additions & 20 deletions multiversx_sdk_cli/projects/project_base.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import glob
import logging
import shutil
from abc import abstractmethod
from os import path
from pathlib import Path
from typing import Any, Dict, List, Union, cast, final
from typing import Any, Dict, List, Union, final

from multiversx_sdk_cli import dependencies, errors, myprocess, utils
from multiversx_sdk_cli.dependencies.modules import StandaloneModule
from multiversx_sdk_cli.projects.constants import PROJECT_CONFIG_FILENAME
from multiversx_sdk_cli.projects.interfaces import IProject
from multiversx_sdk_cli.projects.migrations import migrate_project_config_file
Expand Down Expand Up @@ -129,23 +127,22 @@ def ensure_config_file(self) -> None:
def default_config(self) -> Dict[str, Any]:
return dict()

def run_tests(self, tests_directory: Path, wildcard: str = ""):
vmtools = cast(StandaloneModule, dependencies.get_module_by_key("vmtools"))
tool_env = vmtools.get_env()
tool = path.join(vmtools.get_parent_directory(), "run-scenarios")
test_folder = self.directory / tests_directory

if not wildcard:
args = [tool, str(test_folder)]
myprocess.run_process(args, env=tool_env)
else:
pattern = test_folder / wildcard
test_files = glob.glob(str(pattern))

for test_file in test_files:
print("Run test for:", test_file)
args = [tool, test_file]
myprocess.run_process(args, env=tool_env)
def run_tests(self, args: Any):
command = ["sc-meta", "test"]

if args.path:
command.extend(["--path", str(Path(args.path).expanduser())])

if args.go:
command.append("--go")

if args.scen:
command.append("--scen")

if args.nocapture:
command.append("--nocapture")

myprocess.run_process(command)


def glob_files(folder: Path, pattern: str) -> List[Path]:
Expand Down
4 changes: 2 additions & 2 deletions multiversx_sdk_cli/tests/test_cli_contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ testBuildContracts() {

testRunScenarios() {
echo "testRunScenarios"
${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/adder || return 1
${CLI} --verbose contract test --directory="scenarios" ${SANDBOX}/empty || return 1
${CLI} --verbose contract test --path=${SANDBOX}/adder || return 1
${CLI} --verbose contract test --path=${SANDBOX}/empty || return 1
}

testWasmName() {
Expand Down
12 changes: 0 additions & 12 deletions multiversx_sdk_cli/tests/test_cli_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,6 @@ def test_deps_check_rust():
assert which_twiggy and Path.is_file(Path(which_twiggy))


@pytest.mark.skip_on_windows
def test_deps_install_vmtools():
return_code = main(["deps", "install", "vmtools"])
assert return_code == 0


@pytest.mark.skip_on_windows
def test_deps_check_vmtools():
return_code = main(["deps", "check", "vmtools"])
assert return_code == 0


def test_deps_install_testwallets():
return_code = main(["deps", "install", "testwallets"])
assert return_code == 0
Expand Down

0 comments on commit 689fba6

Please sign in to comment.