Skip to content

Commit 33e1fd2

Browse files
committed
crit: add tests for compress and decompress commands
Add five tests covering compress and decompress round-trips using compress_pages02 which exercises all eight mapping types (anonymous, zeros, shared, file-backed, memfd, read-only, guard pages). - compressed dump, decompress with crit, restore and verify - uncompressed dump, compress with crit, restore and verify - compress already compressed, decompress already decompressed - compress, decompress, compress, verify pages are identical - decompress, compress, decompress, verify pages are identical Each restore runs the test process which verifies all memory regions byte-by-byte. The round-trip tests also compare md5 checksums of the raw pages data across cycles. When lz4 or CRIU compression support is not available, the tests are skipped gracefully. Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
1 parent 841e23d commit 33e1fd2

6 files changed

Lines changed: 215 additions & 4 deletions

File tree

criu/config.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "cpu.h"
1717
#include "crtools.h"
1818
#include "cr_options.h"
19+
#include "compression.h"
1920
#include "filesystems.h"
2021
#include "file-lock.h"
2122
#include "image.h"
@@ -828,8 +829,9 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
828829
char *endptr;
829830
long accel = strtol(optarg, &endptr, 10);
830831

831-
if (*endptr != '\0' || accel < 1 || accel > 65537) {
832-
pr_err("Invalid --compress-acceleration value '%s' (must be 1..65537)\n", optarg);
832+
if (*endptr != '\0' || accel < 1 || accel > LZ4_MAX_ACCELERATION) {
833+
pr_err("Invalid --compress-acceleration value '%s' (must be 1..%d)\n",
834+
optarg, LZ4_MAX_ACCELERATION);
833835
return 1;
834836
}
835837
opts.compress_acceleration = accel;

criu/include/compression.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ enum compress_mode {
5252
* Higher values skip more match candidates, resulting in
5353
* faster compression but fewer and shorter matches.
5454
* Decompression speed is not affected (~4970 MB/s always).
55-
* Valid range: 1 to LZ4_ACCELERATION_MAX (65537).
55+
* Valid range: 1 to LZ4_MAX_ACCELERATION.
5656
*/
57+
#define LZ4_MAX_ACCELERATION 65537
5758
#define LZ4_DEFAULT_ACCELERATION 1
5859

5960
/*

criu/include/cr_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ struct cr_options {
231231
/*
232232
* LZ4 acceleration level for page compression.
233233
* Internal: 0 means the user did not set a value (default acceleration).
234-
* CLI/RPC accept 1..65537 (higher = faster, lower ratio).
234+
* CLI/RPC accept 1..LZ4_MAX_ACCELERATION (higher = faster, lower ratio).
235235
*/
236236
unsigned int compress_acceleration;
237237

test/others/crit/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
*.txt
44
stats-*
55
*.json
6+
comp/
7+
uncomp/
8+
cdc/
9+
dcd/

test/others/crit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ run: clean
44

55
clean:
66
rm -f *.img *.log *.txt stats-* *.json
7+
rm -rf comp/ uncomp/ cdc/ dcd/

test/others/crit/test.sh

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,211 @@ function run_test2 {
101101
${CRIT} x ./ rss || exit 1
102102
}
103103

104+
ZDTM_DIR="${BASE_DIR}/test/zdtm/static"
105+
106+
function dump_test_process {
107+
# Dump compress_pages02 (covers 8 mapping types: anonymous,
108+
# zero-filled, shared anonymous, file-backed private/shared,
109+
# memfd, read-only, PROT_NONE guard) into the given directory.
110+
# Prints the PID on success.
111+
local dir=$1; shift
112+
local pid
113+
114+
make -C "$ZDTM_DIR" compress_pages02 > /dev/null 2>&1
115+
116+
# Clean stale marker files and run from the test directory
117+
# so zdtm pidfile rename works (same filesystem).
118+
rm -f "$dir"/test.out* "$dir"/test.pid "$dir"/test.file
119+
120+
(cd "$dir" && "$ZDTM_DIR/compress_pages02" \
121+
--pidfile=test.pid \
122+
--outfile=test.out \
123+
--filename=test.file)
124+
125+
# Wait for pidfile
126+
local i=0
127+
while [ $i -lt 50 ]; do
128+
if [ -f "$dir/test.pid" ]; then
129+
break
130+
fi
131+
sleep 0.1
132+
i=$((i + 1))
133+
done
134+
135+
pid=$(cat "$dir/test.pid" 2>/dev/null)
136+
if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then
137+
echo "FAIL: test process didn't start"
138+
cat "$dir/test.out" 2>/dev/null
139+
exit 1
140+
fi
141+
142+
if ! $CRIU dump -v4 -o dump.log -D "$dir" -t "$pid" --shell-job "$@"; then
143+
echo "FAIL: dump into $dir"
144+
cat "$dir/dump.log"
145+
kill -9 "$pid" 2>/dev/null
146+
exit 1
147+
fi
148+
echo "$pid"
149+
}
150+
151+
function restore_and_verify {
152+
# Restore from directory, send SIGTERM so compress_pages02
153+
# verifies its own memory, then check the test output for PASS.
154+
local dir=$1
155+
local pid
156+
157+
if ! $CRIU restore -v4 -o restore.log -D "$dir" --shell-job -d; then
158+
echo "FAIL: restore from $dir"
159+
cat "$dir/restore.log"
160+
exit 1
161+
fi
162+
163+
# Get the root PID from the pstree image
164+
pid=$($CRIT decode -i "$dir/pstree.img" 2>/dev/null |
165+
grep -o '"pid": [0-9]*' | head -1 | grep -o '[0-9]*')
166+
167+
if [ -z "$pid" ] || ! kill -0 "$pid" 2>/dev/null; then
168+
echo "FAIL: restored process not running from $dir (pid=$pid)"
169+
exit 1
170+
fi
171+
172+
# Send SIGTERM so compress_pages02 verifies all memory
173+
# regions (zero, pattern, shared, file, memfd, readonly,
174+
# guard) then writes PASS/FAIL to its output file.
175+
kill -TERM "$pid" 2>/dev/null
176+
wait "$pid" 2>/dev/null
177+
sleep 0.5
178+
179+
if ! grep -q PASS "$dir/test.out" 2>/dev/null; then
180+
echo "FAIL: memory verification failed after restore from $dir"
181+
cat "$dir/test.out" 2>/dev/null
182+
exit 1
183+
fi
184+
}
185+
186+
function pages_checksum {
187+
# Print md5sum of all pages-*.img files in a directory.
188+
# This captures the raw page content for comparison.
189+
cat "$1"/pages-*.img | md5sum | awk '{print $1}'
190+
}
191+
192+
function run_test_compress {
193+
echo "=== compress/decompress tests ==="
194+
195+
# -------------------------------------------------------
196+
# Test 1: dump -c -> decompress -> restore
197+
# -------------------------------------------------------
198+
echo " -- Test 1: compressed dump -> decompress -> restore"
199+
dump_test_process comp/ -c > /dev/null
200+
201+
$CRIT decompress comp/ || exit 1
202+
203+
# Verify backup files exist
204+
ls comp/pages-*.img.bak > /dev/null 2>&1 || { echo "FAIL: no pages backup"; exit 1; }
205+
ls comp/pagemap-*.img.bak > /dev/null 2>&1 || { echo "FAIL: no pagemap backup"; exit 1; }
206+
ls comp/inventory.img.bak > /dev/null 2>&1 || { echo "FAIL: no inventory backup"; exit 1; }
207+
208+
restore_and_verify comp/
209+
echo " PASS"
210+
211+
# -------------------------------------------------------
212+
# Test 2: dump uncompressed -> compress -> restore
213+
# -------------------------------------------------------
214+
echo " -- Test 2: uncompressed dump -> compress -> restore"
215+
dump_test_process uncomp/ > /dev/null
216+
217+
$CRIT compress uncomp/ --in-place || exit 1
218+
219+
# Verify no backup files with --in-place
220+
if ls uncomp/*.bak > /dev/null 2>&1; then
221+
echo "FAIL: backup files created with --in-place"
222+
exit 1
223+
fi
224+
225+
restore_and_verify uncomp/
226+
echo " PASS"
227+
228+
# -------------------------------------------------------
229+
# Test 3: compress already compressed, decompress already decompressed
230+
# -------------------------------------------------------
231+
echo " -- Test 3: compress already compressed, decompress already decompressed"
232+
$CRIT compress uncomp/ --in-place 2>&1 | grep -q "already compressed" || {
233+
echo "FAIL: compress should report already compressed"
234+
exit 1
235+
}
236+
$CRIT decompress comp/ 2>&1 | grep -q "already decompressed" || {
237+
echo "FAIL: decompress should report already decompressed"
238+
exit 1
239+
}
240+
echo " PASS"
241+
242+
# -------------------------------------------------------
243+
# Test 4: compress -> decompress -> compress produces same pages
244+
# -------------------------------------------------------
245+
echo " -- Test 4: compress -> decompress -> compress stability"
246+
rm -rf cdc/
247+
mkdir -p cdc/
248+
dump_test_process cdc/ > /dev/null
249+
250+
$CRIT compress cdc/ --in-place || exit 1
251+
local sum1
252+
sum1=$(pages_checksum cdc/)
253+
254+
$CRIT decompress cdc/ --in-place || exit 1
255+
$CRIT compress cdc/ --in-place || exit 1
256+
local sum2
257+
sum2=$(pages_checksum cdc/)
258+
259+
if [ "$sum1" != "$sum2" ]; then
260+
echo "FAIL: compress->decompress->compress changed pages data"
261+
echo " first: $sum1"
262+
echo " second: $sum2"
263+
exit 1
264+
fi
265+
266+
restore_and_verify cdc/
267+
echo " PASS"
268+
269+
# -------------------------------------------------------
270+
# Test 5: decompress -> compress -> decompress produces same pages
271+
# -------------------------------------------------------
272+
echo " -- Test 5: decompress -> compress -> decompress stability"
273+
rm -rf dcd/
274+
mkdir -p dcd/
275+
dump_test_process dcd/ -c > /dev/null
276+
277+
$CRIT decompress dcd/ --in-place || exit 1
278+
local sum3
279+
sum3=$(pages_checksum dcd/)
280+
281+
$CRIT compress dcd/ --in-place || exit 1
282+
$CRIT decompress dcd/ --in-place || exit 1
283+
local sum4
284+
sum4=$(pages_checksum dcd/)
285+
286+
if [ "$sum3" != "$sum4" ]; then
287+
echo "FAIL: decompress->compress->decompress changed pages data"
288+
echo " first: $sum3"
289+
echo " second: $sum4"
290+
exit 1
291+
fi
292+
293+
restore_and_verify dcd/
294+
echo " PASS"
295+
296+
echo "=== compress/decompress: ALL PASS ==="
297+
}
298+
104299
${CRIT} --version
105300

106301
gen_imgs
107302
run_test1
108303
run_test2
304+
305+
# Skip compress/decompress tests if lz4 or CRIU compression is unavailable
306+
if python3 -c "import lz4.block" 2>/dev/null && $CRIU check --feature compress 2>/dev/null; then
307+
mkdir -p comp/ uncomp/
308+
run_test_compress
309+
else
310+
echo "=== Skipping compress/decompress tests (lz4 or CRIU compression not available) ==="
311+
fi

0 commit comments

Comments
 (0)