Some more minor improvements to the test_runner
- Indirect index map instead of bitmap+sparse array - test_define_t and test_type_t - Added back conditional filtering - Added suite-level defines and filtering
This commit is contained in:
+71
-60
@@ -8,12 +8,12 @@
|
|||||||
// disk geometries
|
// disk geometries
|
||||||
struct test_geometry {
|
struct test_geometry {
|
||||||
const char *name;
|
const char *name;
|
||||||
const uintmax_t *defines;
|
const test_define_t *defines;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note this includes the default configuration for test pre-defines
|
// Note this includes the default configuration for test pre-defines
|
||||||
#define TEST_GEOMETRY(name, read, prog, erase, count) \
|
#define TEST_GEOMETRY(name, read, prog, erase, count) \
|
||||||
{name, (const uintmax_t[]){ \
|
{name, (const test_define_t[]){ \
|
||||||
/* READ_SIZE */ read, \
|
/* READ_SIZE */ read, \
|
||||||
/* PROG_SIZE */ prog, \
|
/* PROG_SIZE */ prog, \
|
||||||
/* BLOCK_SIZE */ erase, \
|
/* BLOCK_SIZE */ erase, \
|
||||||
@@ -46,14 +46,14 @@ const size_t test_geometry_count = (
|
|||||||
|
|
||||||
|
|
||||||
// test define lookup and management
|
// test define lookup and management
|
||||||
const uintmax_t *test_defines[3] = {NULL};
|
const test_define_t *test_defines[3] = {NULL};
|
||||||
const bool *test_define_masks[2] = {NULL};
|
const uint8_t *test_define_maps[2] = {NULL};
|
||||||
|
|
||||||
uintmax_t test_define(size_t define) {
|
test_define_t test_define(size_t define) {
|
||||||
if (test_define_masks[0] && test_define_masks[0][define]) {
|
if (test_define_maps[0] && test_define_maps[0][define] != 0xff) {
|
||||||
return test_defines[0][define];
|
return test_defines[0][test_define_maps[0][define]];
|
||||||
} else if (test_define_masks[1] && test_define_masks[1][define]) {
|
} else if (test_define_maps[1] && test_define_maps[1][define] != 0xff) {
|
||||||
return test_defines[1][define];
|
return test_defines[1][test_define_maps[1][define]];
|
||||||
} else {
|
} else {
|
||||||
return test_defines[2][define];
|
return test_defines[2][define];
|
||||||
}
|
}
|
||||||
@@ -70,61 +70,54 @@ void test_define_geometry(const struct test_geometry *geometry) {
|
|||||||
void test_define_case(const struct test_case *case_, size_t perm) {
|
void test_define_case(const struct test_case *case_, size_t perm) {
|
||||||
if (case_ && case_->defines) {
|
if (case_ && case_->defines) {
|
||||||
test_defines[1] = case_->defines[perm];
|
test_defines[1] = case_->defines[perm];
|
||||||
test_define_masks[1] = case_->define_mask;
|
test_define_maps[1] = case_->define_map;
|
||||||
} else {
|
} else {
|
||||||
test_defines[1] = NULL;
|
test_defines[1] = NULL;
|
||||||
test_define_masks[1] = NULL;
|
test_define_maps[1] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct override {
|
|
||||||
const char *name;
|
|
||||||
uintmax_t override;
|
|
||||||
};
|
|
||||||
|
|
||||||
void test_define_overrides(
|
void test_define_overrides(
|
||||||
const struct test_suite *suite,
|
const struct test_suite *suite,
|
||||||
const struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
if (overrides && override_count > 0) {
|
if (override_names && override_defines && override_count > 0) {
|
||||||
uintmax_t *defines = malloc(suite->define_count * sizeof(uintmax_t));
|
uint8_t *define_map = malloc(suite->define_count * sizeof(uint8_t));
|
||||||
memset(defines, 0, suite->define_count * sizeof(uintmax_t));
|
memset(define_map, 0xff, suite->define_count * sizeof(bool));
|
||||||
bool *define_mask = malloc(suite->define_count * sizeof(bool));
|
|
||||||
memset(define_mask, 0, suite->define_count * sizeof(bool));
|
|
||||||
|
|
||||||
// lookup each override in the suite defines, they may have a
|
// lookup each override in the suite defines, they may have a
|
||||||
// different index in each suite
|
// different index in each suite
|
||||||
for (size_t i = 0; i < override_count; i++) {
|
for (size_t i = 0; i < override_count; i++) {
|
||||||
ssize_t index = -1;
|
size_t j = 0;
|
||||||
for (size_t j = 0; j < suite->define_count; j++) {
|
for (; j < suite->define_count; j++) {
|
||||||
if (strcmp(overrides[i].name, suite->define_names[j]) == 0) {
|
if (strcmp(override_names[i], suite->define_names[j]) == 0) {
|
||||||
index = j;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index >= 0) {
|
if (j < suite->define_count) {
|
||||||
defines[index] = overrides[i].override;
|
define_map[j] = i;
|
||||||
define_mask[index] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test_defines[0] = defines;
|
test_defines[0] = override_defines;
|
||||||
test_define_masks[0] = define_mask;
|
test_define_maps[0] = define_map;
|
||||||
} else {
|
} else {
|
||||||
free((uintmax_t *)test_defines[0]);
|
|
||||||
test_defines[0] = NULL;
|
test_defines[0] = NULL;
|
||||||
free((bool *)test_define_masks[0]);
|
free((uint8_t *)test_define_maps[0]);
|
||||||
test_define_masks[0] = NULL;
|
test_define_maps[0] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// operations we can do
|
// operations we can do
|
||||||
void summary(
|
void summary(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
printf("%-36s %7s %7s %7s %7s\n",
|
printf("%-36s %7s %7s %7s %7s\n",
|
||||||
"", "geoms", "suites", "cases", "perms");
|
"", "geoms", "suites", "cases", "perms");
|
||||||
@@ -147,9 +140,11 @@ void summary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void list_suites(
|
void list_suites(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
printf("%-36s %-12s %7s %7s %7s\n",
|
printf("%-36s %-12s %7s %7s %7s\n",
|
||||||
"id", "suite", "types", "cases", "perms");
|
"id", "suite", "types", "cases", "perms");
|
||||||
@@ -169,9 +164,11 @@ void list_suites(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void list_cases(
|
void list_cases(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
printf("%-36s %-12s %-12s %7s %7s\n",
|
printf("%-36s %-12s %-12s %7s %7s\n",
|
||||||
"id", "suite", "case", "types", "perms");
|
"id", "suite", "case", "types", "perms");
|
||||||
@@ -189,9 +186,11 @@ void list_cases(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void list_paths(
|
void list_paths(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
printf("%-36s %-36s\n", "id", "path");
|
printf("%-36s %-36s\n", "id", "path");
|
||||||
for (size_t i = 0; i < test_suite_count; i++) {
|
for (size_t i = 0; i < test_suite_count; i++) {
|
||||||
@@ -204,17 +203,21 @@ void list_paths(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void list_defines(
|
void list_defines(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_geometries(
|
void list_geometries(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
(void)overrides;
|
(void)override_names;
|
||||||
|
(void)override_defines;
|
||||||
(void)override_count;
|
(void)override_count;
|
||||||
printf("%-36s %7s %7s %7s %7s %7s\n",
|
printf("%-36s %7s %7s %7s %7s %7s\n",
|
||||||
"name", "read", "prog", "erase", "count", "size");
|
"name", "read", "prog", "erase", "count", "size");
|
||||||
@@ -232,10 +235,13 @@ void list_geometries(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void run(
|
void run(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) {
|
size_t override_count) {
|
||||||
for (size_t i = 0; i < test_suite_count; i++) {
|
for (size_t i = 0; i < test_suite_count; i++) {
|
||||||
test_define_overrides(test_suites[i], overrides, override_count);
|
test_define_overrides(
|
||||||
|
test_suites[i],
|
||||||
|
override_names, override_defines, override_count);
|
||||||
|
|
||||||
for (size_t j = 0; j < test_suites[i]->case_count; j++) {
|
for (size_t j = 0; j < test_suites[i]->case_count; j++) {
|
||||||
for (size_t perm = 0;
|
for (size_t perm = 0;
|
||||||
@@ -303,7 +309,7 @@ void run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test_define_overrides(NULL, NULL, 0);
|
test_define_overrides(NULL, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,9 +355,11 @@ const char *const help_text[] = {
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
void (*op)(
|
void (*op)(
|
||||||
struct override *overrides,
|
const char *const *override_names,
|
||||||
|
const test_define_t *override_defines,
|
||||||
size_t override_count) = run;
|
size_t override_count) = run;
|
||||||
struct override *overrides = NULL;
|
const char **override_names = NULL;
|
||||||
|
test_define_t *override_defines = NULL;
|
||||||
size_t override_count = 0;
|
size_t override_count = 0;
|
||||||
size_t override_cap = 0;
|
size_t override_cap = 0;
|
||||||
|
|
||||||
@@ -422,24 +430,26 @@ int main(int argc, char **argv) {
|
|||||||
override_count += 1;
|
override_count += 1;
|
||||||
if (override_count > override_cap) {
|
if (override_count > override_cap) {
|
||||||
override_cap = (2*override_cap > 4) ? 2*override_cap : 4;
|
override_cap = (2*override_cap > 4) ? 2*override_cap : 4;
|
||||||
overrides = realloc(overrides, override_cap
|
override_names = realloc(override_names, override_cap
|
||||||
* sizeof(struct override));
|
* sizeof(const char *));
|
||||||
|
override_defines = realloc(override_defines, override_cap
|
||||||
|
* sizeof(test_define_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse into string key/uintmax_t value, cannibalizing the
|
// parse into string key/test_define_t value, cannibalizing the
|
||||||
// arg in the process
|
// arg in the process
|
||||||
char *sep = strchr(optarg, '=');
|
char *sep = strchr(optarg, '=');
|
||||||
char *parsed = NULL;
|
char *parsed = NULL;
|
||||||
if (!sep) {
|
if (!sep) {
|
||||||
goto invalid_define;
|
goto invalid_define;
|
||||||
}
|
}
|
||||||
overrides[override_count-1].override
|
override_defines[override_count-1]
|
||||||
= strtoumax(sep+1, &parsed, 0);
|
= strtoumax(sep+1, &parsed, 0);
|
||||||
if (parsed == sep+1) {
|
if (parsed == sep+1) {
|
||||||
goto invalid_define;
|
goto invalid_define;
|
||||||
}
|
}
|
||||||
|
|
||||||
overrides[override_count-1].name = optarg;
|
override_names[override_count-1] = optarg;
|
||||||
*sep = '\0';
|
*sep = '\0';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -458,15 +468,16 @@ invalid_define:
|
|||||||
getopt_done:
|
getopt_done:
|
||||||
|
|
||||||
for (size_t i = 0; i < override_count; i++) {
|
for (size_t i = 0; i < override_count; i++) {
|
||||||
printf("define: %s %ju\n", overrides[i].name, overrides[i].override);
|
printf("define: %s %ju\n", override_names[i], override_defines[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do the thing
|
// do the thing
|
||||||
op(
|
op(
|
||||||
overrides,
|
override_names,
|
||||||
|
override_defines,
|
||||||
override_count);
|
override_count);
|
||||||
|
|
||||||
// cleanup (need to be done for valgrind testing)
|
// cleanup (need to be done for valgrind testing)
|
||||||
free(overrides);
|
free(override_names);
|
||||||
}
|
free(override_defines);}
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,24 @@
|
|||||||
|
|
||||||
|
|
||||||
// generated test configurations
|
// generated test configurations
|
||||||
enum test_type {
|
enum test_types {
|
||||||
TEST_NORMAL = 0x1,
|
TEST_NORMAL = 0x1,
|
||||||
TEST_REENTRANT = 0x2,
|
TEST_REENTRANT = 0x2,
|
||||||
TEST_VALGRIND = 0x4,
|
TEST_VALGRIND = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint8_t test_types_t;
|
||||||
|
typedef uintmax_t test_define_t;
|
||||||
|
|
||||||
struct test_case {
|
struct test_case {
|
||||||
const char *id;
|
const char *id;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *path;
|
const char *path;
|
||||||
uint8_t types;
|
test_types_t types;
|
||||||
size_t permutations;
|
size_t permutations;
|
||||||
|
|
||||||
const uintmax_t *const *defines;
|
const test_define_t *const *defines;
|
||||||
const bool *define_mask;
|
const uint8_t *define_map;
|
||||||
|
|
||||||
bool (*filter)(struct lfs_config *cfg, uint32_t perm);
|
bool (*filter)(struct lfs_config *cfg, uint32_t perm);
|
||||||
void (*run)(struct lfs_config *cfg, uint32_t perm);
|
void (*run)(struct lfs_config *cfg, uint32_t perm);
|
||||||
@@ -43,7 +46,7 @@ extern const size_t test_suite_count;
|
|||||||
|
|
||||||
|
|
||||||
// access generated test defines
|
// access generated test defines
|
||||||
uintmax_t test_define(size_t define);
|
test_define_t test_define(size_t define);
|
||||||
|
|
||||||
// a few preconfigured defines that control how tests run
|
// a few preconfigured defines that control how tests run
|
||||||
#define READ_SIZE test_define(0)
|
#define READ_SIZE test_define(0)
|
||||||
|
|||||||
+68
-36
@@ -66,23 +66,19 @@ class TestCase:
|
|||||||
self.path = config.pop('path')
|
self.path = config.pop('path')
|
||||||
self.suite = config.pop('suite')
|
self.suite = config.pop('suite')
|
||||||
self.lineno = config.pop('lineno', None)
|
self.lineno = config.pop('lineno', None)
|
||||||
|
self.if_ = config.pop('if', None)
|
||||||
|
if isinstance(self.if_, bool):
|
||||||
|
self.if_ = 'true' if self.if_ else 'false'
|
||||||
|
self.if_lineno = config.pop('if_lineno', None)
|
||||||
self.code = config.pop('code')
|
self.code = config.pop('code')
|
||||||
self.code_lineno = config.pop('code_lineno', None)
|
self.code_lineno = config.pop('code_lineno', None)
|
||||||
|
|
||||||
# figure out defines and the number of resulting permutations
|
# figure out defines and the number of resulting permutations
|
||||||
self.defines = {}
|
self.defines = {}
|
||||||
for k, v in config.pop('defines', {}).items():
|
for k, v in (
|
||||||
try:
|
config.pop('suite_defines', {})
|
||||||
v = eval(v)
|
| config.pop('defines', {})).items():
|
||||||
except:
|
if not isinstance(v, list):
|
||||||
v = v
|
|
||||||
|
|
||||||
if not isinstance(v, str):
|
|
||||||
try:
|
|
||||||
v = list(v)
|
|
||||||
except:
|
|
||||||
v = [v]
|
|
||||||
else:
|
|
||||||
v = [v]
|
v = [v]
|
||||||
|
|
||||||
self.defines[k] = v
|
self.defines[k] = v
|
||||||
@@ -111,14 +107,18 @@ class TestSuite:
|
|||||||
# find line numbers
|
# find line numbers
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
case_linenos = []
|
case_linenos = []
|
||||||
|
if_linenos = []
|
||||||
code_linenos = []
|
code_linenos = []
|
||||||
for i, line in enumerate(f):
|
for i, line in enumerate(f):
|
||||||
match = re.match(
|
match = re.match(
|
||||||
'(?P<case>\[\s*cases\s*\.\s*(?P<name>\w+)\s*\])' +
|
'(?P<case>\[\s*cases\s*\.\s*(?P<name>\w+)\s*\])' +
|
||||||
'|(?P<code>code\s*=\s*(?:\'\'\'|"""))',
|
'|(?P<if>if\s*=)'
|
||||||
|
'|(?P<code>code\s*=)',
|
||||||
line)
|
line)
|
||||||
if match and match.group('case'):
|
if match and match.group('case'):
|
||||||
case_linenos.append((i+1, match.group('name')))
|
case_linenos.append((i+1, match.group('name')))
|
||||||
|
elif match and match.group('if'):
|
||||||
|
if_linenos.append(i+1)
|
||||||
elif match and match.group('code'):
|
elif match and match.group('code'):
|
||||||
code_linenos.append(i+2)
|
code_linenos.append(i+2)
|
||||||
|
|
||||||
@@ -129,18 +129,33 @@ class TestSuite:
|
|||||||
for (lineno, name), (nlineno, _) in it.zip_longest(
|
for (lineno, name), (nlineno, _) in it.zip_longest(
|
||||||
case_linenos, case_linenos[1:],
|
case_linenos, case_linenos[1:],
|
||||||
fillvalue=(float('inf'), None)):
|
fillvalue=(float('inf'), None)):
|
||||||
|
if_lineno = min(
|
||||||
|
(l for l in if_linenos if l >= lineno and l < nlineno),
|
||||||
|
default=None)
|
||||||
code_lineno = min(
|
code_lineno = min(
|
||||||
(l for l in code_linenos if l >= lineno and l < nlineno),
|
(l for l in code_linenos if l >= lineno and l < nlineno),
|
||||||
default=None)
|
default=None)
|
||||||
cases[name]['lineno'] = lineno
|
cases[name]['lineno'] = lineno
|
||||||
|
cases[name]['if_lineno'] = if_lineno
|
||||||
cases[name]['code_lineno'] = code_lineno
|
cases[name]['code_lineno'] = code_lineno
|
||||||
|
|
||||||
|
self.if_ = config.pop('if', None)
|
||||||
|
if isinstance(self.if_, bool):
|
||||||
|
self.if_ = 'true' if self.if_ else 'false'
|
||||||
|
self.if_lineno = min(
|
||||||
|
(l for l in if_linenos
|
||||||
|
if not case_linenos or l < case_linenos[0][0]),
|
||||||
|
default=None)
|
||||||
|
|
||||||
self.code = config.pop('code', None)
|
self.code = config.pop('code', None)
|
||||||
self.code_lineno = min(
|
self.code_lineno = min(
|
||||||
(l for l in code_linenos
|
(l for l in code_linenos
|
||||||
if not case_linenos or l < case_linenos[0][0]),
|
if not case_linenos or l < case_linenos[0][0]),
|
||||||
default=None)
|
default=None)
|
||||||
|
|
||||||
|
# a couple of these we just forward to all cases
|
||||||
|
defines = config.pop('defines', {})
|
||||||
|
|
||||||
self.cases = []
|
self.cases = []
|
||||||
for name, case in sorted(cases.items(),
|
for name, case in sorted(cases.items(),
|
||||||
key=lambda c: c[1].get('lineno')):
|
key=lambda c: c[1].get('lineno')):
|
||||||
@@ -149,6 +164,7 @@ class TestSuite:
|
|||||||
'path': path + (':%d' % case['lineno']
|
'path': path + (':%d' % case['lineno']
|
||||||
if 'lineno' in case else ''),
|
if 'lineno' in case else ''),
|
||||||
'suite': self.name,
|
'suite': self.name,
|
||||||
|
'suite_defines': defines,
|
||||||
**case}))
|
**case}))
|
||||||
|
|
||||||
# combine pre-defines and per-case defines
|
# combine pre-defines and per-case defines
|
||||||
@@ -162,8 +178,6 @@ class TestSuite:
|
|||||||
def id(self):
|
def id(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def compile(**args):
|
def compile(**args):
|
||||||
@@ -208,20 +222,21 @@ def compile(**args):
|
|||||||
for case in suite.cases:
|
for case in suite.cases:
|
||||||
# create case defines
|
# create case defines
|
||||||
if case.defines:
|
if case.defines:
|
||||||
|
sorted_defines = sorted(case.defines.items())
|
||||||
|
|
||||||
for perm, defines in enumerate(
|
for perm, defines in enumerate(
|
||||||
it.product(*(
|
it.product(*(
|
||||||
[(k, v) for v in vs]
|
[(k, v) for v in vs]
|
||||||
for k, vs in case.defines.items()))):
|
for k, vs in sorted_defines))):
|
||||||
f.write('const uintmax_t '
|
f.write('const test_define_t '
|
||||||
'__test__%s__%s__%d__defines[] = {\n'
|
'__test__%s__%s__%d__defines[] = {\n'
|
||||||
% (suite.name, case.name, perm))
|
% (suite.name, case.name, perm))
|
||||||
for k, v in sorted(defines):
|
for k, v in defines:
|
||||||
f.write(4*' '+'[%d] = %s,\n'
|
f.write(4*' '+'%s,\n' % v)
|
||||||
% (suite.defines.index(k), v))
|
|
||||||
f.write('};\n')
|
f.write('};\n')
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
|
||||||
f.write('const uintmax_t *const '
|
f.write('const test_define_t *const '
|
||||||
'__test__%s__%s__defines[] = {\n'
|
'__test__%s__%s__defines[] = {\n'
|
||||||
% (suite.name, case.name))
|
% (suite.name, case.name))
|
||||||
for perm in range(case.permutations):
|
for perm in range(case.permutations):
|
||||||
@@ -230,23 +245,39 @@ def compile(**args):
|
|||||||
f.write('};\n')
|
f.write('};\n')
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
|
||||||
f.write('const bool '
|
f.write('const uint8_t '
|
||||||
'__test__%s__%s__define_mask[] = {\n'
|
'__test__%s__%s__define_map[] = {\n'
|
||||||
% (suite.name, case.name))
|
% (suite.name, case.name))
|
||||||
for i, k in enumerate(suite.defines):
|
for k in suite.defines:
|
||||||
f.write(4*' '+'%s,\n'
|
f.write(4*' '+'%s,\n'
|
||||||
% ('true' if k in case.defines else 'false'))
|
% ([k for k, _ in sorted_defines].index(k)
|
||||||
|
if k in case.defines else '0xff'))
|
||||||
f.write('};\n')
|
f.write('};\n')
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
|
||||||
# create case filter function
|
# create case filter function
|
||||||
f.write('bool __test__%s__%s__filter('
|
if suite.if_ is not None or case.if_ is not None:
|
||||||
'__attribute__((unused)) struct lfs_config *cfg, '
|
f.write('bool __test__%s__%s__filter('
|
||||||
'__attribute__((unused)) uint32_t perm) {\n'
|
'__attribute__((unused)) struct lfs_config *cfg, '
|
||||||
% (suite.name, case.name))
|
'__attribute__((unused)) uint32_t perm) {\n'
|
||||||
f.write(4*' '+'return true;\n')
|
% (suite.name, case.name))
|
||||||
f.write('}\n')
|
if suite.if_ is not None:
|
||||||
f.write('\n')
|
f.write(4*' '+'#line %d "%s"\n'
|
||||||
|
% (suite.if_lineno, suite.path))
|
||||||
|
f.write(4*' '+'if (!(%s)) {\n' % suite.if_)
|
||||||
|
f.write(8*' '+'return false;\n')
|
||||||
|
f.write(4*' '+'}\n')
|
||||||
|
f.write('\n')
|
||||||
|
if case.if_ is not None:
|
||||||
|
f.write(4*' '+'#line %d "%s"\n'
|
||||||
|
% (case.if_lineno, suite.path))
|
||||||
|
f.write(4*' '+'if (!(%s)) {\n' % case.if_)
|
||||||
|
f.write(8*' '+'return false;\n')
|
||||||
|
f.write(4*' '+'}\n')
|
||||||
|
f.write('\n')
|
||||||
|
f.write(4*' '+'return true;\n')
|
||||||
|
f.write('}\n')
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
# create case run function
|
# create case run function
|
||||||
f.write('void __test__%s__%s__run('
|
f.write('void __test__%s__%s__run('
|
||||||
@@ -278,11 +309,12 @@ def compile(**args):
|
|||||||
if case.defines:
|
if case.defines:
|
||||||
f.write(4*' '+'.defines = __test__%s__%s__defines,\n'
|
f.write(4*' '+'.defines = __test__%s__%s__defines,\n'
|
||||||
% (suite.name, case.name))
|
% (suite.name, case.name))
|
||||||
f.write(4*' '+'.define_mask = '
|
f.write(4*' '+'.define_map = '
|
||||||
'__test__%s__%s__define_mask,\n'
|
'__test__%s__%s__define_map,\n'
|
||||||
|
% (suite.name, case.name))
|
||||||
|
if suite.if_ is not None or case.if_ is not None:
|
||||||
|
f.write(4*' '+'.filter = __test__%s__%s__filter,\n'
|
||||||
% (suite.name, case.name))
|
% (suite.name, case.name))
|
||||||
f.write(4*' '+'.filter = __test__%s__%s__filter,\n'
|
|
||||||
% (suite.name, case.name))
|
|
||||||
f.write(4*' '+'.run = __test__%s__%s__run,\n'
|
f.write(4*' '+'.run = __test__%s__%s__run,\n'
|
||||||
% (suite.name, case.name))
|
% (suite.name, case.name))
|
||||||
f.write('};\n')
|
f.write('};\n')
|
||||||
|
|||||||
Reference in New Issue
Block a user