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 (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
320 (1000000*(unsigned int)(ch)), 1, bufp)==-1){
321 printf("Error invis-writing %s at byte %u million: %s\n",
322 (char*)bufp, (unsigned int)ch, ERR_NAME);
324 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
325 (1000000*(unsigned int)(ch)), 1, bufp)==-1){
326 printf("Error invis-reading at byte %u million: %s\n",
327 (unsigned int)ch, ERR_NAME);
329 else if (((char*)bufp)[0]!=ch) {
330 printf("Error: wanted to read %c and instead got %s.\n",
334 printf("Report: \"%c\" was written and \"%s\" was read "
335 "at byte %d million.\n", ch, (char*)bufp, ch);
339 /* Try writing a character in the 2 gigabyte (2^31) range */
340 sprintf(bufp, "%c", ch);
341 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
342 2147840000, 1, bufp)==-1){
343 printf("Error invis-writing %s at 2 gigabytes: %s\n",
344 (char*)bufp, ERR_NAME);
346 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
347 2147840000, 1, bufp)==-1){
348 printf("Error invis-reading at 2 gigabytes: %s\n",
351 else if (((char*)bufp)[0]!=ch) {
352 printf("Error: wanted to read %c and instead got %s.\n",
356 printf("Report: \"%c\" was written and \"%s\" was read "
357 "at 2147840000 bytes\n\t(a bit over 2 gigabytes).\n",
362 printf("\t(errno subtests beginning...)\n");
363 /**** WRITE tests ****/
364 /*---------------------------------------------------------*/
365 EXCLTEST("write", hanp, hlen, test_token,
366 dm_write_invis(sid, hanp, hlen, test_token,
367 0, 0, 13, "write test 1"))
368 /*---------------------------------------------------------*/
369 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
371 "Cannot create a test handle (%s); skipping EBADF test\n",
375 ((char *) test_vp)[hlen/2]++;
378 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
382 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
384 dm_handle_free(test_vp, hlen);
387 /*---------------------------------------------------------*/
390 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
392 /*---------------------------------------------------------*/
395 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
397 /*---------------------------------------------------------*/
399 PROBLEM: write_invis refuses to produce EINVAL for
400 lengths that will not fit in a dm_size_t.
403 "(bad length) write",
404 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
405 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
406 "write invalid length test"))
408 /*---------------------------------------------------------*/
410 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
411 Presumably, this signal is needed to comply with...something.
412 If this is uncommented, the program will abort here, with the
413 error message "exceeded file size limit".
417 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
418 0, (long long)0xFFFFFFFFFFLL,
419 (long long)0xFFFFFFFFFFLL,
422 /*---------------------------------------------------------*/
425 "(bad offset) write",
426 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
427 0, (dm_size_t) ULONG_MAX, 5,
428 "write invalid offset test"))
432 "(bad offset) write",
433 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
434 0, (dm_size_t) ULONGLONG_MAX, 5,
435 "write invalid offset test"))
439 /*---------------------------------------------------------*/
442 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
443 0, 0, 26, "write invalid offset test"))
446 /**** READ tests ****/
447 /*---------------------------------------------------------*/
448 SHAREDTEST("read", hanp, hlen, test_token,
449 dm_read_invis(sid, hanp, hlen, test_token,
451 /*---------------------------------------------------------*/
454 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
456 /*---------------------------------------------------------*/
459 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
461 /*---------------------------------------------------------*/
465 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
466 ULONG_MAX, 5, bufp));
471 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
472 ULONGLONG_MAX, 5, bufp));
476 /*---------------------------------------------------------*/
479 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
481 /*---------------------------------------------------------*/
482 printf("\t(errno subtests complete!)\n");
484 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
486 sprintf(command, "rm %s \n", test_file);
489 printf("Invisible read/write tests complete.\n");
491 dm_handle_free(hanp, hlen);