Skip to content

Commit

Permalink
Add no-workspace with/without plugins tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Corey committed Jul 4, 2023
1 parent a9200fb commit 62cabad
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 36 deletions.
38 changes: 31 additions & 7 deletions .github/workflows/regression_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ jobs:
# - name: Install Poetry
# uses: abatilo/actions-poetry@v2.0.0
# with:
# poetry-version: 1.3.2
# poetry-version: 1.1.14

- name: Setup Python Env - Metal
working-directory: python/origen_metal
Expand Down Expand Up @@ -153,10 +153,34 @@ jobs:
# TODO eventually want to move this into a poetry build step
# For now, manually move the binary. Also keeps us from having to mess with the path across OSs
# 'mv' command should be be fine for both linux & powershell
# - name: Move Origen executable (Linux)
# if: matrix.os == 'ubuntu-latest'
# run: mv rust/origen/target/debug/origen python/origen/origen/__bin__/bin
- name: Move Origen executable (Linux)
if: matrix.os == 'ubuntu-latest'
run: mv rust/origen/target/debug/origen python/origen/origen/__bin__/bin
- name: Move Origen executable (Windows)
if: matrix.os == 'windows-latest'
run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin

- name: Install Origen Packages
run:
pip install python/origen
pip install python/origen_metal

- name: Show Origen Binary Location (Linux)
run: which origen
- name: Show Origen Binary Location (Windows)
run: where.exe origen

# - name: Move Origen executable (Windows)
# if: matrix.os == 'windows-latest'
# run: mv rust/origen/target/debug/origen.exe python/origen/origen/__bin__/bin
# Should be no pyprojects in the root so far. Start with no-workspace tests
- name: Run No-Workspace-No-Plugins Tests
working-directory: test_apps/no_workspace
run: pytest test_no_workspace.py::TestNoWorkspaceNoPlugins -vv

- name: Install Plugins
run:
pip install test_apps/test_apps_shared_test_helpers
pip install test_apps/python_plugin
pip install python/origen_metal

- name: Run No-Workspace-With-Plugins Tests
working-directory: test_apps/no_workspace
run: pytest test_no_workspace.py::TestNoWorkspaceWithPlugins -vv
2 changes: 1 addition & 1 deletion python/origen/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ script = "poetry_build.py"
generate-setup-file = false

[tool.poetry.scripts]
o2 = 'origen.__bin__:run_origen'
origen = 'origen.__bin__:run_origen'

[tool.poetry.dependencies]
python = ">=3.7,<3.11"
Expand Down
4 changes: 2 additions & 2 deletions rust/origen/cli/src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub fn resolve_pyproject() -> Result<DependencySrc> {
}

log_trace!("No pyproject found. Skipping Poetry invocations...");
Ok(DependencySrc::None)
Ok(DependencySrc::NoneFound)
}

impl Config {
Expand All @@ -125,7 +125,7 @@ impl Config {
c.arg("-C");
c.arg(path);
}
DependencySrc::None => {}
DependencySrc::NoneFound => {}
}
} else {
log_error!("Dependency source has not been set - defaulting to global Python installation");
Expand Down
8 changes: 4 additions & 4 deletions rust/origen/src/core/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ pub enum DependencySrc {
Workspace(PathBuf), // current directory tree (in workspace)
UserGlobal(PathBuf), // explicitly given by user, no workspace
Global(PathBuf), // the origen CLI installation directory, no workspace
None, // None available. Use whatever is available in the same install environment as Origen itself
NoneFound, // None available. Use whatever is available in the same install environment as Origen itself
}

impl DependencySrc {
pub fn src_available(&self) -> bool {
match self {
Self::None => false,
Self::NoneFound => false,
_ => true,
}
}

pub fn src_file(&self) -> Option<&PathBuf> {
match self {
Self::App(path) | Self::Workspace(path) | Self::UserGlobal(path) | Self::Global(path) => Some(path),
Self::None => None,
Self::NoneFound => None,
}
}
}
Expand All @@ -99,7 +99,7 @@ where S: AsRef<str> {
"Workspace" => gen_case!(Workspace),
"UserGlobal" => gen_case!(UserGlobal),
"Global" => gen_case!(Global),
"None" => Self::None,
"None" => Self::NoneFound,
_ => bail!("Cannot convert value '{}' to dependency src type", value.0.as_ref())
})
}
Expand Down
4 changes: 2 additions & 2 deletions rust/pyapi/src/infrastructure/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub enum PyProjectSrc {
Workspace,
UserGlobal,
Global,
None,
NoneFound,
}

