X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=ndmp-src%2Fndma_ctst_data.c;fp=ndmp-src%2Fndma_ctst_data.c;h=f5ae194fda04333f593ffe04bdadba4b564bd26f;hb=fd48f3e498442f0cbff5f3606c7c403d0566150e;hp=0000000000000000000000000000000000000000;hpb=96f35b20267e8b1a1c846d476f27fcd330e0b018;p=debian%2Famanda diff --git a/ndmp-src/ndma_ctst_data.c b/ndmp-src/ndma_ctst_data.c new file mode 100644 index 0000000..f5ae194 --- /dev/null +++ b/ndmp-src/ndma_ctst_data.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 1998,1999,2000 + * Traakan, Inc., Los Altos, CA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Project: NDMJOB + * Ident: $Id: $ + * + * Description: + * + ******************************************************************** + * + * NDMP Elements of a test-data session + * + * +-----+ ########### + * | Job |----># CONTROL # + * +-----+ # Agent # + * # # + * ########### + * | # + * +----------------+ # + * | control connection # CONTROL + * V # impersonates + * ############ # TAPE side of + * # DATA # # image stream + * # Agent # # + * +-----+ # +------+ # image # + * |FILES|====|butype|===================# + * +-----+ # +------+ # stream + * ############ + * + * + ******************************************************************** + * + */ + + +#include "ndmagents.h" + + +#ifndef NDMOS_OPTION_NO_CONTROL_AGENT + + +extern int ndmca_td_wrapper (struct ndm_session *sess, + int (*func)(struct ndm_session *sess)); + + +extern int ndmca_op_test_data (struct ndm_session *sess); +extern int ndmca_td_idle (struct ndm_session *sess); + +extern int ndmca_td_listen (struct ndm_session *sess); +extern int ndmca_td_listen_subr (struct ndm_session *sess, + ndmp9_error expect_err, + ndmp9_addr_type addr_type); +extern int ndmca_test_check_data_state (struct ndm_session *sess, + ndmp9_data_state expected, int reason); +extern int ndmca_test_data_get_state (struct ndm_session *sess, + ndmp9_error expect_err); +extern int ndmca_test_data_abort (struct ndm_session *sess, + ndmp9_error expect_err); +extern int ndmca_test_data_stop (struct ndm_session *sess, + ndmp9_error expect_err); + + + +int +ndmca_op_test_data (struct ndm_session *sess) +{ + struct ndm_control_agent *ca = &sess->control_acb; + struct ndmconn * conn; + int (*save_call) (struct ndmconn *conn, + struct ndmp_xa_buf *xa); + int rc; + + rc = ndmca_connect_data_agent(sess); + if (rc) { + ndmconn_destruct (sess->plumb.data); + return rc; + } + + conn = sess->plumb.data; + save_call = conn->call; + conn->call = ndma_call_no_tattle; + + /* perform query to find out about TCP and LOCAL support */ + rc = ndmca_test_query_conn_types (sess, conn); + if (rc) return rc; + + rc = ndmca_td_wrapper (sess, ndmca_td_idle); + if (sess->plumb.data->protocol_version >= 3) { + // version 3 and later adds LISTEN + rc = ndmca_td_wrapper (sess, ndmca_td_listen); + } + + ndmca_test_done_series (sess, "test-data"); + + ca = &sess->control_acb; + if (ca->has_tcp_addr && ca->has_local_addr) { + ndmalogf (sess, "TEST", 0, "LOCAL and TCP addressing tested."); + } else if (ca->has_tcp_addr) { + ndmalogf (sess, "TEST", 0, "TCP addressing ONLY tested."); + } else if (ca->has_local_addr) { + ndmalogf (sess, "TEST", 0, "LOCAL addressing ONLY tested."); + } else { + ndmalogf (sess, "TEST", 0, "Neither TCP or LOCAL addressing tested."); + } + + return 0; +} + +int +ndmca_td_wrapper (struct ndm_session *sess, + int (*func)(struct ndm_session *sess)) +{ + int rc; + + rc = (*func)(sess); + + if (rc != 0) { + ndmalogf (sess, "Test", 1, "Failure"); + } + + ndmca_test_done_phase (sess); + + /* clean up mess */ + ndmca_test_log_note (sess, 2, "Cleaning up..."); + + rc = 0; + + return rc; +} + +int +ndmca_td_idle (struct ndm_session *sess) +{ + int rc; + + ndmca_test_phase (sess, "D-IDLE", "Data IDLE State Series"); + + rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); + if (rc) return rc; + + rc = ndmca_test_data_abort (sess, NDMP9_ILLEGAL_STATE_ERR); + if (rc) return rc; + + rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR); + if (rc) return rc; + + return 0; /* pass */ +} + + + +#define NDMTEST_CALL(CONN) ndmca_test_call(CONN, xa, expect_err); + + + +int +ndmca_test_data_listen (struct ndm_session *sess, ndmp9_error expect_err, + ndmp9_addr_type addr_type) +{ + struct ndmconn * conn = sess->plumb.data; + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + /* close previous test if there is one */ + ndmca_test_close (sess); + + switch (conn->protocol_version) { + default: return -1234; + +#ifndef NDMOS_OPTION_NO_NDMP3 + case NDMP3VER: + NDMC_WITH(ndmp3_data_listen, NDMP3VER) + request->addr_type = addr_type; + + rc = NDMTEST_CALL(conn); + if (rc) return rc; + + if (expect_err == NDMP9_NO_ERR + && request->addr_type + != reply->data_connection_addr.addr_type) { + /* TODO: use proper test format */ + ndmalogf (sess, "Test", 1, + "DATA_LISTEN addr_type mismatch"); + return -1; + } + ndmp_3to9_addr (&reply->data_connection_addr, &ca->data_addr); + NDMC_ENDWITH + break; +#endif /* !NDMOS_OPTION_NO_NDMP3 */ +#ifndef NDMOS_OPTION_NO_NDMP4 + case NDMP4VER: + NDMC_WITH(ndmp4_data_listen, NDMP4VER) + request->addr_type = addr_type; + + rc = NDMTEST_CALL(conn); + if (rc) return rc; + + if (expect_err == NDMP9_NO_ERR + && request->addr_type + != reply->connect_addr.addr_type) { + /* TODO: use proper test format */ + ndmalogf (sess, "Test", 1, + "DATA_LISTEN addr_type mismatch"); + return -1; + } + ndmp_4to9_addr (&reply->connect_addr, &ca->data_addr); + NDMC_ENDWITH + break; +#endif /* !NDMOS_OPTION_NO_NDMP4 */ + } + + return 0; +} + + +int +ndmca_td_listen (struct ndm_session *sess) +{ + struct ndm_control_agent *ca = &sess->control_acb; + int rc; + + ndmca_test_phase (sess, "D-LISTEN", "Data LISTEN State Series"); + + rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); + if (rc) return rc; + + if (ca->has_tcp_addr) { + rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_TCP); + if (rc) return rc; + } + + if (ca->has_local_addr) { + rc = ndmca_td_listen_subr (sess, NDMP9_NO_ERR, NDMP9_ADDR_LOCAL); + if (rc) return rc; + } + + ndmca_test_done_phase (sess); + + /* + * Bogus arguments + */ + ndmca_test_phase (sess, "D-LISTEN/bogus-args", + "Data LISTEN State Series w/ bogus args"); + + rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_ARGS_ERR, + 123); + if (rc) return rc; + + ndmca_test_done_phase (sess); + + + return 0; /* pass */ +} + +int +ndmca_td_listen_subr (struct ndm_session *sess, + ndmp9_error expect_err, + ndmp9_addr_type addr_type) +{ + int rc; + + rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); + if (rc) return rc; + + rc = ndmca_test_data_listen (sess, expect_err, addr_type); + if (rc) return rc; + + if (expect_err != NDMP9_NO_ERR) + return 0; /* got expected error */ + + rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_LISTEN, 0); + if (rc) return rc; + + rc = ndmca_test_data_listen (sess, NDMP9_ILLEGAL_STATE_ERR, + addr_type); + if (rc) return rc; + + rc = ndmca_test_data_stop (sess, NDMP9_ILLEGAL_STATE_ERR); + if (rc) return rc; + + rc = ndmca_test_data_abort (sess, NDMP9_NO_ERR); + if (rc) return rc; + + rc = ndmca_test_check_data_state (sess, + NDMP9_DATA_STATE_HALTED, NDMP9_DATA_HALT_ABORTED); + if (rc) return rc; + + rc = ndmca_test_data_stop (sess, NDMP9_NO_ERR); + if (rc) return rc; + + rc = ndmca_test_check_data_state (sess, NDMP9_DATA_STATE_IDLE, 0); + if (rc) return rc; + + return 0; +} + +int +ndmca_test_check_data_state (struct ndm_session *sess, + ndmp9_data_state expected, int reason) +{ + struct ndm_control_agent * ca = &sess->control_acb; + ndmp9_data_get_state_reply * ds = &ca->data_state; + int rc; + char * what; + char errbuf[100]; + char tmpbuf[256]; + + /* close previous test if there is one */ + ndmca_test_close (sess); + + /* open new test */ + ndmca_test_open (sess, + "data check", + ndmp9_data_state_to_str (expected)); + + strcpy (errbuf, "???"); + + what = "get_state"; + rc = ndmca_data_get_state (sess); + if (rc) goto fail; + + what = "state self-consistent"; + /* make sure the sensed state is self consistent */ + switch (ds->state) { + case NDMP9_DATA_STATE_IDLE: + case NDMP9_DATA_STATE_ACTIVE: + case NDMP9_DATA_STATE_LISTEN: + case NDMP9_DATA_STATE_CONNECTED: + if (ds->halt_reason != NDMP9_DATA_HALT_NA) { + strcpy (errbuf, "reason != NA"); + goto fail; + } + break; + + case NDMP9_DATA_STATE_HALTED: + break; + + default: + strcpy (errbuf, "bogus state"); + goto fail; + } + + what = "state"; + if (ds->state != expected) { + sprintf (errbuf, "expected %s got %s", + ndmp9_data_state_to_str (expected), + ndmp9_data_state_to_str (ds->state)); + goto fail; + } + + what = "reason"; + switch (ds->state) { + case NDMP9_DATA_STATE_HALTED: + if (ds->halt_reason != (ndmp9_data_halt_reason)reason) { + sprintf (errbuf, "expected %s got %s", + ndmp9_data_halt_reason_to_str (reason), + ndmp9_data_halt_reason_to_str (ds->halt_reason)); + goto fail; + } + break; + + default: + break; + } + + /* test passed */ + ndmca_test_close (sess); + + return 0; + + fail: + /* test failed */ + sprintf(tmpbuf, "%s: %s", what, errbuf); + ndmca_test_fail(sess, tmpbuf); + + ndmca_test_close (sess); + + return -1; +} + + + +int +ndmca_test_data_get_state (struct ndm_session *sess, ndmp9_error expect_err) +{ + struct ndmconn * conn = sess->plumb.data; + int rc; + + /* close previous test if there is one */ + ndmca_test_close (sess); + + rc = ndmca_data_get_state (sess); + + rc = ndmca_test_check_expect (conn, rc, expect_err); + + return rc; +} + +int +ndmca_test_data_abort (struct ndm_session *sess, ndmp9_error expect_err) +{ + struct ndmconn * conn = sess->plumb.data; + int rc; + + /* close previous test if there is one */ + ndmca_test_close (sess); + + rc = ndmca_data_abort (sess); + + rc = ndmca_test_check_expect (conn, rc, expect_err); + + return rc; +} + +int +ndmca_test_data_stop (struct ndm_session *sess, ndmp9_error expect_err) +{ + struct ndmconn * conn = sess->plumb.data; + int rc; + + /* close previous test if there is one */ + ndmca_test_close (sess); + + rc = ndmca_data_stop (sess); + + rc = ndmca_test_check_expect (conn, rc, expect_err); + + return rc; +} + + + + + + +#endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */