8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / fm / libdiagcode / common / diagcode_test.c
blob3cee98dcf7ca0c5a06bb2fdc6fbc55d0aa2b9531
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * diagcode library unit test
30 * usually run from "make test" target. takes a single argument
31 * which is the directory where the test dictionaries are found.
32 * this test driver scans the dictionaries for comments of the form:
33 * #TEST:<routine>:<errno>:<input>:<output>
34 * and executes that test.
36 * exit 0 and an "All tests passed" message means no failures. otherwise
37 * error messages are spewed as appropriate and exit value is non-zero.
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <ctype.h>
46 #include <alloca.h>
47 #include <errno.h>
48 #include <sys/types.h>
49 #include <dirent.h>
50 #include <stdarg.h>
52 #include <fm/diagcode.h>
54 #define MAXLINE 10240
55 #define MAXARG 10
56 #define MAXKEY 100
57 #define MAXCODE 100
59 static char *Myname;
60 static char *Dict;
61 static int Line;
62 static int Errcount;
63 static fm_dc_handle_t *Dhp;
65 /*PRINTFLIKE1*/
66 static void
67 err(const char *fmt, ...)
69 va_list ap;
71 va_start(ap, fmt);
72 (void) fprintf(stderr, "%s: %s:%d ", Myname, Dict, Line);
73 (void) vfprintf(stderr, fmt, ap);
74 (void) fprintf(stderr, "\n");
75 Errcount++;
78 /* parse an expected errno value from test line (numeric or some symbolic) */
79 static int
80 geterrno(const char *s)
82 if (*s == '\0' || isspace(*s))
83 return (0);
84 else if (isdigit(*s))
85 return (atoi(s));
86 else if (strcmp(s, "EPERM") == 0)
87 return (EPERM);
88 else if (strcmp(s, "ENOENT") == 0)
89 return (ENOENT);
90 else if (strcmp(s, "ESRCH") == 0)
91 return (ESRCH);
92 else if (strcmp(s, "ENOMEM") == 0)
93 return (ENOMEM);
94 else if (strcmp(s, "EACCES") == 0)
95 return (EACCES);
96 else if (strcmp(s, "EINVAL") == 0)
97 return (EINVAL);
98 else if (strcmp(s, "ERANGE") == 0)
99 return (ERANGE);
100 else if (strcmp(s, "ENOMSG") == 0)
101 return (ENOMSG);
102 else if (strcmp(s, "ENOTSUP") == 0)
103 return (ENOTSUP);
104 else {
105 err("geterrno: don't know errno \"%s\"", s);
106 Errcount++;
107 return (0);
111 /* call fm_dc_opendict() as part of a test */
112 static void
113 do_open(const char *dirpath, const char *dictname, char *argv[], int argc)
115 int reterrno;
116 int experrno;
118 if (argc != 2) {
119 err("argc != 2");
120 return;
122 experrno = geterrno(argv[1]);
124 if ((Dhp = fm_dc_opendict(FM_DC_VERSION, dirpath, dictname)) == NULL)
125 reterrno = errno;
126 else
127 reterrno = 0;
129 if (reterrno != experrno)
130 err("opendict errno %d, expected %d", reterrno, experrno);
133 /* call fm_dc_closedict() as part of a test */
134 static void
135 do_close(const char *dirpath, const char *dictname, char *argv[], int argc)
137 if (Dhp) {
138 fm_dc_closedict(Dhp);
139 Dhp = NULL;
143 /* call fm_dc_codelen() as part of a test */
144 static void
145 do_codelen(const char *dirpath, const char *dictname, char *argv[], int argc)
147 int retcodelen;
148 int expcodelen;
150 if (argc != 3) {
151 err("argc != 3");
152 return;
154 expcodelen = geterrno(argv[2]);
156 if (Dhp == NULL) {
157 err("codelen NULL handle");
158 return;
161 retcodelen = fm_dc_codelen(Dhp);
163 if (retcodelen != expcodelen)
164 err("codelen %d, expected %d", retcodelen, expcodelen);
167 /* call fm_dc_maxkey() as part of a test */
168 static void
169 do_maxkey(const char *dirpath, const char *dictname, char *argv[], int argc)
171 int retmaxkey;
172 int expmaxkey;
174 if (argc != 3) {
175 err("argc != 3");
176 return;
178 expmaxkey = geterrno(argv[2]);
180 if (Dhp == NULL) {
181 err("maxkey NULL handle");
182 return;
185 retmaxkey = fm_dc_maxkey(Dhp);
187 if (retmaxkey != expmaxkey)
188 err("maxkey %d, expected %d", retmaxkey, expmaxkey);
191 /* call fm_dc_key2code() as part of a test */
192 static void
193 do_key2code(const char *dirpath, const char *dictname, char *argv[], int argc)
195 int reterrno;
196 int experrno;
197 const char *key[MAXKEY];
198 char code[MAXCODE];
199 int nel;
200 char *beginp;
201 char *endp;
203 if (argc < 3) {
204 err("argc < 3");
205 return;
207 if (argc > 4) {
208 err("argc > 4");
209 return;
211 experrno = geterrno(argv[1]);
213 /* convert key into array */
214 nel = 0;
215 beginp = argv[2];
216 while (nel < MAXKEY - 1) {
217 key[nel++] = beginp;
218 if ((endp = strchr(beginp, ' ')) != NULL) {
219 *endp++ = '\0';
220 beginp = endp;
221 } else
222 break;
224 key[nel] = NULL;
226 if (Dhp == NULL) {
227 err("key2code NULL handle");
228 return;
231 if (fm_dc_key2code(Dhp, key, code, MAXCODE) < 0)
232 reterrno = errno;
233 else
234 reterrno = 0;
236 if (reterrno != experrno) {
237 err("key2code errno %d, expected %d", reterrno, experrno);
238 return;
241 if (reterrno == 0 && argc > 3 && strcmp(code, argv[3]))
242 err("code \"%s\", expected \"%s\"", code, argv[3]);
245 /* call fm_dc_code2key() as part of a test */
246 static void
247 do_code2key(const char *dirpath, const char *dictname, char *argv[], int argc)
249 int reterrno;
250 int experrno;
251 char keystr[MAXLINE];
252 char *key[MAXKEY];
253 int nel;
255 if (argc < 3) {
256 err("argc < 3");
257 return;
259 if (argc > 4) {
260 err("argc > 4");
261 return;
263 experrno = geterrno(argv[1]);
265 if (Dhp == NULL) {
266 err("code2key NULL handle");
267 return;
270 if (fm_dc_code2key(Dhp, argv[2], key, fm_dc_maxkey(Dhp)) < 0)
271 reterrno = errno;
272 else
273 reterrno = 0;
275 if (reterrno != experrno) {
276 err("errno %d, expected %d", reterrno, experrno);
277 return;
280 if (reterrno)
281 return;
283 if (argc > 3) {
284 /* convert key into string */
285 keystr[0] = '\0';
286 for (nel = 0; key[nel]; nel++) {
287 if (nel)
288 (void) strcat(keystr, " ");
289 (void) strcat(keystr, key[nel]);
292 if (strcmp(keystr, argv[3]))
293 err("key \"%s\", expected \"%s\"", keystr, argv[3]);
295 for (nel = 0; key[nel]; nel++)
296 free(key[nel]);
299 /* call fm_dc_getprop() as part of a test */
300 static void
301 do_getprop(const char *dirpath, const char *dictname, char *argv[], int argc)
303 int reterrno;
304 int experrno;
305 const char *val;
307 if (argc != 4) {
308 err("argc != 4");
309 return;
311 experrno = geterrno(argv[1]);
313 if (Dhp == NULL) {
314 err("getprop NULL handle");
315 return;
318 if ((val = fm_dc_getprop(Dhp, argv[2])) == NULL)
319 reterrno = errno;
320 else
321 reterrno = 0;
323 if (reterrno != experrno) {
324 err("getprop errno %d, expected %d", reterrno, experrno);
325 return;
328 if (reterrno == 0 && strcmp(val, argv[3]))
329 err("val \"%s\", expected \"%s\"", val, argv[3]);
332 /* scan a dictionary, looking for test directives embedded in the comments */
333 static void
334 testdict(const char *dirpath, const char *dictname)
336 char linebuf[MAXLINE];
337 char fname[MAXLINE];
338 FILE *fp;
340 (void) snprintf(fname, MAXLINE, "%s/%s.dict", dirpath, dictname);
342 if ((fp = fopen(fname, "r")) == NULL) {
343 perror(fname);
344 Errcount++;
345 return;
348 Line = 0;
349 Dict = fname;
351 while (fgets(linebuf, MAXLINE, fp) != NULL) {
352 char *argv[MAXARG];
353 int argc;
354 char *beginp;
355 char *endp;
357 Line++;
358 if (strncmp(linebuf, "#TEST:", 6))
359 continue;
361 if ((endp = strchr(linebuf, '\n')) != NULL)
362 *endp = '\0';
363 argc = 0;
364 beginp = &linebuf[6];
365 while (argc < MAXARG - 1) {
366 argv[argc++] = beginp;
367 if ((endp = strchr(beginp, ':')) != NULL) {
368 *endp++ = '\0';
369 beginp = endp;
370 } else
371 break;
373 argv[argc] = NULL;
375 if (strcmp(argv[0], "open") == 0)
376 do_open(dirpath, dictname, argv, argc);
377 else if (strcmp(argv[0], "close") == 0)
378 do_close(dirpath, dictname, argv, argc);
379 else if (strcmp(argv[0], "codelen") == 0)
380 do_codelen(dirpath, dictname, argv, argc);
381 else if (strcmp(argv[0], "maxkey") == 0)
382 do_maxkey(dirpath, dictname, argv, argc);
383 else if (strcmp(argv[0], "key2code") == 0)
384 do_key2code(dirpath, dictname, argv, argc);
385 else if (strcmp(argv[0], "code2key") == 0)
386 do_code2key(dirpath, dictname, argv, argc);
387 else if (strcmp(argv[0], "getprop") == 0)
388 do_getprop(dirpath, dictname, argv, argc);
389 else {
390 err("unknown TEST command: \"%s\"", argv[0]);
391 Errcount++;
395 (void) fclose(fp);
397 if (Dhp) {
398 fm_dc_closedict(Dhp);
399 Dhp = NULL;
403 /* scan a directory, looking for dictionaries to test against */
405 main(int argc, char *argv[])
407 DIR *dirp;
408 struct dirent *dp;
410 if ((Myname = strrchr(argv[0], '/')) == NULL)
411 Myname = argv[0];
412 else
413 Myname++;
415 if (argc != 2) {
416 (void) fprintf(stderr, "usage: %s test-directory\n", argv[0]);
417 exit(1);
420 if ((dirp = opendir(argv[1])) == NULL) {
421 perror(argv[1]);
422 exit(1);
425 while ((dp = readdir(dirp)) != NULL) {
426 char *ptr;
428 if (dp->d_name[0] == '.')
429 continue;
431 if ((ptr = strrchr(dp->d_name, '.')) == NULL ||
432 strcmp(ptr, ".dict"))
433 continue;
435 *ptr = '\0'; /* remove the extension */
436 testdict(argv[1], dp->d_name);
438 (void) closedir(dirp);
440 if (Errcount == 0)
441 (void) printf("%s: All tests passed.\n", Myname);
443 return (Errcount);