More coverage test
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-win (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run

This commit is contained in:
Andrea Mazzoleni 2026-02-28 10:08:09 +01:00
parent 748c086edb
commit 21561e6cf9
10 changed files with 88 additions and 4 deletions

View file

@ -142,6 +142,7 @@ EXTRA_DIST = \
test/test-par1.conf \
test/test-par2.conf \
test/test-par3.conf \
test/test-parz.conf \
test/test-par4.conf \
test/test-par5.conf \
test/test-par6.conf \
@ -271,6 +272,7 @@ RENAME = $(srcdir)/test/test-par6-rename.conf
PAR1 = $(srcdir)/test/test-par1.conf
PAR2 = $(srcdir)/test/test-par2.conf
PAR3 = $(srcdir)/test/test-par3.conf
PARZ = $(srcdir)/test/test-parz.conf
PAR4 = $(srcdir)/test/test-par4.conf
PAR5 = $(srcdir)/test/test-par5.conf
PAR6 = $(srcdir)/test/test-par6.conf
@ -563,8 +565,10 @@ endif
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) status
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-none -c $(PAR1) sync -F --test-io-cache 1
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-sequential -c $(PAR1) sync -F --test-io-stats
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-flush -c $(PAR1) sync -F --test-io-cache 1
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-flush-window -c $(PAR1) sync -F
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-discard-window -c $(PAR1) sync -F
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-io-advise-direct -c $(PAR1) sync -F
#### CHANGE LINKS ####
# Use a different size ("22" instead of "1") to ensure to recognize the file different
# even if it gets the same timestamp in case subsecond timestamp is no available
@ -776,6 +780,12 @@ endif
mv bench/disk4/a/7* bench/disk4/b/
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
#### SNAPRAIDIGNORE
echo "a*" > bench/disk1/a/.snapraidignore
echo "b*" > bench/disk1/.snapraidignore
echo "c/" > bench/disk1/.snapraidignore
echo "/d/" > bench/disk1/.snapraidignore
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
if !HAVE_MEMORY_CHECKER
#### RECOVER 1 ####
$(MSG) Delete one disk, fix and check with PAR1
@ -809,6 +819,20 @@ if !HAVE_MEMORY_CHECKER
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(PAR3) fix -l test.log
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
#### RECOVER Z ####
$(MSG) Compute PARZ - keeping PAR1 and PAR2 as they are
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(PARZ) fix -d 3-parity -l test.log
$(MSG) Delete three disks, fix and check with PARZ
rm -r bench/disk3
mkdir bench/disk3
rm -r bench/disk4
mkdir bench/disk4
rm -r bench/disk5
mkdir bench/disk5
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-expect-recoverable -c $(PARZ) check -l test.log
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(PARZ) fix -l test.log
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) check
$(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) -c $(CONF) sync
#### RECOVER 4 ####
$(MSG) Delete four disks, fix and check with PAR4
rm -r bench/disk3

2
TODO
View file

@ -7,6 +7,8 @@ This is the list of TODO items for SnapRAID.
* Integration with MergeFS ?
* Evaluate use of syscall getdents64() instead of readdir(): https://linux.die.net/man/2/getdents64
* Check Reliability Test
https://github.com/linuxhw/SMART
https://github.com/linuxhw/EnterpriseDrive

View file

@ -101,10 +101,12 @@ void test(int argc, char* argv[])
int i;
char buffer[ESC_MAX];
/* special testing code for quoting */
/* special testing code */
if (argc < 2 || strcmp(argv[1], "test") != 0)
return;
lock_init();
assert(strcmp(strpolish(strcpy(buffer, "\r \n\xFF")), " ") == 0);
assert(strcmp(strtrim(strcpy(buffer, " trim trim \n\r")), "trim trim") == 0);
assert(strcmp(strlwr(strcpy(buffer, " LoWer\n\r")), " lower\n\r") == 0);
@ -486,8 +488,14 @@ void test(int argc, char* argv[])
assert(strcmp(esc_shell("test_2024-01-01.log", buffer), "test_2024-01-01.log") == 0);
#endif
random_seed(0);
assert(random_u8() == 0xAF);
assert(random_u64() == 0x6E789E6AA1B965F4ULL);
printf("Everything OK\n");
lock_done();
exit(EXIT_SUCCESS);
}

View file

