1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
13 #include <lib/errtest.h>
19 /*---------------------------------------------------------------------------
21 Automated test of the DMAPI functions dm_write_invis() and dm_read_invis()
25 test_invis [-s sid] [-v] ls_path pathname
29 is the session ID whose events you you are interested in.
31 is the path to a specific copy of ls, important only for its size
33 is the filesystem to use for the test.
35 DM_WRITE_SYNC is is not supported.
36 ----------------------------------------------------------------------------*/
44 extern char *sys_errlist[];
56 fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path pathname\n",
67 dm_sessid_t sid = DM_NO_SESSION;
68 char *dir_name = NULL;
72 dm_size_t curlength = 0;
88 dm_token_t test_token;
93 Progname = strrchr(argv[0], '/');
100 /* Crack and validate the command line options. */
102 while ((opt = getopt(argc, argv, "vs:")) != EOF) {
114 if (optind + 2 != argc)
116 ls_path = argv[optind];
117 dir_name = argv[optind+1];
119 if (dm_init_service(&name) == -1) {
120 fprintf(stderr, "Can't initialize the DMAPI\n");
123 if (sid == DM_NO_SESSION)
124 find_test_session(&sid);
126 /* Get a random character for read/write tests */
127 srand((unsigned int)time(NULL));
130 printf("Invisible read/write tests beginning...\n");
132 /* File creation loop*/
133 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
134 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
135 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
137 sprintf(command, "cp %s %s\n", ls_path, test_file);
142 /* Write to files, then read them to check for correct results.
143 Do timestamp checking along the way. */
145 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
146 for (j=0; j<OFF_MAX; j+=OFF_STEP) {
148 #define max(a,b) ((a) > (b) ? (a) : (b))
149 length = max((dm_size_t)(i), length);
150 offset = (dm_off_t)(j);
152 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
155 if (stat(test_file, &statbuf)){
157 "Error: unable to stat test file; %s (before test)\n",
162 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
163 fprintf(stderr, "can't get handle for %s; bypassing test\n",
168 if (length > curlength) {
171 if ((bufp = malloc(length)) == NULL) {
172 fprintf(stderr, "malloc of %llu bytes failed\n",
173 (unsigned long long) length);
177 memset(bufp, ch, length);
180 rc = dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
181 0, offset, length, bufp);
184 fprintf(stderr, "dm_write_invis failed, %s\n", ERR_NAME);
186 } else if (rc != length) {
187 fprintf(stderr, "expected to write %lld bytes, actually "
188 "wrote %lld\n", (long long) length, (long long) rc);
194 /* Timestamp checking, part 1 */
195 if (stat(test_file, &checkbuf)){
197 "Error: unable to stat the test file; %s (after write)\n",
201 if ((statbuf.st_atime == checkbuf.st_atime) &&
202 (statbuf.st_mtime == checkbuf.st_mtime) &&
203 (statbuf.st_ctime == checkbuf.st_ctime))
206 printf("Report: time stamp unchanged by write\n");
210 printf("Error: time stamp changed by write\n");
214 rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
215 offset, length, bufp);
217 fprintf(stderr, "dm_read_invis failed, %s\n", ERR_NAME);
220 else if (rc != length) {
221 fprintf(stderr, "expected to read %lld bytes, actually "
222 "wrote %lld\n", (long long) length, (long long) rc);
226 /* Be sure the buffer is filled with the test char */
229 if (((u_char *)bufp)[k] == ch) {
230 if (Vflag) printf(".");
234 printf("Error!(line=%d)\n", __LINE__);
239 if (Vflag) printf("\n");
242 /* Timestamp checking, part 2 */
243 if (stat(test_file, &statbuf)){
245 "Error: unable to stat the test file; %s (after write)\n",
249 if ((statbuf.st_atime == checkbuf.st_atime) &&
250 (statbuf.st_mtime == checkbuf.st_mtime) &&
251 (statbuf.st_ctime == checkbuf.st_ctime))
254 printf("Report: time stamp unchanged by read\n");
258 printf("Error: time stamp changed by read\n");
261 } /* for (j=0; j<OFF_MAX; j+=OFF_STEP) */
262 } /* for(i=0; i<LEN_MAX; i+=LEN_STEP) */
264 /* File deletion loop*/
265 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
266 for(j=0; j<OFF_MAX; j+=OFF_STEP) {
267 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
269 sprintf(command, "rm %s\n", test_file);
274 /*************************************\
275 |* Correct-input testing complete. *|
276 |* Beginning improper-input testing. *|
277 \*************************************/
278 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
280 sprintf(command, "cp %s %s\n", ls_path, test_file);
283 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
284 fprintf(stderr, "can't get handle for %s; bypassing errno tests\n",
290 /* Try writing a character waaaaaay up in the millions range */
291 sprintf(bufp, "%c", ch);
292 if (stat(test_file, &statbuf)){
294 "Error: unable to stat the test file; %s \n",
297 offset = ((1000000*(dm_off_t)(ch)) > statbuf.st_size) ?
298 statbuf.st_size : (1000000*(dm_off_t)(ch));
299 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
300 offset, 1, bufp)==-1){
301 printf("Error invis-writing 0x%x at byte 0x%x million: %s\n",
302 *(u_char *)bufp, (unsigned int)ch, ERR_NAME);
304 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
305 offset, 1, bufp)==-1){
306 printf("Error invis-reading at byte %u million: %s\n",
307 (unsigned int)ch, ERR_NAME);
309 else if (((u_char *)bufp)[0]!=ch) {
310 printf("Error: wanted to read %c and instead got %s.\n",
314 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
315 "at byte %d million.\n", ch, *(u_char *)bufp, ch);
317 printf("\t(errno subtests beginning...)\n");
318 /**** WRITE tests ****/
319 /*---------------------------------------------------------*/
320 EXCLTEST("write", hanp, hlen, test_token,
321 dm_write_invis(sid, hanp, hlen, test_token,
322 0, 0, 13, "write test 1"))
323 /*---------------------------------------------------------*/
324 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
326 "Cannot create a test handle (%s); skipping EBADF test\n",
330 ((char *) test_vp)[hlen/2]++;
333 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
337 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
339 dm_handle_free(test_vp, hlen);
342 /*---------------------------------------------------------*/
345 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
347 /*---------------------------------------------------------*/
350 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
352 /*---------------------------------------------------------*/
354 PROBLEM: write_invis refuses to produce EINVAL for
355 lengths that will not fit in a dm_size_t.
358 "(bad length) write",
359 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
360 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
361 "write invalid length test"))
363 /*---------------------------------------------------------*/
365 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
366 Presumably, this signal is needed to comply with...something.
367 If this is uncommented, the program will abort here, with the
368 error message "exceeded file size limit".
372 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
373 0, (long long)0xFFFFFFFFFFLL,
374 (long long)0xFFFFFFFFFFLL,
377 /*---------------------------------------------------------*/
380 "(bad offset) write",
381 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
382 0, (dm_size_t) ULONG_MAX, 5,
383 "write invalid offset test"))
387 "(bad offset) write",
388 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
389 0, (dm_size_t) ULONGLONG_MAX, 5,
390 "write invalid offset test"))
394 /*---------------------------------------------------------*/
397 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
398 0, 0, 26, "write invalid offset test"))
401 /**** READ tests ****/
402 /*---------------------------------------------------------*/
403 SHAREDTEST("read", hanp, hlen, test_token,
404 dm_read_invis(sid, hanp, hlen, test_token,
406 /*---------------------------------------------------------*/
409 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
411 /*---------------------------------------------------------*/
414 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
416 /*---------------------------------------------------------*/
420 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
421 ULONG_MAX, 5, bufp));
426 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
427 ULONGLONG_MAX, 5, bufp));
431 /*---------------------------------------------------------*/
434 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
436 /*---------------------------------------------------------*/
437 printf("\t(errno subtests complete!)\n");
439 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
441 sprintf(command, "rm %s \n", test_file);
444 printf("Invisible read/write tests complete.\n");
446 dm_handle_free(hanp, hlen);