impl PyProjectSrc {
Expand All @@ -47,7 +47,7 @@ impl From<&DependencySrc> for PyProjectSrc {
DependencySrc::Workspace(_) => Self::Workspace,
DependencySrc::UserGlobal(_) => Self::UserGlobal,
DependencySrc::Global(_) => Self::Global,
DependencySrc::None => Self::None,
DependencySrc::NoneFound => Self::NoneFound,
}
}
}
4 changes: 4 additions & 0 deletions test_apps/no_workspace/eval_scripts/print_pl_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import origen
header = "--Origen Eval--"
print(header)
print(list(origen.plugins.keys()))
4 changes: 4 additions & 0 deletions test_apps/no_workspace/eval_scripts/print_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import origen
header = "--Origen Eval--"
print(header)
print(origen.status)
74 changes: 55 additions & 19 deletions test_apps/no_workspace/t_invocation_env.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# FOR_PR clean up
# Use the dev version but actual tests should be done through 'eval'.
import sys, pathlib
p = pathlib.Path(__file__).parent.parent.parent.joinpath("python/origen")
Expand All @@ -17,6 +18,9 @@
no_workspace_test_dir = pathlib.Path(__file__).parent
o2_root = no_workspace_test_dir.parent.parent
debug_cli_loc = o2_root.joinpath(f"rust/origen/target/debug/origen{'.exe' if origen.running_on_windows else ''}")
eval_scripts_dir = no_workspace_test_dir.joinpath("eval_scripts")
status_eval_script = eval_scripts_dir.joinpath("print_status.py")
pl_names_eval_script = eval_scripts_dir.joinpath("print_pl_names.py")

# Assume pip is installed in 'site-packages'
site_packages_dir = pathlib.Path(pip.__file__).parent.parent
Expand All @@ -30,45 +34,69 @@ class T_InvocationBaseTests(CLI):
@classmethod
def setup(cls):
cls.set_params()
cls.target_pyproj_toml = cls.target_pyproj_dir.joinpath(toml)
cls.target_poetry_lock = cls.target_pyproj_dir.joinpath(lockfile)
if cls.target_pyproj_dir:
cls.target_pyproj_toml = cls.target_pyproj_dir.joinpath(toml)
cls.target_poetry_lock = cls.target_pyproj_dir.joinpath(lockfile)
else:
cls.target_pyproj_toml = None
cls.target_poetry_lock = None

if not hasattr(cls, "file_based_evals"):
cls.file_based_evals = False
cls.cli_location = cls.cli_dir.joinpath(f"origen{'.exe' if origen.running_on_windows else ''}")

@property
def header(self):
return "--Origen Eval--"

def test_invocation_from_pytest(self):
assert origen.status["pyproject"] is None
assert origen.status["invocation"] is None

def eval_and_parse(self, code):
# out = CLI.global_cmds.eval.run(code, "-vv", run_opts={"return_details": True})
out = CLI.global_cmds.eval.run(code)
if isinstance(code, str):
code = [code]
print(code)
# out = CLI.global_cmds.eval.run(*code, run_opts={"return_details": True, "check": False})
out = CLI.global_cmds.eval.run(*code)
print(out)
out = out.split("\n")
idx = out.index(self.header)
return eval(out[idx+1])

def get_status(self):
if self.file_based_evals:
return self.eval_and_parse(["-f", status_eval_script])
else:
return self.eval_and_parse(f"print('{self.header}'); print(origen.status)")

def test_invocation_from_pytest(self):
assert origen.status["pyproject"] is None
assert origen.status["invocation"] is None

def test_pyproject_and_invocation_set(self):
code = f"print('{self.header}'); print(origen.status)"
# code = f"print('{self.header}'); print(origen.status)"
# code = r"print\(\\\"Origen\ Status:\\\"\) print\(origen.status\)"
status = self.eval_and_parse(code)
status = self.get_status()
print(status)
assert status["pyproject"] == self.target_pyproj_toml
assert status["invocation"] == self.invocation

