From 818eafee4581297ce854d7f7a23700f1c7b72f7a Mon Sep 17 00:00:00 2001
From: Simon Rose <simon.rose@ess.eu>
Date: Thu, 18 Aug 2022 17:09:34 +0200
Subject: [PATCH] E3-921: Add test to ensure that failed architectures cause
 build to fail

This adds a test that checks that if a single architecture fails, then the build
fails as a whole.

There are some slight complications in terms of writing good tests, since we do not
want to use real architectures. Since the source files are converted from
`SOURCES -> SRCS -> LIBOBJS` and we finally have the dependency
```make
${DEPFILE}: ${LIBOBJS}
```
we need to ensure that `LIBOBJS` is properly populated before we get to this point.
The challenge, however, is that `LIBOBJS` is defined (in terms of `SRCS` as
```make
LIBOBJS += $(addsuffix $(OBJ),$(notdir $(basename $(filter-out %.$(OBJ) %$(LIB_SUFFIX),$(sort ${SRCS})))))
```
and `LIB_SUFFIX` is set in `${CONFIG}/os/CONFIG.Common.${T_A}`. This is why
we need to do the workaround of hand-defining it at the beginning.
---
 tests/conftest.py   |  2 +-
 tests/test_build.py | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/tests/conftest.py b/tests/conftest.py
index 1f9a5313..7fdf70eb 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -69,7 +69,7 @@ include $(E3_REQUIRE_TOOLS)/driver.makefile
 
     def add_var_to_config_module(self, makefile_var: str, value: str, modifier="+"):
         with open(self.config_module, "a") as f:
-            f.write(f"{makefile_var} {modifier}= {value}\n")
+            f.write(f"export {makefile_var} {modifier}= {value}\n")
 
     def add_var_to_makefile(self, makefile_var: str, value: str, modifier="+"):
         with open(self.makefile, "a") as f:
diff --git a/tests/test_build.py b/tests/test_build.py
index d599658c..c6f9be3f 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -533,3 +533,33 @@ def test_arch_filter(wrapper, installed_archs, param, expected):
     build_archs = [arch for arch in arch_regex.findall(o) if arch != host_arch]
 
     assert build_archs == expected
+
+
+@pytest.mark.parametrize("archs,failing_arch", [("foo bar", "foo"), ("foo bar", "bar")])
+def test_build_fails_if_nth_architecture_fails(wrapper, archs, failing_arch):
+    # LIBOBJS is determined in part based on configuration data coming from
+    # $(CONFIG)/os/CONFIG.Common.$(T_A); since our architectures do not actually
+    # exist, we need to manually define these /before/ driver.makefile is included.
+    mf_content = wrapper.makefile.read_text()
+    with open(wrapper.makefile, "w") as f:
+        f.write(
+            f"""ifeq ($(T_A),{failing_arch})
+                LIBOBJS = nonexistent_{failing_arch}.o
+                endif
+                """
+        )
+        f.write(mf_content)
+
+    wrapper.add_var_to_config_module("OS_CLASS", "Linux")
+
+    host_arch = os.getenv("EPICS_HOST_ARCH")
+    wrapper.add_var_to_makefile("EXCLUDE_ARCHS", host_arch)
+    wrapper.add_var_to_makefile("CROSS_COMPILER_TARGET_ARCHS", archs, modifier="")
+    wrapper.add_var_to_makefile("SOURCES", "-none-")
+
+    rc, _, errs = wrapper.run_make("build")
+    assert rc == 2
+    assert re.search(
+        RE_MISSING_FILE.format(filename=re.escape(f"nonexistent_{failing_arch}.o")),
+        errs,
+    )
-- 
GitLab