From b0823728abd8bb5dd0ee185970dcc7ec17c08cda Mon Sep 17 00:00:00 2001
From: Simon Rose <simon.rose@ess.eu>
Date: Tue, 27 Sep 2022 14:03:33 +0200
Subject: [PATCH] Refactor sequencer to user Wrapper base class

---
 tests/test_sequencer.py | 98 ++++++++++++++---------------------------
 tests/utils.py          | 44 ++++++++++--------
 2 files changed, 59 insertions(+), 83 deletions(-)

diff --git a/tests/test_sequencer.py b/tests/test_sequencer.py
index 327d0925..aa743cb7 100644
--- a/tests/test_sequencer.py
+++ b/tests/test_sequencer.py
@@ -1,9 +1,6 @@
-import os
 import pathlib
-import subprocess
 
 import pytest
-from git import Repo
 
 from .utils import Wrapper
 
@@ -23,55 +20,30 @@ ss ss1 {{
 """
 
 
-class SequencerBuild:
+class Sequencer(Wrapper):
     sequencer_url = f"{GITLAB_URL}/e3/wrappers/core/e3-sequencer.git"
 
     def __init__(self, path: pathlib.Path):
-        self.epics_base = pathlib.Path(os.getenv("EPICS_BASE"))
-        self.base_version = self.epics_base.name.split("base-")[-1]
-        assert self.base_version
-
-        self.require_version = os.getenv("E3_REQUIRE_VERSION")
-        assert self.require_version
+        super().__init__(path, name="sequencer", url=self.sequencer_url)
 
         self.version = "sequencer_test"
 
-        self.host_arch = os.getenv("EPICS_HOST_ARCH")
-        assert self.host_arch
-
-        self.path = path / "e3-sequencer"
-
-        Repo.clone_from(self.sequencer_url, self.path)
-
-        self.config_dir = self.path / "configure"
-        self.config_dir.mkdir(exist_ok=True)
-
-        (self.config_dir / "RELEASE.local").write_text(
-            f"""EPICS_BASE := {self.epics_base}
-E3_REQUIRE_VERSION := {self.require_version}"""
-        )
-        (self.config_dir / "CONFIG_MODULE.local").write_text(
-            f"E3_MODULE_VERSION := {self.version}"
+        self.write_dot_local_data(
+            "RELEASE",
+            {"EPICS_BASE": self.epics_base, "E3_REQUIRE_VERSION": self.require_version},
         )
+        self.write_dot_local_data("CONFIG_MODULE", {"E3_MODULE_VERSION": self.version})
 
         self.cell_path = self.path / "cellMods"
 
-        make_arg = ["make", "-C", self.path]
-        results = subprocess.run(
-            make_arg + ["init"],
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            encoding="utf-8",
-        )
-        assert results.returncode == 0
-        results = subprocess.run(make_arg + ["patch"])
-        assert results.returncode == 0
-        results = subprocess.run(make_arg + ["build"])
-        assert results.returncode == 0
-        results = subprocess.run(
-            make_arg + ["cellinstall", f"E3_CELL_PATH={self.cell_path}"]
-        )
-        assert results.returncode == 0
+        rc, *_ = self.run_make("init")
+        assert rc == 0
+        rc, *_ = self.run_make("patch")
+        assert rc == 0
+        rc, *_ = self.run_make("build")
+        assert rc == 0
+        rc, *_ = self.run_make("cellinstall", cell_path=self.cell_path)
+        assert rc == 0
 
         self.snc_path = (
             self.cell_path
@@ -89,11 +61,11 @@ E3_REQUIRE_VERSION := {self.require_version}"""
 @pytest.fixture(scope="module")
 def sequencer(tmp_path_factory):
     path = tmp_path_factory.mktemp("sequencer_build")
-    yield SequencerBuild(path)
+    yield Sequencer(path)
 
 
-class SequencerWrapper(Wrapper):
-    def __init__(self, sequencer: SequencerBuild, path: pathlib.Path):
+class SNLWrapper(Wrapper):
+    def __init__(self, sequencer: Sequencer, path: pathlib.Path):
         super().__init__(path)
         self.sequencer = sequencer
 
@@ -108,53 +80,51 @@ class SequencerWrapper(Wrapper):
 
 
 @pytest.fixture
-def sequence_wrapper(sequencer, tmp_path):
-    yield SequencerWrapper(sequencer, tmp_path)
+def snl_wrapper(sequencer, tmp_path):
+    yield SNLWrapper(sequencer, tmp_path)
 
 
 @pytest.mark.parametrize("extension", ["st", "stt"])
-def test_compile_snl_file(sequence_wrapper: SequencerWrapper, extension):
+def test_compile_snl_file(snl_wrapper: SNLWrapper, extension):
     snl_filename = "test_filename"
-    seq_source = sequence_wrapper.module_dir / f"{snl_filename}.{extension}"
+    seq_source = snl_wrapper.module_dir / f"{snl_filename}.{extension}"
     seq_source.write_text(TEST_SEQ_SRC.format('""'))
 
-    sequence_wrapper.add_var_to_module_makefile(
-        "SOURCES", f"{snl_filename}.{extension}"
-    )
+    snl_wrapper.add_var_to_module_makefile("SOURCES", f"{snl_filename}.{extension}")
 
-    rc, *_ = sequence_wrapper.run_make("cellbuild")
+    rc, *_ = snl_wrapper.run_make("cellbuild")
     assert rc == 0
 
-    assert (sequence_wrapper.build_dir / f"{snl_filename}.o").is_file()
-    assert (sequence_wrapper.build_dir / f"{snl_filename}_snl.dbd").is_file()
+    assert (snl_wrapper.build_dir / f"{snl_filename}.o").is_file()
+    assert (snl_wrapper.build_dir / f"{snl_filename}_snl.dbd").is_file()
 
 
-def test_preprocess_st_file(sequence_wrapper: SequencerWrapper):
+def test_preprocess_st_file(snl_wrapper: SNLWrapper):
     snl_filename = "test_file.st"
-    seq_src = sequence_wrapper.module_dir / snl_filename
+    seq_src = snl_wrapper.module_dir / snl_filename
     seq_src.write_text(
         '#define MESSAGE "waiting\\n"\n' + TEST_SEQ_SRC.format("MESSAGE")
     )
 
-    sequence_wrapper.add_var_to_module_makefile("SOURCES", snl_filename)
+    snl_wrapper.add_var_to_module_makefile("SOURCES", snl_filename)
 
-    rc, *_ = sequence_wrapper.run_make("cellbuild")
+    rc, *_ = snl_wrapper.run_make("cellbuild")
     assert rc == 0
 
 
-def test_do_not_preprocess_stt_file(sequence_wrapper: SequencerWrapper):
+def test_do_not_preprocess_stt_file(snl_wrapper: SNLWrapper):
     snl_filename = "test_file"
-    seq_src = sequence_wrapper.module_dir / f"{snl_filename}.stt"
+    seq_src = snl_wrapper.module_dir / f"{snl_filename}.stt"
     seq_src.write_text(
         '#define MESSAGE "waiting\\n"\n' + TEST_SEQ_SRC.format("MESSAGE")
     )
 
-    sequence_wrapper.add_var_to_module_makefile("SOURCES", f"{snl_filename}.stt")
+    snl_wrapper.add_var_to_module_makefile("SOURCES", f"{snl_filename}.stt")
 
-    rc, _, errs = sequence_wrapper.run_make("cellbuild")
+    rc, _, errs = snl_wrapper.run_make("cellbuild")
     assert rc == 2
     assert (
         f"No rule to make target `{snl_filename}.c', needed by `{snl_filename}_snl.dbd'"
         in errs
     )
-    assert not (sequence_wrapper.build_dir / f"{snl_filename}.i").is_file()
+    assert not (snl_wrapper.build_dir / f"{snl_filename}.i").is_file()
diff --git a/tests/utils.py b/tests/utils.py
index e8c39439..312f9c32 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -10,7 +10,9 @@ from run_iocsh import IOC
 
 
 class Wrapper:
-    def __init__(self, root_path: Path, name=None, include_dbd=True, **kwargs):
+    def __init__(
+        self, root_path: Path, *, name=None, include_dbd=True, url=None, **kwargs
+    ):
         test_env = os.environ.copy()
 
         assert "EPICS_BASE" in test_env
@@ -30,27 +32,32 @@ class Wrapper:
 
         if name is None:
             name = "test_mod_" + "".join(choice(ascii_lowercase) for _ in range(16))
-        self.path = root_path / f"e3-{name}"
         self.name = name
-
         self.version = "0.0.0+0"
 
+        self.path = root_path / f"e3-{self.name}"
+        self.config_dir = self.path / "configure"
+        self.config_module = self.config_dir / "CONFIG_MODULE"
         module_path = (
-            name if "E3_MODULE_SRC_PATH" not in kwargs else kwargs["E3_MODULE_SRC_PATH"]
+            self.name
+            if "E3_MODULE_SRC_PATH" not in kwargs
+            else kwargs["E3_MODULE_SRC_PATH"]
         )
         self.module_dir = self.path / module_path
-        self.module_dir.mkdir(parents=True)
-
         self.build_dir = self.module_dir / f"O.{self.base_version}_{self.host_arch}"
 
-        self.config_dir = self.path / "configure"
-        self.config_dir.mkdir()
+        self.makefile = self.path / "Makefile"
+        self.module_makefile = self.path / f"{self.name}.Makefile"
 
-        self.config_module = self.config_dir / "CONFIG_MODULE"
-        self.config_module.touch()
+        self.url = url
+        if self.url:
+            Repo.clone_from(self.url, self.path)
+        else:
+            self.module_dir.mkdir(parents=True)
+            self.config_dir.mkdir()
+            self.config_module.touch()
 
-        self.makefile = self.path / "Makefile"
-        makefile_contents = f"""
+            makefile_contents = f"""
 TOP:=$(CURDIR)
 
 E3_MODULE_NAME:={name}
@@ -66,21 +73,20 @@ REQUIRE_CONFIG:={e3_require_config}
 include $(REQUIRE_CONFIG)/CONFIG
 include $(REQUIRE_CONFIG)/RULES_SITEMODS
 """
-        self.makefile.write_text(makefile_contents)
+            self.makefile.write_text(makefile_contents)
 
-        self.module_makefile = self.path / f"{name}.Makefile"
-        module_makefile_contents = """
+            module_makefile_contents = """
 where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
 include $(E3_REQUIRE_TOOLS)/driver.makefile
 
 EXCLUDE_ARCHS+=debug
 """
-        self.module_makefile.write_text(module_makefile_contents)
+            self.module_makefile.write_text(module_makefile_contents)
 
-        if include_dbd:
-            self.add_file("test.dbd")
+            if include_dbd:
+                self.add_file("test.dbd")
 
-        Repo.init(self.path)
+            Repo.init(self.path)
 
     def add_file(self, name):
         (self.module_dir / name).touch()
-- 
GitLab