4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
30 #include <sys/fm/protocol.h>
31 #include <fm/fmd_msg.h>
43 main(int argc
, char *argv
[])
50 nvlist_t
*auth
, *fmri
, *list
, *test_arr
[TEST_ARR_SZ
];
51 const char *code
= "TEST-8000-08";
52 int64_t tod
[] = { 0x9400000, 0 };
55 (void) fprintf(stderr
, "Usage: %s\n", argv
[0]);
60 * Build up a valid list.suspect event for a fictional diagnosis
61 * using a diagnosis code from our test dictionary so we can format
64 if (nvlist_alloc(&auth
, NV_UNIQUE_NAME
, 0) != 0 ||
65 nvlist_alloc(&fmri
, NV_UNIQUE_NAME
, 0) != 0 ||
66 nvlist_alloc(&list
, NV_UNIQUE_NAME
, 0) != 0) {
67 (void) fprintf(stderr
, "%s: nvlist_alloc failed\n", argv
[0]);
71 err
|= nvlist_add_uint8(auth
, FM_VERSION
, FM_FMRI_AUTH_VERSION
);
72 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_PRODUCT
, "product");
73 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_PRODUCT_SN
, "product_sn");
74 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_CHASSIS
, "chassis");
75 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_DOMAIN
, "domain");
76 err
|= nvlist_add_string(auth
, FM_FMRI_AUTH_SERVER
, "server");
79 (void) fprintf(stderr
, "%s: failed to build auth nvlist: %s\n",
80 argv
[0], strerror(err
));
84 err
|= nvlist_add_uint8(fmri
, FM_VERSION
, FM_FMD_SCHEME_VERSION
);
85 err
|= nvlist_add_string(fmri
, FM_FMRI_SCHEME
, FM_FMRI_SCHEME_FMD
);
86 err
|= nvlist_add_nvlist(fmri
, FM_FMRI_AUTHORITY
, auth
);
87 err
|= nvlist_add_string(fmri
, FM_FMRI_FMD_NAME
, "fmd_msg_test");
88 err
|= nvlist_add_string(fmri
, FM_FMRI_FMD_VERSION
, "1.0");
91 (void) fprintf(stderr
, "%s: failed to build fmri nvlist: %s\n",
92 argv
[0], strerror(err
));
96 err
|= nvlist_add_uint8(list
, FM_VERSION
, FM_SUSPECT_VERSION
);
97 err
|= nvlist_add_string(list
, FM_CLASS
, FM_LIST_SUSPECT_CLASS
);
98 err
|= nvlist_add_string(list
, FM_SUSPECT_UUID
, "12345678");
99 err
|= nvlist_add_string(list
, FM_SUSPECT_DIAG_CODE
, code
);
100 err
|= nvlist_add_int64_array(list
, FM_SUSPECT_DIAG_TIME
, tod
, 2);
101 err
|= nvlist_add_nvlist(list
, FM_SUSPECT_DE
, fmri
);
102 err
|= nvlist_add_uint32(list
, FM_SUSPECT_FAULT_SZ
, 0);
105 * Add a contrived nvlist array to our list.suspect so that we can
106 * exercise the expansion syntax for dereferencing nvlist array members
108 for (i
= 0; i
< TEST_ARR_SZ
; i
++) {
109 if (nvlist_alloc(&test_arr
[i
], NV_UNIQUE_NAME
, 0) != 0) {
110 (void) fprintf(stderr
, "%s: failed to alloc nvlist "
111 "array: %s\n", argv
[0], strerror(err
));
114 err
|= nvlist_add_uint8(test_arr
[i
], "index", i
);
116 err
|= nvlist_add_nvlist_array(list
, "test_arr", test_arr
, TEST_ARR_SZ
);
119 (void) fprintf(stderr
, "%s: failed to build list nvlist: %s\n",
120 argv
[0], strerror(err
));
125 * Now initialize the libfmd_msg library for testing, using the message
126 * catalogs found in the proto area of the current workspace.
128 if ((h
= fmd_msg_init(getenv("ROOT"), FMD_MSG_VERSION
)) == NULL
) {
129 (void) fprintf(stderr
, "%s: fmd_msg_init failed: %s\n",
130 argv
[0], strerror(errno
));
135 * Test 0: Verify that both fmd_msg_getitem_id and fmd_msg_gettext_id
136 * return NULL and EINVAL for an illegal message code, and NULL
137 * and ENOENT for a valid but not defined message code.
139 s
= fmd_msg_getitem_id(h
, NULL
, "I_AM_NOT_VALID", 0);
140 if (s
!= NULL
|| errno
!= EINVAL
) {
141 (void) fprintf(stderr
, "%s: test0 FAIL: illegal code returned "
142 "s = %p, errno = %d\n", argv
[0], (void *)s
, errno
);
146 s
= fmd_msg_gettext_id(h
, NULL
, "I_AM_NOT_VALID");
147 if (s
!= NULL
|| errno
!= EINVAL
) {
148 (void) fprintf(stderr
, "%s: test0 FAIL: illegal code returned "
149 "s = %p, errno = %d\n", argv
[0], (void *)s
, errno
);
153 s
= fmd_msg_getitem_id(h
, NULL
, "I_AM_NOT_HERE-0000-0000", 0);
154 if (s
!= NULL
|| errno
!= ENOENT
) {
155 (void) fprintf(stderr
, "%s: test0 FAIL: missing code returned "
156 "s = %p, errno = %d\n", argv
[0], (void *)s
, errno
);
160 s
= fmd_msg_gettext_id(h
, NULL
, "I_AM_NOT_HERE-0000-0000");
161 if (s
!= NULL
|| errno
!= ENOENT
) {
162 (void) fprintf(stderr
, "%s: test0 FAIL: missing code returned "
163 "s = %p, errno = %d\n", argv
[0], (void *)s
, errno
);
168 * Test 1: Use fmd_msg_getitem_id to retrieve the item strings for
169 * a known message code without having any actual event handle.
171 for (i
= 0; i
< FMD_MSG_ITEM_MAX
; i
++) {
172 if ((s
= fmd_msg_getitem_id(h
, NULL
, code
, i
)) == NULL
) {
173 (void) fprintf(stderr
, "%s: fmd_msg_getitem_id failed "
174 "for %s, item %d: %s\n",
175 argv
[0], code
, i
, strerror(errno
));
178 (void) printf("code %s item %d = <<%s>>\n", code
, i
, s
);
183 * Test 2: Use fmd_msg_gettext_id to retrieve the complete message for
184 * a known message code without having any actual event handle.
186 if ((s
= fmd_msg_gettext_id(h
, NULL
, code
)) == NULL
) {
187 (void) fprintf(stderr
, "%s: fmd_msg_gettext_id failed for %s: "
188 "%s\n", argv
[0], code
, strerror(errno
));
192 (void) printf("%s\n", s
);
196 * Test 3: Use fmd_msg_getitem_nv to retrieve the item strings for
197 * our list.suspect event handle.
199 for (i
= 0; i
< FMD_MSG_ITEM_MAX
; i
++) {
200 if ((s
= fmd_msg_getitem_nv(h
, NULL
, list
, i
)) == NULL
) {
201 (void) fprintf(stderr
, "%s: fmd_msg_getitem_nv failed "
202 "for %s, item %d: %s\n",
203 argv
[0], code
, i
, strerror(errno
));
206 (void) printf("code %s item %d = <<%s>>\n", code
, i
, s
);
211 * Test 4: Use fmd_msg_getitem_nv to retrieve the complete message for
212 * a known message code using our list.suspect event handle.
214 if ((s
= fmd_msg_gettext_nv(h
, NULL
, list
)) == NULL
) {
215 (void) fprintf(stderr
, "%s: fmd_msg_gettext_nv failed for %s: "
216 "%s\n", argv
[0], code
, strerror(errno
));
220 (void) printf("%s\n", s
);
224 * Test 5: Use fmd_msg_getitem_nv to retrieve the complete message for
225 * a known message code using our list.suspect event handle, but this
226 * time set the URL to our own customized URL. Our contrived message
227 * has been designed to exercise the key aspects of the variable
230 if (fmd_msg_url_set(h
, "http://foo.bar.com/") != 0) {
231 (void) fprintf(stderr
, "%s: fmd_msg_url_set failed: %s\n",
232 argv
[0], strerror(errno
));
235 if ((s
= fmd_msg_gettext_nv(h
, NULL
, list
)) == NULL
) {
236 (void) fprintf(stderr
, "%s: fmd_msg_gettext_nv failed for %s: "
237 "%s\n", argv
[0], code
, strerror(errno
));
241 (void) printf("%s\n", s
);
244 for (i
= 0; i
< TEST_ARR_SZ
; i
++)
245 nvlist_free(test_arr
[i
]);
250 fmd_msg_fini(h
); /* free library state before dumping core */
251 pid
= fork(); /* fork into background to not bother make(1) */
255 (void) fprintf(stderr
, "FAIL (failed to fork)\n");
262 if (waitpid(pid
, &err
, 0) == -1) {
263 (void) fprintf(stderr
, "FAIL (failed to wait for %d: %s)\n",
264 (int)pid
, strerror(errno
));
268 if (WIFSIGNALED(err
) == 0 || WTERMSIG(err
) != SIGABRT
) {
269 (void) fprintf(stderr
, "FAIL (child did not SIGABRT)\n");
273 if (!WCOREDUMP(err
)) {
274 (void) fprintf(stderr
, "FAIL (no core generated)\n");
278 (void) fprintf(stderr
, "done\n");