Commit graph

58 commits

Author SHA1 Message Date
Christian Kellner
4ab52c3764 formats: move pipeline description here
The description of a pipeline is format dependent and thus needs
to be located at the specific format module.
Temporarily remove two tests; they should be added back to a format
specific test suit.
2021-01-09 18:09:47 +01:00
Christian Kellner
a13783f67b formats: load function takes combined manifest
Instead of having the pipeline and the source option as separate
arguments, the load function now takes the full manifest, which
has those two items combined.
2021-01-09 18:09:47 +01:00
Christian Kellner
0b6f36158d osbuild: use load function via the format module
Instead of importing the load, load_build functions into the osbuild
namespace and using it via that, use the load function via the module
that provides them, i.e. the formats.v1 module.
2021-01-09 18:09:47 +01:00
Christian Kellner
b65211a94d formats/v1: move validation logic here
The validation of the manifest descritpion is eo ipso format
specific and thus belongs into the format specific module.
Adapt all usages throughout the codebase to directly use the
version 1 specific function.
2021-01-09 18:09:47 +01:00
Christian Kellner
d7d84a8eb1 test/mod: use proper host runner
Instead of hard-coding the use of the "org.osbuild.linux" runner,
use the new `osbuild.pipeline.detect_host_runner` function to
dynamically detect the runner for the host system. That should fix
the tests on RHEL systems, where python3 is by default not present
and even if it is manually installed, is an indirection via
alternatives (i.e. a link to /etc/alternatives), which must be
explicitly configured in the build root container for the host.
2020-10-21 11:13:28 +02:00
Christian Kellner
25662fbfbc test/buildroot: more lenient output test checking
In `test_output`, require that the test string is found in the
output, not equal to the output. Other warnings or log messages
might be printed by the runner.
2020-10-21 11:13:28 +02:00
Christian Kellner
9ef642228f test: adapt 'libdir' argument for BuildRoot's ctor
As of commit 1e3c0ae "unified libdir handling", the libdir argument
for the BuildRoot constructor is not a keyword argument anymore.
Adapt the argument accordingly.
2020-10-21 11:13:28 +02:00
Christian Kellner
71f7bf8930 test/api: assert return code for api.exception
Check that the exit code for `api.exception`, called via the
`api.exception_handler` helper, is the correct one.
2020-10-09 10:47:44 +02:00
Christian Kellner
aaa51e22a6 api: properly serialize the exception's traceback
Use `traceback.print_tb()` to serialize the exceptions' backtrace.
The previously used expression `str(e.__traceback__)` will just
give `<traceback object at 0x…>`, which is not very helpful.
Add a test to check that the method name that raises the exception,
also called `exception`, is in the traceback.
2020-10-09 10:47:44 +02:00
Christian Kellner
7a112c27cb test/api: fix white-space error
No double space between class methods, so say the scriptures.
2020-10-09 10:47:44 +02:00
Christian Kellner
f8de164413 api: properly encode exception type
When using `str(type(exception))` this ends up to be something like
`<class 'ValueError'>` for a `ValueError` exception. Get the vanilla
name of the exception type via `type(exception).__name__`.
Add a test to ensure that we encode this properly.
2020-10-09 10:47:44 +02:00
Christian Kellner
f5d00dd043 api: use more generic error member for exceptions
Rename the `API.exception` member to `API.error`, to make it more
generic, so it can also be used for other sort of errors in the
future. Also add a layer of additional structure with `type` and
`data` members so different types of errors apart. Currently only
`exception` is used.
Adapt the tests in test/mod/test_api.py to check for the new
structure and its content.
2020-10-09 10:47:44 +02:00
Christian Kellner
17fbe41b03 test/api: check api.exception exits the process
The `api.exception` method, which is internally also used by
`api.exception_handler` helper, calls `sys.exit` and this no
statement after a call to either method should be reached.
Add an assertion to make sure of that.
2020-10-09 10:47:44 +02:00
Chloe Kaubisch
5dc5ddcf29 api: add exception endpoint
Create a new api endpoint called exception, that communicates
exception backtraces separately back to osbuild, as opposed to
dumping them into the normal log. Additionally, add a corresponding
test to check that a call to api.exception correctly sets
API.exception.
2020-10-02 17:49:45 +02:00
chloenayon
01aae91949 api: remove setup_stdio
API.setup_stdio was replaced in PRs 506 and 507,
remove setup_stdio functions and call sites.
2020-09-09 12:52:50 +02:00
Christian Kellner
fc0c75f40e test/api: race-free api.metadata access
Access metadata.api only after `api` has exited the context and
thus the event loop has stopped and all incoming messages, like
the one setting the metadata, have been processed.
See commit 803433fb62 for a lecture
about the internals and all the details involved.
2020-08-31 15:06:36 +02:00
Christian Kellner
a3934ab947 test/buildroot: check BuildRoot.output
Now that the `org.osbuild.linux` runner does not use `api.setup_stdio`
anymore, the output of the binary run from the BuildRoot must end up
in `BuildRoot.output`. Check for that.
2020-08-31 15:06:36 +02:00
Christian Kellner
10579ee6f5 buildroot: return a new CompletedBuild with output
Create a new CompletedBuild object that wraps and is very similar
to the subprocess.CompletedProcess, i.e. it has a process member
but also has shortcuts for returncode. Additionally, the output
of the process is not only forwarded to the monitor, but also
captured and then handed to CompletedBuild, so its output member
will actually contain the full build output. To be compatible
with the previously returned CompletedProcess, `stderr`, `stdout`
members exist on CompletedBuild that also return `output`.
2020-08-31 15:06:36 +02:00
Christian Kellner
ba94409d23 test/buildroot: check we log bwrap's error output
Check that any errors that bubblewrap spits out on stderr make it
to the log. A common case of bubblewrap failing is a runner failing
to execute.
2020-08-27 08:07:14 +02:00
Christian Kellner
96a5499ed9 buildroot: log bubblewrap's output
In case that bubblewrap fails to, e.g. because it fails to execute
the runner, it will print an error message to stderr. Currently,
this output is not capture and thus not logged. To fix that, the
`BuildRoot.run` method now takes a monitor object and will stream
stdout/stderr to the log via the monitor.
2020-08-27 08:07:14 +02:00
Christian Kellner
fc5e0070c5 test/api: check for 'get-arguments'/api.arguments
Simple check for the new server side method, `get-arguments`, and
client side counterpart, `api.arguments`, that compares that using
the later we get the supplied input (arguments) to API.
2020-08-25 18:51:55 +02:00
David Rheinsberg
803433fb62 api: prevent early output retrieval
Change the API endpoint to prevent retrieving monitor-output from a
running instance. Instead, we require the caller to exit the API context
before querying the monitor-output. This guarantees that the api-thread
was synchronously taken down and scheduled any outstanding events.

