Changed all dir tests to be reentrant

To help with this, added TEST_PL, which is set to true when powerloss
testing. This way tests can check for stronger conditions (no EEXIST)
when not powerloss testing.

With TEST_PL, there's really no reason every test in t5_dirs shouldn't
be reentrant, and this gives us a huge improvement of test coverage very
cheaply.

---

The increased test coverage caught a bug, which is that gstate wasn't
being consumed properly when mtree uninlining. Humorously, this went
unnoticed because the most common form of mtree uninlining, mdir splitting,
ended up incorrectly consuming the gstate twice, which canceled itself
out since the consume operation is basically just xor.

Also added support for printing dstarts to dbglfs.py, to help debugging.
This commit is contained in:
Christopher Haster
2023-07-18 16:32:49 -05:00
parent 97f867b28d
commit c928ed131f
7 changed files with 270 additions and 175 deletions
+7 -5
View File
@@ -478,6 +478,7 @@ extern size_t test_geometry_count;
extern const test_powerloss_t *test_powerlosses;
extern size_t test_powerloss_count;
bool test_pl = false;
const test_id_t *test_ids = (const test_id_t[]) {
{NULL, NULL, 0, NULL, 0},
@@ -606,7 +607,6 @@ void test_trace(const char *fmt, ...) {
}
}
// test prng
uint32_t test_prng(uint32_t *state) {
// A simple xorshift32 generator, easily reproducible. Keep in mind
@@ -771,6 +771,7 @@ static void case_forperm(
// explicit powerloss cycles?
if (cycles) {
test_pl = true;
cb(data, suite, case_, &(test_powerloss_t){
.run=run_powerloss_cycles,
.cycles=cycles,
@@ -778,8 +779,8 @@ static void case_forperm(
} else {
for (size_t p = 0; p < test_powerloss_count; p++) {
// skip non-reentrant tests when powerloss testing
if (test_powerlosses[p].run != run_powerloss_none
&& !(case_->flags & TEST_REENTRANT)) {
test_pl = test_powerlosses[p].run != run_powerloss_none;
if (test_pl && !(case_->flags & TEST_REENTRANT)) {
continue;
}
@@ -820,6 +821,7 @@ static void case_forperm(
}
if (cycles) {
test_pl = true;
cb(data, suite, case_, &(test_powerloss_t){
.run=run_powerloss_cycles,
.cycles=cycles,
@@ -827,8 +829,8 @@ static void case_forperm(
} else {
for (size_t p = 0; p < test_powerloss_count; p++) {
// skip non-reentrant tests when powerloss testing
if (test_powerlosses[p].run != run_powerloss_none
&& !(case_->flags & TEST_REENTRANT)) {
test_pl = test_powerlosses[p].run != run_powerloss_none;
if (test_pl && !(case_->flags & TEST_REENTRANT)) {
continue;
}
+5
View File
@@ -69,6 +69,11 @@ struct test_suite {
};
// this is defined as true when powerloss-testing
extern bool test_pl;
#define TEST_PL test_pl
// deterministic prng for pseudo-randomness in testes
uint32_t test_prng(uint32_t *state);