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 Progname = strrchr(argv[0], '/');
112 /* Crack and validate the command line options. */
114 while ((opt = getopt(argc, argv, "vs:")) != EOF) {
126 if (optind + 2 != argc)
128 ls_path = argv[optind];
129 dir_name = argv[optind+1];
131 if (dm_init_service(&name) == -1) {
132 fprintf(stderr, "Can't initialize the DMAPI\n");
135 if (sid == DM_NO_SESSION)
136 find_test_session(&sid);
138 /* Get a random character for read/write tests */
139 srand((unsigned int)time(NULL));
142 printf("Invisible read/write tests beginning...\n");
144 /* File creation loop*/
145 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
146 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
147 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
149 sprintf(command, "cp %s %s\n", ls_path, test_file);
154 /* Write to files, then read them to check for correct results.
155 Do timestamp checking along the way. */
157 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
158 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
160 #define max(a,b) ((a) > (b) ? (a) : (b))
161 length = max((dm_size_t)(i), length);
162 offset = (dm_off_t)(j);
164 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
167 if (stat(test_file, &statbuf)){
169 "Error: unable to stat test file; %s (before test)\n",
174 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
175 fprintf(stderr, "can't get handle for %s; bypassing test\n",
180 if (length > curlength) {
183 if ((bufp = malloc(length)) == NULL) {
184 fprintf(stderr, "malloc of %llu bytes failed\n",
185 (unsigned long long) length);
189 memset(bufp, ch, length);
192 rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
193 0, offset, length, bufp);
196 fprintf(stderr, "dm_write_invis failed, %s\n", ERR_NAME);
198 } else if (rc != length) {
199 fprintf(stderr, "expected to write %lld bytes, actually "
200 "wrote %lld\n", (long long) length, (long long) rc);
206 /* Timestamp checking, part 1 */
207 if (stat(test_file, &checkbuf)){
209 "Error: unable to stat the test file; %s (after write)\n",
214 if ((statbuf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
215 (statbuf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
216 (statbuf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
217 (statbuf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
218 (statbuf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
219 (statbuf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
221 if ((statbuf.st_atime == checkbuf.st_atime) &&
222 (statbuf.st_mtime == checkbuf.st_mtime) &&
223 (statbuf.st_ctime == checkbuf.st_ctime))
227 printf("Report: time stamp unchanged by write\n");
231 printf("Error: time stamp changed by write\n");
235 rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
236 offset, length, bufp);
238 fprintf(stderr, "dm_read_invis failed, %s\n", ERR_NAME);
241 else if (rc != length) {
242 fprintf(stderr, "expected to read %lld bytes, actually "
243 "wrote %lld\n", (long long) length, (long long) rc);
247 /* Be sure the buffer is filled with the test char */
250 if (((u_char *)bufp)[k] == ch) {
251 if (Vflag) printf(".");
255 printf("Error!(line=%d)\n", __LINE__);
260 if (Vflag) printf("\n");
263 /* Timestamp checking, part 2 */
264 if (stat(test_file, &statbuf)){
266 "Error: unable to stat the test file; %s (after write)\n",
271 if ((statbuf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
272 (statbuf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
273 (statbuf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
274 (statbuf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
275 (statbuf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
276 (statbuf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
278 if ((statbuf.st_atime == checkbuf.st_atime) &&
279 (statbuf.st_mtime == checkbuf.st_mtime) &&
280 (statbuf.st_ctime == checkbuf.st_ctime))
284 printf("Report: time stamp unchanged by read\n");
288 printf("Error: time stamp changed by read\n");
291 } /* for (j=0; j<OFF_MAX; j+=OFF_STEP) */
292 } /* for(i=0; i<LEN_MAX; i+=LEN_STEP) */
294 /* File deletion loop*/
295 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
296 for(j=0; j<OFF_MAX; j+=OFF_STEP) {
297 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
299 sprintf(command, "rm %s\n", test_file);
304 /*************************************\
305 |* Correct-input testing complete. *|
306 |* Beginning improper-input testing. *|
307 \*************************************/
308 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
310 sprintf(command, "cp %s %s\n", ls_path, test_file);
313 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
314 fprintf(stderr, "can't get handle for %s; bypassing errno tests\n",
320 /* Try writing a character waaaaaay up in the millions range */
321 sprintf(bufp, "%c", ch);
322 if (stat(test_file, &statbuf)){
324 "Error: unable to stat the test file; %s \n",
327 offset = ((1000000*(dm_off_t)(ch)) > statbuf.st_size) ?
328 statbuf.st_size : (1000000*(dm_off_t)(ch));
329 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
330 offset, 1, bufp)==-1){
331 printf("Error invis-writing 0x%x at byte 0x%x million: %s\n",
332 *(u_char *)bufp, (unsigned int)ch, ERR_NAME);
334 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
335 offset, 1, bufp)==-1){
336 printf("Error invis-reading at byte %u million: %s\n",
337 (unsigned int)ch, ERR_NAME);
339 else if (((u_char *)bufp)[0]!=ch) {
340 printf("Error: wanted to read %c and instead got %s.\n",
344 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
345 "at byte %d million.\n", ch, *(u_char *)bufp, ch);
349 /* Try writing a character in the 2 gigabyte (2^31) range */
350 sprintf(bufp, "%c", ch);
351 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
352 2147840000, 1, bufp)==-1){
353 printf("Error invis-writing %s at 2 gigabytes: %s\n",
354 (u_char *)bufp, ERR_NAME);
356 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
357 2147840000, 1, bufp)==-1){
358 printf("Error invis-reading at 2 gigabytes: %s\n",
361 else if (((u_char *)bufp)[0]!=ch) {
362 printf("Error: wanted to read %c and instead got %s.\n",
366 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
367 "at 2147840000 bytes\n\t(a bit over 2 gigabytes).\n",
368 ch, *(u_char *)bufp);
372 printf("\t(errno subtests beginning...)\n");
373 /**** WRITE tests ****/
374 /*---------------------------------------------------------*/
375 EXCLTEST("write", hanp, hlen, test_token,
376 dm_write_invis(sid, hanp, hlen, test_token,
377 0, 0, 13, "write test 1"))
378 /*---------------------------------------------------------*/
379 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
381 "Cannot create a test handle (%s); skipping EBADF test\n",
385 ((char *) test_vp)[hlen/2]++;
388 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
392 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
394 dm_handle_free(test_vp, hlen);
397 /*---------------------------------------------------------*/
400 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
402 /*---------------------------------------------------------*/
405 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
407 /*---------------------------------------------------------*/
409 PROBLEM: write_invis refuses to produce EINVAL for
410 lengths that will not fit in a dm_size_t.
413 "(bad length) write",
414 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
415 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
416 "write invalid length test"))
418 /*---------------------------------------------------------*/
420 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
421 Presumably, this signal is needed to comply with...something.
422 If this is uncommented, the program will abort here, with the
423 error message "exceeded file size limit".
427 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
428 0, (long long)0xFFFFFFFFFFLL,
429 (long long)0xFFFFFFFFFFLL,
432 /*---------------------------------------------------------*/
435 "(bad offset) write",
436 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
437 0, (dm_size_t) ULONG_MAX, 5,
438 "write invalid offset test"))
442 "(bad offset) write",
443 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
444 0, (dm_size_t) ULONGLONG_MAX, 5,
445 "write invalid offset test"))
449 /*---------------------------------------------------------*/
452 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
453 0, 0, 26, "write invalid offset test"))
456 /**** READ tests ****/
457 /*---------------------------------------------------------*/
458 SHAREDTEST("read", hanp, hlen, test_token,
459 dm_read_invis(sid, hanp, hlen, test_token,
461 /*---------------------------------------------------------*/
464 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
466 /*---------------------------------------------------------*/
469 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
471 /*---------------------------------------------------------*/
475 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
476 ULONG_MAX, 5, bufp));
481 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
482 ULONGLONG_MAX, 5, bufp));
486 /*---------------------------------------------------------*/
489 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
491 /*---------------------------------------------------------*/
492 printf("\t(errno subtests complete!)\n");
494 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
496 sprintf(command, "rm %s \n", test_file);
499 printf("Invisible read/write tests complete.\n");
501 dm_handle_free(hanp, hlen);