This fixes an issue where a side-channel notifies us of a buildroot
exit, but the api-thread has not yet returned from epoll, and thus might
not have dispatched pending I/O events, yet. If we instead wait for the
thread to exit, we have a synchronous shutdown and know that all
*ordered* kernel events must have been handled.

In particular, imagine a build-root program running (like `echo` in the
test_monitor unittest) which writes data to the stdout-pipe and then
immediately exits. The syscall-order guarantees that the data is written
to the pipe before the SIGCHLD is sent (or wait(2) returns). However, we
retrieve the SIGCHLD from our main-thread usually (p.join() in our test,
and BuildRoot() in our main code), while the pipe-reading is done from
an API thread. Therefore, we might end up handling the SIGCHLD first
(just imagine a single-threaded CPU that schedules the main task before
the thread). To avoid this race, we can simply synchronize with the
api-thread. Since we already have this synchronization as part of the
api-thread takedown, it is as simple as stopping the api-thread before
continuing with operations.

Lastly, if a write operation to a pipe was issued, we are guaranteed
that a SIGCHLD synchronization across processes is ordered correctly.
Furthermore, the python event-loop also guarantees that stopping an
event-loop will necessarily dispatch all outstanding events. A read is
guaranteed to be outstanding in our race-scenario, so the read will be
dispatched. The only possible problem is `_output_ready()` only
dispatching a maximum of 4096 bytes. This might need to be fixed
separately. A comment is left in place.
2020-08-13 14:02:27 +02:00
Christian Kellner
30ad32b174 test/api: checks for metadata passing
Add a simple check to make sure that metadata passing via the api
client and api endpoint is working.
2020-08-13 10:50:34 +02:00
Christian Kellner
e0b7361b26 test/buildroot: check selinuxfs is read-only
This is a crucial pre-condition for the org.osbuild.selinux stage
to work properly, especially that it can set labels that are not
present in the policy on the host. If /sys/fs/selinux is writable,
setfiles will try to verify the labels via /sys/fs/selinux/context
and fail for unknown labels.
2020-08-12 16:52:27 +02:00
Christian Kellner
e2231a8bd2 test/buildroot: simple check for bind mounts
Check that bind-mounting works and read only bind mounts are indeed
read-only and "normal" bind mounts are read-write.
2020-08-12 16:52:27 +02:00
Christian Kellner
28cea491bd test: move api buildroot test to test_buildroot.py
Create a new test suite for BuildRoot related test and move the
the combined api and buildroot check there.
2020-08-12 16:52:27 +02:00
chloenayon
1e3c0aea1b osbuild: unified libdir handling
Change the default of libdir to /usr/lib/osbuild and
remove redundant logic. Additionally, change how the
python package is detected.

