summaryrefslogtreecommitdiff
path: root/corebinutils/ps/tests
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:27:51 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:27:51 +0300
commit76166d4f612e1318ffe99493f9d8b578887b1278 (patch)
tree3bcce2f92ac70b9f282c905397f4bdc32dc70b39 /corebinutils/ps/tests
parente99e87d16cdba1de0cfd84ce1a231ad3371e43db (diff)
parent29b985290c171926c765c571e8711276c4d9aae0 (diff)
downloadProject-Tick-76166d4f612e1318ffe99493f9d8b578887b1278.tar.gz
Project-Tick-76166d4f612e1318ffe99493f9d8b578887b1278.zip
Add 'corebinutils/ps/' from commit '29b985290c171926c765c571e8711276c4d9aae0'
git-subtree-dir: corebinutils/ps git-subtree-mainline: e99e87d16cdba1de0cfd84ce1a231ad3371e43db git-subtree-split: 29b985290c171926c765c571e8711276c4d9aae0
Diffstat (limited to 'corebinutils/ps/tests')
-rw-r--r--corebinutils/ps/tests/spin_helper.c45
-rw-r--r--corebinutils/ps/tests/test.sh150
2 files changed, 195 insertions, 0 deletions
diff --git a/corebinutils/ps/tests/spin_helper.c b/corebinutils/ps/tests/spin_helper.c
new file mode 100644
index 0000000000..eef1d0e3b7
--- /dev/null
+++ b/corebinutils/ps/tests/spin_helper.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/prctl.h>
+
+/*
+ * Small helper to create processes with predictable names/properties for ps tests.
+ */
+
+static void
+handle_sigterm(int sig)
+{
+ (void)sig;
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <name> [arg...]\n", argv[0]);
+ return (1);
+ }
+
+ /* Set name for /proc/self/comm (visible in ps -c) */
+ prctl(PR_SET_NAME, argv[1], 0, 0, 0);
+
+ signal(SIGTERM, handle_sigterm);
+
+ /* Busy wait in background to consume some CPU time if needed */
+ if (argc > 2 && strcmp(argv[2], "busy") == 0) {
+ while (1) {
+ /* Do nothing, just spin */
+ }
+ }
+
+ /* Normal idle wait */
+ while (1) {
+ pause();
+ }
+
+ return (0);
+}
diff --git a/corebinutils/ps/tests/test.sh b/corebinutils/ps/tests/test.sh
new file mode 100644
index 0000000000..004bd9f372
--- /dev/null
+++ b/corebinutils/ps/tests/test.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+
+# ps tests
+#
+# Assumptions:
+# - PS_BIN points to the newly built ps
+# - TEST_HELPER points to tests/spin_helper.c compiled into out/tests/spin_helper
+
+# Colors
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+NC='\033[0m'
+
+fail() {
+ printf "${RED}FAIL: %s${NC}\n" "$1" >&2
+ exit 1
+}
+
+pass() {
+ printf "${GREEN}PASS: %s${NC}\n" "$1"
+}
+
+# Build a ps-specific helper in shared out/ roots to avoid name collisions
+# with other test suites (e.g. pkill also has a spin_helper).
+HELPER_DIR="$(dirname "$0")"
+OUT_DIR="$(dirname "${PS_BIN}")"
+HELPER_BIN="${OUT_DIR}/ps_spin_helper"
+HELPER_SRC="${HELPER_DIR}/spin_helper.c"
+CC_BIN="${CC:-cc}"
+
+if [ ! -x "${HELPER_BIN}" ] || [ "${HELPER_SRC}" -nt "${HELPER_BIN}" ]; then
+ "${CC_BIN}" -O2 "${HELPER_SRC}" -o "${HELPER_BIN}" || fail "failed to compile spin_helper"
+fi
+
+# 1. Basic sanity: run without arguments
+# Should output at least headers and some processes.
+${PS_BIN} > /tmp/ps_out || fail "ps failed to run"
+grep -q "PID" /tmp/ps_out || fail "ps output lacks PID header"
+grep -q "COMMAND" /tmp/ps_out || fail "ps output lacks COMMAND header"
+pass "Basic sanity (no args)"
+
+# 2. Process selection: -p
+# Start a helper, then find it with ps.
+${HELPER_BIN} test-ps-select &
+HELPER_PID=$!
+sleep 0.1
+${PS_BIN} -p ${HELPER_PID} > /tmp/ps_p_out || fail "ps -p failed"
+grep -q "${HELPER_PID}" /tmp/ps_p_out || fail "ps -p did not find helper pid ${HELPER_PID}"
+kill ${HELPER_PID}
+pass "Process selection (-p pid)"
+
+# 3. Format selection: -j
+${HELPER_BIN} test-ps-fmt-j &
+HELPER_PID=$!
+sleep 0.1
+${PS_BIN} -j -p ${HELPER_PID} > /tmp/ps_j_out || fail "ps -j failed"
+grep -q "USER" /tmp/ps_j_out || fail "ps -j output lacks USER header"
+grep -q "PPID" /tmp/ps_j_out || fail "ps -j output lacks PPID header"
+grep -q "SID" /tmp/ps_j_out || fail "ps -j output lacks SID header"
+kill ${HELPER_PID}
+pass "Format selection (-j)"
+
+# 4. Format selection: -u
+${HELPER_BIN} test-ps-fmt-u &
+HELPER_PID=$!
+sleep 0.1
+${PS_BIN} -u -p ${HELPER_PID} > /tmp/ps_u_out || fail "ps -u failed"
+grep -q "%CPU" /tmp/ps_u_out || fail "ps -u output lacks %CPU header"
+grep -q "%MEM" /tmp/ps_u_out || fail "ps -u output lacks %MEM header"
+grep -q "VSZ" /tmp/ps_u_out || fail "ps -u output lacks VSZ header"
+grep -q "RSS" /tmp/ps_u_out || fail "ps -u output lacks RSS header"
+kill ${HELPER_PID}
+pass "Format selection (-u)"
+
+# 5. Format selection: -o (custom)
+${HELPER_BIN} test-ps-fmt-o &
+HELPER_PID=$!
+sleep 0.1
+${PS_BIN} -o pid,comm,nice -p ${HELPER_PID} > /tmp/ps_o_out || fail "ps -o failed"
+grep -q "PID" /tmp/ps_o_out || fail "ps -o output lacks PID header"
+grep -q "COMMAND" /tmp/ps_o_out || fail "ps -o output lacks COMMAND header"
+grep -q "NI" /tmp/ps_o_out || fail "ps -o output lacks NI header"
+# First line is header, second line should contain the PID.
+grep -q "${HELPER_PID}" /tmp/ps_o_out || fail "ps -o did not find helper pid"
+kill ${HELPER_PID}
+pass "Format selection (-o pid,comm,nice)"
+
+# 6. Sorting: -m (by memory) and -r (by cpu)
+${PS_BIN} -m -A > /dev/null || fail "ps -m -A failed"
+${PS_BIN} -r -A > /dev/null || fail "ps -r -A failed"
+pass "Sorting (-m, -r)"
+
+# 7. Negative test: invalid pid
+${PS_BIN} -p 999999 > /tmp/ps_neg_out 2>&1
+# FreeBSD ps should just print header and exits 1 if no matches found?
+# Actually, standard behavior varies. Let's check status.
+EXIT_CODE=$?
+if [ ${EXIT_CODE} -ne 1 ]; then
+ # In some versions, no match means exit 1. In others, exit 0.
+ # FreeBSD ps.c: main() calls exit(1) if nkept == 0.
+ fail "ps -p invalid_pid should exit 1 (got ${EXIT_CODE})"
+fi
+pass "Negative test (invalid pid)"
+
+# 8. Negative test: invalid flag
+${PS_BIN} -Y > /dev/null 2>&1
+if [ $? -eq 0 ]; then
+ fail "ps -Y should fail"
+fi
+pass "Negative test (invalid flag)"
+
+# 9. Width test: -w
+${HELPER_BIN} test-ps-width-very-long-name-to-check-truncation &
+HELPER_PID=$!
+sleep 0.1
+# Record output without -w (should truncate or at least be limited)
+${PS_BIN} -u -p ${HELPER_PID} > /tmp/ps_w1
+# Record output with -ww (no limit)
+${PS_BIN} -u -ww -p ${HELPER_PID} > /tmp/ps_w2
+# Compare -w2 should be longer or equal to -w1 in terms of line length
+LEN1=$(awk '{ print length }' /tmp/ps_w1 | sort -nr | head -1)
+LEN2=$(awk '{ print length }' /tmp/ps_w2 | sort -nr | head -1)
+if [ "${LEN2}" -lt "${LEN1}" ]; then
+ fail "ps -ww output shorter than normal output"
+fi
+kill ${HELPER_PID}
+pass "Width control (-w, -ww)"
+
+# 10. Headers control: -h
+# Start 30 helpers safely.
+I=1
+while [ ${I} -le 30 ]; do
+ ${HELPER_BIN} test-ps-h-${I} &
+ H_PIDS="${H_PIDS} $!"
+ I=$((I+1))
+done
+sleep 0.1
+# Run ps -h -A (repeat headers every 22 lines or so)
+${PS_BIN} -h -A | grep "PID" | wc -l > /tmp/ps_h_count
+COUNT=$(cat /tmp/ps_h_count)
+if [ "${COUNT}" -lt 2 ]; then
+ fail "ps -h should repeat headers (got ${COUNT} headers for 30+ processes)"
+fi
+kill ${H_PIDS}
+pass "Header repetition (-h)"
+
+# Clean up
+rm -f /tmp/ps_*
+printf "${GREEN}All tests passed!${NC}\n"
+exit 0