Skip to content

Commit ae15d29

Browse files
author
Crispin Dent-Young
committed
Support arbitrary tagging and selection of testcases.
A testcase can optionally have a list of tags associated with it. Srunner can be run with an optional include list of tags and an optional exclude list of tags. These will have the effect of filtering testcases that would otherwise be run.
1 parent 6cadd63 commit ae15d29

10 files changed

Lines changed: 428 additions & 3 deletions

src/check.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static void suite_free(Suite * s)
103103
free(s);
104104
}
105105

106+
106107
TCase *tcase_create(const char *name)
107108
{
108109
char *env;
@@ -149,7 +150,19 @@ TCase *tcase_create(const char *name)
149150
tc->ch_sflst = check_list_create();
150151
tc->unch_tflst = check_list_create();
151152
tc->ch_tflst = check_list_create();
153+
tc->tags = NULL;
154+
155+
return tc;
156+
}
157+
158+
TCase *tcase_create_tagged(const char *name, const char *tags)
159+
{
160+
TCase *tc;
152161

162+
tc = tcase_create(name);
163+
if ((tc != NULL) && (tags != NULL)) {
164+
tc->tags = strdup(tags);
165+
}
153166
return tc;
154167
}
155168

@@ -166,7 +179,10 @@ static void tcase_free(TCase * tc)
166179
check_list_free(tc->ch_sflst);
167180
check_list_free(tc->unch_tflst);
168181
check_list_free(tc->ch_tflst);
169-
182+
if (tc->tags) {
183+
free(tc->tags);
184+
tc->tags = NULL;
185+
}
170186
free(tc);
171187
}
172188

src/check.h.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,23 @@ CK_DLL_EXP void CK_EXPORT suite_add_tcase(Suite * s, TCase * tc);
169169
* */
170170
CK_DLL_EXP TCase *CK_EXPORT tcase_create(const char *name);
171171

172+
/**
173+
* Create a test case associated with certain tags.
174+
*
175+
* Once created, tests can be added with the tcase_add_test()
176+
* function, and the test case assigned to a suite with the
177+
* suite_add_tcase() function.
178+
*
179+
* @param name name of the test case
180+
* @param tags string containing arbitrary tags separated by spaces
181+
*
182+
* @return test case containing no tests
183+
*
184+
* @since 0.11.0
185+
* */
186+
CK_DLL_EXP TCase *CK_EXPORT tcase_create_tagged(const char *name,
187+
const char *tags);
188+
172189
/**
173190
* Add a test function to a test case
174191
*
@@ -980,6 +997,7 @@ CK_DLL_EXP void CK_EXPORT srunner_run_all(SRunner * sr,
980997
*/
981998
CK_DLL_EXP void CK_EXPORT srunner_run(SRunner * sr, const char *sname,
982999
const char *tcname,
1000+
const char *inc_tags, const char *exc_tags,
9831001
enum print_output print_mode);
9841002

9851003

src/check_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct TCase
6565
List *unch_tflst;
6666
List *ch_sflst;
6767
List *ch_tflst;
68+
char *tags;
6869
};
6970

7071
typedef struct TestStats

src/check_run.c

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ static void srunner_run_init(SRunner * sr, enum print_output print_mode);
6060
static void srunner_run_end(SRunner * sr, enum print_output print_mode);
6161
static void srunner_iterate_suites(SRunner * sr,
6262
const char *sname, const char *tcname,
63+
const char *inc_tags, const char *exc_tags,
6364
enum print_output print_mode);
6465
static void srunner_iterate_tcase_tfuns(SRunner * sr, TCase * tc);
6566
static void srunner_add_failure(SRunner * sr, TestResult * tf);
@@ -158,8 +159,50 @@ static void srunner_run_end(SRunner * sr,
158159
set_fork_status(CK_FORK);
159160
}
160161