Instead of checking if libdir is None, check if
/usr/lib/osbuild is empty - i.e. if the user has specified
a different directory than the default.
2020-08-04 09:02:22 +02:00
Christian Kellner
785f843901 jsoncomm: remove destination from send
Now that jsoncomm.Socket is using a connection-oriented socket,
the destination in `socket.sendmsg` is ignored and thus can and
should be dropped from the `jsoncomm.Socket.send` method.
Adjust the tests accordingly.
2020-07-29 02:16:20 +01:00
Christian Kellner
43db8082bd test/jsoncomm: check accept with no clients
Ensure that if `accept` is called on a normal listener socket, i.e.
the socket is in non-blocking mode, `None` is returned.
2020-07-29 02:16:20 +01:00
Christian Kellner
8388a64ffa api: remove 'addr' param from message dispatcher
Now that jsoncomm is using a connection oriented protocol, the
`addr` parameter is not needed[*] and can thus be removed from
the `BaseAPI._message` message dispatcher. Adapt all usages
of it, including the tests.

[*] sendmsg ignores the destination parameter for connection
oriented sockets.
2020-07-29 02:16:20 +01:00
Christian Kellner
abbdf06ba5 jsoncomm: switch to use sequenced-packet sockets
Switch to use a connection oriented datagram based protocol, i.e.
`SOCK_SEQPACKET`, instead of `SOCK_DGRAM`. It sill preserves
message boundaries, but since it is connection oriented the client
nor the server do not need to specify the destination addresses
of the peer in sendmsg/recvmesg. Moreover, the host will be able
to send messages to the client, even if the latter is sandboxed
with a separate network namespace. In the `SOCK_DRAM` case the
auto-bound address of the client would not be visible to the host
and thus sending messages would to it would fail.

Adapt the jsoncomm tests as well as `BaseAPI`.
2020-07-29 02:16:20 +01:00
Christian Kellner
6f8b850ef2 test/api: add build root integration check
Add a new test that checks the integration of API end points with
the `BuildRoot`.
2020-07-27 12:50:38 +01:00
Christian Kellner
c236039e0d test/api: use high level message dispatcher
Use the new `BaseAPI._message` high level message dispatcher that
is more convenient to use.
2020-07-27 12:50:38 +01:00
Christian Kellner
0c7284572e osbuild: auto-generate socket addresses for APIs
Rely on the ability of `BaseAPI` to auto-generate socket addresses
when no one was provided. The `BuildRoot` does not rely on the
sockets being created in the `BuildRoot.api` directory anymore and
will instead bind-mount each individual socket address to the well
known location via the `BaseAPI.endpoint` identifier.
Convert all API providers to take the `socket_address` as an
optional keyword argument.
2020-07-27 12:50:38 +01:00
Christian Kellner
28947f3bae util/jsoncomm: support PathLike
Add support for `util.types.PathLike` paths for socket addresses,
instead of just plain strings. Test it by using pathlib.Path to
create the address in the corresponding test.
2020-07-27 12:50:38 +01:00
Christian Kellner
bc81e68727 api: each API defines its 'endpoint' name
Add a new abstract class property to `BaseAPI` called `endpoint`,
meant to be implemented by deriving classes in order to identify
the end point name for the API provider.
Implement the new property in all existing API providers.
2020-07-27 12:50:38 +01:00
Christian Kellner
38e714f229 test/monitor: use osbuild.api.setup_stdio
Use the new `api.setup_stdio` instead of providing an exact copy
of that in the test code.
2020-07-27 12:50:38 +01:00
Christian Kellner
b86b6a4bf8 test/api: add checks for the api infrastructure
Add a check for `api.BaseAPI` by implementing a test API and test
that receiving messages and dispatching them works as planned.
2020-07-27 12:50:38 +01:00
Christian Kellner
1ce517e595 api: extract base class
Split out the part of `api.API` that is responsible for providing
the server infrastructure for the API; i.e. setting up the server
and the corresponding context manager and asynchronous event
handling. This leaves `API` itself which just the implementation
of the high level protocol and makes the API-server part re-usable.

