2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 *****************************************************************
37 * NDMP Elements of a test-tape session
40 * | Job |----># CONTROL #
45 * | +---------------------+
46 * control | connections |
48 * ############ +-------+ #########
49 * # TAPE # | | # ROBOT #
50 * # Agent # | ROBOT |<-># Agent #
52 * # ======|DRIVE|| # #
54 * ############ +-------+ #########
56 ****************************************************************
60 #include "ndmagents.h"
63 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
66 extern int ndmca_tt_wrapper (struct ndm_session *sess,
67 int (*func)(struct ndm_session *sess));
70 extern int ndmca_op_test_tape (struct ndm_session *sess);
71 extern int ndmca_tt_openclose (struct ndm_session *sess);
72 extern int ndmca_tt_basic_getstate (struct ndm_session *sess);
73 extern int ndmca_tt_basic_write (struct ndm_session *sess);
74 extern int ndmca_tt_basic_read (struct ndm_session *sess);
75 extern int ndmca_tt_basic_write_and_read (struct ndm_session *sess);
76 extern int ndmca_tt_write (struct ndm_session *sess);
77 extern int ndmca_tt_read (struct ndm_session *sess);
78 extern int ndmca_tt_mtio (struct ndm_session *sess);
80 extern int ndmca_tt_check_fileno_recno (struct ndm_session *sess,
81 char *what, u_long file_num, u_long blockno,
84 extern int ndmca_test_tape_open (struct ndm_session *sess,
85 ndmp9_error expect_err,
86 char *device, int mode);
87 extern int ndmca_test_tape_close (struct ndm_session *sess,
88 ndmp9_error expect_err);
89 extern int ndmca_test_tape_get_state (struct ndm_session *sess,
90 ndmp9_error expect_err);
91 extern int ndmca_test_tape_mtio (struct ndm_session *sess,
92 ndmp9_error expect_err,
93 ndmp9_tape_mtio_op op, u_long count, u_long *resid);
94 extern int ndmca_check_tape_mtio (struct ndm_session *sess,
95 ndmp9_error expect_err,
96 ndmp9_tape_mtio_op op, u_long count, u_long resid);
97 extern int ndmca_test_tape_write (struct ndm_session *sess,
98 ndmp9_error expect_err,
99 char *buf, unsigned count);
100 extern int ndmca_test_tape_read (struct ndm_session *sess,
101 ndmp9_error expect_err,
102 char *buf, unsigned count);
103 extern int ndmca_test_tape_read_2cnt (struct ndm_session *sess,
104 ndmp9_error expect_err,
105 char *buf, unsigned count, unsigned true_count);
113 struct series tt_series[] = {
129 ndmca_op_test_tape (struct ndm_session *sess)
131 struct ndmconn * conn;
132 int (*save_call) (struct ndmconn *conn,
133 struct ndmp_xa_buf *xa);
136 rc = ndmca_test_load_tape (sess);
139 conn = sess->plumb.tape;
140 save_call = conn->call;
141 conn->call = ndma_call_no_tattle;
144 rc = ndmca_tt_wrapper (sess, ndmca_tt_openclose);
146 rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_getstate);
148 rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_write);
150 rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_read);
152 rc = ndmca_tt_wrapper (sess, ndmca_tt_basic_write_and_read);
154 rc = ndmca_tt_wrapper (sess, ndmca_tt_write);
156 rc = ndmca_tt_wrapper (sess, ndmca_tt_read);
158 rc = ndmca_tt_wrapper (sess, ndmca_tt_mtio);
160 ndmca_test_unload_tape (sess);
162 ndmca_test_done_series (sess, "test-tape");
164 conn->call = save_call;
170 ndmca_tt_wrapper (struct ndm_session *sess,
171 int (*func)(struct ndm_session *sess))
178 ndmalogf (sess, "Test", 1, "Failure");
181 ndmca_test_done_phase (sess);
184 ndmca_test_log_note (sess, 2, "Cleaning up...");
186 ndmca_tape_open (sess); /* Open the tape, OK if already opened */
187 ndmca_tape_mtio (sess, NDMP9_MTIO_REW, 1, 0);
188 rc = ndmca_tape_close (sess); /* close, collective error */
190 ndmca_test_log_note (sess, 0, "Cleaning up failed, quiting");
192 ndmca_test_log_note (sess, 2, "Cleaning up done");
200 ndmca_tt_openclose (struct ndm_session *sess)
204 ndmca_test_phase (sess, "T-OC", "Tape Open/Close");
206 rc = ndmca_test_tape_close (sess, NDMP9_DEV_NOT_OPEN_ERR);
209 rc = ndmca_test_tape_open (sess, NDMP9_NO_DEVICE_ERR,
210 "bogus", NDMP9_TAPE_READ_MODE);
213 rc = ndmca_test_tape_open (sess, NDMP9_ILLEGAL_ARGS_ERR, 0, 123);
216 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
219 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
222 rc = ndmca_test_tape_open (sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
225 rc = ndmca_test_tape_open (sess, NDMP9_DEVICE_OPENED_ERR,
226 0, NDMP9_TAPE_READ_MODE);
229 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
236 ndmca_tt_basic_getstate (struct ndm_session *sess)
240 ndmca_test_phase (sess, "T-BGS", "Tape Get State Basics");
242 rc = ndmca_test_tape_get_state (sess, NDMP9_DEV_NOT_OPEN_ERR);
245 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
248 rc = ndmca_test_tape_get_state (sess, NDMP9_NO_ERR);
251 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
258 * Precedes tt_basic_read() so that we can make a "known" tape.
261 ndmca_tt_basic_write (struct ndm_session *sess)
265 ndmp9_error expect_errs[5];
267 ndmca_test_phase (sess, "T-BW", "Tape Write Basics");
269 rc = ndmca_test_tape_write (sess, NDMP9_DEV_NOT_OPEN_ERR, buf, 1024);
273 * Write w/ read-only open mode
275 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
278 rc = ndmca_test_tape_write (sess, NDMP9_PERMISSION_ERR, buf, 1024);
281 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
284 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
288 * Write w/ bogus lengths
290 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
293 /* OPEN Question: what does len==0 mean? */
294 /* write/len=0 MUST be NDMP[234]_NO_ERR or NDMP[234]_ILLEGAL_ARGS */
295 /* write/len=0 MUST be NDMP4_NO_ERR */
297 if (sess->plumb.tape->protocol_version < 5) {
298 expect_errs[ix++] = NDMP9_ILLEGAL_ARGS_ERR;
300 expect_errs[ix++] = NDMP9_NO_ERR;
301 expect_errs[ix++] = -1;
303 rc = ndmca_tape_write (sess, buf, 0);
305 rc = ndmca_test_check_expect_errs (sess->plumb.tape, rc, expect_errs);
308 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
311 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
321 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
324 rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 1024);
327 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_EOF, 1, 0);
330 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
333 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
341 * Assumes tt_basic_write() passed. Uses resulting tape.
345 ndmca_tt_basic_read (struct ndm_session *sess)
349 ndmp9_error expect_errs[5];
351 ndmca_test_phase (sess, "T-BR", "Tape Read Basics");
353 rc = ndmca_test_tape_read (sess, NDMP9_DEV_NOT_OPEN_ERR, buf, 1024);
358 * Read w/ bogus lengths -- mode=READ_MODE
360 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
363 /* read/len=0 MUST be NDMP[23]_NO_ERR or NDMP[23]_ILLEGAL_ARGS */
364 /* read/len=0 MUST be NDMP4_NO_ERR */
366 if (sess->plumb.tape->protocol_version < 4) {
367 expect_errs[ix++] = NDMP9_ILLEGAL_ARGS_ERR;
369 expect_errs[ix++] = NDMP9_NO_ERR;
370 expect_errs[ix++] = -1;
372 rc = ndmca_tape_read (sess, buf, 0);
374 rc = ndmca_test_check_expect_errs (sess->plumb.tape, rc, expect_errs);
377 rc = ndmca_test_tape_read(sess,NDMP9_ILLEGAL_ARGS_ERR,buf,0x80000000);
380 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
383 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
387 * Read works -- mode=WRITE_MODE (just to mix it up)
389 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
392 rc = ndmca_test_tape_read (sess, NDMP9_NO_ERR, buf, 1024);
395 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024);
398 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
401 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
406 * Read works w/ oversize -- mode=READ_MODE (just to mix it up)
408 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
411 rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, 2048, 1024);
414 rc = ndmca_test_tape_read_2cnt (sess, NDMP9_EOF_ERR, buf, 2048, 1024);
417 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
420 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
425 * Read works w/ undersize -- mode=READ_MODE (just to mix it up)
427 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
430 rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, 512, 512);
433 rc = ndmca_test_tape_read_2cnt (sess, NDMP9_EOF_ERR, buf, 512, 512);
436 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
439 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
445 #define CHECK_FILENO_RECNO(WHAT,FILENO,RECNO) { \
447 rc = ndmca_tt_check_fileno_recno (sess, \
448 WHAT, FILENO, RECNO, note); \
453 * Assumes tt_basic_read() and tt_basic_write() have been done verifying
454 * READ and WRITE operations work...
457 ndmca_tt_basic_write_and_read (struct ndm_session *sess)
463 ndmca_test_phase (sess, "T-BWR", "Tape Write and Read Basics");
466 * check EOF and EOM by rewinding and putting on 1 EOF mark
468 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
471 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
474 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSR, 100, 100);
477 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSF, 100, 100);
480 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_EOF, 1, 0);
483 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSF, 100, 99);
486 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSF, 100, 99);
490 if (sess->plumb.tape->protocol_version < 4) {
491 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, sizeof(buf));
495 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024);
499 rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, sizeof(buf));
503 rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, 1024);
507 /* rewind and place 1 record in tape -- no EOF marker by seeking */
509 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
512 rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 512);
515 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_BSR, 100, 99);
518 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSR, 100, 99);
521 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSR, 100, 100);
524 rc = ndmca_check_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_FSF, 100, 100);
527 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
531 * perform tape label type processing with positioning ops
533 for(pass = 0; pass < 2; pass++) {
535 * open the tape and write 1 record and close it
537 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
540 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
543 for(p = buf, i = 0; i < 1024; i++, p++)
544 *p = ((i - 4) & 0xff);
546 rc = ndmca_test_tape_write (sess, NDMP9_NO_ERR, buf, 1024);
549 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_EOF, 1, 0);
552 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
556 * open the tape and read it
558 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
561 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
565 rc = ndmca_test_tape_read_2cnt (sess, NDMP9_NO_ERR, buf, sizeof(buf), 1024);
567 rc = ndmca_test_tape_read (sess, NDMP9_NO_ERR, buf, 1024);
570 for(p = buf, f = i = 0;
573 if (*p != ((i - 4) & 0xff)) {
577 i, ((i - 4) & 0xff), *p);
578 ndmalogf (sess, "DATA", 6, tmp);
582 ndmca_test_fail (sess, "Failed compare");
586 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024);
590 if (sess->plumb.tape->protocol_version < 4) {
591 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, 1024);
594 /* skip over filemark */
595 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, 1, 0);
597 rc = ndmca_test_tape_read (sess, NDMP9_EOM_ERR, buf, 1024);
601 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
609 * Precedes tt_read() so that we can make a "known" tape.
612 ndmca_tt_write (struct ndm_session *sess)
617 unsigned fileno, recno;
622 ndmca_test_phase (sess, "T-WRITE", "Tape Write Series");
624 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_RDWR_MODE);
627 for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) {
628 n_rec = tt_series[fileno].n_rec;
629 recsize = tt_series[fileno].recsize;
631 sprintf (note, "Write tape file %d", fileno+1);
632 ndmca_test_open (sess, note, 0);
634 sprintf (note, "file #%d, %d records, %d bytes/rec",
635 fileno+1, n_rec, recsize);
636 ndmca_test_log_note (sess, 2, note);
638 for (recno = 0; recno < n_rec; recno++) {
639 ndmca_test_fill_data (buf, recsize, recno, fileno);
642 rc = ndmca_tape_write (sess, buf, recsize);
645 CHECK_FILENO_RECNO ("write", fileno, recno+1);
648 what = "write filemark";
649 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_EOF, 1, 0);
652 CHECK_FILENO_RECNO ("wfm", fileno+1, 0);
654 /* no test calls so the file operation is the test */
655 sprintf (buf, "Passed tape write %s", note);
656 ndmca_test_log_step (sess, 2, buf);
659 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
662 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
668 sprintf (buf, "Failed %s recno=%d; %s", what, recno, note);
669 ndmca_test_fail (sess, buf);
677 * Assumes tt_write() passed
680 ndmca_tt_read (struct ndm_session *sess)
685 unsigned fileno, recno;
691 ndmca_test_phase (sess, "T-READ", "Tape Read Series");
693 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
696 for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) {
697 n_rec = tt_series[fileno].n_rec;
698 recsize = tt_series[fileno].recsize;
700 sprintf (note, "Read tape file %d", fileno+1);
701 ndmca_test_open (sess, note, 0);
703 sprintf (note, "file #%d, %d records, %d bytes/rec",
704 fileno+1, n_rec, recsize);
705 ndmca_test_log_note (sess, 2, note);
707 for (recno = 0; recno < n_rec; recno++) {
708 ndmca_test_fill_data (pbuf, recsize, recno, fileno);
711 rc = ndmca_tape_read (sess, buf, recsize);
714 CHECK_FILENO_RECNO ("read", fileno, recno+1);
718 if (bcmp (buf, pbuf, recsize) != 0)
721 if (bcmp (buf, pbuf, recsize) != 0) {
722 unsigned char *expect_p = (unsigned char *)pbuf;
723 unsigned char *got_p = (unsigned char *)buf;
726 f < 64 && i < recsize;
727 i++, expect_p++, got_p++) {
728 if (*expect_p != *got_p) {
732 i, *expect_p, *got_p);
733 ndmalogf (sess, "DATA", 6, tmp);
743 rc = ndmca_test_tape_read (sess, NDMP9_EOF_ERR, buf, recsize);
746 if (sess->plumb.tape->protocol_version > 3) {
747 CHECK_FILENO_RECNO ("eof", fileno, -1);
749 what = "skip filemark";
750 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, 1, 0);
753 CHECK_FILENO_RECNO ("skip", fileno+1, 0);
755 CHECK_FILENO_RECNO ("eof", fileno+1, 0);
758 sprintf (buf, "Passed tape read %s", note);
759 ndmca_test_log_step (sess, 2, buf);
762 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
765 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
771 sprintf (buf, "Failed %s recno=%d; %s", what, recno, note);
772 ndmca_test_fail (sess, buf);
778 * Assumes tt_write() passed
781 ndmca_tt_mtio (struct ndm_session *sess)
786 unsigned fileno, recno;
793 ndmca_test_phase (sess, "T-MTIO", "Tape MTIO");
795 rc = ndmca_test_tape_open(sess,NDMP9_NO_ERR,0,NDMP9_TAPE_READ_MODE);
798 rc = ndmca_test_tape_mtio (sess, NDMP9_NO_ERR, NDMP9_MTIO_REW, 1, 0);
801 for (fileno = 0; tt_series[fileno].n_rec > 0; fileno++) {
802 n_rec = tt_series[fileno].n_rec;
803 recsize = tt_series[fileno].recsize;
805 sprintf (note, "Seek around tape file %d", fileno+1);
806 ndmca_test_open (sess, note, 0);
808 sprintf (note, "file #%d, %d records, %d bytes/rec",
809 fileno+1, n_rec, recsize);
810 ndmca_test_log_note (sess, 2, note);
814 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_REW, count, &resid);
821 CHECK_FILENO_RECNO ("rew", 0, 0);
826 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, count, &resid);
829 what = "fsf(n) resid";
833 CHECK_FILENO_RECNO ("fsf", fileno, 0);
838 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid);
841 what = "fsr(1m) resid";
842 if (n_rec + resid != count)
845 if (sess->plumb.tape->protocol_version < 4) {
846 CHECK_FILENO_RECNO ("fsr(1m)", fileno + 1, 0);
848 what = "bsf 1 after fsr(1m)";
850 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSF, count, 0);
853 CHECK_FILENO_RECNO (what, fileno, -1);
857 /* EOT side of EOF marker */
859 CHECK_FILENO_RECNO ("fsr(1m)", fileno, recno);
864 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSR, count, &resid);
867 what = "bsr(1m) resid";
868 if (n_rec + resid != count)
871 if ((fileno > 0) && (sess->plumb.tape->protocol_version < 4)) {
872 /* at BOT side of EOF marker (not BOT) */
873 CHECK_FILENO_RECNO ("bsr(1m)", fileno - 1, -1);
875 what = "fsf 1 after bsr(1m)";
877 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSF, count, 0);
882 CHECK_FILENO_RECNO ("bsr(1m)", fileno, recno);
886 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid);
889 what = "fsr(0) resid";
894 CHECK_FILENO_RECNO ("fsr(0)", fileno, recno);
899 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_FSR, count, &resid);
902 what = "fsr(x) resid";
907 CHECK_FILENO_RECNO ("fsr(x)", fileno, recno);
909 what = "fsr(x) read";
910 rc = ndmca_tape_read (sess, buf, recsize);
913 what = "fsr(x) compare";
914 ndmca_test_fill_data (pbuf, recsize, recno, fileno);
915 if (bcmp (buf, pbuf, recsize) != 0)
918 recno++; /* caused by tape_read */
923 rc = ndmca_tape_mtio (sess, NDMP9_MTIO_BSR,
927 what = "bsr(2) resid";
932 CHECK_FILENO_RECNO ("bsr(2)", fileno, recno);
934 what = "bsr(2) read";
935 rc = ndmca_tape_read (sess, buf, recsize);
938 what = "bsr(2) compare";
939 ndmca_test_fill_data (pbuf, recsize, recno, fileno);
940 if (bcmp (buf, pbuf, recsize) != 0)
944 sprintf (buf, "Passed %s", note);
945 ndmca_test_log_step (sess, 2, buf);
948 rc = ndmca_test_tape_close (sess, NDMP9_NO_ERR);
954 sprintf (buf, "Failed %s: %s", what, note);
955 ndmca_test_fail (sess, buf);
962 * Check the tape_state accurately reflects position
966 ndmca_tt_check_fileno_recno (struct ndm_session *sess,
967 char *what, u_long file_num, u_long blockno, char *note)
969 struct ndm_control_agent *ca = &sess->control_acb;
970 struct ndmp9_tape_get_state_reply *ts = 0;
976 rc = ndmca_tape_get_state (sess);
979 ts = &ca->tape_state;
981 oper = "check file_num";
982 if (ts->file_num.value != file_num)
985 oper = "check blockno";
986 if ((ts->blockno.value != blockno) && (ts->blockno.value != NDMP9_INVALID_U_LONG))
992 sprintf (buf, "Failed %s while testing %s", oper, what);
993 ndmca_test_log_note (sess, 1, buf);
995 sprintf (buf, " expect file_num=%ld got file_num=%ld",
996 (long)file_num, (long)ts->file_num.value);
997 ndmca_test_log_note (sess, 1, buf);
999 sprintf (buf, " expect blockno=%ld got blockno=%ld",
1000 (long)blockno, (long)ts->blockno.value);
1001 ndmca_test_log_note (sess, 1, buf);
1004 sprintf (buf, " note: %s", note);
1005 ndmca_test_fail (sess, buf);
1012 #define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err);
1016 ndmca_test_tape_open (struct ndm_session *sess, ndmp9_error expect_err,
1017 char *device, int mode)
1019 struct ndmconn * conn = sess->plumb.tape;
1020 struct ndm_control_agent *ca = &sess->control_acb;
1023 /* close previous test if there is one */
1024 ndmca_test_close (sess);
1026 switch (conn->protocol_version) {
1027 default: return -1234;
1029 #ifndef NDMOS_OPTION_NO_NDMP2
1031 NDMC_WITH (ndmp2_tape_open, NDMP2VER)
1033 request->device.name = device;
1035 request->device.name = ca->job.tape_device;
1037 request->mode = mode;
1039 request->mode = ca->tape_mode;
1040 rc = NDMTEST_CALL(conn);
1043 #endif /* !NDMOS_OPTION_NO_NDMP2 */
1044 #ifndef NDMOS_OPTION_NO_NDMP3
1046 NDMC_WITH (ndmp3_tape_open, NDMP3VER)
1048 request->device = device;
1050 request->device = ca->job.tape_device;
1052 request->mode = mode;
1054 request->mode = ca->tape_mode;
1055 rc = NDMTEST_CALL(conn);
1058 #endif /* !NDMOS_OPTION_NO_NDMP3 */
1059 #ifndef NDMOS_OPTION_NO_NDMP4
1061 NDMC_WITH (ndmp4_tape_open, NDMP4VER)
1063 request->device = device;
1065 request->device = ca->job.tape_device;
1067 request->mode = mode;
1069 request->mode = ca->tape_mode;
1070 rc = NDMTEST_CALL(conn);
1073 #endif /* !NDMOS_OPTION_NO_NDMP4 */
1080 ndmca_test_tape_close (struct ndm_session *sess, ndmp9_error expect_err)
1082 struct ndmconn * conn = sess->plumb.tape;
1085 /* close previous test if there is one */
1086 ndmca_test_close (sess);
1088 rc = ndmca_tape_close (sess);
1090 rc = ndmca_test_check_expect (conn, rc, expect_err);
1096 ndmca_test_tape_get_state (struct ndm_session *sess, ndmp9_error expect_err)
1098 struct ndmconn * conn = sess->plumb.tape;
1101 /* close previous test if there is one */
1102 ndmca_test_close (sess);
1104 rc = ndmca_tape_get_state (sess);
1106 rc = ndmca_test_check_expect (conn, rc, expect_err);
1112 ndmca_test_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err,
1113 ndmp9_tape_mtio_op op, u_long count, u_long *resid)
1115 struct ndmconn * conn = sess->plumb.tape;
1118 /* close previous test if there is one */
1119 ndmca_test_close (sess);
1121 rc = ndmca_tape_mtio (sess, op, count, resid);
1123 rc = ndmca_test_check_expect (conn, rc, expect_err);
1129 ndmca_check_tape_mtio (struct ndm_session *sess, ndmp9_error expect_err,
1130 ndmp9_tape_mtio_op op, u_long count, u_long resid)
1132 struct ndmconn * conn = sess->plumb.tape;
1136 /* close previous test if there is one */
1137 ndmca_test_close (sess);
1141 rc = ndmca_tape_mtio (sess, op, count, &got_resid);
1143 rc = ndmca_test_check_expect (conn, rc, expect_err);
1146 if (resid != got_resid) {
1149 "Residual incorrect, got %lu expected %lu",
1152 ndmca_test_fail (sess, tmp);
1161 ndmca_test_tape_write (struct ndm_session *sess, ndmp9_error expect_err,
1162 char *buf, unsigned count)
1164 struct ndmconn * conn = sess->plumb.tape;
1167 /* close previous test if there is one */
1168 ndmca_test_close (sess);
1170 rc = ndmca_tape_write (sess, buf, count);
1172 rc = ndmca_test_check_expect (conn, rc, expect_err);
1178 ndmca_test_tape_read (struct ndm_session *sess, ndmp9_error expect_err,
1179 char *buf, unsigned count)
1181 struct ndmconn * conn = sess->plumb.tape;
1184 /* close previous test if there is one */
1185 ndmca_test_close (sess);
1187 rc = ndmca_tape_read (sess, buf, count);
1189 rc = ndmca_test_check_expect (conn, rc, expect_err);
1195 ndmca_test_tape_read_2cnt (struct ndm_session *sess, ndmp9_error expect_err,
1196 char *buf, unsigned count, unsigned true_count)
1198 struct ndmconn * conn = sess->plumb.tape;
1201 /* close previous test if there is one */
1202 ndmca_test_close (sess);
1204 switch (conn->protocol_version) {
1205 default: return -1234;
1207 #ifndef NDMOS_OPTION_NO_NDMP2
1209 NDMC_WITH(ndmp2_tape_read, NDMP2VER)
1210 request->count = count;
1211 rc = NDMTEST_CALL(conn);
1212 if (rc == 0 && expect_err == NDMP9_NO_ERR) {
1213 if (reply->data_in.data_in_len == true_count) {
1214 bcopy (reply->data_in.data_in_val,
1223 #endif /* !NDMOS_OPTION_NO_NDMP2 */
1224 #ifndef NDMOS_OPTION_NO_NDMP3
1226 NDMC_WITH(ndmp3_tape_read, NDMP3VER)
1227 request->count = count;
1228 rc = NDMTEST_CALL(conn);
1229 if (rc == 0 && expect_err == NDMP9_NO_ERR) {
1230 if (reply->data_in.data_in_len == true_count) {
1231 bcopy (reply->data_in.data_in_val,
1240 #endif /* !NDMOS_OPTION_NO_NDMP3 */
1241 #ifndef NDMOS_OPTION_NO_NDMP4
1243 NDMC_WITH(ndmp4_tape_read, NDMP4VER)
1244 request->count = count;
1245 rc = NDMTEST_CALL(conn);
1246 if (rc == 0 && expect_err == NDMP9_NO_ERR) {
1247 if (reply->data_in.data_in_len == true_count) {
1248 bcopy (reply->data_in.data_in_val,
1257 #endif /* !NDMOS_OPTION_NO_NDMP4 */
1262 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */