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",
213 if ((statbuf.st_atime == checkbuf.st_atime) &&
214 (statbuf.st_mtime == checkbuf.st_mtime) &&
215 (statbuf.st_ctime == checkbuf.st_ctime))
218 printf("Report: time stamp unchanged by write\n");
222 printf("Error: time stamp changed by write\n");
226 rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
227 offset, length, bufp);
229 fprintf(stderr, "dm_read_invis failed, %s\n", ERR_NAME);
232 else if (rc != length) {
233 fprintf(stderr, "expected to read %lld bytes, actually "
234 "wrote %lld\n", (long long) length, (long long) rc);
238 /* Be sure the buffer is filled with the test char */
241 if (((u_char *)bufp)[k] == ch) {
242 if (Vflag) printf(".");
246 printf("Error!(line=%d)\n", __LINE__);
251 if (Vflag) printf("\n");
254 /* Timestamp checking, part 2 */
255 if (stat(test_file, &statbuf)){
257 "Error: unable to stat the test file; %s (after write)\n",
261 if ((statbuf.st_atime == checkbuf.st_atime) &&
262 (statbuf.st_mtime == checkbuf.st_mtime) &&
263 (statbuf.st_ctime == checkbuf.st_ctime))
266 printf("Report: time stamp unchanged by read\n");
270 printf("Error: time stamp changed by read\n");
273 } /* for (j=0; j<OFF_MAX; j+=OFF_STEP) */
274 } /* for(i=0; i<LEN_MAX; i+=LEN_STEP) */
276 /* File deletion loop*/
277 for(i=0; i<LEN_MAX; i+=LEN_STEP) {
278 for(j=0; j<OFF_MAX; j+=OFF_STEP) {
279 sprintf(test_file, "%s/DMAPI_invis_test_file.%02d%02d",
281 sprintf(command, "rm %s\n", test_file);
286 /*************************************\
287 |* Correct-input testing complete. *|
288 |* Beginning improper-input testing. *|
289 \*************************************/
290 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
292 sprintf(command, "cp %s %s\n", ls_path, test_file);
295 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
296 fprintf(stderr, "can't get handle for %s; bypassing errno tests\n",
302 /* Try writing a character waaaaaay up in the millions range */
303 sprintf(bufp, "%c", ch);
304 if (stat(test_file, &statbuf)){
306 "Error: unable to stat the test file; %s \n",
309 offset = ((1000000*(dm_off_t)(ch)) > statbuf.st_size) ?
310 statbuf.st_size : (1000000*(dm_off_t)(ch));
311 if (dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN, 0,
312 offset, 1, bufp)==-1){
313 printf("Error invis-writing 0x%x at byte 0x%x million: %s\n",
314 *(u_char *)bufp, (unsigned int)ch, ERR_NAME);
316 else if (dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
317 offset, 1, bufp)==-1){
318 printf("Error invis-reading at byte %u million: %s\n",
319 (unsigned int)ch, ERR_NAME);
321 else if (((u_char *)bufp)[0]!=ch) {
322 printf("Error: wanted to read %c and instead got %s.\n",
326 printf("Report: \"0x%x\" was written and \"0x%x\" was read "
327 "at byte %d million.\n", ch, *(u_char *)bufp, ch);
329 printf("\t(errno subtests beginning...)\n");
330 /**** WRITE tests ****/
331 /*---------------------------------------------------------*/
332 EXCLTEST("write", hanp, hlen, test_token,
333 dm_write_invis(sid, hanp, hlen, test_token,
334 0, 0, 13, "write test 1"))
335 /*---------------------------------------------------------*/
336 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
338 "Cannot create a test handle (%s); skipping EBADF test\n",
342 ((char *) test_vp)[hlen/2]++;
345 dm_write_invis(sid, test_vp, hlen, DM_NO_TOKEN,
349 dm_read_invis(sid, test_vp, hlen, DM_NO_TOKEN,
351 dm_handle_free(test_vp, hlen);
354 /*---------------------------------------------------------*/
357 dm_write_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
359 /*---------------------------------------------------------*/
362 dm_write_invis(sid, NULL, hlen, DM_NO_TOKEN,
364 /*---------------------------------------------------------*/
366 PROBLEM: write_invis refuses to produce EINVAL for
367 lengths that will not fit in a dm_size_t.
370 "(bad length) write",
371 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
372 0, 4096, (long long)0xFFFFFFFFFFFFFFFFLL,
373 "write invalid length test"))
375 /*---------------------------------------------------------*/
377 PROBLEM (somewhat fixed): A signal is sent, rather than EFBIG.
378 Presumably, this signal is needed to comply with...something.
379 If this is uncommented, the program will abort here, with the
380 error message "exceeded file size limit".
384 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
385 0, (long long)0xFFFFFFFFFFLL,
386 (long long)0xFFFFFFFFFFLL,
389 /*---------------------------------------------------------*/
392 "(bad offset) write",
393 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
394 0, (dm_size_t) ULONG_MAX, 5,
395 "write invalid offset test"))
399 "(bad offset) write",
400 dm_write_invis(sid, hanp, hlen, DM_NO_TOKEN,
401 0, (dm_size_t) ULONGLONG_MAX, 5,
402 "write invalid offset test"))
406 /*---------------------------------------------------------*/
409 dm_write_invis(-100, hanp, hlen, DM_NO_TOKEN,
410 0, 0, 26, "write invalid offset test"))
413 /**** READ tests ****/
414 /*---------------------------------------------------------*/
415 SHAREDTEST("read", hanp, hlen, test_token,
416 dm_read_invis(sid, hanp, hlen, test_token,
418 /*---------------------------------------------------------*/
421 dm_read_invis(sid, hanp, hlen-1, DM_NO_TOKEN,
423 /*---------------------------------------------------------*/
426 dm_read_invis(sid, NULL, hlen, DM_NO_TOKEN,
428 /*---------------------------------------------------------*/
432 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
433 ULONG_MAX, 5, bufp));
438 dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN,
439 ULONGLONG_MAX, 5, bufp));
443 /*---------------------------------------------------------*/
446 dm_read_invis(-100, hanp, hlen, DM_NO_TOKEN,
448 /*---------------------------------------------------------*/
449 printf("\t(errno subtests complete!)\n");
451 sprintf(test_file, "%s/DMAPI_invis_test_file.ERRNO",
453 sprintf(command, "rm %s \n", test_file);
456 printf("Invisible read/write tests complete.\n");
458 dm_handle_free(hanp, hlen);