mirror of https://github.com/krallin/tini.git
Using the child subreaper mechanism, we can actually run tests inside the CI environment without depending on Docker. While this does not replace the existing tests, it allows at least some functional coverage within CI.pull/5/head
parent
5ed5f227e9
commit
1a863f8366
12 changed files with 156 additions and 14 deletions
@ -1,5 +1,7 @@ |
||||
FROM ubuntu:precise |
||||
|
||||
RUN apt-get update \ |
||||
&& apt-get install --no-install-recommends --yes build-essential git gdb valgrind cmake rpm python3 \ |
||||
&& apt-get install --no-install-recommends --yes build-essential git gdb valgrind cmake rpm python-dev libcap-dev python-pip python-virtualenv \ |
||||
&& rm -rf /var/lib/apt/lists/* |
||||
|
||||
RUN pip install psutil |
||||
|
@ -0,0 +1,35 @@ |
||||
From b8c6ccd4575837e3901bbdee7b219ef951dc2065 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Orozco <thomas@orozco.fr>
|
||||
Date: Sun, 28 Jun 2015 15:25:37 +0200
|
||||
Subject: [PATCH] Add PR_SET_CHILD_SUBREAPER
|
||||
|
||||
---
|
||||
_prctlmodule.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/_prctlmodule.c b/_prctlmodule.c
|
||||
index 14121c3..19ad141 100644
|
||||
--- a/_prctlmodule.c
|
||||
+++ b/_prctlmodule.c
|
||||
@@ -15,6 +15,18 @@
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
+/* Our builds run in a Docker environment that has those, but they are
|
||||
+ * not in the kernel headers. Add them.
|
||||
+ */
|
||||
+
|
||||
+#ifndef PR_SET_CHILD_SUBREAPER
|
||||
+#define PR_SET_CHILD_SUBREAPER 36
|
||||
+#endif
|
||||
+
|
||||
+#ifndef PR_GET_CHILD_SUBREAPER
|
||||
+#define PR_GET_CHILD_SUBREAPER 37
|
||||
+#endif
|
||||
+
|
||||
/* New in 2.6.32, but named and implemented inconsistently. The linux
|
||||
* implementation has two ways of setting the policy to the default, and thus
|
||||
* needs an extra argument. We ignore the first argument and always call
|
||||
--
|
||||
2.4.3
|
||||
|
@ -1,25 +1,34 @@ |
||||
#!/usr/bin/env python3 |
||||
#!/usr/bin/env python |
||||
from __future__ import print_function |
||||
import os |
||||
import subprocess |
||||
import time |
||||
|
||||
import psutil |
||||
|
||||
if __name__ == "__main__": |
||||
|
||||
def main(): |
||||
p = subprocess.Popen([os.path.join(os.path.dirname(__file__), "stage_2.py")]) |
||||
p.wait() |
||||
|
||||
# These are the only PIDs that should remain if the system is well-behaved: |
||||
# - This process |
||||
# - Init |
||||
expected_pids = [1, os.getpid()] |
||||
# In tests, we assume this process is the direct child of init |
||||
this_process = psutil.Process(os.getpid()) |
||||
init_process = this_process.parent() |
||||
|
||||
print("Reaping test: stage_1 is pid{0}, init is pid{1}".format(this_process.pid, init_process.pid)) |
||||
|
||||
# The only child PID that should persist is this one. |
||||
expected_pids = [this_process.pid] |
||||
|
||||
print("Expecting pids to remain: {0}".format(", ".join(str(pid) for pid in expected_pids))) |
||||
|
||||
while 1: |
||||
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] |
||||
print("Has pids: {0}".format(", ".join(pids))) |
||||
if set(int(pid) for pid in pids) == set(expected_pids): |
||||
pids = [p.pid for p in init_process.children(recursive=True)] |
||||
print("Has pids: {0}".format(", ".join(str(pid) for pid in pids))) |
||||
if set(pids) == set(expected_pids): |
||||
break |
||||
time.sleep(1) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
main() |
||||
|
@ -0,0 +1,33 @@ |
||||
#!/usr/bin/env python |
||||
#coding:utf-8 |
||||
import os |
||||
import sys |
||||
import signal |
||||
import subprocess |
||||
|
||||
|
||||
def main(): |
||||
src = os.environ["SOURCE_DIR"] |
||||
build = os.environ["BUILD_DIR"] |
||||
|
||||
proxy = os.path.join(src, "test", "subreaper-proxy.py") |
||||
tini = os.path.join(build, "tini") |
||||
|
||||
# Run the reaping test |
||||
print "Running reaping test" |
||||
p = subprocess.Popen([proxy, tini, "--", os.path.join(src, "test", "reaping", "stage_1.py")]) |
||||
ret = p.wait() |
||||
assert ret == 0, "Reaping test failed!" |
||||
|
||||
# Run the signals test |
||||
for signame in "SIGINT", "SIGTERM": |
||||
print "running signal test for: {0}".format(signame) |
||||
p = subprocess.Popen([proxy, tini, "--", os.path.join(src, "test", "signals", "test.py")]) |
||||
sig = getattr(signal, signame) |
||||
p.send_signal(sig) |
||||
ret = p.wait() |
||||
assert ret == - sig, "Signals test failed!" |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
main() |
@ -0,0 +1,19 @@ |
||||
#!/usr/bin/env python |
||||
#coding:utf-8 |
||||
import os |
||||
import sys |
||||
|
||||
import prctl |
||||
|
||||
|
||||
def main(): |
||||
args = sys.argv[1:] |
||||
|
||||
print "subreaper-proxy: running '%s'" % (" ".join(args)) |
||||
|
||||
prctl.set_child_subreaper(1) |
||||
os.execv(args[0], args) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
Loading…
Reference in new issue