Skip to content
Snippets Groups Projects
Commit a9c917de authored by Simon Rose's avatar Simon Rose
Browse files

Add tests for e3-sequencer compilation

This commit also modifies how driver.makefile processes .st/.stt files.
According to the SNL documentation, .stt files should not be pre-processed.
However, driver.makefile has historically been performing the exact same
actions to both types of files, counter to what the documentation said.
parent bb242afb
No related branches found
No related tags found
No related merge requests found
...@@ -514,7 +514,7 @@ DBDFILES += $(patsubst %.stt,%_snl.dbd,$(notdir $(filter %.stt,${SRCS}))) ...@@ -514,7 +514,7 @@ DBDFILES += $(patsubst %.stt,%_snl.dbd,$(notdir $(filter %.stt,${SRCS})))
DBDFILES += $(patsubst %.gt,%.dbd,$(notdir $(filter %.gt,${SRCS}))) DBDFILES += $(patsubst %.gt,%.dbd,$(notdir $(filter %.gt,${SRCS})))
# snc location # snc location
SNCALL=$(shell ls -dv $(E3_SITEMODS_PATH)/sequencer/$(sequencer_VERSION)/bin/$(EPICS_HOST_ARCH) 2> /dev/null)) SNCALL=$(shell ls -dv $(E3_SITEMODS_PATH)/sequencer/$(sequencer_VERSION)/bin/$(EPICS_HOST_ARCH) 2> /dev/null)
SNC=$(lastword $(SNCALL))/snc SNC=$(lastword $(SNCALL))/snc
ifneq (,$(strip $(VLIBS))) ifneq (,$(strip $(VLIBS)))
...@@ -698,59 +698,35 @@ ${INSTALL_BINS}: $(addprefix ../,$(filter-out /%,${BINS})) $(filter /%,${BINS}) ...@@ -698,59 +698,35 @@ ${INSTALL_BINS}: $(addprefix ../,$(filter-out /%,${BINS})) $(filter /%,${BINS})
# Create SNL code from st/stt file. # Create SNL code from st/stt file.
# Important to have %.o: %.st and %.o: %.stt rule before %.o: %.c rule! # Important to have %.o: %.st and %.o: %.stt rule before %.o: %.c rule!
# Preprocess in any case because docu and implemented EPICS rules mismatch here.
CPPSNCFLAGS1 = $(filter -D%, ${OP_SYS_CFLAGS}) CPPSNCFLAGS1 = $(filter -D%, ${OP_SYS_CFLAGS})
CPPSNCFLAGS1 += $(filter-out ${OP_SYS_INCLUDE_CPPFLAGS} ,${CPPFLAGS}) ${CPPSNCFLAGS} CPPSNCFLAGS1 += $(filter-out ${OP_SYS_INCLUDE_CPPFLAGS} ,${CPPFLAGS}) ${CPPSNCFLAGS}
CPPSNCFLAGS1 += -I $(dir $(SNC))../../include CPPSNCFLAGS1 += -I $(dir $(SNC))../../include
SNCFLAGS += -r SNCFLAGS += -r
%.i: %.st
@echo ">> Preprocessing $(<F)"
$(CPP) ${CPPSNCFLAGS1} $< > $(*F).i
# 1) ESS uses 7.0.3.1 as the minimal EPICS BASE, so we don't need to check 3.13, %.c: %.i
# 2) We also need -c option in $(COMPILE.c) in order to compile generated source file properly
# 3) SNC (2.1.21) should use -o, because without them, snc returns $(*F).i.c instead of $(*F).c
# With the EPICS standard building rule, -o and mv are used.
#
# Tuesday, November 28 15:59:37 CET 2017, Jeong Han Lee
%$(OBJ) %_snl.dbd: %.st
@echo "" @echo ""
@echo ">> SNC building process .... " @echo ">> SNC building process .... "
@echo ">> SNC : $(SNC)" @echo ">> SNC : $(SNC)"
@echo ">> SNC_VERSION : $(sequencer_VERSION)" @echo ">> SNC_VERSION : $(sequencer_VERSION)"
@echo ">> Preprocessing $(<F)"
$(RM) $(*F).i
$(CPP) ${CPPSNCFLAGS1} $< > $(*F).i
@echo ">> Converting $(*F).i to $(*F).c"
$(RM) $@
@echo ">> SNC is defined as $(SNC)" @echo ">> SNC is defined as $(SNC)"
$(SNC) $(TARGET_SNCFLAGS) $(SNCFLAGS) $(*F).i -o $(*F).c.tmp $(SNC) $(TARGET_SNCFLAGS) $(SNCFLAGS) $(*F).i -o $(*F).c
@mv $(*F).c.tmp $(*F).c
@echo ">> Compiling $(*F).c" %_snl.dbd: %.c
$(RM) $@
$(COMPILE.c) -c ${SNC_CFLAGS} $(*F).c
@echo ">> Building $(*F)_snl.dbd" @echo ">> Building $(*F)_snl.dbd"
awk -F [\(\)] '/epicsExportRegistrar/ { print "registrar (" $$2 ")"}' $(*F).c > $(*F)_snl.dbd awk -F [\(\)] '/epicsExportRegistrar/ { print "registrar (" $$2 ")"}' $(*F).c > $(*F)_snl.dbd
%$(OBJ) %_snl.dbd: %.stt %.c: %.stt
@echo "" @echo ""
@echo ">> SNC building process .... " @echo ">> SNC building process .... "
@echo ">> SNC : $(SNC)" @echo ">> SNC : $(SNC)"
@echo ">> SNC_VERSION : $(sequencer_VERSION)" @echo ">> SNC_VERSION : $(sequencer_VERSION)"
@echo ">> Preprocessing $(<F)"
$(RM) $(*F).i
$(CPP) ${CPPSNCFLAGS1} $< > $(*F).i
@echo ">> Converting $(*F).i to $(*F).c"
$(RM) $@
@echo ">> SNC is defined as $(SNC)" @echo ">> SNC is defined as $(SNC)"
$(SNC) $(TARGET_SNCFLAGS) $(SNCFLAGS) $(*F).i -o $(*F).c.tmp $(SNC) $(TARGET_SNCFLAGS) $(SNCFLAGS) $< -o $(*F).c
@mv $(*F).c.tmp $(*F).c
@echo ">> Compiling $(*F).c"
$(RM) $@
$(COMPILE.c) -c ${SNC_CFLAGS} $(*F).c
@echo "Building $(*F)_snl.dbd"
awk -F [\(\)] '/epicsExportRegistrar/ { print "registrar(" $$2 ")"}' $(*F).c > $(*F)_snl.dbd
# Create GPIB code from *.gt file. # Create GPIB code from *.gt file.
......
import os
import pathlib
import subprocess
import pytest
from git import Repo
from .utils import Wrapper
GITLAB_URL = "https://gitlab.esss.lu.se"
TEST_SEQ_SRC = """
program test
ss ss1 {{
state init {{
when(delay(1)) {{
printf({});
}}
state init
}}
}}
"""
class SequencerBuild:
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
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.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
self.snc_path = (
self.cell_path
/ f"base-{self.base_version}"
/ f"require-{self.require_version}"
/ "sequencer"
/ self.version
/ "bin"
/ self.host_arch
/ "snc"
)
assert self.snc_path.is_file()
@pytest.fixture(scope="module")
def sequencer(tmp_path_factory):
path = tmp_path_factory.mktemp("sequencer_build")
yield SequencerBuild(path)
class SequencerWrapper(Wrapper):
def __init__(self, sequencer: SequencerBuild, path: pathlib.Path):
super().__init__(path)
self.sequencer = sequencer
self.add_var_to_config_module("SEQUENCER_DEP_VERSION", self.sequencer.version)
def run_make(self, *args):
return super().run_make(
*args,
f"E3_CELL_PATH={self.sequencer.cell_path}",
f"SNC={self.sequencer.snc_path}",
)
@pytest.fixture
def sequence_wrapper(sequencer, tmp_path):
yield SequencerWrapper(sequencer, tmp_path)
@pytest.mark.parametrize("extension", ["st", "stt"])
def test_compile_snl_file(sequence_wrapper: SequencerWrapper, extension):
snl_filename = "test_filename"
seq_source = sequence_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}"
)
rc, *_ = sequence_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()
def test_preprocess_st_file(sequence_wrapper: SequencerWrapper):
snl_filename = "test_file.st"
seq_src = sequence_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)
rc, *_ = sequence_wrapper.run_make("cellbuild")
assert rc == 0
def test_do_not_preprocess_stt_file(sequence_wrapper: SequencerWrapper):
snl_filename = "test_file"
seq_src = sequence_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")
rc, _, errs = sequence_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()
...@@ -15,12 +15,15 @@ class Wrapper: ...@@ -15,12 +15,15 @@ class Wrapper:
assert "EPICS_BASE" in test_env assert "EPICS_BASE" in test_env
assert "E3_REQUIRE_VERSION" in test_env assert "E3_REQUIRE_VERSION" in test_env
assert "EPICS_HOST_ARCH" in test_env
self.epics_base = Path(os.getenv("EPICS_BASE"))
self.base_version = self.epics_base.name.split("base-")[-1]
self.host_arch = os.getenv("EPICS_HOST_ARCH")
self.require_version = os.getenv("E3_REQUIRE_VERSION")
e3_require_config = ( e3_require_config = (
Path(os.environ.get("EPICS_BASE")) self.epics_base / "require" / self.require_version / "configure"
/ "require"
/ os.environ.get("E3_REQUIRE_VERSION")
/ "configure"
) )
assert e3_require_config.is_dir() assert e3_require_config.is_dir()
...@@ -38,6 +41,8 @@ class Wrapper: ...@@ -38,6 +41,8 @@ class Wrapper:
self.module_dir = self.path / module_path self.module_dir = self.path / module_path
self.module_dir.mkdir(parents=True) 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 = self.path / "configure"
self.config_dir.mkdir() self.config_dir.mkdir()
...@@ -61,7 +66,7 @@ REQUIRE_CONFIG:={e3_require_config} ...@@ -61,7 +66,7 @@ REQUIRE_CONFIG:={e3_require_config}
include $(REQUIRE_CONFIG)/CONFIG include $(REQUIRE_CONFIG)/CONFIG
include $(REQUIRE_CONFIG)/RULES_SITEMODS 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" self.module_makefile = self.path / f"{name}.Makefile"
module_makefile_contents = """ module_makefile_contents = """
...@@ -70,7 +75,7 @@ include $(E3_REQUIRE_TOOLS)/driver.makefile ...@@ -70,7 +75,7 @@ include $(E3_REQUIRE_TOOLS)/driver.makefile
EXCLUDE_ARCHS+=debug EXCLUDE_ARCHS+=debug
""" """
(self.module_makefile).write_text(module_makefile_contents) self.module_makefile.write_text(module_makefile_contents)
if include_dbd: if include_dbd:
self.add_file("test.dbd") self.add_file("test.dbd")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment