• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2001
3  *
4  * This program is free software;  you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  * the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program;  if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 /*
21  * File:        ltpapicmd.c
22  *
23  * Description: This program impliments a command line version of some of the
24  *              LTP harness API's. This will enable tests written in shell and
25  *              other scripts to report problems and log results in the LTP
26  *              harness format. The intent is to have a common format in which
27  *              the C tests and tests written in scripts report results in
28  *              a common format.
29  *
30  *              The following LTP API's are available currently in command line
31  *              form:
32  *              tst_brk   - Print result message and break remaining test cases
33  *              tst_brkm  - Print result message, including file contents, and
34  *                          break remaining test cases
35  *              tst_res   - Print result message, including file contents
36  *              tst_resm  - Print result message
37  *              tst_exit  - Exit test with a meaningful exit value
38  *
39  *              These are the minimum set of functions or commands required to
40  *              report results.
41  *
42  * Exit:        All commands exit with
43  *               0   - on success
44  *              -1  - on failure
45  *
46  * History
47  * Dec 10 2002 - Created - Manoj Iyer manjo@mail.utexas.edu
48  * Dec 12 2002 - Modified - Code that checked if the environment variables
49  *               TCID and TST_TOTAL were set did not print usage message.
50  *               Modified code to print usage message in each case.
51  * Dec 16 2002 - Modified - Code to get the test number, gets environment
52  *               variable TST_COUNT and initializes tst_count.
53  * Dec 16 2002 - Documentation and comment changes.
54  * Feb 11 2003 - tst_count was set to -1 during init or setup in the script.
55  *               this was causing tst_resm to issue a warning message.
56  *               This bug is now fixed.
57  *
58  */
59 
60 #include <sys/socket.h>
61 #include <stdio.h>
62 #include <string.h>
63 #include <stdlib.h>
64 #include <stdint.h>
65 #include "test.h"
66 #include "usctest.h"
67 #include "safe_macros.h"
68 
69 char *TCID;			/* Name of the testcase */
70 int TST_TOTAL;			/* Total number of testcases */
71 
72 static char cmd_name[1024];	/* name by which this program is invoked tst_brk etc */
73 static char *tst_total;		/* total number of tests in the file. */
74 static char *tst_cntstr;	/* sets the value of tst_count with this value */
75 
76 
77 /*
78  * Function:    ident_ttype - Return test result type.
79  *
80  * Description: This function will return the test result type, it actually
81  *              the string that is entered by the user to an integer value that
82  *              is understood by the API's.
83  *
84  * Return:      test type TPASS, TFAIL, TBROK, TCONF, TWARN, or TINFO
85  *              on success
86  *              -1 on failure
87  */
ident_ttype(char * tstype)88 int ident_ttype(char *tstype)
89 {
90 	/* test result type one of TPASS, TFAIL, etc */
91 	if (strcmp(tstype, "TBROK") == 0)
92 		return TBROK;
93 	else if (strcmp(tstype, "TFAIL") == 0)
94 		return TFAIL;
95 	else if (strcmp(tstype, "TPASS") == 0)
96 		return TPASS;
97 	else if (strcmp(tstype, "TCONF") == 0)
98 		return TCONF;
99 	else if (strcmp(tstype, "TWARN") == 0)
100 		return TWARN;
101 	else if (strcmp(tstype, "TINFO") == 0)
102 		return TINFO;
103 	else
104 		return -1;
105 }
106 
tst_cat_file(const char * filename)107 void tst_cat_file(const char *filename)
108 {
109 	const char *cmd[] = {"cat", filename, NULL};
110 
111 	tst_cmd(NULL, cmd, NULL, NULL, 0);
112 }
113 
apicmd_brk(int argc,char * argv[])114 void apicmd_brk(int argc, char *argv[])
115 {
116 	int trestype;
117 	char *file_name;
118 
119 	if (argc < 5) {
120 		fprintf(stderr, "Usage: %s TTYPE FNAME FUNC STRING\n"
121 			"\tTTYPE  - Test Result Type; one of TFAIL, TBROK "
122 			"and TCONF.\n"
123 			"\tFNAME  - Print contents of this file after the message\n"
124 			"\tFUNC   - Cleanup function (ignored), but MUST be provided\n"
125 			"\tSTRING - Message explaining the test result\n",
126 			cmd_name);
127 		exit(1);
128 	}
129 	trestype = ident_ttype((argv++)[0]);
130 	file_name = (argv++)[0];
131 	tst_cat_file(file_name);
132 	argv++;
133 	tst_brkm(trestype, NULL, "%s", *argv);
134 
135 }
136 
apicmd_res(int argc,char * argv[])137 void apicmd_res(int argc, char *argv[])
138 {
139 	int trestype;
140 	char *file_name;
141 
142 	if (argc < 4) {
143 		fprintf(stderr, "Usage: %s TTYPE FNAME STRING\n"
144 			"\tTTYPE  - Test Result Type; one of TFAIL, TBROK "
145 			"and  TCONF.\n"
146 			"\tFNAME  - Print contents of this file after the message\n"
147 			"\tSTRING - Message explaining the test result\n",
148 			cmd_name);
149 		exit(1);
150 	}
151 	trestype = ident_ttype((argv++)[0]);
152 	file_name = (argv++)[0];
153 	tst_cat_file(file_name);
154 	tst_resm(trestype, "%s", *argv);
155 }
156 
apicmd_brkm(int argc,char * argv[])157 void apicmd_brkm(int argc, char *argv[])
158 {
159 	int trestype;
160 
161 	if (argc < 4) {
162 		fprintf(stderr, "Usage: %s TTYPE FUNC STRING\n"
163 			"\tTTYPE  - Test Result Type; one of TFAIL, TBROK "
164 			"and TCONF.\n"
165 			"\tFUNC   - Cleanup function (ignored), but MUST be provided\n"
166 			"\tSTRING - Message explaining the test result\n",
167 			cmd_name);
168 		exit(1);
169 	}
170 	trestype = ident_ttype((argv++)[0]);
171 	argv++;
172 	tst_brkm(trestype, NULL, "%s", *argv);
173 }
174 
apicmd_resm(int argc,char * argv[])175 void apicmd_resm(int argc, char *argv[])
176 {
177 	int trestype;
178 
179 	if (argc < 3) {
180 		fprintf(stderr, "Usage: %s TTYPE STRING\n"
181 			"\tTTYPE  - Test Result Type; one of TFAIL, TBROK"
182 			"and TCONF.\n"
183 			"\tSTRING - Message explaining the test result\n",
184 			cmd_name);
185 		exit(1);
186 	}
187 	trestype = ident_ttype((argv++)[0]);
188 	tst_resm(trestype, "%s", *argv);
189 }
190 
191 struct param_pair {
192 	char *cmd;
193 	int value;
194 };
195 
apicmd_fs_has_free(int argc,char * argv[])196 int apicmd_fs_has_free(int argc, char *argv[])
197 {
198 	if (argc != 3) {
199 		fprintf(stderr, "Usage: tst_fs_has_free path required_bytes\n"
200 			"path: the pathname of the mounted filesystem\n"
201 			"required_bytes: the required free space"
202 			" (supports kB, MB and GB suffixes)\n");
203 		exit(2);
204 	}
205 
206 	char *endptr;
207 	unsigned int required_kib = strtoull(argv[1], &endptr, 0);
208 	unsigned int mul = TST_BYTES;
209 
210 	if (*argv[1] == '\0')
211 		goto fs_has_free_err;
212 
213 	if (*endptr != '\0') {
214 		if (!strcasecmp(endptr, "kB")) {
215 			mul = TST_KB;
216 		} else if (!strcasecmp(endptr, "MB")) {
217 			mul = TST_MB;
218 		} else if (!strcasecmp(endptr, "GB")) {
219 			mul = TST_GB;
220 		} else {
221 			goto fs_has_free_err;
222 		}
223 	}
224 
225 	exit(!tst_fs_has_free(NULL, argv[0], required_kib, mul));
226 
227 fs_has_free_err:
228 	fprintf(stderr, "%s is not a valid size\n", argv[1]);
229 	exit(2);
230 }
231 
232 /*
233  * Function:    main - entry point of this program
234  *
235  * Description: Parses the arguments to each command. Most commands have in
236  *              common atlest 2 arguments, type of test result, which is one of
237  *              TPASS, TFAIL, TBROK, TCONF, etc, and a message that describes
238  *              the result. Other arguments are a file, the contents of which
239  *              are printed after the type of test result and associated message
240  *              is printed, also a cleanup function that will be executed.
241  *              Currently this function name is ignored but MUST be provided
242  *              for compatability reasons.
243  *
244  *              The different commands are actually a hard link to this program
245  *              the program invokes the appropriate function based on the
246  *              command name with which it was invoked.
247  *
248  *              Set the values for TCID to the name of the test case.
249  *              set the value for TST_TOTAL for total number of tests this is
250  *              required in case one test breaks and all following tests also
251  *              should be reported as broken.
252  *              Set tst_count before every individual test.
253  *
254  * Exit:        0 on success
255  *              -1 on failure
256  */
main(int argc,char * argv[])257 int main(int argc, char *argv[])
258 {
259 	strcpy(cmd_name, SAFE_BASENAME(NULL, (argv++)[0]));
260 
261 	TCID = getenv("TCID");
262 	tst_total = getenv("TST_TOTAL");
263 	tst_cntstr = getenv("TST_COUNT");
264 	if (TCID == NULL || tst_total == NULL || tst_cntstr == NULL) {
265 		 if(!strcmp(cmd_name, "tst_fs_has_free")) {
266 			fprintf(stderr,
267 				"\nSet variables TCID, TST_TOTAL, and TST_COUNT before each test:\n"
268 				"export TCID=<test name>\n"
269 				"export TST_TOTAL=<Total Number of Tests >\n"
270 				"export TST_COUNT=<Test case number>\n\n");
271 			/* Make sure the user knows there's an error. */
272 			abort();
273 		}
274 	} else {
275 		TST_TOTAL = atoi(tst_total);
276 		tst_count = atoi(tst_cntstr);
277 		if (tst_count > 0)
278 			tst_count--;
279 
280 		if (strcmp(TCID, " ") == 0) {
281 			fprintf(stderr,
282 				"Variable TCID not set, use: TCID=<test name>\n");
283 			exit(1);
284 		}
285 		if (TST_TOTAL <= 0) {
286 			fprintf(stderr,
287 				"Variable TST_TOTAL is set to 0, must be "
288 				"greater than zero\n");
289 			exit(1);
290 		}
291 	}
292 
293 	if (strcmp(cmd_name, "tst_brk") == 0) {
294 		apicmd_brk(argc, argv);
295 	} else if (strcmp(cmd_name, "tst_res") == 0) {
296 		apicmd_res(argc, argv);
297 	} else if (strcmp(cmd_name, "tst_brkm") == 0) {
298 		apicmd_brkm(argc, argv);
299 	} else if (strcmp(cmd_name, "tst_resm") == 0) {
300 		apicmd_resm(argc, argv);
301 	} else if (strcmp(cmd_name, "tst_exit") == 0) {
302 		tst_exit();
303 	} else if (strcmp(cmd_name, "tst_ncpus") == 0) {
304 		printf("%li\n", tst_ncpus());
305 	} else if (strcmp(cmd_name, "tst_ncpus_conf") == 0) {
306 		printf("%li\n", tst_ncpus_conf());
307 	} else if (strcmp(cmd_name, "tst_ncpus_max") == 0) {
308 		printf("%li\n", tst_ncpus_max());
309 	} else if (strcmp(cmd_name, "tst_fs_has_free") == 0) {
310 		apicmd_fs_has_free(argc, argv);
311 	}
312 
313 	exit(0);
314 }
315