162+
/*
163+
* Helper func to compare two lists of tags and return true if there is a
164+
* common tag.
165+
*/
166+
static unsigned int matching_tag(const char *tags1_orig, const char *tags2_orig)
167+
{
168+
169+
char *saveptr1;
170+
char *saveptr2;
171+
char *tags1;
172+
char *tag1;
173+
174+
175+
if ((tags1_orig == NULL) || (tags2_orig == NULL))
176+
return 0;
177+
178+
tags1 = strdup(tags1_orig);
179+
tag1 = strtok_r(tags1, " ", &saveptr1);
180+
while (tag1) {
181+
182+
char *tags2, *tag2;
183+
184+
tags2 = strdup(tags2_orig);
185+
tag2 = strtok_r(tags2, " ", &saveptr2);
186+
while (tag2) {
187+
if (strcmp(tag1, tag2) == 0) {
188+
189+
free(tags2);
190+
free(tags1);
191+
return 1;
192+
}
193+
194+
tag2 = strtok_r(NULL, " ", &saveptr2);
195+
}
196+
free(tags2);
197+
tag1 = strtok_r(NULL, " ", &saveptr1);
198+
}
199+
free(tags1);
200+
return 0;
201+
}
202+
161203
static void srunner_iterate_suites(SRunner * sr,
162204
const char *sname, const char *tcname,
205+
const char *inc_tags, const char *exc_tags,
163206
enum print_output CK_ATTRIBUTE_UNUSED
164207
print_mode)
165208
{
@@ -191,6 +234,14 @@ static void srunner_iterate_suites(SRunner * sr,
191234
{
192235
continue;
193236
}
237+
if (inc_tags != NULL) {
238+
if (!matching_tag(inc_tags, tc->tags))
239+
continue;
240+
}
241+
if (exc_tags != NULL) {
242+
if (matching_tag(inc_tags, tc->tags))
243+
continue;
244+
}
194245

195246
srunner_run_tcase(sr, tc);
196247
}
@@ -738,10 +789,13 @@ void srunner_run_all(SRunner * sr, enum print_output print_mode)
738789
{
739790
srunner_run(sr, NULL, /* All test suites. */
740791
NULL, /* All test cases. */
792+
NULL, /* Include all tags */
793+
NULL, /* Exclude no tags */
741794
print_mode);
742795
}
743796

744797
void srunner_run(SRunner * sr, const char *sname, const char *tcname,
798+
const char *inc_tags, const char *exc_tags,
745799
enum print_output print_mode)
746800
{
747801
#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
@@ -756,7 +810,11 @@ void srunner_run(SRunner * sr, const char *sname, const char *tcname,
756810
if(!tcname)
757811
tcname = getenv("CK_RUN_CASE");
758812
if(!sname)
759-
sname = getenv("CK_RUN_SUITE");
813+
sname = getenv("CK_RUN_SUITE");
814+
if(!inc_tags)
815+
inc_tags = getenv("CK_INC_TAGS");
816+
if(!exc_tags)
817+
exc_tags = getenv("CK_EXC_TAGS");
760818

761819
if(sr == NULL)
762820
return;
@@ -779,7 +837,7 @@ void srunner_run(SRunner * sr, const char *sname, const char *tcname,
779837
sigaction(SIGTERM, &sigterm_new_action, &sigterm_old_action);
780838
#endif /* HAVE_SIGACTION && HAVE_FORK */
781839
srunner_run_init(sr, print_mode);
782-
srunner_iterate_suites(sr, sname, tcname, print_mode);
840+
srunner_iterate_suites(sr, sname, tcname, inc_tags, exc_tags, print_mode);
783841
srunner_run_end(sr, print_mode);
784842
#if defined(HAVE_SIGACTION) && defined(HAVE_FORK)
785843
sigaction(SIGALRM, &sigalarm_old_action, NULL);

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ set(CHECK_CHECK_SOURCES
5353
check_check_pack.c
5454
check_check_selective.c
5555
check_check_sub.c
56+
check_check_tags.c
5657
check_list.c)
5758
set(CHECK_CHECK_HEADERS check_check.h)
5859
add_executable(check_check ${CHECK_CHECK_HEADERS} ${CHECK_CHECK_SOURCES})

tests/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ check_check_export_SOURCES = \
4141
check_check_master.c \
4242
check_check_log.c \
4343
check_check_fork.c \
44+
check_check_tags.c \
4445
check_check_export_main.c
4546
check_check_export_LDADD = $(top_builddir)/src/libcheck.la $(top_builddir)/lib/libcompat.la
4647

@@ -58,6 +59,7 @@ check_check_SOURCES = \
5859
check_check_pack.c \
5960
check_check_exit.c \
6061
check_check_selective.c \
62+
check_check_tags.c \
6163
check_check_main.c
6264
check_check_LDADD = $(top_builddir)/src/libcheckinternal.la $(top_builddir)/lib/libcompat.la
6365

@@ -67,6 +69,7 @@ check_mem_leaks_SOURCES = \
6769
check_check_fork.c \
6870
check_check_exit.c \
6971
check_check_selective.c \
72+
check_check_tags.c \
7073
check_check_sub.c \
7174
check_check_master.c
7275
check_mem_leaks_LDADD = $(top_builddir)/src/libcheck.la $(top_builddir)/lib/libcompat.la

tests/check_check.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Suite *make_fixture_suite(void);
5555
Suite *make_pack_suite(void);
5656
Suite *make_exit_suite(void);
5757
Suite *make_selective_suite(void);
58+
Suite *make_tag_suite(void);
5859

5960
extern int master_tests_lineno[];
6061
void init_master_tests_lineno(int num_master_tests);

tests/check_check_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int main (void)
4343
srunner_add_suite(sr, make_fork_suite());
4444
srunner_add_suite(sr, make_fixture_suite());
4545
srunner_add_suite(sr, make_pack_suite());
46+
srunner_add_suite(sr, make_tag_suite());
4647

4748
#if defined(HAVE_FORK) && HAVE_FORK==1
4849
srunner_add_suite(sr, make_exit_suite());

tests/check_check_selective.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ START_TEST(test_srunner_run_run_all)
100100
srunner_run (sr,
101101
NULL, /* NULL tsuite name. */
102102
NULL, /* NULL tcase name. */
103+
NULL, /* include any tags */
104+
NULL, /* exclude no tags */
103105
CK_VERBOSE);
104106

105107
ck_assert_msg (srunner_ntests_run(sr) == 3,
@@ -116,6 +118,8 @@ START_TEST(test_srunner_run_suite)
116118
srunner_run (sr,
117119
"suite1",
118120
NULL, /* NULL tcase name. */
121+
NULL, /* include any tags */
122+
NULL, /* exclude no tags */
119123
CK_VERBOSE);
120124

121125
ck_assert_msg (test_tc11_executed
@@ -134,6 +138,8 @@ START_TEST(test_srunner_run_no_suite)
134138
srunner_run (sr,
135139
"non-existing-suite",
136140
NULL, /* NULL tcase name. */
141+
NULL, /* include any tags */
142+
NULL, /* exclude no tags */
137143
CK_VERBOSE);
138144

139145
ck_assert_msg (!(test_tc11_executed
@@ -152,6 +158,8 @@ START_TEST(test_srunner_run_tcase)
152158
srunner_run (sr,
153159
NULL, /* NULL suite name. */
154160
"tcase12",
161+
NULL, /* include any tags */
162+
NULL, /* exclude no tags */
155163
CK_VERBOSE);
156164

157165
ck_assert_msg (!test_tc11_executed
@@ -170,6 +178,8 @@ START_TEST(test_srunner_no_tcase)
170178
srunner_run (sr,
171179
NULL, /* NULL suite name. */
172180
"non-existant-test-case",
181+
NULL, /* include any tags */
182+
NULL, /* exclude no tags */
173183
CK_VERBOSE);
174184

175185
ck_assert_msg (!(test_tc11_executed
@@ -188,6 +198,8 @@ START_TEST(test_srunner_suite_tcase)
188198
srunner_run (sr,
189199
"suite2",
190200
"tcase21",
201+
NULL, /* include any tags */
202+
NULL, /* exclude no tags */
191203
CK_VERBOSE);
192204

193205
ck_assert_msg (!test_tc11_executed
@@ -206,6 +218,8 @@ START_TEST(test_srunner_suite_no_tcase)
206218
srunner_run (sr,
207219
"suite1",
208220
"non-existant-test-case",
221+
NULL, /* include any tags */
222+
NULL, /* exclude no tags */
209223
CK_VERBOSE);
210224

211225
ck_assert_msg (!(test_tc11_executed

0 commit comments

Comments
 (0)