Created new test_runner.c and test_.py
This is to try a different design for testing, the goals are to make the test infrastructure a bit simpler, with clear stages for building and running, and faster, by avoiding rebuilding lfs.c n-times.
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
|
||||
#include "runners/test_runner.h"
|
||||
#include <getopt.h>
|
||||
|
||||
|
||||
// disk geometries
|
||||
struct test_geometry {
|
||||
const char *name;
|
||||
lfs_size_t read_size;
|
||||
lfs_size_t prog_size;
|
||||
lfs_size_t erase_size;
|
||||
lfs_size_t erase_count;
|
||||
};
|
||||
|
||||
const struct test_geometry test_geometries[] = {
|
||||
// Made up geometries that works well for testing
|
||||
{"small", 16, 16, 512, (1024*1024)/512},
|
||||
{"medium", 16, 16, 4096, (1024*1024)/4096},
|
||||
{"big", 16, 16, 32*1024, (1024*1024)/(32*1024)},
|
||||
// EEPROM/NVRAM
|
||||
{"eeprom", 1, 1, 512, (1024*1024)/512},
|
||||
// SD/eMMC
|
||||
{"emmc", 512, 512, 512, (1024*1024)/512},
|
||||
// NOR flash
|
||||
{"nor", 1, 1, 4096, (1024*1024)/4096},
|
||||
// NAND flash
|
||||
{"nand", 4096, 4096, 32*1024, (1024*1024)/(32*1024)},
|
||||
};
|
||||
const size_t test_geometry_count = (
|
||||
sizeof(test_geometries) / sizeof(test_geometries[0]));
|
||||
|
||||
|
||||
// option handling
|
||||
enum opt_flags {
|
||||
OPT_HELP = 'h',
|
||||
OPT_LIST = 'l',
|
||||
OPT_LIST_PATHS = 1,
|
||||
OPT_LIST_DEFINES = 2,
|
||||
OPT_LIST_GEOMETRIES = 3,
|
||||
};
|
||||
|
||||
const struct option long_opts[] = {
|
||||
{"help", no_argument, NULL, OPT_HELP},
|
||||
{"list", no_argument, NULL, OPT_LIST},
|
||||
{"list-paths", no_argument, NULL, OPT_LIST_PATHS},
|
||||
{"list-defines", no_argument, NULL, OPT_LIST_DEFINES},
|
||||
{"list-geometries", no_argument, NULL, OPT_LIST_GEOMETRIES},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
const char *const help_text[] = {
|
||||
"Show this help message.",
|
||||
"List test cases.",
|
||||
"List the path for each test case.",
|
||||
"List the defines for each test permutation.",
|
||||
"List the disk geometries used for testing.",
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bool list = false;
|
||||
bool list_paths = false;
|
||||
bool list_defines = false;
|
||||
bool list_geometries = false;
|
||||
|
||||
// parse options
|
||||
while (true) {
|
||||
int index = 0;
|
||||
int c = getopt_long(argc, argv, "hl", long_opts, &index);
|
||||
switch (c) {
|
||||
// generate help message
|
||||
case OPT_HELP: {
|
||||
printf("usage: %s [options] [test_case]\n", argv[0]);
|
||||
printf("\n");
|
||||
|
||||
printf("options:\n");
|
||||
size_t i = 0;
|
||||
while (long_opts[i].name) {
|
||||
size_t indent;
|
||||
if (long_opts[i].val >= '0' && long_opts[i].val < 'z') {
|
||||
printf(" -%c, --%-16s",
|
||||
long_opts[i].val,
|
||||
long_opts[i].name);
|
||||
indent = 8+strlen(long_opts[i].name);
|
||||
} else {
|
||||
printf(" --%-20s", long_opts[i].name);
|
||||
indent = 4+strlen(long_opts[i].name);
|
||||
}
|
||||
|
||||
// a quick, hacky, byte-level method for text wrapping
|
||||
size_t len = strlen(help_text[i]);
|
||||
size_t j = 0;
|
||||
if (indent < 24) {
|
||||
printf("%.80s\n", &help_text[i][j]);
|
||||
j += 80;
|
||||
}
|
||||
|
||||
while (j < len) {
|
||||
printf("%24s%.80s\n", "", &help_text[i][j]);
|
||||
j += 80;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
// list flags
|
||||
case OPT_LIST:
|
||||
list = true;
|
||||
break;
|
||||
case OPT_LIST_PATHS:
|
||||
list_paths = true;
|
||||
break;
|
||||
case OPT_LIST_DEFINES:
|
||||
list_defines = true;
|
||||
break;
|
||||
case OPT_LIST_GEOMETRIES:
|
||||
list_geometries = true;
|
||||
break;
|
||||
// done parsing
|
||||
case -1:
|
||||
goto getopt_done;
|
||||
// unknown arg, getopt prints a message for us
|
||||
default:
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
getopt_done:
|
||||
|
||||
// what do we need to do?
|
||||
if (list) {
|
||||
printf("%-36s %-12s %-12s %7s %7s\n",
|
||||
"id", "suite", "case", "type", "perms");
|
||||
for (size_t i = 0; i < test_suite_count; i++) {
|
||||
for (size_t j = 0; j < test_suites[i]->case_count; j++) {
|
||||
printf("%-36s %-12s %-12s %7s %7d\n",
|
||||
test_suites[i]->cases[j]->id,
|
||||
test_suites[i]->name,
|
||||
test_suites[i]->cases[j]->name,
|
||||
"n", // TODO
|
||||
test_suites[i]->cases[j]->permutations);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (list_paths) {
|
||||
printf("%-36s %-36s\n", "id", "path");
|
||||
for (size_t i = 0; i < test_suite_count; i++) {
|
||||
for (size_t j = 0; j < test_suites[i]->case_count; j++) {
|
||||
printf("%-36s %-36s\n",
|
||||
test_suites[i]->cases[j]->id,
|
||||
test_suites[i]->cases[j]->path);
|
||||
}
|
||||
}
|
||||
} else if (list_defines) {
|
||||
// TODO
|
||||
} else if (list_geometries) {
|
||||
printf("%-12s %7s %7s %7s %7s %7s\n",
|
||||
"name", "read", "prog", "erase", "count", "size");
|
||||
for (size_t i = 0; i < test_geometry_count; i++) {
|
||||
printf("%-12s %7d %7d %7d %7d %7d\n",
|
||||
test_geometries[i].name,
|
||||
test_geometries[i].read_size,
|
||||
test_geometries[i].prog_size,
|
||||
test_geometries[i].erase_size,
|
||||
test_geometries[i].erase_count,
|
||||
test_geometries[i].erase_size
|
||||
* test_geometries[i].erase_count);
|
||||
}
|
||||
} else {
|
||||
printf("remaining: ");
|
||||
for (int i = optind; i < argc; i++) {
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user