@ -1655,7 +1655,7 @@ static void state_map(struct snapraid_state* state)
/* recommend number of parities */
if (!state->opt.no_warnings) {
/* intentionally use log_fatal() instead of log_error() to give more visibility at the warning */
/* LCOV_EXCL_START */
if (diskcount >= 36 && state->level < 6) {
log_error(EUSER, "WARNING! For %u disks, it's recommended to use six parity levels.\n", diskcount);
} else if (diskcount >= 29 && state->level < 5) {
@ -1667,6 +1667,7 @@ static void state_map(struct snapraid_state* state)
} else if (diskcount >= 5 && state->level < 2) {
log_error(EUSER, "WARNING! For %u disks, it's recommended to use two parity levels.\n", diskcount);
}
/* LCOV_EXCL_STOP */
}
}

View file

@ -98,6 +98,11 @@ void lock_done(void)
static uint64_t random_state = 1;
void random_seed(uint64_t seed)
{
random_state = seed;
}
void random_reseed(void)
{
random_state = tick();
@ -138,6 +143,7 @@ uint64_t random_u64(void)
int is_hw(int err)
{
/* LCOV_EXCL_START */
if (err == EIO)
return 1;
#ifdef EFSCORRUPTED
@ -164,11 +170,13 @@ int is_hw(int err)
if (err == EHWPOISON) /* hardware memory error */
return 1;
#endif
/* LCOV_EXCL_STOP */
return 0;
}
void log_fatal_errno(int err, const char* name)
{
/* LCOV_EXCL_START */
if (err == EIO) {
log_fatal(err, "DANGER! Unexpected input/output error in disk %s. It isn't possible to continue.\n", name);
#ifdef EFSCORRUPTED
@ -202,10 +210,12 @@ void log_fatal_errno(int err, const char* name)
} else {
log_fatal(err, "WARNING! Without a working %s disk, it isn't possible to continue.\n", name);
}
/* LCOV_EXCL_STOP */
}
void log_error_errno(int err, const char* name)
{
/* LCOV_EXCL_START */
if (err == EIO) {
log_fatal(err, "DANGER! Unexpected input/output error in disk %s.\n", name);
#ifdef EFSCORRUPTED
@ -232,6 +242,7 @@ void log_error_errno(int err, const char* name)
} else if (err == EHWPOISON) {
log_fatal(err, "DANGER! Unexpected memory error in disk %s.\n", name);
#endif
/* LCOV_EXCL_STOP */
} else if (err == EACCES) {
log_error(err, "WARNING! Grant permission in the disk %s.\n", name);
} else if (err == ENOSPC) {

View file

@ -56,7 +56,12 @@ void unlock_memory(void);
/* random */
/**
* Reseed the random pseudo random number generator
* Seed the random pseudo random number generator
*/
void random_seed(uint64_t seed);
/**
* Reseed the random pseudo random number generator with the tick count
*/
void random_reseed(void);

View file

@ -764,6 +764,7 @@ const char* hash_config_name(unsigned kind)
case HASH_MURMUR3 : return "murmur3";
case HASH_SPOOKY2 : return "spooky2";
case HASH_METRO : return "metro";
case HASH_MUSEAIR : return "museair";
default :
/* LCOV_EXCL_START */
return "unknown";

View file

@ -9,8 +9,22 @@ if ! ./configure --enable-coverage --enable-sde; then
exit 1
fi
if ! make lcov_reset check lcov_capture lcov_html; then
if ! make lcov_reset; then
exit 1
fi
if ! make check; then
exit 1
fi
# Run commands on a real array to test smartctl
sudo ./snapraid probe
sudo ./snapraid up
sudo ./snapraid smart
sudo ./snapraid probe
sudo ./snapraid devices
sudo ./snapraid down
if ! make lcov_capture lcov_html; then
exit 1
fi

View file

@ -1,4 +1,5 @@
# Test configuration file
hashsize 16
blocksize 1
parity bench/parity.0,bench/parity.1,bench/parity.2,bench/parity.3
content bench/content

17
test/test-parz.conf Normal file
View file

@ -0,0 +1,17 @@
blocksize 1
parity bench/parity.0,bench/parity.1,bench/parity.2,bench/parity.3
2-parity bench/2-parity.0,bench/2-parity.1,bench/2-parity.2,bench/2-parity.3
z-parity bench/z-parity.0,bench/z-parity.1,bench/z-parity.2,bench/z-parity.3
content bench/content
content bench/1-content
content bench/2-content
content bench/3-content
disk disk1 bench/disk1/
disk disk2 bench/disk2/
disk disk3 bench/disk3/
disk disk4 bench/disk4/
disk disk5 bench/disk5/
disk disk6 bench/disk6/
include *.hidden
exclude *.unrecoverable