Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief XA transaction processing - tx.h tests
0003  *
0004  * @file atmiclt21tx.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <math.h>
0039 #include <unistd.h>
0040 
0041 #include <atmi.h>
0042 #include <ubf.h>
0043 #include <ndebug.h>
0044 #include <test.fd.h>
0045 #include <ndrstandard.h>
0046 #include <nstopwatch.h>
0047 #include <tx.h>
0048 
0049 /*---------------------------Externs------------------------------------*/
0050 /*---------------------------Macros-------------------------------------*/
0051 /*---------------------------Enums--------------------------------------*/
0052 /*---------------------------Typedefs-----------------------------------*/
0053 /*---------------------------Globals------------------------------------*/
0054 /*---------------------------Statics------------------------------------*/
0055 /*---------------------------Prototypes---------------------------------*/
0056 
0057 /*
0058  * Do the test call to the server
0059  */
0060 int main(int argc, char** argv) {
0061 
0062     UBFH *p_ub = (UBFH *)tpalloc("UBF", NULL, 9216);
0063     long rsplen;
0064     int i=0;
0065     int ret=EXSUCCEED;
0066     ndrx_stopwatch_t w;
0067     long delta1, delta2;
0068     TXINFO txinf;
0069     TXINFO txinf2;
0070     /***************************************************************************/
0071     NDRX_LOG(log_debug, "Test errors... try begin with not open");
0072     /***************************************************************************/
0073     
0074     if (TX_PROTOCOL_ERROR!=(ret=tx_begin()))
0075     {
0076         NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d, must be %d", 
0077                 ret, TX_PROTOCOL_ERROR);
0078         EXFAIL_OUT(ret);
0079     }
0080     
0081     if (TX_PROTOCOL_ERROR!=(ret=tx_commit()))
0082     {
0083         NDRX_LOG(log_error, "TESTERROR: tx_commit() fail: %d, must be %d", 
0084                 ret, TX_PROTOCOL_ERROR);
0085         EXFAIL_OUT(ret);
0086     }
0087     
0088     if (TX_PROTOCOL_ERROR!=(ret=tx_rollback()))
0089     {
0090         NDRX_LOG(log_error, "TESTERROR: tx_rollback() fail: %d, must be %d", 
0091                 ret, TX_PROTOCOL_ERROR);
0092         EXFAIL_OUT(ret);
0093     }
0094     
0095     if (TX_OK!=(ret=tx_open()))
0096     {
0097         NDRX_LOG(log_error, "TESTERROR: tx_open() fail: %d", ret);
0098         EXFAIL_OUT(ret);
0099     }
0100     
0101     if (0!=(ret=tx_info(&txinf)))
0102     {
0103         NDRX_LOG(log_error, "TESTERROR: tx_info()==%d must be in 0 (not in tran)", 
0104                 ret);
0105         EXFAIL_OUT(ret);
0106     }
0107     
0108     /***************************************************************************/
0109     NDRX_LOG(log_debug, "Testing normal tx processing - commit() ...");
0110     /***************************************************************************/
0111     
0112     /* set tout to 5 */        
0113     if (TX_OK!=(ret=tx_set_transaction_timeout(5)))
0114     {
0115         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d", 
0116                 ret);
0117         EXFAIL_OUT(ret);
0118     }
0119 
0120     for (i=0; i<100; i++)
0121     {
0122         if (TX_OK!=(ret=tx_begin()))
0123         {
0124             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0125             EXFAIL_OUT(ret);
0126         }
0127 
0128         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI COMMIT", 0L);
0129 
0130         /* Call Svc1 */
0131         if (EXFAIL == (ret=tpcall("RUNTX", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0132         {
0133             NDRX_LOG(log_error, "TX3SVC failed: %s", tpstrerror(tperrno));
0134             EXFAIL_OUT(ret);
0135         }
0136 
0137         if (TX_OK!=(ret=tx_commit()))
0138         {
0139             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d", ret);
0140             EXFAIL_OUT(ret);
0141         }
0142     }
0143     
0144     /***************************************************************************/
0145     NDRX_LOG(log_debug, "Testing normal tx processing - abort() ...");
0146     /***************************************************************************/
0147     for (i=0; i<100; i++)
0148     {
0149         if (TX_OK!=(ret=tx_begin()))
0150         {
0151             NDRX_LOG(log_error, "TESTERROR: tx_begin() %d", ret);
0152             EXFAIL_OUT(ret);
0153         }
0154 
0155         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI ABORT", 0L);
0156 
0157         /* Call Svc1 */
0158         if (EXFAIL == (ret=tpcall("RUNTX", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0159         {
0160             NDRX_LOG(log_error, "TX3SVC failed: %s", tpstrerror(tperrno));
0161             EXFAIL_OUT(ret);
0162         }
0163 
0164         if (TX_OK!=(ret=tx_rollback()))
0165         {
0166             NDRX_LOG(log_error, "TESTERROR: tx_rollback()==%d", ret);
0167             EXFAIL_OUT(ret);
0168         }
0169     }
0170     
0171     /***************************************************************************/
0172     NDRX_LOG(log_debug, "Service returns fail");
0173     /***************************************************************************/
0174     for (i=0; i<100; i++)
0175     {
0176         if (TX_OK!=(ret=tx_begin()))
0177         {
0178             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0179             ret=EXFAIL;
0180             goto out;
0181         }
0182 
0183         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI SVCFAIL", 0L);
0184 
0185         /* Call Svc1 */
0186         if (EXFAIL != (ret=tpcall("RUNTXFAIL", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0187         {
0188             NDRX_LOG(log_error, "RUNTXFAIL should return fail!");
0189         }
0190 
0191         ret=tx_commit();
0192         
0193         if (TX_ROLLBACK!=ret)
0194         {
0195             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d (!=TX_ROLLBACK)", ret);
0196             ret=EXFAIL;
0197             goto out;
0198         }
0199         
0200         ret = EXSUCCEED;
0201     }    
0202     /***************************************************************************/
0203     NDRX_LOG(log_debug, "Transaction time-out (by tmsrv)");
0204     /***************************************************************************/
0205     
0206     /* set tout to 5 */        
0207     if (TX_OK!=(ret=tx_set_transaction_timeout(7)))
0208     {
0209         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d", 
0210                 ret);
0211         EXFAIL_OUT(ret);
0212     }
0213     
0214     for (i=0; i<5; i++)
0215     {
0216         if (EXSUCCEED!=(ret=tx_begin()))
0217         {
0218             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0219             EXFAIL_OUT(ret);
0220         }
0221 
0222         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI TOUT", 0L);
0223 
0224         /* Call Svc1 */
0225         if (EXFAIL == (ret=tpcall("RUNTX", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0226         {
0227             NDRX_LOG(log_error, "TESTERROR: RUNTX should not return fail!");
0228             EXFAIL_OUT(ret);
0229         }
0230         
0231         if (1!=(ret=tx_info(&txinf)))
0232         {
0233             NDRX_LOG(log_error, "TESTERROR: tx_info()==%d fail", ret);
0234             EXFAIL_OUT(ret);
0235         }
0236         
0237         /* transaction must rolled back... */
0238         if (TX_ACTIVE!=txinf.transaction_state)
0239         {
0240             NDRX_LOG(log_error, "TESTERROR: tx_info not active: %d expected %d", 
0241                     txinf.transaction_state, TX_ACTIVE);
0242             EXFAIL_OUT(ret);
0243         }
0244         
0245         sleep(10);
0246 
0247         /* get transaction info, are we in state of rollback by TMSRV? */
0248         if (1!=(ret=tx_info(&txinf)))
0249         {
0250             NDRX_LOG(log_error, "TESTERROR: tx_info()==%d fail", ret);
0251             EXFAIL_OUT(ret);
0252         }
0253         
0254         /* transaction must rolled back... */
0255         if (TX_TIMEOUT_ROLLBACK_ONLY!=txinf.transaction_state)
0256         {
0257             NDRX_LOG(log_error, "TESTERROR: tx_info not rollback state: %d expected %d", 
0258                     txinf.transaction_state, TX_TIMEOUT_ROLLBACK_ONLY);
0259             EXFAIL_OUT(ret);
0260         }
0261         
0262         /* check other flags... */
0263         if (7!=txinf.transaction_timeout)
0264         {
0265             NDRX_LOG(log_error, "TESTERROR: tx_info tout: %d expected %d", 
0266                     txinf.transaction_timeout, 7);
0267             EXFAIL_OUT(ret);
0268         }
0269         
0270         if (TX_COMMIT_COMPLETED!=txinf.when_return)
0271         {
0272             NDRX_LOG(log_error, "TESTERROR: tx_info when_return: %d expected %d", 
0273                     txinf.when_return, TX_COMMIT_COMPLETED);
0274             EXFAIL_OUT(ret);
0275         }
0276         
0277         if (TX_UNCHAINED!=txinf.transaction_control)
0278         {
0279             NDRX_LOG(log_error, "TESTERROR: tx_info transaction_control: %d expected %d", 
0280                     txinf.transaction_control, TX_UNCHAINED);
0281             EXFAIL_OUT(ret);
0282         }
0283         
0284         ret=tx_commit();
0285         
0286         if (ret!=TX_ROLLBACK)
0287         {
0288             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d must be TX_ROLLBACK!", 
0289                                                 ret);
0290             EXFAIL_OUT(ret);
0291         }
0292         
0293         ret = EXSUCCEED;
0294     }    
0295 
0296     /***************************************************************************/
0297     NDRX_LOG(log_debug, "Call service, but not in tran mode - transaction must not be aborted!");
0298     /***************************************************************************/
0299     
0300     /* set tout to 5 */        
0301     if (TX_OK!=(ret=tx_set_transaction_timeout(5)))
0302     {
0303         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d", 
0304                 ret);
0305         EXFAIL_OUT(ret);
0306     }
0307     for (i=0; i<200; i++)
0308     {
0309         if (TX_OK!=(ret=tx_begin()))
0310         {
0311             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0312             ret=EXFAIL;
0313             goto out;
0314         }
0315 
0316         Bchg(p_ub, T_STRING_FLD, 0, "TEST HELLO WORLD SVCFAIL", 0L);
0317 
0318         /* Call Svc1 */
0319         if (EXFAIL != (ret=tpcall("NOTRANFAIL", (char *)p_ub, 0L, (char **)&p_ub, 
0320                 &rsplen,TPNOTRAN)))
0321         {
0322             NDRX_LOG(log_error, "TESTERROR: NOTRANFAIL should return fail!");
0323             EXFAIL_OUT(ret);
0324         }
0325 
0326         ret=tx_commit();
0327         
0328         if (TX_OK!=ret)
0329         {
0330             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d fail!", ret);
0331             ret=EXFAIL;
0332             goto out;
0333         }
0334     }
0335     
0336     /* TODO: Test decision logged... - i.e. we need a benchmark
0337      * 1. say 300 txns with decision logged
0338      * 2. sleep 
0339      * 3. and 300 txns with standard completed
0340      * The 1. shall be faster than 3.
0341      */
0342     /***************************************************************************/
0343     NDRX_LOG(log_debug, "take time for 300txns with logged!");
0344     /***************************************************************************/
0345     
0346     /* seems on mac needs more time to complete */
0347     if (TX_OK!=(ret=tx_set_transaction_timeout(20)))
0348     {
0349         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d",
0350                 ret);
0351         EXFAIL_OUT(ret);
0352     }
0353 
0354     ndrx_stopwatch_reset(&w);
0355     if (TX_OK!=(ret=tx_set_commit_return(TX_COMMIT_DECISION_LOGGED)))
0356     {
0357         NDRX_LOG(log_error, "TESTERROR: tx_set_commit_return() fail: %d", 
0358                 ret);
0359         EXFAIL_OUT(ret);
0360     }
0361      
0362     for (i=0; i<300; i++)
0363     {
0364         if (TX_OK!=(ret=tx_begin()))
0365         {
0366             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0367             EXFAIL_OUT(ret);
0368         }
0369         /* needs newline for solaris grep, otherwise we get 1 line */
0370         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI LOGGED\n", 0L);
0371 
0372         /* Call Svc1 */
0373         if (EXFAIL == (ret=tpcall("RUNTX", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0374         {
0375             NDRX_LOG(log_error, "TX3SVC failed: %s", tpstrerror(tperrno));
0376             EXFAIL_OUT(ret);
0377         }
0378 
0379         if (TX_OK!=(ret=tx_commit()))
0380         {
0381             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d at %d", ret, i);
0382             EXFAIL_OUT(ret);
0383         }
0384     }
0385     
0386     delta1 = ndrx_stopwatch_get_delta(&w);
0387     
0388     NDRX_LOG(log_debug, "Sleep 60 -> wait for complete..!");
0389     sleep(60);
0390     /***************************************************************************/
0391     NDRX_LOG(log_debug, "take time for 300txns with completed!");
0392     /***************************************************************************/
0393     
0394     ndrx_stopwatch_reset(&w);
0395     
0396     if (TX_OK!=(ret=tx_set_commit_return(TX_COMMIT_COMPLETED)))
0397     {
0398         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d", 
0399                 ret);
0400         EXFAIL_OUT(ret);
0401     }
0402     
0403     if (TP_CMT_COMPLETE!=(ret=tpscmt(TP_CMT_LOGGED)))
0404     {
0405         NDRX_LOG(log_error, "TESTERROR: tpscmt() fail %d: %s", 
0406                 ret, tpstrerror(tperrno));
0407         EXFAIL_OUT(ret);
0408     }
0409     
0410     if (TP_CMT_LOGGED!=(ret=tpscmt(TP_CMT_COMPLETE)))
0411     {
0412         NDRX_LOG(log_error, "TESTERROR: tpscmt() fail %d: %s", 
0413                 ret, tpstrerror(tperrno));
0414         EXFAIL_OUT(ret);
0415     }
0416     
0417     if (TP_CMT_COMPLETE!=(ret=tpscmt(TP_CMT_COMPLETE)))
0418     {
0419         NDRX_LOG(log_error, "TESTERROR: tpscmt() fail %d: %s", 
0420                 ret, tpstrerror(tperrno));
0421         EXFAIL_OUT(ret);
0422     }
0423      
0424     for (i=0; i<300; i++)
0425     {
0426         if (TX_OK!=(ret=tx_begin()))
0427         {
0428             NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0429             EXFAIL_OUT(ret);
0430         }
0431 
0432         Bchg(p_ub, T_STRING_FLD, 0, "TXAPI FULL\n", 0L);
0433 
0434         /* Call Svc1 */
0435         if (EXFAIL == (ret=tpcall("RUNTX", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0)))
0436         {
0437             NDRX_LOG(log_error, "TX3SVC failed: %s", tpstrerror(tperrno));
0438             EXFAIL_OUT(ret);
0439         }
0440 
0441         if (TX_OK!=(ret=tx_commit()))
0442         {
0443             NDRX_LOG(log_error, "TESTERROR: tx_commit()==%d at %d", ret, i);
0444             EXFAIL_OUT(ret);
0445         }
0446     }
0447     
0448     delta2 = ndrx_stopwatch_get_delta(&w);
0449     
0450     NDRX_LOG(log_warn, "Logged %ld msec vs %ld msec completed", delta1, delta2);
0451     /*  might not be true as commit takes very short operation here in test..
0452     if (delta2 <= delta1)
0453     {
0454         NDRX_LOG(log_error, "TESTERROR: Logged is slower or equal to full "
0455                 "complete %ld vs %ld!", delta1, delta2);
0456         ret=EXFAIL;
0457         goto out;
0458     }
0459     */
0460 
0461     if (TX_OK!=(ret=tx_set_transaction_timeout(7)))
0462     {
0463         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_timeout() fail: %d",
0464                 ret);
0465         EXFAIL_OUT(ret);
0466     }
0467 
0468     
0469     /***************************************************************************/
0470     NDRX_LOG(log_debug, "Testing chained ops...");
0471     /***************************************************************************/
0472     
0473     if (TX_OK!=(ret=tx_set_transaction_control(TX_CHAINED)))
0474     {
0475         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_control() fail: %d", 
0476                 ret);
0477         EXFAIL_OUT(ret);
0478     }
0479     
0480     /* Test for transaction control -> chained action 
0481      * Begin txn
0482      * getinfo
0483      * commit
0484      * Begin another txn
0485      * getinfo -> shall be different tx
0486      * abort
0487      * getinfo -> shall be another tx
0488      * set contol to unchained
0489      * commit -> shall not be in txn.
0490      * getinfo
0491      *   - no txn...
0492      */
0493     
0494     if (TX_OK!=(ret=tx_begin()))
0495     {
0496         NDRX_LOG(log_error, "TESTERROR: tx_begin() fail: %d", ret);
0497         ret=EXFAIL;
0498         goto out;
0499     }
0500     
0501     if (1!=(ret=tx_info(&txinf)))
0502     {
0503         NDRX_LOG(log_error, "TESTERROR: tx_info()==%d fail", ret);
0504         EXFAIL_OUT(ret);
0505     }
0506     
0507     if (TX_OK!=(ret=tx_commit()))
0508     {
0509         NDRX_LOG(log_error, "TESTERROR: tx_commit() fail: %d", ret);
0510         ret=EXFAIL;
0511         goto out;
0512     }
0513     
0514     txinf2.transaction_state = TX_ROLLBACK_ONLY;
0515     if (1!=(ret=tx_info(&txinf2)))
0516     {
0517         NDRX_LOG(log_error, "TESTERROR: tx_info()==%d fail", ret);
0518         EXFAIL_OUT(ret);
0519     }
0520     
0521     if (TX_ACTIVE!=txinf2.transaction_state)
0522     {
0523         NDRX_LOG(log_error, "TESTERROR: chained tran not active: %d vs %d", 
0524                 txinf2.transaction_state, TX_ACTIVE);
0525         EXFAIL_OUT(ret);
0526     }
0527     
0528     if (0==memcmp(&txinf.xid, &txinf2.xid, sizeof(XID)))
0529     {
0530         NDRX_LOG(log_error, "TESTERROR: XID not changed!");
0531         EXFAIL_OUT(ret);
0532     }
0533 
0534     if (TX_OK!=(ret=tx_rollback()))
0535     {
0536         NDRX_LOG(log_error, "TESTERROR: tx_rollback() fail: %d", ret);
0537         ret=EXFAIL;
0538         goto out;
0539     }
0540     
0541     txinf.transaction_state = TX_ROLLBACK_ONLY;
0542     if (1!=(ret=tx_info(&txinf)))
0543     {
0544         NDRX_LOG(log_error, "TESTERROR: tx_info()==%d fail", ret);
0545         EXFAIL_OUT(ret);
0546     }
0547     
0548     if (TX_ACTIVE!=txinf2.transaction_state)
0549     {
0550         NDRX_LOG(log_error, "TESTERROR: chained tran not active: %d vs %d", 
0551                 txinf2.transaction_state, TX_ACTIVE);
0552         EXFAIL_OUT(ret);
0553     }
0554     
0555     if (0==memcmp(&txinf.xid, &txinf2.xid, sizeof(XID)))
0556     {
0557         NDRX_LOG(log_error, "TESTERROR: XID not changed!");
0558         EXFAIL_OUT(ret);
0559     }
0560     
0561     /* try some error.. with commit, maybe close tm? */
0562 #if 0
0563     if (TX_OK!=tx_close())
0564     {
0565         NDRX_LOG(log_error, "TESTERROR: tx_close() fail: %d", ret);
0566         EXFAIL_OUT(ret);
0567     }
0568     
0569     if (TX_PROTOCOL_ERROR!=(ret=tx_rollback()))
0570     {
0571         NDRX_LOG(log_error, "TESTERROR: tx_rollback() fail: "
0572                 "%d not %d (TX_PROTOCOL_ERROR)", ret, TX_PROTOCOL_ERROR);
0573         ret=EXFAIL;
0574         goto out;
0575     }
0576     
0577     if (TX_OK!=tx_open())
0578     {
0579         NDRX_LOG(log_error, "TESTERROR: tx_open() fail: %d", ret);
0580         EXFAIL_OUT(ret);
0581     }
0582 #endif
0583     
0584     if (TX_OK!=(ret=tx_set_transaction_control(TX_UNCHAINED)))
0585     {
0586         NDRX_LOG(log_error, "TESTERROR: tx_set_transaction_control() fail: %d", 
0587                 ret);
0588         EXFAIL_OUT(ret);
0589     }
0590     
0591     /* finish it off... */
0592     if (TX_OK!=(ret=tx_rollback()))
0593     {
0594         NDRX_LOG(log_error, "TESTERROR: tx_rollback() fail: %d", ret);
0595         ret=EXFAIL;
0596         goto out;
0597     }
0598     
0599     
0600     /* we shall be outside of global tran -> timed out by RM */
0601     sleep(5);
0602     
0603     /***************************************************************************/
0604     NDRX_LOG(log_debug, "Done...");
0605     /***************************************************************************/
0606     
0607     if (TX_OK!=(ret=tx_close()))
0608     {
0609         NDRX_LOG(log_error, "TESTERROR: tx_close() fail: %d", ret);
0610         EXFAIL_OUT(ret);
0611     }
0612     
0613 out:
0614     if (EXSUCCEED!=ret)
0615     {
0616         /* atleast try... */
0617         if (TX_OK!=(ret=tx_rollback()))
0618         {
0619             NDRX_LOG(log_error, "TESTERROR: tx_rollback() fail: %d", ret);
0620         }
0621         
0622         tx_close();
0623     }
0624 
0625     tpterm();
0626     
0627     NDRX_LOG(log_error, "Exiting with %d", ret);
0628             
0629     return ret;
0630 }
0631 
0632 /* vim: set ts=4 sw=4 et smartindent: */