Skip to content

Commit bb9c820

Browse files
committed
Add pipe_stress_test.sh
1 parent 0071ad0 commit bb9c820

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

dd.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import sys
2+
import time
3+
4+
total_bytes = 0
5+
input_file = sys.argv[1] if len(sys.argv) > 1 else "/dev/stdin"
6+
output_file = sys.argv[2] if len(sys.argv) > 2 else "/dev/stdout"
7+
8+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Opening input stream\n")
9+
with open(input_file, "rb") as input_stream:
10+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Opened input stream\n")
11+
12+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Opening output stream\n")
13+
with open(output_file, "wb") as output_stream:
14+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Opened output stream\n")
15+
16+
while True:
17+
chunk = input_stream.read(4096)
18+
if not chunk:
19+
break
20+
output_stream.write(chunk)
21+
total_bytes += len(chunk)
22+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Transferred {len(chunk)} bytes, total {total_bytes}\n")
23+
24+
sys.stderr.write(f"[{time.time_ns()}][dd.py] Transferred total {total_bytes} bytes\n")

pipe_stress_test.sh

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env bash
2+
3+
BYTE_LENGTH="$1"
4+
READER_MODE="${2:-dd}"
5+
WRITER_MODE="${3:-dd}"
6+
7+
TEST_FILE="$(mktemp -t protopipe)"
8+
dd if=/dev/urandom of="$TEST_FILE" bs=1 count="$BYTE_LENGTH" 2>/dev/null
9+
10+
test_pipe() {
11+
# Create a unique temporary directory for the pipe
12+
PIPE_DIR=$(mktemp -d -t protopipe)
13+
PIPE_PATH="$PIPE_DIR/output"
14+
PIPE_DATA_PATH="$PIPE_DIR/pipe_data"
15+
16+
# Create the named pipe
17+
mkfifo "$PIPE_PATH"
18+
echo "Created named pipe at $PIPE_PATH"
19+
20+
# Start monitoring the pipe using fs_usage in the background
21+
# sudo fs_usage -w | grep "$PIPE_PATH" &
22+
# MONITOR_PID=$!
23+
# echo "Started monitoring the pipe $PIPE_PATH (PID: $MONITOR_PID)"
24+
25+
# Start dumping random bytes to the pipe in the background
26+
if [[ "$READER_MODE" == "dd" ]]; then
27+
(dd if="$TEST_FILE" of="$PIPE_PATH" 2>/dev/null && echo "Completed dumping random bytes to the pipe") &
28+
elif [[ "$READER_MODE" == "dd.py" ]]; then
29+
(python3 "$(dirname "$0")"/dd.py "$TEST_FILE" "$PIPE_PATH" && echo "Completed dumping random bytes to the pipe") &
30+
elif [[ "$READER_MODE" == "cat" ]]; then
31+
(cat "$TEST_FILE" > "$PIPE_PATH" && echo "Completed dumping random bytes to the pipe") &
32+
else
33+
echo "Invalid reader mode: $READER_MODE"
34+
exit 1
35+
fi
36+
DUMP_PID=$!
37+
echo "Started dumping random bytes to the pipe (PID: $DUMP_PID)"
38+
39+
# Randomize the sleep duration
40+
SLEEP_DURATION=$((RANDOM % 100))
41+
echo "Sleeping for: $SLEEP_DURATION milliseconds"
42+
sleep "$(echo "scale=3; $SLEEP_DURATION/1000" | bc)"
43+
44+
# Start a process to consume the data from the pipe
45+
if [[ "$WRITER_MODE" == "dd" ]]; then
46+
(dd if="$PIPE_PATH" of="$PIPE_DATA_PATH" 2>/dev/null && echo "Completed consuming random bytes from the pipe") &
47+
elif [[ "$WRITER_MODE" == "dd.py" ]]; then
48+
(python3 "$(dirname "$0")"/dd.py "$PIPE_PATH" "$PIPE_DATA_PATH" && echo "Completed consuming random bytes from the pipe") &
49+
elif [[ "$WRITER_MODE" == "cat" ]]; then
50+
(cat "$PIPE_PATH" > "$PIPE_DATA_PATH" && echo "Completed consuming random bytes from the pipe") &
51+
else
52+
echo "Invalid writer mode: $WRITER_MODE"
53+
exit 1
54+
fi
55+
CONSUME_PID=$!
56+
echo "Started consuming data from the pipe (PID: $CONSUME_PID)"
57+
58+
# Ensure the dumping process is killed
59+
wait $DUMP_PID 2>/dev/null
60+
echo "The dumping process has stopped (PID: $DUMP_PID)"
61+
62+
# Ensure the consuming process is killed
63+
wait $CONSUME_PID 2>/dev/null
64+
echo "The consuming process has stopped (PID: $CONSUME_PID)"
65+
66+
# Stop the monitoring
67+
# kill $MONITOR_PID 2>/dev/null
68+
# wait $MONITOR_PID 2>/dev/null
69+
# echo "Stopped monitoring the pipe (PID: $MONITOR_PID)"
70+
71+
# Check the size of the data read from the pipe
72+
DATA_SIZE=$(wc -c < "$PIPE_DATA_PATH")
73+
if [ "$DATA_SIZE" -ne "$BYTE_LENGTH" ]; then
74+
echo "Error: Expected $BYTE_LENGTH bytes, but read $DATA_SIZE bytes"
75+
exit 1
76+
else
77+
echo "Successfully read $BYTE_LENGTH bytes from the pipe"
78+
fi
79+
80+
# Remove the pipe
81+
rm "$PIPE_PATH"
82+
rm "$PIPE_DATA_PATH"
83+
84+
# Remove the temporary directory
85+
rmdir "$PIPE_DIR"
86+
}
87+
88+
# Kill existing fs_usage instances
89+
# sudo pkill fs_usage
90+
91+
# Repeat the process
92+
counter=0;
93+
while test_pipe; do
94+
((counter++)); echo "Iterations completed: $counter";
95+
done
96+
echo "Command failed after $counter successful iterations."

0 commit comments

Comments
 (0)