2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <sys/types.h>
25 #include <lib/errtest.h>
31 /*---------------------------------------------------------------------------
33 Automated test of the DMAPI functions dm_write_invis() and dm_read_invis()
37 test_invis [-s sid] [-v] ls_path pathname
41 is the session ID whose events you you are interested in.
43 is the path to a specific copy of ls, important only for its size
45 is the filesystem to use for the test.
47 DM_WRITE_SYNC is is not supported.
48 ----------------------------------------------------------------------------*/
56 extern char *sys_errlist[];
68 fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path pathname\n",
79 dm_sessid_t sid = DM_NO_SESSION;
80 char *dir_name = NULL;
84 dm_size_t curlength = 0;
100 dm_token_t test_token;
105 if (Progname = strrchr(argv[0], '/')) {
111 /* Crack and validate the command line options. */
113 while ((opt = getopt(argc, argv, "vs:")) != EOF) {
125 if (optind + 2 != argc)
127 ls_path = argv[optind];
128 dir_name = argv[optind+1];
130 if (dm_init_service(&name) == -1) {
131 fprintf(stderr, "Can't initialize the DMAPI\n");
134 if (sid == DM_NO_SESSION)
135 find_test_session(&sid);
137 /* Get a random character for read/write tests */
138 srand((unsigned int)time(NULL));
141 printf("Invisible read/write tests beginning...\n");
143 /* File creation loop*/
144 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
145 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
146 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
148 sprintf(command, "cp %s %s\n", ls_path, test_file);
153 /* Write to files, then read them to check for correct results.
154 Do timestamp checking along the way. */
156 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
157 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
159 #define max(a,b) ((a) > (b) ? (a) : (b))
160 length = max((dm_size_t)(i), length);
161 offset = (dm_off_t)(j);
163 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
166 if (stat(test_file, &statbuf)){
168 "Error: unable to stat test file; %s (before test)\n",
173 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
174 fprintf(stderr, "can't get handle for %s; bypassing test\n",
179 if (length > curlength) {
182 if ((bufp = malloc(length)) == NULL) {
183 fprintf(stderr, "malloc of %llu bytes failed\n", length);
187 memset(bufp, ch, length);
190 rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
191 0, offset, length, bufp);
194 fprintf(stderr, "dm_write_invis failed, %s\n", ERR_NAME);
196 } else if (rc != length) {
197 fprintf(stderr, "expected to write %lld bytes, actually "
198 "wrote %lld\n", length, rc);
204 /* Timestamp checking, part 1 */
205 if (stat(test_file, &checkbuf)){
207 "Error: unable to stat the test file; %s (after write)\n",
212 if ((statbuf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
213 (statbuf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
214 (statbuf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
215 (statbuf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
216 (statbuf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
217 (statbuf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
219 if ((statbuf.st_atime == checkbuf.st_atime) &&
220 (statbuf.st_mtime == checkbuf.st_mtime) &&
221 (statbuf.st_ctime == checkbuf.st_ctime))
225 printf("Report: time stamp unchanged by write\n");
229 printf("Error: time stamp changed by write\n");
233 rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
234 offset, length, bufp);
236 fprintf(stderr, "dm_read_invis failed, %s\n", ERR_NAME);
239 else if (rc != length) {
240 fprintf(stderr, "expected to read %lld bytes, actually "
241 "wrote %lld\n", length, rc);
245 /* Be sure the buffer is filled with the test char */
248 if (((u_char *)bufp)[k] == ch) {
249 if (Vflag) printf(".");
253 printf("Error!(line=%d)\n", __LINE__);
258 if (Vflag) printf("\n");
261 /* Timestamp checking, part 2 */
262 if (stat(test_file, &statbuf)){
264 "Error: unable to stat the test file; %s (after write)\n",
269 if ((statbuf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
270 (statbuf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
271 (statbuf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
272 (statbuf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
273 (statbuf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
274 (statbuf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
276 if ((statbuf.st_atime == checkbuf.st_atime) &&
277 (statbuf.st_mtime == checkbuf.st_mtime) &&
278 (statbuf.st_ctime == checkbuf.st_ctime))
282 printf("Report: time stamp unchanged by read\n");
286 printf("Error: time stamp changed by read\n");
289 } /* for (j=0; j<OFF_MAX; j+=OFF_STEP) */
290 } /* for(i=0; i<LEN_MAX; i+=LEN_STEP) */
292 /* File deletion loop*/
293 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
294 for(j=0; j<OFF_MAX; j+=OFF_STEP) {
295 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
297 sprintf(command, "rm %s\n", test_file);
302 /*************************************\
303 |* Correct-input testing complete. *|
304 |* Beginning improper-input testing. *|
305 \*************************************/
306 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
308 sprintf(command, "cp %s %s\n", ls_path, test_file);
311 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
312 fprintf(stderr, "can't get handle for %s; bypassing errno tests\n",
317 /* Try writing a character waaaaaay up in the millions range */
318 sprintf(bufp, "%c", ch);
319 if (stat(test_file, &statbuf)){
321 "Error: unable to stat the test file; %s \n",
324 dm_off_t offset = ((1000000*(dm_off_t)(ch)) > statbuf.st_size) ?
325 statbuf.st_size : (1000000*(dm_off_t)(ch));
326 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
327 offset, 1, bufp)==-1){
328 printf("Error invis-writing 0x%x at byte 0x%x million: %s\n",
329 *(u_char *)bufp, (unsigned int)ch, ERR_NAME);
331 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
332 offset, 1, bufp)==-1){
333 printf("Error invis-reading at byte %u million: %s\n",
334 (unsigned int)ch, ERR_NAME);
336 else if (((u_char *)bufp)[0]!=ch) {
337 printf("Error: wanted to read %c and instead got %s.\n",
341 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
342 "at byte %d million.\n", ch, *(u_char *)bufp, ch);
346 /* Try writing a character in the 2 gigabyte (2^31) range */
347 sprintf(bufp, "%c", ch);
348 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
349 2147840000, 1, bufp)==-1){
350 printf("Error invis-writing %s at 2 gigabytes: %s\n",
351 (u_char *)bufp, ERR_NAME);
353 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
354 2147840000, 1, bufp)==-1){
355 printf("Error invis-reading at 2 gigabytes: %s\n",
358 else if (((u_char *)bufp)[0]!=ch) {
359 printf("Error: wanted to read %c and instead got %s.\n",
363 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
364 "at 2147840000 bytes\n\t(a bit over 2 gigabytes).\n",
365 ch, *(u_char *)bufp);
369 printf("\t(errno subtests beginning...)\n");
370 /**** WRITE tests ****/
371 /*---------------------------------------------------------*/
372 EXCLTEST("write", hanp, hlen, test_token,
373 dm_write_invis(sid, hanp, hlen, test_token,
374 0, 0, 13, "write test 1"))
375 /*---------------------------------------------------------*/
376 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
378 "Cannot create a test handle (%s); skipping EBADF test\n",
382 ((char *) test_vp)[hlen/2]++;
385 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
389 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
391 dm_handle_free(test_vp, hlen);
394 /*---------------------------------------------------------*/
397 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
399 /*---------------------------------------------------------*/
402 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
404 /*---------------------------------------------------------*/
406 PROBLEM: write_invis refuses to produce EINVAL for
407 lengths that will not fit in a dm_size_t.
410 "(bad length) write",
411 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
412 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
413 "write invalid length test"))
415 /*---------------------------------------------------------*/
417 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
418 Presumably, this signal is needed to comply with...something.
419 If this is uncommented, the program will abort here, with the
420 error message "exceeded file size limit".
424 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
425 0, (long long)0xFFFFFFFFFFLL,
426 (long long)0xFFFFFFFFFFLL,
429 /*---------------------------------------------------------*/
432 "(bad offset) write",
433 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
434 0, (dm_size_t) ULONG_MAX, 5,
435 "write invalid offset test"))
439 "(bad offset) write",
440 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
441 0, (dm_size_t) ULONGLONG_MAX, 5,
442 "write invalid offset test"))
446 /*---------------------------------------------------------*/
449 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
450 0, 0, 26, "write invalid offset test"))
453 /**** READ tests ****/
454 /*---------------------------------------------------------*/
455 SHAREDTEST("read", hanp, hlen, test_token,
456 dm_read_invis(sid, hanp, hlen, test_token,
458 /*---------------------------------------------------------*/
461 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
463 /*---------------------------------------------------------*/
466 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
468 /*---------------------------------------------------------*/
472 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
473 ULONG_MAX, 5, bufp));
478 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
479 ULONGLONG_MAX, 5, bufp));
483 /*---------------------------------------------------------*/
486 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
488 /*---------------------------------------------------------*/
489 printf("\t(errno subtests complete!)\n");
491 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
493 sprintf(command, "rm %s \n", test_file);
496 printf("Invisible read/write tests complete.\n");
498 dm_handle_free(hanp, hlen);