A RFC patch related to meson test

Lei YU mine260309 at gmail.com
Sat Sep 7 03:13:19 AEST 2019


This email is to ask for comments about a patch to meson test, which is kind of
a hack done in the OpenBMC hackathon.

Background:
1. If we are using OpenBMC x86-64 SDK about a month ago to build and test a
repo with meson, the unit test is not really run but skipped.
The sample output looks like:

ninja: no work to do.
1/2 util                                    SKIP     0.00 s
2/2 item_updater                            SKIP     0.00 s
Ok:                    0
Skipped:               2

The log shows that `Not run because can not execute cross compiled binaries,
while the test actually could be run on x86-64 host, because we are cross
compiling x86-64 on a x86-64 host.

2. If we use the latest OpenBMC SDK, the above issue is gone because it uses a
newer version of meson and it somehow does not think the test is cross-compiled
anymore.
However, if we are using the ARM SDK, and run the meson build and test, it will
still run the arm binaries and got a failure:

OSError: [Errno 8] Exec format error:
'/home/leiyu/work/phosphor-psu-code-mgmt/build/test/test_util'
FAILED: meson-test


So I come up with the below patch, as the concept of making meson to run the
test only if the test case is compatible with the build machine.

```
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index 1dca0759..52a01ba3 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -441,6 +441,20 @@ def load_tests(build_dir: str) ->
typing.List['TestSerialisation']:
         obj = typing.cast(typing.List['TestSerialisation'], pickle.load(f))
     return obj

+def is_compatible(test_case):
+    from subprocess import Popen, PIPE, STDOUT
+    cmd = 'file ' + test_case[0]
+    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
stderr=STDOUT, close_fds=True)
+    output = p.stdout.read().decode('utf-8')
+    splitted = output.split(',')
+    test_arch = splitted[1].strip()
+    test_arch = test_arch.replace('-', '_')
+
+    import platform
+    build_machine_arch = platform.machine()
+    build_machine_arch = build_machine_arch.replace('-', '_')
+
+    return test_arch == build_machine_arch

 class SingleTestRunner:

@@ -457,7 +471,7 @@ class SingleTestRunner:
         elif not self.test.is_cross_built and
run_with_mono(self.test.fname[0]):
             return ['mono'] + self.test.fname
         else:
-            if self.test.is_cross_built:
+            if self.test.is_cross_built or not is_compatible(self.test.fname):
                 if self.test.exe_runner is None:
                     # Can not run test on cross compiled executable
                     # because there is no execute wrapper.
```


The idea here is to check if the test binary's architecture by `file` command,
compare it with the build machine's architecture, and return the test case if
they match.

With the patch, the meson unit test works well:
* If using x86-64 SDK, it runs the tests and reports the result correctly:
1/2 util                                    OK       0.02 s
2/2 item_updater                            OK       0.02 s
Ok:                    2
* If using ARM SDK, it skips the tests:
1/2 util                                    SKIP     0.00 s
2/2 item_updater                            SKIP     0.00 s
Skipped:               2

So I am asking comments here:
1. Does the patch make sense? (If yes, I would like to push it to
meson upstream)
2. Is there a better way to check if test case is really cross-compiled or not?
   Likely it is better to be fixed in `backend/backends.py`
   `serialize_executable()` function, which really set the `test.is_cross_built`
   property.


More information about the openbmc mailing list