mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 12:13:33 +08:00
tests: add test for StartAuxiliaryScope()
This commit is contained in:
parent
84c01612de
commit
fd7fd59b6d
@ -600,4 +600,8 @@ executables += [
|
||||
libudev_basic,
|
||||
],
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-aux-scope.c'),
|
||||
'type' : 'manual',
|
||||
},
|
||||
]
|
||||
|
160
src/test/test-aux-scope.c
Normal file
160
src/test/test-aux-scope.c
Normal file
@ -0,0 +1,160 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "bus-error.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-wait-for-jobs.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "process-util.h"
|
||||
#include "tests.h"
|
||||
|
||||
static int on_sigusr1(sd_event_source *s, const struct signalfd_siginfo *ssi, void *userdata) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
|
||||
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
|
||||
PidRef *pids = (PidRef *) userdata;
|
||||
const char *job;
|
||||
int r;
|
||||
|
||||
assert(pids);
|
||||
|
||||
r = sd_bus_open_system(&bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire bus: %m");
|
||||
|
||||
r = sd_bus_message_new_method_call(bus, &message,
|
||||
"org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1",
|
||||
"org.freedesktop.systemd1.Manager",
|
||||
"StartAuxiliaryScope");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create bus message: %m");
|
||||
|
||||
r = sd_bus_message_append_basic(message, 's', "test-aux-scope.scope");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to attach scope name: %m");
|
||||
|
||||
r = sd_bus_message_open_container(message, 'a', "h");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create array of FDs: %m");
|
||||
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
r = sd_bus_message_append_basic(message, 'h', &pids[i].fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to append PIDFD to message: %m");
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(message);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to close container: %m");
|
||||
|
||||
r = sd_bus_message_append(message, "ta(sv)", UINT64_C(0), 1, "Description", "s", "Test auxiliary scope");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to append unit properties: %m");
|
||||
|
||||
r = sd_bus_call(bus, message, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start auxiliary scope: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &job);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read reply: %m");
|
||||
|
||||
r = bus_wait_for_jobs_new(bus, &w);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not watch jobs: %m");
|
||||
|
||||
r = bus_wait_for_jobs_one(w, job, false, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy_pidrefs(PidRef *pids, size_t npids) {
|
||||
assert(pids || npids == 0);
|
||||
|
||||
for (size_t i = 0; i < npids; i++)
|
||||
pidref_done(&pids[i]);
|
||||
|
||||
free(pids);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
||||
PidRef *pids = NULL;
|
||||
size_t npids = 0;
|
||||
int r, fd;
|
||||
|
||||
CLEANUP_ARRAY(pids, npids, destroy_pidrefs);
|
||||
|
||||
test_setup_logging(LOG_INFO);
|
||||
|
||||
fd = pidfd_open(getpid_cached(), 0);
|
||||
if (fd < 0 && (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno)))
|
||||
return log_tests_skipped("pidfds are not available");
|
||||
else if (fd < 0) {
|
||||
log_error_errno(errno, "pidfd_open() failed: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
safe_close(fd);
|
||||
|
||||
r = sd_event_new(&event);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to allocate event loop: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
npids = 10;
|
||||
pids = new0(PidRef, npids);
|
||||
assert(pids);
|
||||
|
||||
r = sd_event_add_signal(event, NULL, SIGUSR1|SD_EVENT_SIGNAL_PROCMASK, on_sigusr1, pids);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to setup SIGUSR1 signal handling: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < npids; i++) {
|
||||
PidRef pidref = PIDREF_NULL;
|
||||
pid_t pid;
|
||||
|
||||
r = safe_fork("(worker)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS, &pid);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to fork(): %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
/* Worker */
|
||||
sleep(3600);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
r = pidref_set_pid(&pidref, pid);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to initialize PID ref: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
assert_se(pidref.pid == pid);
|
||||
assert_se(pidref.fd != -EBADF);
|
||||
|
||||
pids[i] = TAKE_PIDREF(pidref);
|
||||
}
|
||||
|
||||
r = sd_event_loop(event);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to run event loop: %m");
|
||||
|
||||
return 0;
|
||||
}
|
34
test/units/testsuite-07.aux-scope.sh
Executable file
34
test/units/testsuite-07.aux-scope.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -ex
|
||||
set -o pipefail
|
||||
|
||||
export SYSTEMD_PAGER=cat
|
||||
|
||||
if ! grep -q pidfd_open /proc/kallsyms; then
|
||||
echo "pidfds not available, skipping the test..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
systemd-run --unit test-aux-scope.service \
|
||||
-p Slice=aux.slice -p Type=exec -p TasksMax=99 -p CPUWeight=199 -p IPAccounting=yes \
|
||||
/usr/lib/systemd/tests/unit-tests/manual/test-aux-scope
|
||||
kill -s USR1 "$(systemctl show --value --property MainPID test-aux-scope.service)"
|
||||
|
||||
sleep 1
|
||||
|
||||
systemctl status test-aux-scope.service
|
||||
# shellcheck disable=SC2009
|
||||
test "$(ps -eo pid,unit | grep -c test-aux-scope.service)" = 1
|
||||
|
||||
systemctl status test-aux-scope.scope
|
||||
# shellcheck disable=SC2009
|
||||
test "$(ps -eo pid,unit | grep -c test-aux-scope.scope)" = 10
|
||||
|
||||
test "$(systemctl show -p Slice --value test-aux-scope.scope)" = aux.slice
|
||||
test "$(systemctl show -p TasksMax --value test-aux-scope.scope)" = 99
|
||||
test "$(systemctl show -p CPUWeight --value test-aux-scope.scope)" = 199
|
||||
test "$(systemctl show -p IPAccounting --value test-aux-scope.scope)" = yes
|
||||
|
||||
systemctl stop test-aux-scope.scope
|
||||
systemctl stop test-aux-scope.service
|
Loading…
Reference in New Issue
Block a user