From: "T. Schaffner" <tobias.schaffner@siemens.com>
To: <isar-users@googlegroups.com>
Cc: <quirin.gylstorff@siemens.com>, <henning.schild@siemens.com>,
"Tobias Schaffner" <tobias.schaffner@siemens.com>
Subject: [PATCH 2/4] create a minimal python unittest infrastructure
Date: Thu, 30 Mar 2023 13:08:02 +0200 [thread overview]
Message-ID: <20230330110804.1016614-3-tobias.schaffner@siemens.com> (raw)
In-Reply-To: <20230330110804.1016614-1-tobias.schaffner@siemens.com>
From: Tobias Schaffner <tobias.schaffner@siemens.com>
Add some some infrastructure for python unittesting. The unittest_isar
module exposes a function that uses the bb.parse module to import
python functions that are defined in bitbake files.
Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
testsuite/unittests/README.md | 28 +++++++++++++++++++++
testsuite/unittests/bitbake.py | 37 ++++++++++++++++++++++++++++
testsuite/unittests/rootfs.py | 45 ++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 testsuite/unittests/README.md
create mode 100644 testsuite/unittests/bitbake.py
create mode 100644 testsuite/unittests/rootfs.py
diff --git a/testsuite/unittests/README.md b/testsuite/unittests/README.md
new file mode 100644
index 00000000..75a3bb01
--- /dev/null
+++ b/testsuite/unittests/README.md
@@ -0,0 +1,28 @@
+# Isar Unittests
+
+The unittest python module adds some simple infrastructure that allows to
+unittest python functions defined in bitbake files.
+
+## Running the tests
+
+You can run the tests using avocado with `avocado --show=app,test run testsuite/unittests/`
+or by using the buildin module with `python3 -m unittest discover testsuite/unittests/`
+
+## Creating new tests
+
+See the [unittest documentation](https://docs.python.org/3/library/unittest.html)
+on how to create a test module and name it test_*bitbake_module_name*.py
+
+Use the function `load_function(file_name: str, function_name: str) -> Callable`
+in the bitbake module to load the function.
+
+Example:
+```python
+from bitbake import load_function
+
+my_function = load_function("meta/classes/my_module.bbclass", "my_function")
+my_function(arg1, arg2)
+```
+
+Use the [unittest.mock](https://docs.python.org/3/library/unittest.mock.html)
+library to mock the bb modules as needed.
diff --git a/testsuite/unittests/bitbake.py b/testsuite/unittests/bitbake.py
new file mode 100644
index 00000000..1e2f685a
--- /dev/null
+++ b/testsuite/unittests/bitbake.py
@@ -0,0 +1,37 @@
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2023
+#
+# SPDX-License-Identifier: MIT
+
+import sys
+import pathlib
+from typing import Callable
+
+location = pathlib.Path(__file__).parent.resolve()
+sys.path.insert(0, "{}/../../bitbake/lib".format(location))
+
+from bb.parse import handle
+from bb.data import init
+
+# Modules added for reimport from testfiles
+from bb.data_smart import DataSmart
+
+
+def load_function(file_name: str, function_name: str) -> Callable:
+ """Load a python function defined in a bitbake file.
+
+ Args:
+ file_name (str): The path to the file e.g. `meta/classes/my_special.bbclass`.
+ function_name (str): The name of the python function without braces e.g. `my_special_function`
+
+ Returns:
+ Callable: The loaded function.
+ """
+ d = init()
+ parse = handle("{}/../../{}".format(location, file_name), d)
+ if function_name not in parse:
+ raise KeyError("Function {} does not exist in {}".format(
+ function_name, file_name))
+ namespace = {}
+ exec(parse[function_name], namespace)
+ return namespace[function_name]
diff --git a/testsuite/unittests/rootfs.py b/testsuite/unittests/rootfs.py
new file mode 100644
index 00000000..6c511493
--- /dev/null
+++ b/testsuite/unittests/rootfs.py
@@ -0,0 +1,45 @@
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2023
+#
+# SPDX-License-Identifier: MIT
+
+import tempfile
+import pathlib
+import shutil
+import atexit
+
+temp_dirs = []
+
+
+class TemporaryRootfs:
+ """ A temporary rootfs folder that will be removed after the testrun. """
+
+ def __init__(self):
+ self._rootfs_path = tempfile.mkdtemp()
+ temp_dirs.append(self._rootfs_path)
+
+ def path(self) -> str:
+ return self._rootfs_path
+
+ def create_file(self, path: str, content: str) -> None:
+ """ Create a file with the given content.
+
+ Args:
+ path (str): The path to the file e.g. `/etc/hostname`.
+ content (str): The content of the file e.g. `my_special_host`
+
+ Returns:
+ None
+ """
+ pathlib.Path(self._rootfs_path +
+ path).parent.mkdir(parents=True, exist_ok=True)
+ with open(self._rootfs_path + path, 'w') as file:
+ file.write(content)
+
+
+def cleanup():
+ for temp_dir in temp_dirs:
+ shutil.rmtree(temp_dir)
+
+
+atexit.register(cleanup)
--
2.34.1
next prev parent reply other threads:[~2023-03-30 11:08 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-30 11:08 [PATCH 0/4] Rewrite the image-account-extension in python T. Schaffner
2023-03-30 11:08 ` [PATCH 1/4] simplify image-account-extension T. Schaffner
2023-03-30 19:55 ` Henning Schild
2023-03-30 21:39 ` Schaffner, Tobias
2023-03-30 11:08 ` T. Schaffner [this message]
2023-03-30 11:08 ` [PATCH 3/4] add unittests for the image-account-extension T. Schaffner
2023-03-30 11:08 ` [PATCH 4/4] set minimal python version in user_manual to 3.5 T. Schaffner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230330110804.1016614-3-tobias.schaffner@siemens.com \
--to=tobias.schaffner@siemens.com \
--cc=henning.schild@siemens.com \
--cc=isar-users@googlegroups.com \
--cc=quirin.gylstorff@siemens.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox