mirror of
https://github.com/ivan-usov-org/bec.git
synced 2025-04-20 01:40:02 +02:00
194 lines
6.6 KiB
Python
194 lines
6.6 KiB
Python
import importlib
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
import pytest
|
|
from pytest import TempPathFactory
|
|
|
|
from bec_lib import metadata_schema, plugin_helper
|
|
|
|
|
|
def install(package):
|
|
subprocess.check_call([sys.executable, "-m", "pip", "-v", "install", package])
|
|
|
|
|
|
def uninstall(package):
|
|
subprocess.check_call([sys.executable, "-m", "pip", "uninstall", "-y", package])
|
|
|
|
|
|
TEST_SCHEMA_FILE = """
|
|
from bec_lib.metadata_schema import BasicScanMetadata
|
|
|
|
class ExampleSchema(BasicScanMetadata):
|
|
treatment_description: str
|
|
treatment_temperature_k: int
|
|
|
|
"""
|
|
|
|
TEST_SCHEMA_REGISTRY = """
|
|
from .example_schema import ExampleSchema
|
|
|
|
METADATA_SCHEMA_REGISTRY = {
|
|
"test_scan_fail_on_type": "FailOnType",
|
|
"example_scan": ExampleSchema,
|
|
}
|
|
|
|
DEFAULT_SCHEMA = None
|
|
|
|
"""
|
|
|
|
TEST_SCAN_CLASS = """
|
|
from bec_server.scan_server.scans import ScanBase
|
|
class ScanForTesting(ScanBase):
|
|
...
|
|
"""
|
|
|
|
|
|
class TestPluginSystem:
|
|
|
|
@pytest.fixture(scope="class", autouse=True)
|
|
def setup_env(self, tmp_path_factory: TempPathFactory):
|
|
print("\n\nSetting up plugin for tests: generating files...\n")
|
|
TestPluginSystem._tmp_plugin_dir = tmp_path_factory.mktemp("test_plugin")
|
|
TestPluginSystem._tmp_plugin_name = TestPluginSystem._tmp_plugin_dir.name
|
|
TestPluginSystem._plugin_script = (
|
|
os.path.dirname(os.path.abspath(__file__))
|
|
+ "/../util_scripts/create_plugin_structure.py"
|
|
)
|
|
print("Done. Modifying files with test code...\n")
|
|
# run plugin generation script
|
|
subprocess.check_call(
|
|
[sys.executable, TestPluginSystem._plugin_script, str(TestPluginSystem._tmp_plugin_dir)]
|
|
)
|
|
|
|
# add some test things
|
|
with open(
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ f"{TestPluginSystem._tmp_plugin_name}/scans/__init__.py",
|
|
"w+",
|
|
) as f:
|
|
f.write(TEST_SCAN_CLASS)
|
|
|
|
with open(
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ f"{TestPluginSystem._tmp_plugin_name}/scans/metadata_schema/metadata_schema_registry.py",
|
|
"w",
|
|
) as f:
|
|
f.write(TEST_SCHEMA_REGISTRY)
|
|
|
|
with open(
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ f"{TestPluginSystem._tmp_plugin_name}/scans/metadata_schema/example_schema.py",
|
|
"w",
|
|
) as f:
|
|
f.write(TEST_SCHEMA_FILE)
|
|
|
|
print("\nDone. Installing into environment...\n")
|
|
|
|
# install into current environment
|
|
install(TestPluginSystem._tmp_plugin_dir)
|
|
importlib.invalidate_caches()
|
|
plugin_helper._get_available_plugins.cache_clear()
|
|
plugin_helper.get_metadata_schema_registry.cache_clear()
|
|
|
|
piplist = subprocess.Popen(("pip", "list"), stdout=subprocess.PIPE)
|
|
output = subprocess.check_output(("grep", "test_plugin"), stdin=piplist.stdout)
|
|
piplist.wait()
|
|
print("$ pip list | grep test_plugin: \n" + output.decode("utf-8"))
|
|
|
|
print("Done. Yielding to test class...\n")
|
|
|
|
yield
|
|
|
|
print("\n\nDone. Uninstalling test plugin:\n")
|
|
|
|
uninstall(TestPluginSystem._tmp_plugin_name)
|
|
importlib.invalidate_caches()
|
|
plugin_helper._get_available_plugins.cache_clear()
|
|
metadata_schema._METADATA_SCHEMA_REGISTRY = {}
|
|
del sys.modules["bec_lib.metadata_schema"]
|
|
TestPluginSystem._tmp_plugin_dir = None
|
|
|
|
def test_generated_files_in_plugin_deployment(self):
|
|
files = os.listdir(TestPluginSystem._tmp_plugin_dir)
|
|
for file in [
|
|
TestPluginSystem._tmp_plugin_name,
|
|
"pyproject.toml",
|
|
".git_hooks",
|
|
".gitignore",
|
|
"LICENSE",
|
|
"tests",
|
|
"bin",
|
|
".gitlab-ci.yml",
|
|
]:
|
|
assert file in files
|
|
files = os.listdir(TestPluginSystem._tmp_plugin_dir / TestPluginSystem._tmp_plugin_name)
|
|
for file in ["scans"]:
|
|
assert file in files
|
|
|
|
def test_test_created_files_in_plugin_deployment(self):
|
|
files = os.listdir(
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ f"{TestPluginSystem._tmp_plugin_name}/scans/metadata_schema"
|
|
)
|
|
for file in ["example_schema.py", "metadata_schema_registry.py"]:
|
|
assert file in files
|
|
|
|
def test_plugin_module_import_from_generated_file(self):
|
|
try:
|
|
package_spec = importlib.util.spec_from_file_location(
|
|
TestPluginSystem._tmp_plugin_name,
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ TestPluginSystem._tmp_plugin_name
|
|
/ "__init__.py",
|
|
)
|
|
plugin_module = importlib.util.module_from_spec(package_spec)
|
|
package_spec.loader.exec_module(plugin_module)
|
|
|
|
md_reg_mod_name = (
|
|
TestPluginSystem._tmp_plugin_name
|
|
+ ".scans.metadata_schema.metadata_schema_registry"
|
|
)
|
|
md_reg_spec = importlib.util.spec_from_file_location(
|
|
md_reg_mod_name,
|
|
TestPluginSystem._tmp_plugin_dir
|
|
/ TestPluginSystem._tmp_plugin_name
|
|
/ "scans/metadata_schema"
|
|
/ "metadata_schema_registry.py",
|
|
)
|
|
md_reg_module = importlib.util.module_from_spec(md_reg_spec)
|
|
md_reg_spec.loader.exec_module(md_reg_module)
|
|
assert md_reg_module.METADATA_SCHEMA_REGISTRY is not None
|
|
finally:
|
|
for mod in [TestPluginSystem._tmp_plugin_name, md_reg_mod_name]:
|
|
if mod in sys.modules:
|
|
del sys.modules[mod]
|
|
|
|
def test_plugin_modules_import_from_file(self):
|
|
importlib.import_module(TestPluginSystem._tmp_plugin_name)
|
|
for submod in [
|
|
"scans",
|
|
"devices",
|
|
"bec_widgets",
|
|
"bec_ipython_client",
|
|
"services",
|
|
"file_writer",
|
|
]:
|
|
importlib.import_module(TestPluginSystem._tmp_plugin_name + "." + submod)
|
|
|
|
def test_plugin_helper_for_scans(self):
|
|
plugin_scans_modules = plugin_helper._get_available_plugins("bec.scans")
|
|
assert len(plugin_scans_modules) > 0
|
|
scan_plugins = plugin_helper.get_scan_plugins()
|
|
assert "ScanForTesting" in scan_plugins.keys()
|
|
|
|
def test_plugin_helper_for_metadata_schema(self):
|
|
metadata_schema_plugin_module = plugin_helper._get_available_plugins(
|
|
"bec.scans.metadata_schema"
|
|
)
|
|
assert len(metadata_schema_plugin_module) > 0
|
|
metadata_registry, default_schema = plugin_helper.get_metadata_schema_registry()
|
|
assert set(["test_scan_fail_on_type", "example_scan"]) == set(metadata_registry.keys())
|
|
assert default_schema is None
|