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-data session
40 * | Job |----># CONTROL #
45 * +----------------+ #
46 * | control connection # CONTROL
48 * ############ # TAPE side of
49 * # DATA # # image stream
51 * +-----+ # +------+ # image #
52 * |FILES|====|butype|===================#
53 * +-----+ # +------+ # stream
57 ********************************************************************
62 #include "ndmagents.h"
65 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
68 extern int ndmca_td_wrapper (struct ndm_session *sess,
69 int (*func)(struct ndm_session *sess));
72 extern int ndmca_op_test_data (struct ndm_session *sess);
73 extern int ndmca_td_idle (struct ndm_session *sess);
75 extern int ndmca_td_listen (struct ndm_session *sess);
76 extern int ndmca_td_listen_subr (struct ndm_session *sess,
77 ndmp9_error expect_err,
78 ndmp9_addr_type addr_type);
79 extern int ndmca_test_check_data_state (struct ndm_session *sess,
80 ndmp9_data_state expected, int reason);
81 extern int ndmca_test_data_get_state (struct ndm_session *sess,
82 ndmp9_error expect_err);
83 extern int ndmca_test_data_abort (struct ndm_session *sess,
84 ndmp9_error expect_err);
85 extern int ndmca_test_data_stop (struct ndm_session *sess,
86 ndmp9_error expect_err);
91 ndmca_op_test_data (struct ndm_session *sess)
93 struct ndm_control_agent *ca = &sess->control_acb;
94 struct ndmconn * conn;
95 int (*save_call) (struct ndmconn *conn,
96 struct ndmp_xa_buf *xa);
99 rc = ndmca_connect_data_agent(sess);
101 ndmconn_destruct (sess->plumb.data);
105 conn = sess->plumb.data;
106 save_call = conn->call;
107 conn->call = ndma_call_no_tattle;
109 /* perform query to find out about TCP and LOCAL support */
110 rc = ndmca_test_query_conn_types (sess, conn);
113 rc = ndmca_td_wrapper (sess, ndmca_td_idle);
114 if (sess->plumb.data->protocol_version >= 3) {
115 // version 3 and later adds LISTEN
116 rc = ndmca_td_wrapper (sess, ndmca_td_listen);
119 ndmca_test_done_series (sess, "test-data");
121 ca = &sess->control_acb;
122 if (ca->has_tcp_addr && ca->has_local_addr) {
123 ndmalogf (sess, "TEST", 0, "LOCAL and TCP addressing tested.");
124 } else if (ca->has_tcp_addr) {
125 ndmalogf (sess, "TEST", 0, "TCP addressing ONLY tested.");
126 } else if (ca->has_local_addr) {
127 ndmalogf (sess, "TEST", 0, "LOCAL addressing ONLY tested.");
129 ndmalogf (sess, "TEST", 0, "Neither TCP or LOCAL addressing tested.");
136 ndmca_td_wrapper (struct ndm_session *sess,
137 int (*func)(struct ndm_session *sess))
144 ndmalogf (sess, "Test", 1, "Failure");
147 ndmca_test_done_phase (sess);
150 ndmca_test_log_note (sess, 2, "Cleaning up...");
158 ndmca_td_idle (struct ndm_session *sess)
162 ndmca_test_phase (sess, "D-IDLE", "Data IDLE State Series");
164 rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0);
167 rc = ndmca_test_data_abort (sess, NDMP9_ILLEGAL_STATE_ERR);
170 rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR);
178 #define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err);
183 ndmca_test_data_listen (struct ndm_session *sess, ndmp9_error expect_err,
184 ndmp9_addr_type addr_type)
186 struct ndmconn * conn = sess->plumb.data;
187 struct ndm_control_agent *ca = &sess->control_acb;
190 /* close previous test if there is one */
191 ndmca_test_close (sess);
193 switch (conn->protocol_version) {
194 default: return -1234;
196 #ifndef NDMOS_OPTION_NO_NDMP3
198 NDMC_WITH(ndmp3_data_listen, NDMP3VER)
199 request->addr_type = addr_type;
201 rc = NDMTEST_CALL(conn);
204 if (expect_err == NDMP9_NO_ERR
205 && request->addr_type
206 != reply->data_connection_addr.addr_type) {
207 /* TODO: use proper test format */
208 ndmalogf (sess, "Test", 1,
209 "DATA_LISTEN addr_type mismatch");
212 ndmp_3to9_addr (&reply->data_connection_addr, &ca->data_addr);
215 #endif /* !NDMOS_OPTION_NO_NDMP3 */
216 #ifndef NDMOS_OPTION_NO_NDMP4
218 NDMC_WITH(ndmp4_data_listen, NDMP4VER)
219 request->addr_type = addr_type;
221 rc = NDMTEST_CALL(conn);
224 if (expect_err == NDMP9_NO_ERR
225 && request->addr_type
226 != reply->connect_addr.addr_type) {
227 /* TODO: use proper test format */
228 ndmalogf (sess, "Test", 1,
229 "DATA_LISTEN addr_type mismatch");
232 ndmp_4to9_addr (&reply->connect_addr, &ca->data_addr);
235 #endif /* !NDMOS_OPTION_NO_NDMP4 */
243 ndmca_td_listen (struct ndm_session *sess)
245 struct ndm_control_agent *ca = &sess->control_acb;
248 ndmca_test_phase (sess, "D-LISTEN", "Data LISTEN State Series");
250 rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0);
253 if (ca->has_tcp_addr) {
254 rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP);
258 if (ca->has_local_addr) {
259 rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL);
263 ndmca_test_done_phase (sess);
268 ndmca_test_phase (sess, "D-LISTEN/bogus-args",
269 "Data LISTEN State Series w/ bogus args");
271 rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_ARGS_ERR,
275 ndmca_test_done_phase (sess);
282 ndmca_td_listen_subr (struct ndm_session *sess,
283 ndmp9_error expect_err,
284 ndmp9_addr_type addr_type)
288 rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0);
291 rc = ndmca_test_data_listen (sess, expect_err, addr_type);
294 if (expect_err != NDMP9_NO_ERR)
295 return 0; /* got expected error */
297 rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_LISTEN, 0);
300 rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_STATE_ERR,
304 rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR);
307 rc = ndmca_test_data_abort (sess, NDMP9_NO_ERR);
310 rc = ndmca_test_check_data_state (sess,
311 NDMP9_DATA_STATE_HALTED, NDMP9_DATA_HALT_ABORTED);
314 rc = ndmca_test_data_stop (sess, NDMP9_NO_ERR);
317 rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0);
324 ndmca_test_check_data_state (struct ndm_session *sess,
325 ndmp9_data_state expected, int reason)
327 struct ndm_control_agent * ca = &sess->control_acb;
328 ndmp9_data_get_state_reply * ds = &ca->data_state;
334 /* close previous test if there is one */
335 ndmca_test_close (sess);
338 ndmca_test_open (sess,
340 ndmp9_data_state_to_str (expected));
342 strcpy (errbuf, "???");
345 rc = ndmca_data_get_state (sess);
348 what = "state self-consistent";
349 /* make sure the sensed state is self consistent */
351 case NDMP9_DATA_STATE_IDLE:
352 case NDMP9_DATA_STATE_ACTIVE:
353 case NDMP9_DATA_STATE_LISTEN:
354 case NDMP9_DATA_STATE_CONNECTED:
355 if (ds->halt_reason != NDMP9_DATA_HALT_NA) {
356 strcpy (errbuf, "reason != NA");
361 case NDMP9_DATA_STATE_HALTED:
365 strcpy (errbuf, "bogus state");
370 if (ds->state != expected) {
371 sprintf (errbuf, "expected %s got %s",
372 ndmp9_data_state_to_str (expected),
373 ndmp9_data_state_to_str (ds->state));
379 case NDMP9_DATA_STATE_HALTED:
380 if (ds->halt_reason != (ndmp9_data_halt_reason)reason) {
381 sprintf (errbuf, "expected %s got %s",
382 ndmp9_data_halt_reason_to_str (reason),
383 ndmp9_data_halt_reason_to_str (ds->halt_reason));
393 ndmca_test_close (sess);
399 sprintf(tmpbuf, "%s: %s", what, errbuf);
400 ndmca_test_fail(sess, tmpbuf);
402 ndmca_test_close (sess);
410 ndmca_test_data_get_state (struct ndm_session *sess, ndmp9_error expect_err)
412 struct ndmconn * conn = sess->plumb.data;
415 /* close previous test if there is one */
416 ndmca_test_close (sess);
418 rc = ndmca_data_get_state (sess);
420 rc = ndmca_test_check_expect (conn, rc, expect_err);
426 ndmca_test_data_abort (struct ndm_session *sess, ndmp9_error expect_err)
428 struct ndmconn * conn = sess->plumb.data;
431 /* close previous test if there is one */
432 ndmca_test_close (sess);
434 rc = ndmca_data_abort (sess);
436 rc = ndmca_test_check_expect (conn, rc, expect_err);
442 ndmca_test_data_stop (struct ndm_session *sess, ndmp9_error expect_err)
444 struct ndmconn * conn = sess->plumb.data;
447 /* close previous test if there is one */
448 ndmca_test_close (sess);
450 rc = ndmca_data_stop (sess);
452 rc = ndmca_test_check_expect (conn, rc, expect_err);
462 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */