@@ -33,7 +33,7 @@ static void print_subinterp(void)
3333 );
3434}
3535
36- static void test_repeated_init_and_subinterpreters (void )
36+ static int test_repeated_init_and_subinterpreters (void )
3737{
3838 PyThreadState * mainstate , * substate ;
3939#ifdef WITH_THREAD
@@ -70,6 +70,7 @@ static void test_repeated_init_and_subinterpreters(void)
7070 PyEval_RestoreThread (mainstate );
7171 Py_Finalize ();
7272 }
73+ return 0 ;
7374}
7475
7576/*****************************************************
@@ -103,7 +104,7 @@ static void check_stdio_details(const char *encoding, const char * errors)
103104 Py_Finalize ();
104105}
105106
106- static void test_forced_io_encoding (void )
107+ static int test_forced_io_encoding (void )
107108{
108109 /* Check various combinations */
109110 printf ("--- Use defaults ---\n" );
@@ -122,19 +123,51 @@ static void test_forced_io_encoding(void)
122123 printf ("Unexpected success calling Py_SetStandardStreamEncoding" );
123124 }
124125 Py_Finalize ();
126+ return 0 ;
125127}
126128
127- /* Different embedding tests */
128- int main (int argc , char * argv [])
129+ /* *********************************************************
130+ * List of test cases and the function that implements it.
131+ *
132+ * Names are compared case-sensitively with the first
133+ * argument. If no match is found, or no first argument was
134+ * provided, the names of all test cases are printed and
135+ * the exit code will be -1.
136+ *
137+ * The int returned from test functions is used as the exit
138+ * code, and test_capi treats all non-zero exit codes as a
139+ * failed test.
140+ *********************************************************/
141+ struct TestCase
129142{
143+ const char * name ;
144+ int (* func )(void );
145+ };
146+
147+ static struct TestCase TestCases [] = {
148+ { "forced_io_encoding" , test_forced_io_encoding },
149+ { "repeated_init_and_subinterpreters" , test_repeated_init_and_subinterpreters },
150+ { NULL , NULL }
151+ };
130152
131- /* TODO: Check the argument string to allow for more test cases */
153+ int main (int argc , char * argv [])
154+ {
132155 if (argc > 1 ) {
133- /* For now: assume "forced_io_encoding */
134- test_forced_io_encoding ();
135- } else {
136- /* Run the original embedding test case by default */
137- test_repeated_init_and_subinterpreters ();
156+ for (struct TestCase * tc = TestCases ; tc && tc -> name ; tc ++ ) {
157+ if (strcmp (argv [1 ], tc -> name ) == 0 )
158+ return (* tc -> func )();
159+ }
138160 }
139- return 0 ;
161+
162+ /* No match found, or no test name provided, so display usage */
163+ printf ("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n"
164+ "Normally executed via 'EmbeddingTests' in Lib/test/test_capi.py\n\n"
165+ "Usage: %s TESTNAME\n\nAll available tests:\n" , argv [0 ]);
166+ for (struct TestCase * tc = TestCases ; tc && tc -> name ; tc ++ ) {
167+ printf (" %s\n" , tc -> name );
168+ }
169+
170+ /* Non-zero exit code will cause test_capi.py tests to fail.
171+ This is intentional. */
172+ return -1 ;
140173}
0 commit comments