NB: pylint, for some reason, confuses `API` and `BaseAPI`, like in
`test_monitor`. Annotate that accordingly.
2020-07-27 12:50:38 +01:00
Christian Kellner
5142046396 test/osbuild: add run tests for stages, assembler
Create small test cases that check the execution of Stages and
Assembler. This ensure that path handling, the sandbox, as well
as basic result reporting works as expected.
2020-07-22 09:37:30 +01:00
Christian Kellner
ec531ee9ed test/osbuild: fix whitespace
Fix indent of pipeline definition.
2020-07-22 09:37:30 +01:00
Christian Kellner
80e96c8494 test/objectstore: proper path concatenation
Instead of using string interpolation and concatenation to build
file system paths, use `os.path.join` or directly the constructor
for `pathlib.Path`, which can take path segments.
2020-07-22 09:37:30 +01:00
Christian Kellner
d3a97a90a5 test/monitor: check monitor functions are invoked
Create a new monitor that records all the invocations of the
monitoring (virtual) functions and use that to check that when
running (i.e. building) a pipeline all of them are executed
the excepted number of times (and with the correct arguments).
2020-07-21 13:25:04 +02:00
Christian Kellner
5d226b2e15 test: add basic checks for monitoring and API
Add a basic test that will set up an 'API' endpoint, then spawn a
child process that uses that 'API' endpoint to setup its stdio in
very much the same way as runners do. This is used to verify that
the API itself works properly as well as the new LogMonitor class
by comparing the inputs and outputs.
2020-07-21 13:25:04 +02:00
Christian Kellner
7a2ad6f0f8 osbuild: replace capture_output in subprocess.run
The `capture_output` argument for subprocess.run was added in 3.7,
but want to support 3.6 as well. Change all the usages of it with
`stdout=subprocess.PIPE` that will have the same effect, at least
for stdout.
2020-06-09 13:42:35 +02:00
David Rheinsberg
e8445da3d9 test: move test_osbuild.py into module tests
Move the `test_osbuild.py` test into the module-test directory. This
test contains just a bunch of basic functionality tests for a selection
of osbuild modules. Hence, it can be run together with the other module
tests.
2020-06-05 09:27:40 +02:00
David Rheinsberg
3cf8b79e80 test: move test_objectstore into module-tests
Move `test_objectstore` into the module-level tests. This allows us to
run it as part of `make test-module.

Make sure to properly guard it as root-only module.
2020-06-05 09:27:40 +02:00
David Rheinsberg
240905d4a0 test: make TestBase inherit unittest.TestCase
We want to extend our base-class to support extensions to
unittest.TestCase, so make sure we inherit from it.

Adjust all callers to no longer inherit from TestCase, since this is now
done automatically by TestBase.
2020-06-05 09:27:40 +02:00
David Rheinsberg
451ec33d9e test: turn test-doc into test-comment
We use comments in all other tests, rather than doc-strings. Convert the
os-release test to do the same. If we wanted doc-strings, we can convert
all tests over. This commit just tries to keep the tests in-sync.

Note that doc-strings cause `unittest` to print the doc-strings to
stdout during test-execution, making it overly verbose (especially for
multiline docs). By converting it to comments, this behavior is
suppressed.
2020-05-28 11:06:05 +02:00
David Rheinsberg
b830bb7480 test: convert os-release-tests to test-data
Use the new `locate_test_data()` helper to get access to test-data.
Guard the test with `have_test_data()` to skip it in case test-data
access is not available.
2020-05-13 14:26:05 +02:00