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
38 #include "ndmagents.h"
41 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
44 ndmca_test_query_conn_types (struct ndm_session *sess,
45 struct ndmconn *ref_conn)
47 struct ndmconn *conn = ref_conn;
48 struct ndm_control_agent *ca = &sess->control_acb;
52 switch (conn->protocol_version) {
53 default: return -1234;
55 #ifndef NDMOS_OPTION_NO_NDMP2
57 NDMC_WITH_VOID_REQUEST(ndmp2_config_get_mover_type, NDMP2VER)
60 ndmalogf (sess, "Test", 1, "GET_MOVER_TYPE failed");
64 for (i = 0; i < reply->methods.methods_len; i++) {
65 switch(reply->methods.methods_val[i]) {
66 case NDMP2_ADDR_LOCAL:
67 ca->has_local_addr = 1;
80 #endif /* !NDMOS_OPTION_NO_NDMP2 */
82 #ifndef NDMOS_OPTION_NO_NDMP3
84 NDMC_WITH_VOID_REQUEST(ndmp3_config_get_connection_type, NDMP3VER)
87 ndmalogf (sess, "Test", 1, "GET_CONNECTION_TYPE failed");
91 for (i = 0; i < reply->addr_types.addr_types_len; i++) {
92 switch(reply->addr_types.addr_types_val[i]) {
93 case NDMP3_ADDR_LOCAL:
94 ca->has_local_addr = 1;
106 #endif /* !NDMOS_OPTION_NO_NDMP3 */
108 #ifndef NDMOS_OPTION_NO_NDMP4
110 NDMC_WITH_VOID_REQUEST(ndmp4_config_get_connection_type, NDMP4VER)
111 rc = NDMC_CALL(conn);
113 ndmalogf (sess, "Test", 1, "GET_CONNECTION_TYPE failed");
117 for (i = 0; i < reply->addr_types.addr_types_len; i++) {
118 switch(reply->addr_types.addr_types_val[i]) {
119 case NDMP4_ADDR_LOCAL:
120 ca->has_local_addr = 1;
123 ca->has_tcp_addr = 1;
132 #endif /* !NDMOS_OPTION_NO_NDMP4 */
140 ndmca_test_load_tape (struct ndm_session *sess)
142 struct ndm_control_agent *ca = &sess->control_acb;
145 ca->tape_mode = NDMP9_TAPE_READ_MODE;
148 rc = ndmca_op_robot_startup (sess, 1);
151 rc = ndmca_connect_tape_agent(sess);
153 ndmconn_destruct (sess->plumb.tape);
154 return rc; /* already tattled */
157 rc = ndmca_media_load_first (sess);
160 ndmca_tape_close (sess);
166 ndmca_test_unload_tape (struct ndm_session *sess)
168 ndmca_tape_open (sess);
170 ndmca_media_unload_current(sess);
176 ndmca_test_check_expect_errs (struct ndmconn *conn, int rc,
177 ndmp9_error expect_errs[])
179 struct ndm_session *sess = conn->context;
180 int protocol_version = conn->protocol_version;
181 struct ndmp_xa_buf *xa = &conn->call_xa_buf;
182 unsigned msg = xa->request.header.message;
183 char * msgname = ndmp_message_to_str (protocol_version, msg);
184 ndmp9_error reply_error = conn->last_reply_error;
187 /* make sure we have a 'test' active */
188 ndmca_test_open (sess, msgname, ndmp9_error_to_str (expect_errs[0]));
191 /* Call succeeded. Body valid */
193 for (i = 0; (int)expect_errs[i] >= 0; i++) {
194 if (reply_error == expect_errs[i]) {
201 if (reply_error != NDMP9_NO_ERR
202 && expect_errs[0] != NDMP9_NO_ERR) {
203 /* both are errors, don't be picky */
206 /* intolerable mismatch */
209 /* Worked as expected */
216 for (i = 0; (int)expect_errs[i] >= 0; i++) {
217 ndmalogf (sess, "Test", 1,
218 "%s #%d -- .... %s %s",
219 sess->control_acb.test_phase,
220 sess->control_acb.test_step,
221 (i==0) ? "expected" : "or",
222 ndmp9_error_to_str (expect_errs[i]));
225 sprintf(tmpbuf, "got %s (error expected)", ndmp9_error_to_str (reply_error));
228 ndmca_test_warn (sess, tmpbuf);
230 ndmca_test_fail (sess, tmpbuf);
232 ndma_tattle (conn, xa, rc);
242 ndmca_test_check_expect (struct ndmconn *conn, int rc, ndmp9_error expect_err)
246 errs[0] = expect_err;
249 return ndmca_test_check_expect_errs (conn, rc, errs);
253 ndmca_test_check_expect_no_err (struct ndmconn *conn, int rc)
255 return ndmca_test_check_expect (conn, rc, NDMP9_NO_ERR);
259 ndmca_test_check_expect_illegal_state (struct ndmconn *conn, int rc)
261 return ndmca_test_check_expect (conn, rc, NDMP9_ILLEGAL_STATE_ERR);
265 ndmca_test_check_expect_illegal_args (struct ndmconn *conn, int rc)
267 return ndmca_test_check_expect (conn, rc, NDMP9_ILLEGAL_ARGS_ERR);
272 ndmca_test_call (struct ndmconn *conn,
273 struct ndmp_xa_buf *xa, ndmp9_error expect_err)
275 struct ndm_session *sess = conn->context;
276 int protocol_version = conn->protocol_version;
277 unsigned msg = xa->request.header.message;
278 char * msgname = ndmp_message_to_str (protocol_version, msg);
279 unsigned reply_error;
282 /* close previous test if there is one */
283 ndmca_test_close (sess);
285 /* open new 'test' */
286 ndmca_test_open (sess, msgname, ndmp9_error_to_str (expect_err));
288 rc = ndma_call_no_tattle (conn, xa);
290 reply_error = ndmnmb_get_reply_error (&xa->reply);
293 /* Call succeeded. Body valid */
294 if (reply_error == expect_err) {
295 /* Worked exactly as expected */
297 } else if (reply_error != NDMP9_NO_ERR
298 && expect_err != NDMP9_NO_ERR) {
299 /* both are errors, don't be picky about the codes */
302 /* intolerable mismatch */
309 sprintf(tmpbuf, "got %s (call)", ndmp9_error_to_str (reply_error));
311 ndmca_test_warn (sess, tmpbuf);
313 ndmca_test_fail (sess, tmpbuf);
315 ndma_tattle (conn, xa, rc);
325 * start or open a test if not already opened
328 ndmca_test_open (struct ndm_session *sess, char *test_name, char *sub_test_name)
330 static char test_name_buf[512];
332 if (sess->control_acb.active_test == 0) {
335 sprintf(test_name_buf, "%s/%s", test_name, sub_test_name);
337 strcpy(test_name_buf, test_name);
338 sess->control_acb.active_test = test_name_buf;
340 /* make sure flags are cleared */
341 sess->control_acb.active_test_failed = (char *)0;
342 sess->control_acb.active_test_warned = (char *)0;
348 ndmca_test_warn (struct ndm_session *sess, char *warn_msg)
350 static char warn_msg_buf[512];
352 ndmca_test_open (sess, "UNKNOWN WARN", 0);
354 strcpy(warn_msg_buf, warn_msg);
355 sess->control_acb.active_test_warned = warn_msg_buf;
359 ndmca_test_fail (struct ndm_session *sess, char *fail_msg)
361 static char fail_msg_buf[512];
363 ndmca_test_open (sess, "UNKNOWN FAIL", 0);
365 strcpy(fail_msg_buf, fail_msg);
366 sess->control_acb.active_test_failed = fail_msg_buf;
372 * close or end a test if not already closed
375 ndmca_test_close (struct ndm_session *sess)
377 if (sess->control_acb.active_test != 0) {
379 sess->control_acb.n_step_tests++;
381 /* display results */
382 if (sess->control_acb.active_test_failed) {
383 ndmalogf (sess, "Test", 1,
384 "%s #%d -- Failed %s %s",
385 sess->control_acb.test_phase,
386 sess->control_acb.test_step,
387 sess->control_acb.active_test,
388 sess->control_acb.active_test_failed);
389 sess->control_acb.n_step_fail++;
391 } else if (sess->control_acb.active_test_warned) {
392 ndmalogf (sess, "Test", 1,
393 "%s #%d -- Almost %s %s",
394 sess->control_acb.test_phase,
395 sess->control_acb.test_step,
396 sess->control_acb.active_test,
397 sess->control_acb.active_test_warned);
398 sess->control_acb.n_step_warn++;
401 ndmalogf (sess, "Test", 2,
402 "%s #%d -- Passed %s",
403 sess->control_acb.test_phase,
404 sess->control_acb.test_step,
405 sess->control_acb.active_test);
406 sess->control_acb.n_step_pass++;
410 sess->control_acb.active_test = (char *)0;
411 sess->control_acb.active_test_failed = (char *)0;
412 sess->control_acb.active_test_warned = (char *)0;
414 /* advance test count */
415 sess->control_acb.test_step++;
422 * start a test phase (part of a series)
425 ndmca_test_phase (struct ndm_session *sess, char *test_phase, char *desc)
427 ndmalogf (sess, "TEST", 0, "Test %s -- %s", test_phase, desc);
429 sess->control_acb.test_phase = test_phase;
430 sess->control_acb.test_step = 1;
431 sess->control_acb.n_step_pass = 0;
432 sess->control_acb.n_step_fail = 0;
433 sess->control_acb.n_step_warn = 0;
434 sess->control_acb.n_step_tests = 0;
438 ndmca_test_log_step (struct ndm_session *sess, int level, char *msg)
440 int had_active = (sess->control_acb.active_test != 0);
442 ndmalogf (sess, "Test", level, "%s #%d -- %s",
443 sess->control_acb.test_phase,
444 sess->control_acb.test_step,
447 /* in case we have a open test -- close it */
448 ndmca_test_close (sess);
450 /* advance test count if we didn't have an active test */
452 sess->control_acb.test_step++;
457 ndmca_test_log_note (struct ndm_session *sess, int level, char *msg)
459 ndmalogf (sess, "Test", level, "%s #%d %s",
460 sess->control_acb.test_phase,
461 sess->control_acb.test_step,
466 * finish a test phase (part of a series)
469 ndmca_test_done_phase (struct ndm_session *sess)
471 struct ndm_control_agent *ca = &sess->control_acb;
473 int had_active = (sess->control_acb.active_test != 0);
475 /* close previous test if there is one */
476 ndmca_test_close (sess);
480 else if (ca->n_step_warn)
482 else if (ca->n_step_pass > 0)
487 ndmalogf (sess, "TEST", 0, "Test %s %s -- pass=%d warn=%d fail=%d (total %d)",
495 ca->total_n_step_pass += ca->n_step_pass;
496 ca->total_n_step_warn += ca->n_step_warn;
497 ca->total_n_step_fail += ca->n_step_fail;
498 ca->total_n_step_tests += ca->n_step_tests;
500 /* advance test count if we didn't have an active test so
501 * clean up phases have a new test count
504 sess->control_acb.test_step++;
508 * finish a test series (which may include test phases)
511 ndmca_test_done_series (struct ndm_session *sess, char *series_name)
513 struct ndm_control_agent *ca = &sess->control_acb;
516 /* close previous test if there is one */
517 ndmca_test_close (sess);
519 if (ca->total_n_step_fail)
521 else if (ca->total_n_step_warn)
526 ndmalogf (sess, "TEST", 0, "FINAL %s %s -- pass=%d warn=%d fail=%d (total %d)",
529 ca->total_n_step_pass,
530 ca->total_n_step_warn,
531 ca->total_n_step_fail,
532 ca->total_n_step_tests);
538 ndmca_test_fill_data (char *buf, int bufsize, int recno, int fileno)
543 char * dstend = buf+bufsize;
544 unsigned short sequence = 0;
546 unsigned short fileno;
547 unsigned short sequence;
554 srcend = (char *) &x;
557 while (dst < dstend) {
558 x.sequence = sequence++;
561 while (src < srcend && dst < dstend)
565 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */