Skip to content

Commit 3f1b676

Browse files
authored
Add test framework support for running individual tests. (#310)
* Add test framework support for running individual tests. * Add support for -ff to the test framework to fail fast without specifying an individual test to run.
1 parent 03e2f43 commit 3f1b676

File tree

5 files changed

+41
-16
lines changed

5 files changed

+41
-16
lines changed

Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ ifeq ($(VALGRIND),1)
6363
override CFLAGS += -DUSE_VALGRIND
6464
override TEST_CFLAGS += -DUSE_VALGRIND
6565
endif
66-
ifeq ($(TEST_FAIL_FAST),1)
67-
override TEST_CFLAGS += -DTEST_FAIL_FAST=1
68-
endif
6966

7067
CLEANLIBS = $(ARLIB)
7168
CLEANOBJS = $(OBJ_FILES)

test/framework/main.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
*/
1212
const size_t ARBITRARY_LENGTH_LIMIT = 500;
1313

14+
int
15+
TEST_INIT_impl(TestState * test_state, const char *func, size_t line)
16+
{
17+
if ((test_state->wanted_test != NULL) && (strcmp(test_state->wanted_test, func) != 0))
18+
return 1;
19+
20+
printf("%s (line %li)\n", func, line);
21+
return 0;
22+
}
23+
1424
int
1525
TEST_BOUNDED_STRCMP(char *s1, char *s2)
1626
{
@@ -188,10 +198,27 @@ TEST_ASSERT_LIST_EQUAL_impl(TestState * test_state, char *actual_str, List *actu
188198
// implementation.
189199
static
190200
int
191-
test_run_impl(TestFn * tests[], TestCleanupFn * test_cleanup, bool use_mctx)
201+
test_run_impl(int argc, char *argv[], TestFn * tests[], TestCleanupFn * test_cleanup, bool use_mctx)
192202
{
193203
TestState test_state = {0};
194204

205+
bool fail_fast = false;
206+
207+
for (size_t i = 1; i < argc; i++)
208+
{
209+
// This loop only runs if an argument was passed.
210+
// That argument will be -ff or a test name, and in both
211+
// cases we want to fail fast.
212+
fail_fast = true;
213+
214+
// If the argument isn't -ff, we assume it's a test name.
215+
if (strncmp(argv[i], "-ff", 4) != 0) {
216+
test_state.wanted_test = argv[i];
217+
break;
218+
}
219+
}
220+
221+
195222
pg_query_init();
196223

197224
for (size_t i = 0; tests[i] != NULL; i++)
@@ -207,10 +234,8 @@ test_run_impl(TestFn * tests[], TestCleanupFn * test_cleanup, bool use_mctx)
207234
if (use_mctx)
208235
pg_query_exit_memory_context(ctx);
209236

210-
#ifdef TEST_FAIL_FAST
211-
if (test_state.failed > 0)
237+
if (fail_fast && test_state.failed > 0)
212238
break;
213-
#endif
214239
}
215240

216241
bool failed = (test_state.failed > 0);
@@ -223,13 +248,13 @@ test_run_impl(TestFn * tests[], TestCleanupFn * test_cleanup, bool use_mctx)
223248
}
224249

225250
int
226-
test_run(TestFn * tests[], TestCleanupFn * test_cleanup)
251+
test_run(int argc, char *argv[], TestFn * tests[], TestCleanupFn * test_cleanup)
227252
{
228-
return test_run_impl(tests, test_cleanup, false);
253+
return test_run_impl(argc, argv, tests, test_cleanup, false);
229254
}
230255

231256
int
232-
test_run_with_mcxt(TestFn * tests[], TestCleanupFn * test_cleanup)
257+
test_run_with_mcxt(int argc, char *argv[], TestFn * tests[], TestCleanupFn * test_cleanup)
233258
{
234-
return test_run_impl(tests, test_cleanup, true);
259+
return test_run_impl(argc, argv, tests, test_cleanup, true);
235260
}

test/framework/main.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
typedef struct
4242
{
43+
char *wanted_test;
4344
size_t passed;
4445
size_t failed;
4546
size_t skipped;
@@ -50,6 +51,7 @@ typedef void (TestFn) (TestState * test_state);
5051
typedef void (TestCleanupFn) (void);
5152

5253
/* Functions defined in framework/main.c */
54+
int TEST_INIT_impl(TestState * test_state, const char *func, size_t line);
5355
int TEST_BOUNDED_STRCMP(char *s1, char *s2);
5456
void TEST_ASSERT_NULL_impl(TestState * test_state, char *actual_str, void *actual);
5557
void TEST_ASSERT_LIST_EQUAL_impl(TestState * test_state, char *actual_str, List *actual, List *expected);
@@ -63,7 +65,7 @@ void TEST_ASSERT_STR_EQUAL_impl(TestState * test_state, char *actual_str, char
6365
#define TEST_SKIP(...) (printf(" SKIP: " __VA_ARGS__), test_state->skipped++)
6466

6567
/* Prints the name of the test and the line number. */
66-
#define TEST_INIT() printf("%s (line %i)\n", __func__, __LINE__)
68+
#define TEST_INIT() do { if (TEST_INIT_impl(test_state, __func__, __LINE__) != 0) return; } while(0)
6769

6870
/* Assert that `actual` is NULL. */
6971
#define TEST_ASSERT_NULL(actual) TEST_ASSERT_NULL_impl(test_state, #actual, actual)
@@ -79,8 +81,9 @@ void TEST_ASSERT_STR_EQUAL_impl(TestState * test_state, char *actual_str, char
7981

8082
/* Run each test in order, passing the same TestState object. */
8183
/* `test_cleanup()` is run between each test if it is not NULL. */
82-
int test_run(TestFn * tests[], TestCleanupFn * test_cleanup);
83-
int test_run_with_mcxt(TestFn * tests[], TestCleanupFn * test_cleanup);
84+
/* If argc is >1, the first argument is treated as a filter for tests. */
85+
int test_run(int argc, char *argv[], TestFn * tests[], TestCleanupFn * test_cleanup);
86+
int test_run_with_mcxt(int argc, char *argv[], TestFn * tests[], TestCleanupFn * test_cleanup);
8487

8588
#define TEST_LIST_MAKE6(a,b,c,d,e,f) lappend(list_make5(a,b,c,d,e), f)
8689
#define TEST_LIST_MAKE7(a,b,c,d,e,f,g) lappend(TEST_LIST_MAKE6(a,b,c,d,e,f), g)

test/summary.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,5 +253,5 @@ main(int argc, char *argv[])
253253
NULL
254254
};
255255

256-
return test_run_with_mcxt(tests, &test_cleanup);
256+
return test_run_with_mcxt(argc, argv, tests, &test_cleanup);
257257
}

test/summary_truncate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,5 @@ main(int argc, char *argv[])
198198
NULL
199199
};
200200

201-
return test_run_with_mcxt(tests, NULL);
201+
return test_run_with_mcxt(argc, argv, tests, NULL);
202202
}

0 commit comments

Comments
 (0)