PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/usr/src/tools/tet/contrib/kshdapi/dapi/dtcm.ksh

https://bitbucket.org/illumos/illumos-stc
Korn Shell | 1531 lines | 1039 code | 134 blank | 358 comment | 81 complexity | f78b4df69860bb8fb44de638d91c64c5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. #
  2. # SCCS: @(#)dtcm.ksh 1.3 (04/11/26)
  3. #
  4. # UniSoft Ltd., London, England
  5. #
  6. # (C) Copyright 1996 X/Open Company Limited
  7. # (C) Copyright 1999 UniSoft Ltd.
  8. #
  9. # All rights reserved. No part of this source code may be reproduced,
  10. # stored in a retrieval system, or transmitted, in any form or by any
  11. # means, electronic, mechanical, photocopying, recording or otherwise,
  12. # except as stated in the end-user licence agreement, without the prior
  13. # permission of the copyright owners.
  14. # A copy of the end-user licence agreement is contained in the file
  15. # Licence which accompanies this distribution.
  16. #
  17. # X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
  18. # the UK and other countries.
  19. #
  20. # ************************************************************************
  21. # Portions of this file are derived from the file tcm.ksh which
  22. # contains the following notice:
  23. #
  24. # Copyright 1990 Open Software Foundation (OSF)
  25. # Copyright 1990 Unix International (UI)
  26. # Copyright 1990 X/Open Company Limited (X/Open)
  27. # Copyright 1991 Hewlett-Packard Co. (HP)
  28. #
  29. # Permission to use, copy, modify, and distribute this software and its
  30. # documentation for any purpose and without fee is hereby granted, provided
  31. # that the above copyright notice appear in all copies and that both that
  32. # copyright notice and this permission notice appear in supporting
  33. # documentation, and that the name of HP, OSF, UI or X/Open not be used in
  34. # advertising or publicity pertaining to distribution of the software
  35. # without specific, written prior permission. HP, OSF, UI and X/Open make
  36. # no representations about the suitability of this software for any purpose.
  37. # It is provided "as is" without express or implied warranty.
  38. #
  39. # HP, OSF, UI and X/Open DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  40. # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  41. # EVENT SHALL HP, OSF, UI or X/Open BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  42. # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  43. # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  44. # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  45. # PERFORMANCE OF THIS SOFTWARE.
  46. #
  47. # ***********************************************************************
  48. #
  49. # SCCS: @(#)dtcm.ksh 1.3 04/11/26 TETware release 3.8
  50. # NAME: Distributed Korn Shell Test Case Manager
  51. # PRODUCT: TETware
  52. # AUTHOR: Andrew Dingwall, UniSoft Ltd.
  53. # DATE CREATED: May 1999
  54. # Parts of this file derived from (non-distributed) tcm.ksh v1.7
  55. #
  56. # DESCRIPTION:
  57. # The distributed Korn Shell TCM must be invoked in the environment
  58. # that is provided by the Distributed tcc.
  59. # It cannot be run stand-alone or under the control of the Lite tcc.
  60. #
  61. # This file contains the support routines for the sequencing and control
  62. # of invocable components and test purposes.
  63. # It should be sourced (by means of the shell . command) into a shell
  64. # script containing definitions of the invocable components and test
  65. # purposes that may be executed, after those definitions have been made.
  66. # Test purposes may be written as shell functions or executable
  67. # shell scripts.
  68. #
  69. # This file sources tetdapi.sh which contains the shell API functions.
  70. # Test purposes written as separate shell scripts must also source
  71. # tetdapi.sh in order to use those functions.
  72. #
  73. # The user-supplied shell variable iclist should contain a list of all
  74. # the invocable components in the testset;
  75. # these are named ic1, ic2 ... etc.
  76. # For each invocable component thus specified, the user should define
  77. # a variable whose name is the same as that of the component.
  78. # Each such variable should contain the names of the test purposes
  79. # associated with each invocable component; for example:
  80. # iclist="ic1 ic2"
  81. # ic1="test1-1 test1-2 test1-3"
  82. # ic2="test2-1 test2-2"
  83. #
  84. # The NUMBERS of the invocable components to be executed are specified
  85. # on the command line.
  86. # In addition, the user may define the variables tet_startup and
  87. # tet_cleanup; if defined, the related functions (or shell scripts)
  88. # are executed at the start and end of processing, respectively.
  89. #
  90. # The TCM makes the NAME of the currently executing test purpose
  91. # available in the environment variable tet_thistest.
  92. #
  93. # The TCM reads configuration variables from the file specified by the
  94. # TET_CONFIG environment variable; these are placed in the environment
  95. # and marked as readonly.
  96. #
  97. # MODIFICATIONS:
  98. #
  99. # ***********************************************************************
  100. if let TET_XXXXX=1
  101. then
  102. unset TET_XXXXX
  103. else
  104. echo "ERROR: this is not a Korn Shell"
  105. exit 2
  106. fi
  107. #
  108. # TCM signal definitions
  109. #
  110. # The XXX_SIGNAL_LIST markers are replaced with proper lists by make INSTALL
  111. #
  112. # standard signals - may not be specified in TET_SIG_IGN and TET_SIG_LEAVE
  113. typeset -r TET_STD_SIGNALS="STD_SIGNAL_LIST"
  114. # signals that are always unhandled
  115. typeset -r TET_SPEC_SIGNALS="SPEC_SIGNAL_LIST"
  116. #
  117. # TCM global variables
  118. #
  119. typeset -x tet_thistest=""
  120. #
  121. # "private" TCM variables
  122. # these are not published interfaces and may go away one day
  123. #
  124. typeset TET_CWD=`pwd` # must be first
  125. typeset TET_A=
  126. typeset TET_B=
  127. typeset -i TET_ASYNC_NSYS=0
  128. typeset TET_ASYNC_SYNCSTAT
  129. typeset -x TET_DEFAULT_SIGS=
  130. typeset -rx TET_DELETES=$TET_CWD/tet_deletes
  131. typeset -x TET_DEVNULL=
  132. typeset -i TET_ICCOUNT=0
  133. typeset TET_ICLIST=
  134. typeset -i TET_ICMAX=-1
  135. typeset -i TET_ICMIN=-1
  136. typeset -i TET_ICNUM=0
  137. typeset TET_ICS
  138. typeset -x TET_MASTER=
  139. typeset -xi TET_MYSYSID=-1
  140. typeset TET_NSIG=
  141. typeset -rx TET_OSNAME="`uname -s`"
  142. typeset TET_REASON=
  143. typeset TET_SIG_IGN=
  144. typeset TET_SIG_IGN2=
  145. typeset TET_SIG_LEAVE=
  146. typeset TET_SIG_LEAVE2=
  147. typeset -x TET_SNAMES=
  148. typeset -i TET_SPNO=-1
  149. typeset TET_TCM_ARGS=
  150. typeset TET_temp=
  151. typeset TET_TESTNAME=
  152. typeset -ix TET_TESTNUM=0
  153. typeset TET_TMP1=$TET_CWD/tet1.$$
  154. typeset TET_TMPFILES=
  155. typeset -i TET_TPCOUNT=0
  156. typeset -i TET_TPNUM=0
  157. typeset -i TET_TPSTART_RC=0
  158. typeset TET_TRAP_FUNCTION=
  159. typeset TET_VOTE=
  160. # some constants from <inc/synreq.h>
  161. # field widths, shifts and masks used to generate an auto-sync number
  162. typeset -ri TET_S_ICBITS=15
  163. typeset -ri TET_S_TPBITS=15
  164. typeset -ri TET_S_SEBITS=1
  165. typeset -ri TET_S_TPSHIFT=$TET_S_SEBITS
  166. typeset -ri TET_S_ICSHIFT=$((TET_S_TPSHIFT + TET_S_TPBITS))
  167. typeset -ri TET_S_ICMASK=$((~0 << TET_S_ICSHIFT))
  168. typeset -ri TET_S_TPMASK=$(((~TET_S_ICMASK << TET_S_TPSHIFT) & ~TET_S_ICMASK))
  169. typeset -ri TET_S_SEMASK=$((~(TET_S_ICMASK | TET_S_TPMASK)))
  170. # sync point number and timeout for initial sync
  171. typeset -ri TET_SV_EXEC_SPNO=1
  172. typeset -ri TET_SV_EXEC_TIMEOUT=60
  173. # sync timeout for IC/TP start
  174. typeset -ri TET_SV_SYNC_TIMEOUT=60
  175. # ***********************************************************************
  176. #
  177. # "private" TCM function definitions
  178. # these interfaces may go away one day
  179. #
  180. #
  181. # this function emulates the command tr for simple substitutions
  182. # Usage: ksh_tr $1 $2 $3
  183. # where ksh_tr substitutes $2 for $1 in $3
  184. #
  185. tet_ksh_tr()
  186. {
  187. typeset TET_out=
  188. typeset TET_in=${3?}
  189. typeset TET_token=${TET_in%%${1:?}*}
  190. : ${2?}
  191. while test ${#TET_token} -ne ${#TET_in}
  192. do
  193. TET_in=${TET_in##${TET_token}$1}
  194. TET_out=${TET_out}${TET_token}$2
  195. TET_token=${TET_in%%$1*}
  196. done
  197. TET_out=${TET_out}$TET_in
  198. print -R "$TET_out"
  199. }
  200. # tet_ismember - return 0 if $1 is in the set $2 ...
  201. # otherwise return 1
  202. tet_ismember()
  203. {
  204. typeset -i TET_X=${1:?}
  205. typeset -i TET_Y=0
  206. shift
  207. for TET_Y in $*
  208. do
  209. if test $TET_X -eq $TET_Y
  210. then
  211. return 0
  212. fi
  213. done
  214. return 1
  215. }
  216. # tet_abandon - signal handler used during startup and cleanup
  217. tet_abandon()
  218. {
  219. typeset -i TET_CAUGHTSIG=$1
  220. if test 15 -eq ${TET_CAUGHTSIG:?}
  221. then
  222. tet_sigterm $TET_CAUGHTSIG
  223. else
  224. tet_error "Abandoning testset: caught unexpected signal $TET_CAUGHTSIG"
  225. fi
  226. tet_exit $TET_CAUGHTSIG
  227. }
  228. # tet_sigterm - signal handler for SIGTERM
  229. tet_sigterm()
  230. {
  231. typeset -i TET_CAUGHTSIG=$1
  232. tet_error "Abandoning test case: received signal ${TET_CAUGHTSIG:?}"
  233. tet_docleanup
  234. tet_exit $TET_CAUGHTSIG
  235. }
  236. # tet_sigskip - signal handler used during test execution
  237. tet_sigskip()
  238. {
  239. typeset -i TET_CAUGHTSIG=$1
  240. tet_infoline "unexpected signal ${TET_CAUGHTSIG:?} received"
  241. tet_result UNRESOLVED
  242. if test 15 -eq ${TET_CAUGHTSIG:?}
  243. then
  244. tet_sigterm $TET_CAUGHTSIG
  245. else
  246. continue
  247. fi
  248. }
  249. # tet_tcminit - initialise the dtet stuff
  250. # this function is analogous to tet_tcminit() in the C API
  251. tet_tcminit()
  252. {
  253. # local variables
  254. typeset -i tet_l8_nsname=0
  255. # get the TI args out of the environment
  256. # we only need our system ID (-s) and the system name list (-l)
  257. set -- ${TET_TIARGS:?}
  258. while test $# -gt 0
  259. do
  260. case "$1" in
  261. -l*)
  262. TET_SNAMES=
  263. tet_l8_nsname=0
  264. TET_A="${1#??}"
  265. until test -z "$TET_A"
  266. do
  267. TET_SNAMES="$TET_SNAMES${TET_SNAMES:+ }${TET_A%%,*}"
  268. : $((tet_l8_nsname += 1))
  269. case $TET_A in
  270. *,*)
  271. TET_A=${TET_A#*,}
  272. ;;
  273. *)
  274. TET_A=
  275. ;;
  276. esac
  277. done
  278. readonly TET_SNAMES
  279. ;;
  280. -s*)
  281. TET_MYSYSID=${1#??}
  282. readonly TET_MYSYSID
  283. ;;
  284. *)
  285. ;;
  286. esac
  287. shift
  288. done
  289. # ensure that we have a system ID and a system name list
  290. if test $TET_MYSYSID -lt 0
  291. then
  292. tet_fatal "sysid not assigned"
  293. fi
  294. if test $tet_l8_nsname -eq 0
  295. then
  296. tet_fatal "system name list not assigned"
  297. fi
  298. # determine whether we are a master TCM
  299. if test $tet_l8_nsname -lt 2 -o $TET_MYSYSID -eq ${TET_SNAMES%% *}
  300. then
  301. TET_MASTER=yes
  302. else
  303. TET_MASTER=no
  304. fi
  305. readonly TET_MASTER
  306. # all the TCMs sync with each other (the "initial sync")
  307. if tet_kshapid_async $TET_SV_EXEC_SPNO YES $TET_SV_EXEC_TIMEOUT
  308. then
  309. : ok
  310. else
  311. tet_fatal "initial sync failed, server reply code = $tet_reply_code"
  312. fi
  313. if test $tet_reply_code != OK
  314. then
  315. tet_async_report "initial sync error"
  316. tet_exit 1
  317. fi
  318. }
  319. # tet_mkaspno - generate an automatic sync point number
  320. # usage: tet_mkaspno icno tpno flag
  321. # flag should be START or END
  322. # on return TET_SPNO contains the generated sync point number
  323. # (this is because ksh functions can't return the full range of 32 bit values)
  324. #
  325. # this function mimics the MK_ASPNO macro in <src/tet3/inc/synreq.h>
  326. tet_mkaspno()
  327. {
  328. typeset -i tet_l1_icnum=${1:?}
  329. typeset -i tet_l1_tpnum=${2:?}
  330. typeset -i tet_l1_flag=0
  331. case "${3:?}" in
  332. START)
  333. tet_l1_flag=0
  334. ;;
  335. END)
  336. tet_l1_flag=1
  337. ;;
  338. *)
  339. tet_fatal "internal: invalid flag value \"$3\"" \
  340. "passed to function tet_mkaspno"
  341. ;;
  342. esac
  343. TET_SPNO=$((((tet_l1_icnum + 1) << TET_S_ICSHIFT) | \
  344. ((tet_l1_tpnum << TET_S_TPSHIFT) & TET_S_TPMASK) | tet_l1_flag))
  345. }
  346. # tet_icstart - signal IC start
  347. # usage: tet_icstart icno tpcount
  348. # return 0 if successful or 1 to abort the test case
  349. tet_icstart()
  350. {
  351. typeset -i tet_l2_n=0
  352. typeset -i tet_l2_icno=${1:?}
  353. typeset -i tet_l2_tpcount=${2:?}
  354. typeset tet_l2_msg
  355. # the master TCM informs XRESD of the IC start
  356. if test ${TET_MASTER:?} = yes
  357. then
  358. if tet_kshapid_icstart $tet_l2_icno $tet_l2_tpcount
  359. then
  360. : ok
  361. else
  362. tet_fatal \
  363. "can't inform XRESD of IC start," \
  364. "server reply code = $tet_reply_code"
  365. fi
  366. fi
  367. # then all the TCMs sync on IC start
  368. tet_mkaspno $tet_l2_icno 0 START
  369. if tet_kshapid_async $TET_SPNO YES $TET_SV_SYNC_TIMEOUT
  370. then
  371. : ok
  372. else
  373. tet_fatal "Auto Sync failed at start of IC ${tet_l2_icno}:" \
  374. "server reply code = $tet_reply_code"
  375. fi
  376. if test "$tet_reply_code" = OK
  377. then
  378. return 0
  379. fi
  380. # here if the autosync failed in an expected way -
  381. # a NO vote from the MTCM means that the test case is to be aborted
  382. unset tet_l2_msg
  383. tet_l2_n=-1
  384. while test $((tet_l2_n += 1)) -lt ${TET_ASYNC_NSYS:?}
  385. do
  386. test $# -gt 0 && shift $#
  387. set -- ${TET_ASYNC_SYNCSTAT[$tet_l2_n]:?}
  388. case $1:$2 in
  389. *:SYNC-YES|0:SYNC-NO)
  390. ;;
  391. *)
  392. tet_l2_msg[$tet_l2_n]="Auto Sync error at start of IC $tet_l2_icno, sysid = $1, state = $2: server reply code = $tet_reply_code"
  393. ;;
  394. esac
  395. done
  396. # print the error messages if there are any
  397. if test ${#tet_l2_msg[*]} -gt 0
  398. then
  399. tet_mfatal "${tet_l2_msg[@]}"
  400. fi
  401. return 1
  402. }
  403. # tet_icend - signal IC end
  404. # usage: tet_icend
  405. tet_icend()
  406. {
  407. # the master TCM informs XRESD of the IC end
  408. if test ${TET_MASTER:?} = yes
  409. then
  410. if tet_kshapid_icend
  411. then
  412. : ok
  413. else
  414. tet_fatal \
  415. "can't inform XRESD of IC end" \
  416. "server reply code = $tet_reply_code"
  417. fi
  418. fi
  419. }
  420. # tet_tpstart - signal TP start
  421. # usage: tet_tpstart icno tpno testnum sync_vote
  422. # (where testnum is the absolute test purpose number for this TP)
  423. #
  424. # Return 0 if successful or non-zero to indicate that this TP has been
  425. # deleted in another TCM
  426. tet_tpstart()
  427. {
  428. # local variables
  429. typeset -i tet_l3_n=0
  430. typeset -i tet_l3_icno=${1:?}
  431. typeset -i tet_l3_tpno=${2:?}
  432. typeset -i tet_l3_testnum=${3:?}
  433. typeset tet_l3_msg
  434. typeset tet_l3_svote=${4:?}
  435. # set tet_thistest in the helper process
  436. tet_kshapid_thistest $tet_l3_testnum
  437. # this sets the context, and resets the block and sequence to 1
  438. TET_CONTEXT=0
  439. tet_setcontext
  440. # the master TCM informs XRESD of TP start
  441. if test ${TET_MASTER:?} = yes
  442. then
  443. if tet_kshapid_tpstart $tet_l3_testnum
  444. then
  445. : ok
  446. else
  447. tet_fatal \
  448. "can't inform XRESD of TP start" \
  449. "server reply code = $tet_reply_code"
  450. fi
  451. fi
  452. # then all the TCMs sync on TP start
  453. tet_mkaspno $tet_l3_icno $tet_l3_tpno START
  454. if tet_kshapid_async $TET_SPNO $tet_l3_svote $TET_SV_SYNC_TIMEOUT
  455. then
  456. : ok
  457. else
  458. tet_fatal "Auto Sync failed at start of TP ${tet_thistest}:" \
  459. "server reply code = $tet_reply_code"
  460. fi
  461. if test "$tet_reply_code" = OK
  462. then
  463. return 0
  464. fi
  465. # here if the autosync failed in an expected way -
  466. # a NO vote from another TCM means that the test case has been deleted
  467. unset tet_l3_msg
  468. tet_l3_n=-1
  469. while test $((tet_l3_n += 1)) -lt ${TET_ASYNC_NSYS:?}
  470. do
  471. test $# -gt 0 && shift $#
  472. set -- ${TET_ASYNC_SYNCSTAT[$tet_l3_n]:?}
  473. case $2 in
  474. SYNC-YES|SYNC-NO)
  475. ;;
  476. *)
  477. tet_l3_msg[$tet_l3_n]="Auto Sync error at start of TP $tet_thistest, sysid = $1, state = $2: server reply code = $tet_reply_code"
  478. ;;
  479. esac
  480. done
  481. # print the error messages if there are any
  482. if test ${#tet_l3_msg[*]} -gt 0
  483. then
  484. tet_mfatal "${tet_l3_msg[@]}"
  485. fi
  486. return 1
  487. }
  488. # tet_tpend - signal TP end
  489. # usage: tet_tpend icno tpno
  490. #
  491. # Returns 0 if successful or non-zero to abort the test case
  492. tet_tpend()
  493. {
  494. # local variables
  495. typeset -i tet_l4_icno=${1:?}
  496. typeset -i tet_l4_tpno=${2:?}
  497. typeset tet_l4_err=
  498. # all the TCMs sync YES on TP end -
  499. # there is an assumption here that the parts of a TP will arrive
  500. # at their ends within 10 minutes of each other;
  501. # if this is not so for a particular TP, the test author is expected
  502. # to use tet_remsync with a longer timeout to delay the ends of
  503. # the quicker test parts
  504. tet_mkaspno $tet_l4_icno $tet_l4_tpno END
  505. if tet_kshapid_async $TET_SPNO YES $((TET_SV_SYNC_TIMEOUT * 10))
  506. then
  507. : ok
  508. else
  509. tet_fatal "Auto Sync failed at end of TP ${tet_thistest}:" \
  510. "server reply code = $tet_reply_code"
  511. fi
  512. tet_l4_err=$tet_reply_code
  513. # then the master TCM informs XRESD of TP end
  514. if test ${TET_MASTER:?} = yes
  515. then
  516. if tet_mtcm_tpend
  517. then
  518. : ok
  519. else
  520. return 1
  521. fi
  522. fi
  523. if test "$tet_l4_err" = OK
  524. then
  525. return 0
  526. fi
  527. # here if a TCM voted NO ("can't happen"), timed out or died
  528. tet_async_report "Auto Sync error at end of TP $tet_thistest"
  529. tet_exit 1
  530. }
  531. # tet_mtcm_tpend - inform XRESD of TP end from MTCM
  532. # usage: tet_mtcm_tpend
  533. #
  534. # Return 0 if successful or non-zero to abort the test case
  535. tet_mtcm_tpend()
  536. {
  537. # local variables
  538. typeset -i tet_l5_n=0
  539. typeset tet_l5_msg
  540. # signal TP end to XRESD
  541. if tet_kshapid_tpend
  542. then
  543. if test $tet_reply_code = OK
  544. then
  545. return 0
  546. fi
  547. else
  548. tet_fatal "can't inform XRESD of TP end" \
  549. "server reply code = $tet_reply_code"
  550. fi
  551. # here if the previous TP result code action was Abort
  552. # signal IC end to XRESD
  553. if tet_kshapid_icend
  554. then
  555. : ok
  556. else
  557. tet_error "ABORT: can't inform XRESD of IC end" \
  558. "server reply code = $tet_reply_code"
  559. fi
  560. # sync NO to the end of the last IC -
  561. # this communicates the Abort action to the other TCMs
  562. tet_mkaspno $TET_ICMAX ~0 END
  563. if tet_kshapid_async $TET_SPNO NO $TET_SV_SYNC_TIMEOUT
  564. then
  565. : ok
  566. else
  567. tet_fatal "Abort Auto Sync failed:" \
  568. "server reply code = $tet_reply_code"
  569. fi
  570. # make sure that the other TCMs are still alive
  571. unset tet_l5_msg
  572. tet_l5_n=-1
  573. while test $((tet_l5_n += 1)) -lt ${TET_ASYNC_NSYS:?}
  574. do
  575. test $# -gt 0 && shift $#
  576. set -- ${TET_ASYNC_SYNCSTAT[$tet_l5_n]:?}
  577. case $2 in
  578. SYNC-YES|SYNC-NO)
  579. ;;
  580. *)
  581. tet_l5_msg[$tet_l5_n]="Abort Auto Sync error, sysid = $1, state = $2: server reply code = $tet_reply_code"
  582. ;;
  583. esac
  584. done
  585. # print the error messages if there are any
  586. if test ${#tet_l5_msg[*]} -gt 0
  587. then
  588. tet_mfatal "${tet_l5_msg[@]}"
  589. fi
  590. # here if we should attempt to call tet_cleanup
  591. return 1
  592. }
  593. # tet_docleanup - execute the tet_cleanup function
  594. # usage: tet_docleanup
  595. #
  596. # return 0 if successful or non-zero on error
  597. tet_docleanup()
  598. {
  599. # do an auto-sync
  600. tet_mkaspno $((TET_ICMAX + 1)) 1 START
  601. if tet_kshapid_async $TET_SPNO YES $TET_SV_SYNC_TIMEOUT
  602. then
  603. : ok
  604. else
  605. tet_fatal "cleanup function Auto Sync failed:" \
  606. "server reply code = $tet_reply_code"
  607. fi
  608. if test $tet_reply_code != OK
  609. then
  610. tet_async_report "cleanup function Auto Sync error"
  611. return 1
  612. fi
  613. # call the user-supplied cleanup function if there is one
  614. if test -n "$tet_cleanup"
  615. then
  616. tet_thistest=
  617. tet_kshapid_thistest 0
  618. TET_CONTEXT=0
  619. tet_setcontext
  620. eval $tet_cleanup
  621. fi
  622. return 0
  623. }
  624. # tet_async_report - report on the startup and cleanup auto-syncs
  625. # this function can be used when anything other than a YES vote is an error
  626. # usage: tet_async_report text
  627. tet_async_report()
  628. {
  629. # local variables
  630. typeset -i tet_l6_n=0
  631. typeset tet_l6_text="${1:?}"
  632. typeset tet_l6_msg
  633. unset tet_l6_msg
  634. tet_l6_n=-1
  635. while test $((tet_l6_n += 1)) -lt ${TET_ASYNC_NSYS:?}
  636. do
  637. test $# -gt 0 && shift $#
  638. set -- ${TET_ASYNC_SYNCSTAT[$tet_l6_n]:?}
  639. case $2 in
  640. SYNC-YES)
  641. ;;
  642. *)
  643. tet_l6_msg[$tet_l6_n]="$text, sysid = $1, state = $2: server reply code = $tet_reply_code"
  644. ;;
  645. esac
  646. done
  647. tet_merror "${tet_l6_msg[@]}"
  648. }
  649. # ******************************************************************
  650. #
  651. # IC list building and lookup functions
  652. #
  653. # tet_build_ics - build the list of ICs that are defined in this test case
  654. # usage: tet_build_ics
  655. #
  656. # This function constructs an array called TET_ICS.
  657. # The array is indexed by IC number.
  658. # Each element of the array contains one or more (space-separated) fields.
  659. # The first field is the absolute test number of the first TP in the IC.
  660. # Other fields are the name(s) of the TP function(s) that make(s)
  661. # up the IC.
  662. #
  663. # This function also sets the values of TET_ICMIN and TET_ICMAX to the
  664. # minimum and maximum IC number defined in this test case, respectively.
  665. tet_build_ics()
  666. {
  667. typeset -i tet_l31_icnum
  668. typeset -i tet_l31_testnum=1
  669. typeset -i tet_l31_n=0
  670. typeset tet_l31_err=no
  671. typeset tet_l31_icname
  672. typeset tet_l31_tplist
  673. # process each ICname defined in the iclist
  674. unset TET_ICS
  675. for tet_l31_icname in $iclist
  676. do
  677. # extract the IC number from the ICname
  678. if (tet_l31_icnum=${tet_l31_icname#ic})
  679. then
  680. tet_l31_icnum=${tet_l31_icname#ic}
  681. else
  682. tet_error "badly formatted IC name \"$tet_l31_icname\" in iclist"
  683. tet_l31_err=yes
  684. continue
  685. fi
  686. # ignore an IC number that is <= 0
  687. if test $tet_l31_icnum -lt 0
  688. then
  689. tet_error "warning: ignored -ve IC number: $tet_l31_icnum"
  690. continue
  691. fi
  692. # extract the list of TP function names defined by this ICname
  693. tet_l31_tplist="`eval echo \\$$tet_l31_icname`"
  694. if test -z "$tet_l31_tplist"
  695. then
  696. tet_error "warning: empty IC definition: $tet_l31_icname"
  697. fi
  698. # add the testnum of the first TP, and the list of TP
  699. # function names to the TET_ICS element for this IC
  700. test $# -gt 0 && shift $#
  701. set -- $tet_l31_tplist
  702. if test $# -gt 0
  703. then
  704. tet_l31_n=$tet_l31_testnum
  705. : $((tet_l31_testnum += $#))
  706. else
  707. tet_l31_n=0
  708. fi
  709. TET_ICS[$tet_l31_icnum]="$tet_l31_n${tet_l31_tplist:+ }$tet_l31_tplist"
  710. # update TET_ICMIN and TET_ICMAX if appropriate
  711. if test $TET_ICMIN -lt 0
  712. then
  713. TET_ICMIN=$tet_l31_icnum
  714. elif test $tet_l31_icnum -lt $TET_ICMIN
  715. then
  716. TET_ICMIN=$tet_l31_icnum
  717. fi
  718. if test $tet_l31_icnum -gt $TET_ICMAX
  719. then
  720. TET_ICMAX=$tet_l31_icnum
  721. fi
  722. done
  723. # exit now if there were any errors in the iclist
  724. if test $tet_l31_err = yes
  725. then
  726. tet_exit 1
  727. fi
  728. readonly TET_ICS TET_ICMIN TET_ICMAX
  729. }
  730. # tet_gettpcount - calculate the number of TPs in a particular IC
  731. # usage: tet_gettpcount icnum
  732. #
  733. # Returns 0 if there is at least one TP in the specified IC.
  734. # Returns non-zero if the specified IC is undefined or contains no TPs.
  735. # The number of TPs is returned in the global variable TET_TPCOUNT.
  736. tet_gettpcount()
  737. {
  738. typeset -i tet_l32_icnum=${1:?}
  739. # look up the IC and peel off the testnum of the first TP
  740. test $# -gt 0 && shift $#
  741. set -- ${TET_ICS[$tet_l32_icnum]}
  742. if test $# -gt 0
  743. then
  744. shift
  745. else
  746. return 1
  747. fi
  748. # the remaining fields are TP function names
  749. TET_TPCOUNT=$#
  750. if test $TET_TPCOUNT -gt 0
  751. then
  752. return 0
  753. else
  754. return 1
  755. fi
  756. }
  757. # tet_gettestnum - calculate the absolute test purpose number of the
  758. # specified TP within the specified IC
  759. # usage: tet_gettestnum icnum tpnum
  760. #
  761. # Returns 0 if the specified (icnum,tpnum) is defined in this test case,
  762. # otherwise returns non-zero.
  763. # When this function returns 0, the absolute test purpose number is
  764. # returned in the global variable TET_TESTNUM and the name of the test
  765. # purpose function is returned in the global variable TET_TESTNAME.
  766. # The values of these variables are undefined when this function returns
  767. # non-zero.
  768. tet_gettestnum()
  769. {
  770. typeset -i tet_l33_icnum=${1:?}
  771. typeset -i tet_l33_tpnum=${2:?}
  772. typeset -i tet_l33_n=0
  773. TET_TESTNAME=
  774. TET_TESTNUM=0
  775. # ensure that icnum and tpnum are within range
  776. if test $tet_l33_icnum -lt 0 -o $tet_l33_tpnum -lt 1
  777. then
  778. return 1
  779. fi
  780. # extract the tplist, and the testnum of the first TP
  781. test $# -gt 0 && shift $#
  782. set -- ${TET_ICS[$tet_l33_icnum]}
  783. if test $# -gt 1
  784. then
  785. TET_TESTNUM=$1
  786. shift
  787. else
  788. return 1
  789. fi
  790. # if tpnum is defined in this IC, bump up testnum and set testname
  791. if test $tet_l33_tpnum -le $#
  792. then
  793. : $((TET_TESTNUM += tet_l33_tpnum - 1))
  794. eval TET_TESTNAME=\$$tet_l33_tpnum
  795. return 0
  796. fi
  797. # here if the requested TP is not defined
  798. TET_TESTNUM=0
  799. return 1
  800. }
  801. # tet_build_iclist - build the list of ICs to be executed
  802. # usage: tet_build_iclist icspec ...
  803. #
  804. # The icspecs are taken from the TCM command line.
  805. # Each specification can contain one or more comma-separated elements.
  806. # Each element can be an IC number (n), a range of IC numbers (m-n),
  807. # or the word "all".
  808. #
  809. # When a element consists of a range of IC numbers (m-n), a missing m means
  810. # the lowest IC number defined in the test case, and a missing n means the
  811. # highest number defined in the test case.
  812. #
  813. # When the word "all" appears and is not the first element, it means all of
  814. # the ICs beyond the highest IC specified in the previous element.
  815. #
  816. # On return the variable TET_ICLIST contains the list of all the IC
  817. # numbers to execute.
  818. tet_build_iclist()
  819. {
  820. # local variables
  821. typeset tet_l34_icspecs="$*"
  822. typeset tet_l34_icspec=
  823. # note this is set here, but modified in lower level functions
  824. typeset -i tet_l34_last_icend=-1
  825. TET_ICLIST=
  826. # return now if there are no ICs defined in this test case
  827. if test ${TET_ICMIN:?} -lt 0 -o ${TET_ICMAX:?} -lt 0
  828. then
  829. readonly TET_ICLIST
  830. return
  831. fi
  832. # ensure that the largest IC number is within bounds
  833. tet_mkaspno $((TET_ICMAX + 1)) 0 START
  834. if test $TET_SPNO -lt 0 -o \
  835. $(((TET_ICMAX + 1) & ~(~0 << TET_S_ICBITS))) -ne \
  836. $((TET_ICMAX + 1))
  837. then
  838. tet_fatal "the largest IC number defined in this test case" \
  839. "is too big"
  840. fi
  841. # if we hve one or more IC specifications, use them to build
  842. # the IC list; otherwise, build the IC list from all the ICs defined
  843. # in this test case
  844. if test -z "$tet_l34_icspecs"
  845. then
  846. tet_build_icl3 all
  847. else
  848. for tet_l34_icspec in $tet_l34_icspecs
  849. do
  850. tet_build_icl2 $tet_l34_icspec
  851. done
  852. fi
  853. readonly TET_ICLIST
  854. }
  855. # tet_build_icl2 - extend the tet_build_iclist processing for a group of
  856. # elements in a single IC specification
  857. # usage: tet_build_icl2 icspec
  858. tet_build_icl2()
  859. {
  860. typeset tet_l35_icspec=${1:?}
  861. # process each comma-separated element in turn
  862. while :
  863. do
  864. case "$tet_l35_icspec" in
  865. *,*)
  866. tet_build_icl3 "${tet_l35_icspec%%,*}"
  867. tet_l35_icspec="${tet_l35_icspec#*,}"
  868. ;;
  869. "")
  870. break
  871. ;;
  872. *)
  873. tet_build_icl3 "$tet_l35_icspec"
  874. tet_l35_icspec=
  875. ;;
  876. esac
  877. done
  878. }
  879. # tet_build_icl3 - extend the tet_build_iclist processing some more
  880. # process an individual IC number or number range
  881. # usage: tet_build_icl3 icspec
  882. tet_build_icl3()
  883. {
  884. typeset tet_l36_icspec=${1:?}
  885. typeset tet_l36_tmp=
  886. typeset -i tet_l36_icstart=0
  887. typeset -i tet_l36_icend=0
  888. # process the icspec;
  889. # note the use of tet_l34_* variables (defined in a higher-level
  890. # function) to preserve state between calls
  891. case $tet_l36_icspec in
  892. "")
  893. return
  894. ;;
  895. all)
  896. if test $tet_l34_last_icend -eq -1 -o \
  897. $tet_l34_last_icend -lt $TET_ICMAX
  898. then
  899. tet_l36_icstart=$TET_ICMIN
  900. if test $tet_l36_icstart -lt $((tet_l34_last_icend + 1))
  901. then
  902. tet_l36_icstart=$((tet_l34_last_icend + 1))
  903. fi
  904. tet_l36_icend=$TET_ICMAX
  905. if test $tet_l34_last_icend -ge 0
  906. then
  907. while test $tet_l36_icstart -le $tet_l36_icend
  908. do
  909. if tet_gettpcount $tet_l36_icstart
  910. then
  911. break
  912. else
  913. : $((tet_l36_icstart += 1))
  914. fi
  915. done
  916. fi
  917. tet_build_icl4 $tet_l36_icstart $tet_l36_icend
  918. fi
  919. return
  920. ;;
  921. *-)
  922. tet_l36_icstart=${tet_l36_icspec%%[!0-9]*}
  923. tet_l36_icend=$TET_ICMAX
  924. ;;
  925. -*)
  926. tet_l36_icstart=$TET_ICMIN
  927. tet_l36_tmp=${tet_l36_icspec#*-}
  928. tet_l36_icend=${tet_l36_tmp%%[!0-9]*}
  929. ;;
  930. *-*)
  931. tet_l36_icstart=${tet_l36_icspec%%[!0-9]*}
  932. tet_l36_tmp=${tet_l36_icspec#*-}
  933. tet_l36_icend=${tet_l36_tmp%%[!0-9]*}
  934. ;;
  935. *)
  936. tet_l36_icstart=${tet_l36_icspec%%[!0-9]*}
  937. tet_l36_icend=$tet_l36_icstart
  938. ;;
  939. esac
  940. # find the lowest defined IC that is greater than or equal to
  941. # the specified start IC;
  942. # print a diagnostic if the specified start IC does not exist
  943. # or is empty
  944. if tet_gettpcount $tet_l36_icstart
  945. then
  946. : ok
  947. else
  948. tet_error "IC $tet_l36_icstart is not defined or is empty" \
  949. "in this test case"
  950. while test $((tet_l36_icstart += 1)) -le $tet_l36_icend
  951. do
  952. if tet_gettpcount $tet_l36_icstart
  953. then
  954. break
  955. fi
  956. done
  957. fi
  958. # return now if no ICs have been defined in the test case
  959. if test $tet_l36_icstart -gt $tet_l36_icend
  960. then
  961. return
  962. fi
  963. # here the IC referenced by the (possibly modified) tet_l36_icstart
  964. # is know to be defined;
  965. # find the highest defined IC that is less than or equal to
  966. # the specified end IC;
  967. # print a diagnostic if the specified end IC does not exist
  968. # or is empty
  969. if test $tet_l36_icstart -ne $tet_l36_icend
  970. then
  971. if tet_gettpcount $tet_l36_icend
  972. then
  973. : ok
  974. else
  975. tet_error "IC $tet_l36_icend is not defined or" \
  976. "is empty in this test case"
  977. while test $((tet_l36_icend -= 1)) -gt $tet_l36_icstart
  978. do
  979. if tet_gettpcount $tet_l36_icend
  980. then
  981. break
  982. fi
  983. done
  984. fi
  985. fi
  986. # here we have a known good start and end IC (which might be the same);
  987. # add the range to the list and return
  988. tet_build_icl4 $tet_l36_icstart $tet_l36_icend
  989. }
  990. # tet_build_icl4 - extend the tet_build_iclist processing yet more
  991. # add each IC in a range of IC numbers to the IC list
  992. # usage: tet_build_icl4 icstart icend
  993. tet_build_icl4()
  994. {
  995. typeset -i tet_l37_icstart=${1:?}
  996. typeset -i tet_l37_icend=${2:?}
  997. typeset -i tet_l37_icnum=$((tet_l37_icstart - 1))
  998. while test $((tet_l37_icnum += 1)) -le $tet_l37_icend
  999. do
  1000. TET_ICLIST="$TET_ICLIST${TET_ICLIST:+ }$tet_l37_icnum"
  1001. done
  1002. tet_l34_last_icend=$tet_l37_icend
  1003. }
  1004. # ******************************************************************
  1005. #
  1006. # ksh API helper process interface functions
  1007. #
  1008. # tet_kshapid_tcmstart - send a TCM Start message to XRESD
  1009. # usage: tet_kshapid_tcmstart iccount
  1010. #
  1011. # return 0 if successful or 1 on error
  1012. tet_kshapid_tcmstart()
  1013. {
  1014. tet_kshapid_request tet_tcmstart ${1:?} 1
  1015. tet_kshapid_request_data "3.8"
  1016. tet_kshapid_check_reply tet_tcmstart 0 ANY
  1017. tet_kshapid_release
  1018. case "$tet_reply_code" in
  1019. OK)
  1020. return 0
  1021. ;;
  1022. *)
  1023. return 1
  1024. ;;
  1025. esac
  1026. }
  1027. # tet_kshapid_icstart - send an IC Start message to XRESD
  1028. # usage: tet_kshapid_icstart icno tpcount
  1029. #
  1030. # return 0 if successful or 1 on error
  1031. tet_kshapid_icstart()
  1032. {
  1033. tet_kshapid_request tet_icstart ${1:?} ${2:?}
  1034. tet_kshapid_check_reply tet_icstart 0 ANY !PERM
  1035. tet_kshapid_release
  1036. case "$tet_reply_code" in
  1037. OK)
  1038. return 0
  1039. ;;
  1040. *)
  1041. return 1
  1042. ;;
  1043. esac
  1044. }
  1045. # tet_kshapid_icend - send an IC End message to XRESD
  1046. # usage: tet_kshapid_icend
  1047. #
  1048. # return 0 if successful or 1 on error
  1049. tet_kshapid_icend()
  1050. {
  1051. tet_kshapid_request tet_icend
  1052. tet_kshapid_check_reply tet_icend 0 ANY !PERM
  1053. tet_kshapid_release
  1054. case "$tet_reply_code" in
  1055. OK)
  1056. return 0
  1057. ;;
  1058. *)
  1059. return 1
  1060. ;;
  1061. esac
  1062. }
  1063. # tet_kshapid_tpstart - send a TP Start message to XRESD
  1064. # usage: tet_kshapid_tpstart testnum
  1065. #
  1066. # return 0 if successful or 1 on error
  1067. tet_kshapid_tpstart()
  1068. {
  1069. tet_kshapid_request tet_tpstart ${1:?}
  1070. tet_kshapid_check_reply tet_tpstart 0 ANY !PERM
  1071. tet_kshapid_release
  1072. case "$tet_reply_code" in
  1073. OK)
  1074. return 0
  1075. ;;
  1076. *)
  1077. return 1
  1078. ;;
  1079. esac
  1080. }
  1081. # tet_kshapid_tpend - send a TP End message to XRESD
  1082. # usage: tet_kshapid_tpend
  1083. #
  1084. # return 0 if successful or 1 on error
  1085. tet_kshapid_tpend()
  1086. {
  1087. tet_kshapid_request tet_tpend
  1088. tet_kshapid_check_reply tet_tpend 0 ANY !PERM
  1089. tet_kshapid_release
  1090. case "$tet_reply_code" in
  1091. OK|ABORT)
  1092. return 0
  1093. ;;
  1094. *)
  1095. return 1
  1096. ;;
  1097. esac
  1098. }
  1099. # tet_kshapid_async - send an auto-sync request to the helper process
  1100. # usage: tet_kshapid_async spno vote timeout
  1101. # vote should be YES or NO
  1102. #
  1103. # Return 0 if OK or non-zero on error.
  1104. # When successful, the list of (sysid, {spno|sync-state}) pairs is
  1105. # in TET_ASYNC_SYNCSTAT[],
  1106. # and the number of systems in the list is in TET_ASYNC_NSYS.
  1107. tet_kshapid_async()
  1108. {
  1109. # local variables
  1110. typeset -i tet_l7_n=0
  1111. # send the request and receive the reply
  1112. tet_kshapid_request tet_async ${1:?} ${2:?} ${3:?}
  1113. tet_kshapid_check_reply tet_async 1 SYNCERR TIMEDOUT DONE SYSID
  1114. TET_ASYNC_NSYS=${TET_REPLY_ARGV[0]}
  1115. tet_kshapid_read_reply_data $TET_ASYNC_NSYS
  1116. tet_kshapid_release
  1117. # process the per-system information
  1118. unset TET_ASYNC_SYNCSTAT
  1119. case "$tet_reply_code" in
  1120. OK|SYNCERR|TIMEDOUT)
  1121. tet_l7_n=-1
  1122. while test $((tet_l7_n += 1)) -lt $TET_ASYNC_NSYS
  1123. do
  1124. TET_ASYNC_SYNCSTAT[$tet_l7_n]="${TET_REPLY_DATA_LINE[$tet_l7_n]}"
  1125. done
  1126. return 0
  1127. ;;
  1128. DONE|SYSID)
  1129. return 1
  1130. ;;
  1131. *)
  1132. tet_fatal "$tet_reply_code unexpected" \
  1133. "in function tet_kshapid_async"
  1134. ;;
  1135. esac
  1136. }
  1137. # ***********************************************************************
  1138. # read in API functions
  1139. . ${TET_ROOT:?}/lib/ksh/tetdapi.ksh
  1140. # ***********************************************************************
  1141. #
  1142. # TCM main flow
  1143. #
  1144. # capture the command line args before they disappear
  1145. TET_TCM_ARGS="$*"
  1146. # arrange to clean up on exit
  1147. # these traps only apply to the top-level TCM shell -
  1148. # they are reset to default in each subshell that executes a TP function
  1149. trap 'tet_exit 0' 0
  1150. trap 'tet_exit 1' 1 2 3 13 15
  1151. # work out the name of the null device
  1152. case "${TET_OSNAME:?}" in
  1153. Windows_NT|Windows_9[58]|DOS)
  1154. TET_DEVNULL=nul
  1155. ;;
  1156. *)
  1157. TET_DEVNULL=/dev/null
  1158. ;;
  1159. esac
  1160. typeset -rx TET_DEVNULL
  1161. # initialise the API and start up the helper process
  1162. tet_api_init
  1163. # open local files
  1164. rm -f $TET_DELETES $TET_TMP1
  1165. for TET_A in $TET_DELETES $TET_TMP1
  1166. do
  1167. TET_TMPFILES="$TET_TMPFILES${TET_TMPFILES:+ }$TET_A"
  1168. > $TET_A
  1169. done
  1170. # do the distributed TCM initialisation
  1171. tet_tcminit
  1172. # read in configuration variables and make them readonly
  1173. # strip comments and other non-variable assignments
  1174. # protect embedded spaces and single quotes in the value part
  1175. if test -n "$TET_CONFIG"
  1176. then
  1177. if test ! -r "$TET_CONFIG"
  1178. then
  1179. tet_error "can't read config file" $TET_CONFIG
  1180. else
  1181. while read TET_line
  1182. do
  1183. TET_nline=${TET_line%%\#*}
  1184. if test ${#TET_nline} -ne 0
  1185. then
  1186. typeset -r "$TET_nline"
  1187. fi
  1188. done < $TET_CONFIG
  1189. fi
  1190. fi
  1191. # Initialise the TET_ICS array.
  1192. # The array is indexed by IC number.
  1193. # Each element in the array contains the names of the TP functions
  1194. # (defined in this test case) that are associated with the IC.
  1195. # This stage also initialises the variables TET_ICMIN and TET_ICMAX.
  1196. tet_build_ics
  1197. # Build the list of ICs to execute.
  1198. # This stage sets TET_ICLIST to the list of the ICs to execute.
  1199. tet_build_iclist $TET_TCM_ARGS
  1200. # print a startup message to execution results file
  1201. if test ${TET_MASTER:?} = yes
  1202. then
  1203. TET_ICCOUNT=0
  1204. for TET_ICNUM in $TET_ICLIST
  1205. do
  1206. if tet_gettpcount $TET_ICNUM
  1207. then
  1208. : $((TET_ICCOUNT += 1))
  1209. fi
  1210. done
  1211. if tet_kshapid_tcmstart $TET_ICCOUNT
  1212. then
  1213. :
  1214. else
  1215. tet_fatal \
  1216. "can't send \"TCM Start\" journal line to XRESD," \
  1217. "server reply code = $tet_reply_code"
  1218. fi
  1219. fi
  1220. # do initial signal list processing
  1221. if test $((${#TET_SIG_LEAVE} + ${#TET_SIG_IGN})) -eq 0
  1222. then
  1223. print TET_SIG_LEAVE2=\"\\n\"\\nTET_SIG_IGN2=\"\\n\" > $TET_TMP1
  1224. else
  1225. for TET_A in TET_SIG_LEAVE TET_SIG_IGN
  1226. do
  1227. echo ${TET_A}2=\"
  1228. eval TET_temp="\$$TET_A"
  1229. tet_ksh_tr , "
  1230. " "$TET_temp" | while read TET_B TET_JUNK
  1231. do
  1232. if test -z "$TET_B"
  1233. then
  1234. continue
  1235. elif tet_ismember $TET_B $TET_STD_SIGNALS $TET_SPEC_SIGNALS
  1236. then
  1237. tet_error "warning: illegal entry $TET_B" \
  1238. "in $TET_A ignored"
  1239. else
  1240. echo $TET_B
  1241. fi
  1242. done
  1243. echo \"
  1244. done > $TET_TMP1
  1245. fi
  1246. . $TET_TMP1
  1247. TET_SIG_LEAVE2="$TET_SIG_LEAVE2 $TET_SPEC_SIGNALS"
  1248. TET_A=1
  1249. if test -z "$TET_NSIG"
  1250. then
  1251. TET_NSIG=TET_NSIG_NUM
  1252. fi
  1253. # install signal handlers
  1254. TET_TRAP_FUNCTION=tet_abandon
  1255. TET_DEFAULT_SIGS=
  1256. while test $TET_A -lt $TET_NSIG
  1257. do
  1258. if tet_ismember $TET_A $TET_SIG_LEAVE2
  1259. then
  1260. :
  1261. elif tet_ismember $TET_A $TET_SIG_IGN2
  1262. then
  1263. trap "" $TET_A
  1264. else
  1265. trap "trap \"\" $TET_A; \$TET_TRAP_FUNCTION $TET_A" $TET_A
  1266. TET_DEFAULT_SIGS="$TET_DEFAULT_SIGS $TET_A"
  1267. fi
  1268. let TET_A=TET_A+1
  1269. done
  1270. typeset -rx TET_DEFAULT_SIGS
  1271. # do startup processing
  1272. tet_mkaspno -1 1 START
  1273. if tet_kshapid_async $TET_SPNO YES $TET_SV_SYNC_TIMEOUT
  1274. then
  1275. : ok
  1276. else
  1277. tet_fatal "startup function Auto Sync failed," \
  1278. "server reply code = $tet_reply_code"
  1279. fi
  1280. if test $tet_reply_code != OK
  1281. then
  1282. tet_async_report "startup function Auto Sync error"
  1283. tet_exit 1
  1284. fi
  1285. eval $tet_startup
  1286. #
  1287. # do main loop processing
  1288. #
  1289. # process each IC in the IC list
  1290. for TET_ICNUM in $TET_ICLIST
  1291. do
  1292. # skip an undefined or empty IC
  1293. if tet_gettpcount $TET_ICNUM
  1294. then
  1295. : TET_TPCOUNT is set by tet_gettpcount
  1296. else
  1297. continue
  1298. fi
  1299. # signal IC start
  1300. if tet_icstart $TET_ICNUM $TET_TPCOUNT
  1301. then
  1302. : ok
  1303. else
  1304. # test case is to be aborted (in a slave TCM)
  1305. tet_docleanup
  1306. tet_exit 1
  1307. fi
  1308. # process each TP in the current IC
  1309. TET_TPNUM=0
  1310. while test $((TET_TPNUM += 1)) -le $TET_TPCOUNT
  1311. do
  1312. # ensure that the TP number is in range
  1313. if test $((TET_TPNUM & ~(~0 << TET_S_TPBITS))) -ne $TET_TPNUM
  1314. then
  1315. tet_error "too many TPs defined in this IC"
  1316. break
  1317. fi
  1318. if tet_gettestnum $TET_ICNUM $TET_TPNUM
  1319. then
  1320. # TET_TESTNUM and TET_TESTNAME are set
  1321. # by tet_gettestnum
  1322. tet_thistest=$TET_TESTNAME
  1323. else
  1324. # this should never happen!
  1325. continue
  1326. fi
  1327. # see if this TP is deleted in this TCM
  1328. # and set our sync vote accordingly
  1329. TET_REASON=`tet_reason $tet_thistest`
  1330. if test $? -eq 0
  1331. then
  1332. TET_VOTE=NO
  1333. else
  1334. TET_VOTE=YES
  1335. fi
  1336. # signal TP start -
  1337. # when tet_tpstart returns non-zero,
  1338. # TP has been deleted in another TCM
  1339. tet_tpstart $TET_ICNUM $TET_TPNUM $TET_TESTNUM $TET_VOTE
  1340. TET_TPSTART_RC=$?
  1341. if test $TET_VOTE = YES -a $TET_TPSTART_RC -eq 0
  1342. then
  1343. # invoke the TP
  1344. TET_TRAP_FUNCTION=tet_sigskip
  1345. (
  1346. trap 0
  1347. trap $TET_DEFAULT_SIGS
  1348. "$tet_thistest"
  1349. )
  1350. else
  1351. # TP has been deleted
  1352. if test $TET_VOTE = NO
  1353. then
  1354. # TP has been deleted in this TCM
  1355. tet_infoline "$TET_REASON"
  1356. fi
  1357. tet_result UNINITIATED
  1358. fi
  1359. # signal TP end
  1360. if tet_tpend $TET_ICNUM $TET_TPNUM
  1361. then
  1362. : ok
  1363. else
  1364. # test case is to be aborted (in a master TCM)
  1365. tet_docleanup
  1366. tet_exit 1
  1367. fi
  1368. done
  1369. # signal IC end
  1370. tet_icend
  1371. done
  1372. # do cleanup processing and exit
  1373. TET_TRAP_FUNCTION=tet_abandon
  1374. tet_docleanup
  1375. tet_exit $?