xref: /src/contrib/kyua/utils/process/executor_pid_test.cpp (revision 6b13d60bf49ee40626d7e3a5d5a80519f0067307)
15f174897SMuhammad Moinur Rahman /*-
25f174897SMuhammad Moinur Rahman  * SPDX-License-Identifier: BSD-2-Clause
35f174897SMuhammad Moinur Rahman  *
45f174897SMuhammad Moinur Rahman  * Copyright (c) 2022 Dell Inc.
55f174897SMuhammad Moinur Rahman  * Author: Eric van Gyzen
65f174897SMuhammad Moinur Rahman  *
75f174897SMuhammad Moinur Rahman  * Redistribution and use in source and binary forms, with or without
85f174897SMuhammad Moinur Rahman  * modification, are permitted provided that the following conditions
95f174897SMuhammad Moinur Rahman  * are met:
105f174897SMuhammad Moinur Rahman  * 1. Redistributions of source code must retain the above copyright
115f174897SMuhammad Moinur Rahman  *    notice, this list of conditions and the following disclaimer.
125f174897SMuhammad Moinur Rahman  * 2. Redistributions in binary form must reproduce the above copyright
135f174897SMuhammad Moinur Rahman  *    notice, this list of conditions and the following disclaimer in the
145f174897SMuhammad Moinur Rahman  *    documentation and/or other materials provided with the distribution.
155f174897SMuhammad Moinur Rahman  *
165f174897SMuhammad Moinur Rahman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
175f174897SMuhammad Moinur Rahman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185f174897SMuhammad Moinur Rahman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195f174897SMuhammad Moinur Rahman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
205f174897SMuhammad Moinur Rahman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215f174897SMuhammad Moinur Rahman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
225f174897SMuhammad Moinur Rahman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235f174897SMuhammad Moinur Rahman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
245f174897SMuhammad Moinur Rahman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255f174897SMuhammad Moinur Rahman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265f174897SMuhammad Moinur Rahman  * SUCH DAMAGE.
275f174897SMuhammad Moinur Rahman  */
285f174897SMuhammad Moinur Rahman 
295f174897SMuhammad Moinur Rahman #if 0
305f174897SMuhammad Moinur Rahman 
315f174897SMuhammad Moinur Rahman 1. Run some "bad" tests that prevent kyua from removing the work directory.
325f174897SMuhammad Moinur Rahman    We use "chflags uunlink".  Mounting a file system from an md(4) device
335f174897SMuhammad Moinur Rahman    is another common use case.
345f174897SMuhammad Moinur Rahman 2. Fork a lot, nearly wrapping the PID number space, so step 3 will re-use
355f174897SMuhammad Moinur Rahman    a PID from step 1.  Running the entire FreeBSD test suite is a more
365f174897SMuhammad Moinur Rahman    realistic scenario for this step.
375f174897SMuhammad Moinur Rahman 3. Run some more tests.  If the stars align, the bug is not fixed yet, and
385f174897SMuhammad Moinur Rahman    kyua is built with debugging, kyua will abort with the following messages.
395f174897SMuhammad Moinur Rahman    Without debugging, the tests in step 3 will reuse the context from step 1,
405f174897SMuhammad Moinur Rahman    including stdout, stderr, and working directory, which are still populated
415f174897SMuhammad Moinur Rahman    with stuff from step 1.  When I found this bug, step 3 was
425f174897SMuhammad Moinur Rahman    __test_cases_list__, which expects a certain format in stdout and failed
435f174897SMuhammad Moinur Rahman    when it found something completely unrelated.
445f174897SMuhammad Moinur Rahman 4. You can clean up with: chflags -R nouunlink /tmp/kyua.*; rm -rf /tmp/kyua.*
455f174897SMuhammad Moinur Rahman 
465f174897SMuhammad Moinur Rahman $ cc -o pid_wrap -latf-c pid_wrap.c
475f174897SMuhammad Moinur Rahman $ kyua test
485f174897SMuhammad Moinur Rahman pid_wrap:leak_0  ->  passed  [0.001s]
495f174897SMuhammad Moinur Rahman pid_wrap:leak_1  ->  passed  [0.001s]
505f174897SMuhammad Moinur Rahman pid_wrap:leak_2  ->  passed  [0.001s]
515f174897SMuhammad Moinur Rahman pid_wrap:leak_3  ->  passed  [0.001s]
525f174897SMuhammad Moinur Rahman pid_wrap:leak_4  ->  passed  [0.001s]
535f174897SMuhammad Moinur Rahman pid_wrap:leak_5  ->  passed  [0.001s]
545f174897SMuhammad Moinur Rahman pid_wrap:leak_6  ->  passed  [0.001s]
555f174897SMuhammad Moinur Rahman pid_wrap:leak_7  ->  passed  [0.001s]
565f174897SMuhammad Moinur Rahman pid_wrap:leak_8  ->  passed  [0.001s]
575f174897SMuhammad Moinur Rahman pid_wrap:leak_9  ->  passed  [0.001s]
585f174897SMuhammad Moinur Rahman pid_wrap:pid_wrap  ->  passed  [1.113s]
595f174897SMuhammad Moinur Rahman pid_wrap:pid_wrap_0  ->  passed  [0.001s]
605f174897SMuhammad Moinur Rahman pid_wrap:pid_wrap_1  ->  passed  [0.001s]
615f174897SMuhammad Moinur Rahman pid_wrap:pid_wrap_2  ->  passed  [0.001s]
625f174897SMuhammad Moinur Rahman pid_wrap:pid_wrap_3  ->  *** /usr/src/main/contrib/kyua/utils/process/executor.cpp:779: Invariant check failed: PID 60876 already in all_exec_handles; not properly cleaned up or reused too fast
635f174897SMuhammad Moinur Rahman *** Fatal signal 6 received
645f174897SMuhammad Moinur Rahman *** Log file is /home/vangyzen/.kyua/logs/kyua.20221006-193544.log
655f174897SMuhammad Moinur Rahman *** Please report this problem to kyua-discuss@googlegroups.com detailing what you were doing before the crash happened; if possible, include the log file mentioned above
665f174897SMuhammad Moinur Rahman Abort trap (core dumped)
675f174897SMuhammad Moinur Rahman 
685f174897SMuhammad Moinur Rahman #endif
695f174897SMuhammad Moinur Rahman 
705f174897SMuhammad Moinur Rahman #include <sys/stat.h>
715f174897SMuhammad Moinur Rahman 
725f174897SMuhammad Moinur Rahman #include <atf-c++.hpp>
735f174897SMuhammad Moinur Rahman 
745f174897SMuhammad Moinur Rahman #include <fcntl.h>
755f174897SMuhammad Moinur Rahman #include <signal.h>
765f174897SMuhammad Moinur Rahman #include <unistd.h>
775f174897SMuhammad Moinur Rahman 
785f174897SMuhammad Moinur Rahman #include <cerrno>
795f174897SMuhammad Moinur Rahman #include <cstring>
805f174897SMuhammad Moinur Rahman 
815f174897SMuhammad Moinur Rahman void
leak_work_dir()825f174897SMuhammad Moinur Rahman leak_work_dir()
835f174897SMuhammad Moinur Rahman {
845f174897SMuhammad Moinur Rahman 	int fd;
855f174897SMuhammad Moinur Rahman 
865f174897SMuhammad Moinur Rahman 	ATF_REQUIRE((fd = open("unforgettable", O_CREAT|O_EXCL|O_WRONLY, 0600))
875f174897SMuhammad Moinur Rahman 	    >= 0);
885f174897SMuhammad Moinur Rahman 	ATF_REQUIRE_EQ(0, fchflags(fd, UF_NOUNLINK));
895f174897SMuhammad Moinur Rahman 	ATF_REQUIRE_EQ(0, close(fd));
905f174897SMuhammad Moinur Rahman }
915f174897SMuhammad Moinur Rahman 
925f174897SMuhammad Moinur Rahman void
wrap_pids()935f174897SMuhammad Moinur Rahman wrap_pids()
945f174897SMuhammad Moinur Rahman {
955f174897SMuhammad Moinur Rahman 	pid_t begin, current, target;
965f174897SMuhammad Moinur Rahman 	bool wrapped;
975f174897SMuhammad Moinur Rahman 
985f174897SMuhammad Moinur Rahman 	begin = getpid();
995f174897SMuhammad Moinur Rahman 	target = begin - 15;
1005f174897SMuhammad Moinur Rahman 	if (target <= 1) {
1015f174897SMuhammad Moinur Rahman 		target += 99999;    // PID_MAX
1025f174897SMuhammad Moinur Rahman 		wrapped = true;
1035f174897SMuhammad Moinur Rahman 	} else {
1045f174897SMuhammad Moinur Rahman 		wrapped = false;
1055f174897SMuhammad Moinur Rahman 	}
1065f174897SMuhammad Moinur Rahman 
1075f174897SMuhammad Moinur Rahman 	ATF_REQUIRE(signal(SIGCHLD, SIG_IGN) != SIG_ERR);
1085f174897SMuhammad Moinur Rahman 
1095f174897SMuhammad Moinur Rahman 	do {
1105f174897SMuhammad Moinur Rahman 		current = vfork();
1115f174897SMuhammad Moinur Rahman 		if (current == 0) {
1125f174897SMuhammad Moinur Rahman 			_exit(0);
1135f174897SMuhammad Moinur Rahman 		}
1145f174897SMuhammad Moinur Rahman 		ATF_REQUIRE(current != -1);
1155f174897SMuhammad Moinur Rahman 		if (current < begin) {
1165f174897SMuhammad Moinur Rahman 			wrapped = true;
1175f174897SMuhammad Moinur Rahman 		}
1185f174897SMuhammad Moinur Rahman 	} while (!wrapped || current < target);
1195f174897SMuhammad Moinur Rahman }
1205f174897SMuhammad Moinur Rahman 
1215f174897SMuhammad Moinur Rahman void
test_work_dir_reuse()1225f174897SMuhammad Moinur Rahman test_work_dir_reuse()
1235f174897SMuhammad Moinur Rahman {
1245f174897SMuhammad Moinur Rahman 	// If kyua is built with debugging, it would abort here before the fix.
1255f174897SMuhammad Moinur Rahman }
1265f174897SMuhammad Moinur Rahman 
1275f174897SMuhammad Moinur Rahman void
clean_up()1285f174897SMuhammad Moinur Rahman clean_up()
1295f174897SMuhammad Moinur Rahman {
1305f174897SMuhammad Moinur Rahman 	(void)system("chflags -R nouunlink ../..");
1315f174897SMuhammad Moinur Rahman }
1325f174897SMuhammad Moinur Rahman 
1335f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_0);
ATF_TEST_CASE_BODY(leak_0)1345f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_0) { leak_work_dir(); }
1355f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_1);
ATF_TEST_CASE_BODY(leak_1)1365f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_1) { leak_work_dir(); }
1375f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_2);
ATF_TEST_CASE_BODY(leak_2)1385f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_2) { leak_work_dir(); }
1395f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_3);
ATF_TEST_CASE_BODY(leak_3)1405f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_3) { leak_work_dir(); }
1415f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_4);
ATF_TEST_CASE_BODY(leak_4)1425f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_4) { leak_work_dir(); }
1435f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_5);
ATF_TEST_CASE_BODY(leak_5)1445f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_5) { leak_work_dir(); }
1455f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_6);
ATF_TEST_CASE_BODY(leak_6)1465f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_6) { leak_work_dir(); }
1475f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_7);
ATF_TEST_CASE_BODY(leak_7)1485f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_7) { leak_work_dir(); }
1495f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_8);
ATF_TEST_CASE_BODY(leak_8)1505f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_8) { leak_work_dir(); }
1515f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(leak_9);
ATF_TEST_CASE_BODY(leak_9)1525f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(leak_9) { leak_work_dir(); }
1535f174897SMuhammad Moinur Rahman 
1545f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap);
ATF_TEST_CASE_BODY(pid_wrap)1555f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap) { wrap_pids(); }
1565f174897SMuhammad Moinur Rahman 
1575f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_0);
ATF_TEST_CASE_BODY(pid_wrap_0)1585f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_0) { test_work_dir_reuse(); }
1595f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_1);
ATF_TEST_CASE_BODY(pid_wrap_1)1605f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_1) { test_work_dir_reuse(); }
1615f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_2);
ATF_TEST_CASE_BODY(pid_wrap_2)1625f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_2) { test_work_dir_reuse(); }
1635f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_3);
ATF_TEST_CASE_BODY(pid_wrap_3)1645f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_3) { test_work_dir_reuse(); }
1655f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_4);
ATF_TEST_CASE_BODY(pid_wrap_4)1665f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_4) { test_work_dir_reuse(); }
1675f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_5);
ATF_TEST_CASE_BODY(pid_wrap_5)1685f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_5) { test_work_dir_reuse(); }
1695f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_6);
ATF_TEST_CASE_BODY(pid_wrap_6)1705f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_6) { test_work_dir_reuse(); }
1715f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_7);
ATF_TEST_CASE_BODY(pid_wrap_7)1725f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_7) { test_work_dir_reuse(); }
1735f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_8);
ATF_TEST_CASE_BODY(pid_wrap_8)1745f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_8) { test_work_dir_reuse(); }
1755f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(pid_wrap_9);
ATF_TEST_CASE_BODY(pid_wrap_9)1765f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(pid_wrap_9) { test_work_dir_reuse(); }
1775f174897SMuhammad Moinur Rahman 
1785f174897SMuhammad Moinur Rahman ATF_TEST_CASE_WITHOUT_HEAD(really_clean_up);
ATF_TEST_CASE_BODY(really_clean_up)1795f174897SMuhammad Moinur Rahman ATF_TEST_CASE_BODY(really_clean_up) { clean_up(); }
1805f174897SMuhammad Moinur Rahman 
ATF_INIT_TEST_CASES(tcs)1815f174897SMuhammad Moinur Rahman ATF_INIT_TEST_CASES(tcs)
1825f174897SMuhammad Moinur Rahman {
1835f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_0);
1845f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_1);
1855f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_2);
1865f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_3);
1875f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_4);
1885f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_5);
1895f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_6);
1905f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_7);
1915f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_8);
1925f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, leak_9);
1935f174897SMuhammad Moinur Rahman 
1945f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap);
1955f174897SMuhammad Moinur Rahman 
1965f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_0);
1975f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_1);
1985f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_2);
1995f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_3);
2005f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_4);
2015f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_5);
2025f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_6);
2035f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_7);
2045f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_8);
2055f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, pid_wrap_9);
2065f174897SMuhammad Moinur Rahman 
2075f174897SMuhammad Moinur Rahman 	ATF_ADD_TEST_CASE(tcs, really_clean_up);
2085f174897SMuhammad Moinur Rahman }
209