1 /* Test support_record_failure state sharing.
2    Copyright (C) 2016-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <support/check.h>
20 #include <support/support.h>
21 #include <support/test-driver.h>
22 #include <support/xunistd.h>
23 
24 #include <getopt.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 static int exit_status_with_failure = -1;
31 static bool test_verify;
32 static bool test_verify_exit;
33 enum
34   {
35     OPT_STATUS = 10001,
36     OPT_TEST_VERIFY,
37     OPT_TEST_VERIFY_EXIT,
38   };
39 #define CMDLINE_OPTIONS                                                 \
40   { "status", required_argument, NULL, OPT_STATUS },                    \
41   { "test-verify", no_argument, NULL, OPT_TEST_VERIFY },                \
42   { "test-verify-exit", no_argument, NULL, OPT_TEST_VERIFY_EXIT },
43 static void
cmdline_process(int c)44 cmdline_process (int c)
45 {
46   switch (c)
47     {
48     case OPT_STATUS:
49       exit_status_with_failure = atoi (optarg);
50       break;
51     case OPT_TEST_VERIFY:
52       test_verify = true;
53       break;
54     case OPT_TEST_VERIFY_EXIT:
55       test_verify_exit = true;
56       break;
57     }
58 }
59 #define CMDLINE_PROCESS cmdline_process
60 
61 static void
check_failure_reporting(int phase,int zero,int unsupported)62 check_failure_reporting (int phase, int zero, int unsupported)
63 {
64   int status = support_report_failure (0);
65   if (status != zero)
66     {
67       printf ("real-error (phase %d): support_report_failure (0) == %d\n",
68               phase, status);
69       exit (1);
70     }
71   status = support_report_failure (1);
72   if (status != 1)
73     {
74       printf ("real-error (phase %d): support_report_failure (1) == %d\n",
75               phase, status);
76       exit (1);
77     }
78   status = support_report_failure (2);
79   if (status != 2)
80     {
81       printf ("real-error (phase %d): support_report_failure (2) == %d\n",
82               phase, status);
83       exit (1);
84     }
85   status = support_report_failure (EXIT_UNSUPPORTED);
86   if (status != unsupported)
87     {
88       printf ("real-error (phase %d): "
89               "support_report_failure (EXIT_UNSUPPORTED) == %d\n",
90               phase, status);
91       exit (1);
92     }
93 }
94 
95 static int
do_test(void)96 do_test (void)
97 {
98   if (exit_status_with_failure >= 0)
99     {
100       /* External invocation with requested error status.  Used by
101          tst-support_report_failure-2.sh.  */
102       support_record_failure ();
103       return exit_status_with_failure;
104     }
105   TEST_VERIFY (true);
106   TEST_VERIFY_EXIT (true);
107   if (test_verify)
108     {
109       TEST_VERIFY (false);
110       if (test_verbose)
111         printf ("info: execution passed failed TEST_VERIFY\n");
112       return 2; /* Expected exit status.  */
113     }
114   if (test_verify_exit)
115     {
116       TEST_VERIFY_EXIT (false);
117       return 3; /* Not reached.  Expected exit status is 1.  */
118     }
119 
120   printf ("info: This test tests the test framework.\n"
121           "info: It reports some expected errors on stdout.\n");
122 
123   /* Check that the status is passed through unchanged.  */
124   check_failure_reporting (1, 0, EXIT_UNSUPPORTED);
125 
126   /* Check state propagation from a subprocess.  */
127   pid_t pid = xfork ();
128   if (pid == 0)
129     {
130       support_record_failure ();
131       _exit (0);
132     }
133   int status;
134   xwaitpid (pid, &status, 0);
135   if (status != 0)
136     {
137       printf ("real-error: incorrect status from subprocess: %d\n", status);
138       return 1;
139     }
140   check_failure_reporting (2, 1, 1);
141 
142   /* Also test directly in the parent process.  */
143   support_record_failure_reset ();
144   check_failure_reporting (3, 0, EXIT_UNSUPPORTED);
145   support_record_failure ();
146   check_failure_reporting (4, 1, 1);
147 
148   /* We need to mask the failure above.  */
149   support_record_failure_reset ();
150   return 0;
151 }
152 
153 #include <support/test-driver.c>
154