def test_cli_location(self):
code = f"print('{self.header}'); print(origen.status)"
status = self.eval_and_parse(code)
# code = f"print('{self.header}'); print(origen.status)"
# status = self.eval_and_parse(code)
status = self.get_status()
assert status['cli_location'] == self.cli_location

class T_InvocationEnv(T_InvocationBaseTests):
@classmethod
def setup(cls):
def setup_method(cls):
super().setup()
# cls.set_params()
cls._pyproj_src_file = cls.gen_pyproj()
if cls.target_pyproj_dir:
cls._pyproj_src_file = cls.gen_pyproj()
if not hasattr(cls, "move_pyproject"):
cls.move_pyproject = True
if cls.target_pyproj_dir:
cls.move_pyproject = True
else:
cls.move_pyproject = False
# TODO clear any existing pyproject/poetry.locks ?
# cls._pyproj_lock = cls._pyproj_file.parent.joinpath("poetry.lock")
# for d in origen_exe_loc.parents:
Expand All @@ -81,11 +109,12 @@ def setup(cls):
target = cls.target_pyproj_dir.joinpath(toml)
print(f"Moving pyproject {cls._pyproj_src_file} to {target}")
shutil.copy(cls._pyproj_src_file, target)
subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir)
subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir)
if cls.target_pyproj_dir:
subprocess.run(["poetry", "--version"], check=True, cwd=cls.target_pyproj_dir)
subprocess.run(["poetry", "install"], check=True, cwd=cls.target_pyproj_dir)

@classmethod
def teardown(cls):
def teardown_method(cls):
if cls.move_pyproject:
print(f"Cleaning pyproject and lockfile {cls.target_pyproj_toml}, {cls.target_poetry_lock}")
cls.target_pyproj_toml.unlink()
Expand Down Expand Up @@ -118,13 +147,20 @@ def gen_pyproj(cls):
# # if id == "_origen_metal":
# assert isinstance(origen_metal._origen_metal, ModuleType)

def get_plugin_names(self):
if self.file_based_evals:
return self.eval_and_parse(["-f", pl_names_eval_script])
else:
return self.eval_and_parse(f"print('{self.header}'); print(list(origen.plugins.keys()))")

@pytest.mark.skip
def test_origen_h(self):
fail

def test_plugins(self):
code = f"print('{self.header}'); print(list(origen.plugins.keys()))"
pls = self.eval_and_parse(code)
# code = f"print('{self.header}'); print(list(origen.plugins.keys()))"
pls = self.get_plugin_names()
# pls = self.eval_and_parse(code)
if self.has_pls:
# TODO consistent plugin loading
assert set(pls) == {'pl_ext_cmds', 'test_apps_shared_test_helpers', 'python_plugin'}
Expand Down
27 changes: 27 additions & 0 deletions test_apps/no_workspace/test_no_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from .t_invocation_env import T_InvocationEnv, no_workspace_test_dir, PyProjectSrc, site_packages_dir

class TestNoWorkspaceNoPlugins(T_InvocationEnv):
user_install_dir = no_workspace_test_dir.joinpath("user_install")

@classmethod
def set_params(cls):
cls.target_pyproj_dir = None
cls.invocation = PyProjectSrc.NoneFound
cls.cli_dir = site_packages_dir.joinpath("origen/__bin__/bin")
cls.has_pls = False

@classmethod
def setup_method(cls):
cls.file_based_evals = True
super().setup_method()

class TestNoWorkspaceWithPlugins(TestNoWorkspaceNoPlugins):
@classmethod
def set_params(cls):
super().set_params()
cls.has_pls = True

def test_exts_in_user_global_context(self):
out = self.global_cmds.eval.run("1==1", "-b", "-a")
assert "Hi from python-plugin during 'eval'!" in out
assert "Hi again from python-plugin during 'eval'!" in out
2 changes: 1 addition & 1 deletion test_apps/pl_ext_cmds/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["Origen-SDK"]
[tool.poetry.dependencies]
python = ">=3.7,<3.11"
origen = { path = "../../python/origen", develop = true }
origen_metal = { path = "../../python/origen_metal", develop = true }
origen_metal = ">=0.0.0"

[tool.poetry.dev-dependencies]
pytest = "^3"
Expand Down

0 comments on commit 62cabad

Please sign in to comment.