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",
318 /* Try writing a character waaaaaay up in the millions range */
319 sprintf(bufp, "%c", ch);
320 if (stat(test_file, &statbuf)){
322 "Error: unable to stat the test file; %s \n",
325 offset = ((1000000*(dm_off_t)(ch)) > statbuf.st_size) ?
326 statbuf.st_size : (1000000*(dm_off_t)(ch));
327 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
328 offset, 1, bufp)==-1){
329 printf("Error invis-writing 0x%x at byte 0x%x million: %s\n",
330 *(u_char *)bufp, (unsigned int)ch, ERR_NAME);
332 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
333 offset, 1, bufp)==-1){
334 printf("Error invis-reading at byte %u million: %s\n",
335 (unsigned int)ch, ERR_NAME);
337 else if (((u_char *)bufp)[0]!=ch) {
338 printf("Error: wanted to read %c and instead got %s.\n",
342 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
343 "at byte %d million.\n", ch, *(u_char *)bufp, ch);
347 /* Try writing a character in the 2 gigabyte (2^31) range */
348 sprintf(bufp, "%c", ch);
349 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
350 2147840000, 1, bufp)==-1){
351 printf("Error invis-writing %s at 2 gigabytes: %s\n",
352 (u_char *)bufp, ERR_NAME);
354 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
355 2147840000, 1, bufp)==-1){
356 printf("Error invis-reading at 2 gigabytes: %s\n",
359 else if (((u_char *)bufp)[0]!=ch) {
360 printf("Error: wanted to read %c and instead got %s.\n",
364 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
365 "at 2147840000 bytes\n\t(a bit over 2 gigabytes).\n",
366 ch, *(u_char *)bufp);
370 printf("\t(errno subtests beginning...)\n");
371 /**** WRITE tests ****/
372 /*---------------------------------------------------------*/
373 EXCLTEST("write", hanp, hlen, test_token,
374 dm_write_invis(sid, hanp, hlen, test_token,
375 0, 0, 13, "write test 1"))
376 /*---------------------------------------------------------*/
377 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
379 "Cannot create a test handle (%s); skipping EBADF test\n",
383 ((char *) test_vp)[hlen/2]++;
386 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
390 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
392 dm_handle_free(test_vp, hlen);
395 /*---------------------------------------------------------*/
398 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
400 /*---------------------------------------------------------*/
403 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
405 /*---------------------------------------------------------*/
407 PROBLEM: write_invis refuses to produce EINVAL for
408 lengths that will not fit in a dm_size_t.
411 "(bad length) write",
412 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
413 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
414 "write invalid length test"))
416 /*---------------------------------------------------------*/
418 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
419 Presumably, this signal is needed to comply with...something.
420 If this is uncommented, the program will abort here, with the
421 error message "exceeded file size limit".
425 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
426 0, (long long)0xFFFFFFFFFFLL,
427 (long long)0xFFFFFFFFFFLL,
430 /*---------------------------------------------------------*/
433 "(bad offset) write",
434 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
435 0, (dm_size_t) ULONG_MAX, 5,
436 "write invalid offset test"))
440 "(bad offset) write",
441 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
442 0, (dm_size_t) ULONGLONG_MAX, 5,
443 "write invalid offset test"))
447 /*---------------------------------------------------------*/
450 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
451 0, 0, 26, "write invalid offset test"))
454 /**** READ tests ****/
455 /*---------------------------------------------------------*/
456 SHAREDTEST("read", hanp, hlen, test_token,
457 dm_read_invis(sid, hanp, hlen, test_token,
459 /*---------------------------------------------------------*/
462 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
464 /*---------------------------------------------------------*/
467 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
469 /*---------------------------------------------------------*/
473 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
474 ULONG_MAX, 5, bufp));
479 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
480 ULONGLONG_MAX, 5, bufp));
484 /*---------------------------------------------------------*/
487 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
489 /*---------------------------------------------------------*/
490 printf("\t(errno subtests complete!)\n");
492 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
494 sprintf(command, "rm %s \n", test_file);
497 printf("Invisible read/write tests complete.\n");
499 dm_handle_free(hanp, hlen);