Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief PostgreSQL PQ TMSRV driver tests / branch transactions - client
0003  *   Perform local calls with help of PQ commands.
0004  *   the server process shall run the code with Embedded SQL
0005  *
0006  * @file atmiclt67.c
0007  */
0008 /* -----------------------------------------------------------------------------
0009  * Enduro/X Middleware Platform for Distributed Transaction Processing
0010  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0011  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0012  * This software is released under one of the following licenses:
0013  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0014  * See LICENSE file for full text.
0015  * -----------------------------------------------------------------------------
0016  * AGPL license:
0017  *
0018  * This program is free software; you can redistribute it and/or modify it under
0019  * the terms of the GNU Affero General Public License, version 3 as published
0020  * by the Free Software Foundation;
0021  *
0022  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0023  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0024  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0025  * for more details.
0026  *
0027  * You should have received a copy of the GNU Affero General Public License along 
0028  * with this program; if not, write to the Free Software Foundation, Inc.,
0029  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030  *
0031  * -----------------------------------------------------------------------------
0032  * A commercial use license is available from Mavimax, Ltd
0033  * contact@mavimax.com
0034  * -----------------------------------------------------------------------------
0035  */
0036 #include <string.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <memory.h>
0040 #include <math.h>
0041 #include <signal.h>
0042 
0043 #include <atmi.h>
0044 #include <ubf.h>
0045 #include <ndebug.h>
0046 #include <test.fd.h>
0047 #include <ndrstandard.h>
0048 #include <nstopwatch.h>
0049 #include <fcntl.h>
0050 #include <unistd.h>
0051 #include <nstdutil.h>
0052 #include <libpq-fe.h>
0053 #include "test67.h"
0054 /*---------------------------Externs------------------------------------*/
0055 /*---------------------------Macros-------------------------------------*/
0056 /*---------------------------Enums--------------------------------------*/
0057 /*---------------------------Typedefs-----------------------------------*/
0058 /*---------------------------Globals------------------------------------*/
0059 /*---------------------------Statics------------------------------------*/
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 /**
0063  * RUn list of SQLs
0064  * @param [in] array of string with statements
0065  * @param [in] should we return from last stmt first value
0066  * @param [out] return value of the first col/row
0067  * @return EXSUCCEED/EXFAIL and return value 
0068  */
0069 expublic long sql_run(char **list, int ret_col_row_1, long *ret_val)
0070 {
0071     PGconn * conn = (PGconn *)tpgetconn();
0072     long ret = EXSUCCEED;
0073     char *command, *codes;
0074     int i;
0075     PGresult *res = NULL;
0076     ExecStatusType estat;
0077     
0078     /* get connection object */
0079     if (NULL==conn)
0080     {
0081         NDRX_LOG(log_error, "TESTERROR: Failed to get connection!");
0082         EXFAIL_OUT(ret);
0083     }
0084     
0085     /* process the commands */
0086     for (i=0; NULL!=list[i]; i+=2)
0087     {
0088         PQclear(res);
0089         
0090         command = list[i];
0091         codes = list[i+1];
0092         
0093         NDRX_LOG(log_debug, "Command [%s] codes [%s]", command, codes);
0094         
0095         res = PQexec(conn, command);
0096         
0097         estat =PQresultStatus(res);
0098         if (PGRES_COMMAND_OK != estat && PGRES_TUPLES_OK != estat) 
0099         {
0100             char *state = PQresultErrorField(res, PG_DIAG_SQLSTATE);
0101             char *ok = "0000";
0102             if (NULL==state)
0103             {
0104                 state = ok;
0105             }
0106             
0107             if (0==strstr(codes,state))
0108             {
0109                 NDRX_LOG(log_error, "TESTERROR: Statement [%s] failed with [%s] accepted [%s]",
0110                         command, state, codes);
0111                 EXFAIL_OUT(ret);
0112             }
0113         }
0114         
0115     }
0116     
0117     if (ret_col_row_1)
0118     {
0119         if (PGRES_TUPLES_OK != estat)
0120         {
0121             NDRX_LOG(log_error, "TESTERROR: Requested result, but none provided!");
0122             EXFAIL_OUT(ret);
0123         }
0124         else
0125         {
0126             *ret_val = atol(PQgetvalue(res, 0, 0));
0127             
0128             NDRX_LOG(log_info, "Value extracted: %ld", *ret_val);
0129         }
0130     }
0131     
0132 out:
0133     PQclear(res);
0134 
0135     return ret;
0136 }
0137 
0138 /**
0139  * Create tables
0140  * @return  EXSUCCEED/EXFAIL
0141  */
0142 expublic int sql_mktab(void)
0143 {
0144 
0145     char *commands[]   = {
0146             /* Command code       Accepted SQL states*/
0147             "drop table extest;", "0000;42P01"
0148             ,"CREATE TABLE extest(userid integer UNIQUE NOT NULL);", "0000"
0149             ,NULL, NULL};
0150     return sql_run(commands, EXFALSE, NULL);
0151 }
0152 
0153 /**
0154  * Delete from table
0155  * @return EXSUCCEED/EXFAIL
0156  */
0157 expublic int sql_delete(void)
0158 {
0159     char *commands[]   = {
0160             /* Command code       Accepted SQL states*/
0161             "delete from extest;", "0000"
0162             ,NULL, NULL};
0163     
0164     return sql_run(commands, EXFALSE, NULL);
0165 }
0166 
0167 /**
0168  * Count records added to table
0169  * @return count/EXFAIL
0170  */
0171 expublic long sql_count(void)
0172 {
0173     long ret_val = EXSUCCEED;
0174     char *commands[]   = {
0175             /* Command code       Accepted SQL states*/
0176             "select count(*) from extest;", "0000"
0177             ,NULL, NULL};
0178     
0179     if (EXSUCCEED!=sql_run(commands, EXTRUE, &ret_val))
0180     {
0181         NDRX_LOG(log_error, "TESTERROR: Failed to get count!");
0182         ret_val = EXFAIL;
0183         goto out;
0184     }
0185     
0186 out:
0187     return ret_val;
0188 }
0189 
0190 /**
0191  * Seems like if we try to insert the same unique value in prepared transaction
0192  * it will lock up and wait for prep transaction result thus to have some
0193  * more data, call sql_insert2
0194  * @return 
0195  */
0196 expublic int sql_insert(void)
0197 {
0198     /* run some insert */
0199     
0200     char *commands[]   = {
0201             /* Command code       Accepted SQL states*/
0202             "insert into extest(userid) values ((select COALESCE(max(userid), 1)+1 from extest));", "0000"
0203             ,NULL, NULL};
0204     
0205     return sql_run(commands, EXFALSE, NULL);
0206 }
0207 
0208 
0209 /**
0210  * In transaction inserts / for suspended
0211  * @return 
0212  */
0213 expublic int sql_insert2(void)
0214 {
0215     /* run some insert */
0216     
0217     char *commands[]   = {
0218             /* Command code       Accepted SQL states*/
0219             "insert into extest(userid) values (999990);", "0000"
0220             ,"insert into extest(userid) values (999991);", "0000"
0221             ,"insert into extest(userid) values (999992);", "0000"
0222             ,NULL, NULL};
0223     
0224     return sql_run(commands, EXFALSE, NULL);
0225 }
0226 
0227 /**
0228  * Insert something into queue
0229  * @param p_ub UBF buffer to insert
0230  * @param queue queue name
0231  * @return EXSUCCEED/EXFAIL
0232  */
0233 expublic int q_insert(UBFH *p_ub, char *queue)
0234 {
0235     int ret = EXSUCCEED;
0236     TPQCTL qc;
0237     
0238     memset(&qc, 0, sizeof(qc));
0239     if (EXSUCCEED!=tpenqueue("MYSPACE", queue, &qc, (char *)p_ub, 0L, 0L))
0240     {
0241         NDRX_LOG(log_error, "TESTERROR: tpenqueue() failed %s diag: %d:%s", 
0242                 tpstrerror(tperrno), qc.diagnostic, qc.diagmsg);
0243         EXFAIL_OUT(ret);
0244     }
0245     
0246 out:
0247     return ret;
0248 }
0249 
0250 /**
0251  * get queue message stats, the message by it self is discarded
0252  * @param p_ub UBF buffer to insert
0253  * @param queue queue name
0254  * @return EXSUCCEED/EXFAIL
0255  */
0256 expublic int q_count(UBFH **pp_ub, char *queue)
0257 {
0258     int ret = EXSUCCEED;
0259     TPQCTL qc;
0260     long len;
0261     
0262     while(1)
0263     {
0264         memset(&qc, 0, sizeof(qc));
0265         
0266         if (EXSUCCEED!=tpdequeue("MYSPACE", queue, &qc, (char **)pp_ub, &len, 0L))
0267         {
0268             if (TPEDIAGNOSTIC==tperrno && QMENOMSG==qc.diagnostic)
0269             {
0270                 /* finish the counting */
0271                 break;
0272             }
0273             else
0274             {
0275                 NDRX_LOG(log_error, "TESTERROR: tpenqueue() failed %s diag: %d:%s", 
0276                         tpstrerror(tperrno), qc.diagnostic, qc.diagmsg);
0277                 EXFAIL_OUT(ret);
0278             }
0279         }
0280         
0281         ret++;
0282     }
0283     
0284 out:
0285     NDRX_LOG(log_debug, "Found %d messages in [%s] queue", ret, queue);
0286     return ret;
0287 }
0288 
0289 
0290 /**
0291  * 1. Do the test call to the server
0292  * Also we need some test cases from shell processing with stalled commits.
0293  * Thus needs some parameters to be passed to executable.
0294  * 
0295  * Additional tests:
0296  * 2. postgresql prepare fails / commit shall fail / transaction aborted result
0297  * 3. run some inserts commit but leave prepared in db, test the commit/rollback
0298  *  command line commands.
0299  */
0300 int main(int argc, char** argv)
0301 {
0302     UBFH *p_ub = (UBFH *)tpalloc("UBF", NULL, 56000);
0303     long rsplen;
0304     long i;
0305     int ret=EXSUCCEED;
0306     TPTRANID t;
0307     
0308     /* open connection */
0309     if (EXSUCCEED!=tpopen())
0310     {
0311         NDRX_LOG(log_error, "TESTERROR: Failed to open: %s", tpstrerror(tperrno));
0312         EXFAIL_OUT(ret);
0313     }
0314     
0315     if (argc > 1)
0316     {
0317         NDRX_LOG(log_debug, "Got test case: [%s]", argv[1]);
0318         if (0==strcmp("endfail", argv[1]))
0319         {
0320             sql_mktab();
0321             
0322             for (i=0; i<100; i++)
0323             {
0324                 if (EXSUCCEED!=tpbegin(60, 0))
0325                 {
0326                     NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", 
0327                             tpstrerror(tperrno));
0328                     EXFAIL_OUT(ret);
0329                 }
0330 
0331                 if (EXSUCCEED!=sql_insert())
0332                 {
0333                     NDRX_LOG(log_error, "TESTERROR: Failed to insert: %s");
0334                     EXFAIL_OUT(ret);
0335                 }
0336 
0337                 if (EXSUCCEED==tpcommit(0))
0338                 {
0339                     NDRX_LOG(log_error, "TESTERROR: Commit must fail!");
0340                     EXFAIL_OUT(ret);
0341                 }
0342 
0343                 if (tperrno!=TPEABORT)
0344                 {
0345                     NDRX_LOG(log_error, "TESTERROR: Expected TPEABORT got: %d!", 
0346                             tperrno);
0347                     EXFAIL_OUT(ret);
0348                 }
0349             }
0350             
0351             ret = EXSUCCEED;
0352             goto out;
0353         } /* end fail test */
0354         else if (0==strcmp("doinsert", argv[1]))
0355         {
0356             sql_mktab();
0357 
0358             /* run some inserts... say 50 */
0359             
0360             if (EXSUCCEED!=tpbegin(60, 0))
0361             {
0362                 NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", 
0363                         tpstrerror(tperrno));
0364                 EXFAIL_OUT(ret);
0365             }
0366 
0367             for (i=0; i<50; i++)
0368             {
0369 
0370                 if (EXSUCCEED!=sql_insert())
0371                 {
0372                     NDRX_LOG(log_error, "TESTERROR: Failed to insert: %s");
0373                     EXFAIL_OUT(ret);
0374                 }
0375                 
0376             }
0377             
0378             if (EXSUCCEED==tpcommit(0))
0379             {
0380                 NDRX_LOG(log_error, "TESTERROR: Commit must fail!");
0381                 EXFAIL_OUT(ret);
0382             }
0383             
0384             goto out;
0385             
0386         }
0387         else if (0==strcmp("insert2", argv[1]))
0388         {
0389 
0390             sql_mktab();
0391 
0392             /* run some inserts... say 50 */
0393             
0394             if (EXSUCCEED!=tpbegin(60, 0))
0395             {
0396                 NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", 
0397                         tpstrerror(tperrno));
0398                 EXFAIL_OUT(ret);
0399             }
0400 
0401             /* generate multiple TIDS: */
0402             for (i=0; i<100; i++)
0403             {
0404                 if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0405                 {
0406                     NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0407                     EXFAIL_OUT(ret);
0408                 }
0409 
0410                 if (EXFAIL == tpcall("TESTSV", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0))
0411                 {
0412                     NDRX_LOG(log_error, "TESTERROR: TESTSV failed: %s", tpstrerror(tperrno));
0413                     EXFAIL_OUT(ret);
0414                 }
0415             }
0416 
0417             if (EXSUCCEED==tpcommit(0))
0418             {
0419                 NDRX_LOG(log_error, "TESTERROR: Commit must fail!");
0420                 EXFAIL_OUT(ret);
0421             }
0422             
0423             goto out;
0424             
0425         }      
0426         else if (0==strcmp("ck50", argv[1]))
0427         {
0428          
0429             if (50!=(ret=(int)sql_count()))
0430             {
0431                 NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 50", ret);
0432                 EXFAIL_OUT(ret);
0433             }
0434             ret = EXSUCCEED;
0435             goto out;
0436             
0437         }
0438         else if (0==strcmp("ck0", argv[1]))
0439         {
0440             if (0!=(ret=(int)sql_count()))
0441             {
0442                 NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0443                 EXFAIL_OUT(ret);
0444             }
0445             ret = EXSUCCEED;
0446             goto out;
0447         }
0448         else if (0==strcmp("ck1", argv[1]))
0449         {
0450             if (1!=(ret=(int)sql_count()))
0451             {
0452                 NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 1", ret);
0453                 EXFAIL_OUT(ret);
0454             }
0455             ret = EXSUCCEED;
0456             goto out;
0457         }
0458         else if (0==strcmp("testq", argv[1]))
0459         {
0460             ret = q_run(&p_ub);
0461             goto out;
0462         }
0463         else if (0==strcmp("tout", argv[1]))
0464         {
0465             if (EXSUCCEED!=tpbegin(80, 0))
0466             {
0467                 NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", 
0468                         tpstrerror(tperrno));
0469                 EXFAIL_OUT(ret);
0470             }
0471             
0472             /* Bug #417 */
0473             if (EXSUCCEED == tpcall("TOUTSV", (char *)p_ub, 0L, (char **)&p_ub, 
0474                     &rsplen,TPTRANSUSPEND))
0475             {
0476                 NDRX_LOG(log_error, "TESTERROR: expected error got OK");
0477                 EXFAIL_OUT(ret);
0478             }
0479             
0480             if (TPETIME!=tperrno)
0481             {
0482                 NDRX_LOG(log_error, "TESTERROR: expected TPETIME, got %d",
0483                         tperrno);
0484                 EXFAIL_OUT(ret);
0485             }
0486             
0487             if (EXSUCCEED==tpcommit(0))
0488             {
0489                 NDRX_LOG(log_error, "TESTERROR: Commit must fail!");
0490                 EXFAIL_OUT(ret);
0491             }
0492             
0493             if (TPEABORT!=tperrno)
0494             {
0495                 NDRX_LOG(log_error, "TESTERROR: Commit not TPEABORT got %d!", tperrno);
0496                 EXFAIL_OUT(ret);
0497             }
0498             ret = EXSUCCEED;
0499             goto out;
0500         }
0501         else if (0==strcmp("enqfail", argv[1]))
0502         {
0503             /* clear the table */
0504             sql_mktab();
0505             
0506             i=999;
0507             if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0508             {
0509                 NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0510                 EXFAIL_OUT(ret);
0511             }
0512 
0513             /* enqueue to fail server */
0514             if (EXSUCCEED!=q_insert(p_ub, "BADQ1"))
0515             {
0516                 NDRX_LOG(log_error, "Failed to enq to BADQ1!");
0517                 EXFAIL_OUT(ret);
0518             }
0519             
0520             ret = EXSUCCEED;
0521             goto out;
0522             
0523         } /* if test q */
0524         else if (0==strcmp("enqok", argv[1]))
0525         {
0526             /* clear the table */
0527             sql_mktab();
0528             
0529             i=777;
0530             if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0531             {
0532                 NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0533                 EXFAIL_OUT(ret);
0534             }
0535 
0536             /* enqueue to fail server */
0537             if (EXSUCCEED!=q_insert(p_ub, "OKQ1"))
0538             {
0539                 NDRX_LOG(log_error, "Failed to enq to OKQ1!");
0540                 EXFAIL_OUT(ret);
0541             }
0542             
0543             ret = EXSUCCEED;
0544             goto out;
0545             
0546         } /* if test q */
0547         
0548     }
0549     
0550     sql_mktab();
0551     
0552     /**************************************************************************/
0553     NDRX_LOG(log_debug, "Test commit");
0554     /**************************************************************************/
0555     if (EXSUCCEED!=tpbegin(90, 0))
0556     {
0557         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0558         EXFAIL_OUT(ret);
0559     }
0560     
0561     for (i=0; i<900; i++)
0562     {
0563         if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0564         {
0565             NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0566             EXFAIL_OUT(ret);
0567         }    
0568 
0569         if (EXFAIL == tpcall("TESTSV", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0))
0570         {
0571             NDRX_LOG(log_error, "TESTERROR: TESTSV failed: %s", tpstrerror(tperrno));
0572             EXFAIL_OUT(ret);
0573         }
0574     }
0575     
0576     /* test that we have 0 records here... */
0577     if (EXSUCCEED!=(ret=(int)sql_count()))
0578     {
0579         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0580         EXFAIL_OUT(ret);
0581     }
0582         
0583     /* set larger timeout, as in slow machines we might get timeout here...*/
0584     if (EXSUCCEED!=tpcommit(0))
0585     {
0586         NDRX_LOG(log_error, "TESTERROR: Failed to commit: %s", tpstrerror(tperrno));
0587         EXFAIL_OUT(ret);
0588     }
0589     
0590     if (900!=(ret=(int)sql_count()))
0591     {
0592         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 900", ret);
0593         EXFAIL_OUT(ret);
0594     }
0595     
0596     ret = EXSUCCEED;
0597     
0598     
0599     /**************************************************************************/
0600     NDRX_LOG(log_debug, "Test suspend");
0601     /**************************************************************************/
0602     
0603     sql_delete();
0604     
0605     if (EXSUCCEED!=tpbegin(90, 0))
0606     {
0607         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0608         EXFAIL_OUT(ret);
0609     }
0610     
0611     for (i=0; i<1000; i++)
0612     {
0613         sql_insert();
0614     }
0615     
0616     if (1000!=(ret=(int)sql_count()))
0617     {
0618         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 1000", ret);
0619         EXFAIL_OUT(ret);
0620     }
0621     
0622     /* suspend transaction, shall get 0 */
0623     
0624     if (EXSUCCEED!=tpsuspend(&t, 0L))
0625     {
0626         NDRX_LOG(log_error, "TESTERROR: Failed to suspend: %s", tpstrerror(tperrno));
0627         EXFAIL_OUT(ret);
0628     }
0629     
0630     if (0!=(ret=(int)sql_count()))
0631     {
0632         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0633         EXFAIL_OUT(ret);
0634     }
0635     
0636     /* start another transaction */
0637     NDRX_LOG(log_debug, "running tran within");
0638     
0639     if (EXSUCCEED!=tpbegin(60, 0))
0640     {
0641         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0642         EXFAIL_OUT(ret);
0643     }
0644     
0645     sql_insert2();
0646     
0647     if (3!=(ret=(int)sql_count()))
0648     {
0649         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 1000", ret);
0650         EXFAIL_OUT(ret);
0651     }
0652     
0653     if (EXSUCCEED!=tpcommit(0))
0654     {
0655         NDRX_LOG(log_error, "TESTERROR: Failed to commit: %s", tpstrerror(tperrno));
0656         EXFAIL_OUT(ret);
0657     }
0658     
0659     NDRX_LOG(log_debug, "continue with org tran...");
0660     if (EXSUCCEED!=tpresume(&t, 0L))
0661     {
0662         NDRX_LOG(log_error, "TESTERROR: Failed to resume: %s", tpstrerror(tperrno));
0663         EXFAIL_OUT(ret);
0664     }
0665     
0666     /* as this is new branch tran, we get 0 */
0667     if (3!=(ret=(int)sql_count()))
0668     {
0669         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 3", ret);
0670         EXFAIL_OUT(ret);
0671     }
0672     
0673     if (EXSUCCEED!=tpcommit(0))
0674     {
0675         NDRX_LOG(log_error, "TESTERROR: Failed to commit: %s", tpstrerror(tperrno));
0676         EXFAIL_OUT(ret);
0677     }
0678     
0679     /* as this is new branch tran, we get 0 */
0680     if (1003!=(ret=(int)sql_count()))
0681     {
0682         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 1000", ret);
0683         EXFAIL_OUT(ret);
0684     }
0685     
0686     /**************************************************************************/
0687     NDRX_LOG(log_debug, "Test abort");
0688     /**************************************************************************/
0689     
0690     sql_delete();
0691     
0692     if (EXSUCCEED!=tpbegin(90, 0))
0693     {
0694         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0695         EXFAIL_OUT(ret);
0696     }
0697     
0698     for (i=0; i<499; i++)
0699     {
0700         sql_insert();
0701     }
0702     
0703     /* as this is new branch tran, we get 0 */
0704     if (499!=(ret=(int)sql_count()))
0705     {
0706         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 499", ret);
0707         EXFAIL_OUT(ret);
0708     }
0709     
0710     if (EXSUCCEED!=tpabort(0))
0711     {
0712         NDRX_LOG(log_error, "TESTERROR: Failed to abort: %s", tpstrerror(tperrno));
0713         EXFAIL_OUT(ret);
0714     }
0715     
0716     if (0!=(ret=(int)sql_count()))
0717     {
0718         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0719         EXFAIL_OUT(ret);
0720     }
0721     
0722     
0723     /**************************************************************************/
0724     NDRX_LOG(log_debug, "Test timeout");
0725     /**************************************************************************/
0726     
0727     sql_delete();
0728     
0729     if (EXSUCCEED!=tpbegin(5, 0))
0730     {
0731         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0732         EXFAIL_OUT(ret);
0733     }
0734     
0735     for (i=0; i<10; i++)
0736     {
0737         sql_insert();
0738     }
0739     
0740     /* as this is new branch tran, we get 0 */
0741     if (10!=(ret=(int)sql_count()))
0742     {
0743         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 10", ret);
0744         EXFAIL_OUT(ret);
0745     }
0746     
0747     /* tmsrv must rollback in this time */
0748     sleep(10);
0749     
0750     if (EXSUCCEED==tpcommit(0))
0751     {
0752         NDRX_LOG(log_error, "TESTERROR: Commit OK, must fail!");
0753         EXFAIL_OUT(ret);
0754     }
0755     
0756     if (TPEABORT!=tperrno)
0757     {
0758         NDRX_LOG(log_error, "TESTERROR: Transaction must be aborted!");
0759         EXFAIL_OUT(ret);
0760     }
0761 
0762     /* as this is new branch tran, we get 0 */
0763     if (0!=(ret=(int)sql_count()))
0764     {
0765         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0766         EXFAIL_OUT(ret);
0767     }
0768     
0769     /* this shall work out fine, as preared was aborted... */
0770     for (i=0; i<10; i++)
0771     {
0772         sql_insert();
0773     }
0774     
0775     
0776     /**************************************************************************/
0777     NDRX_LOG(log_debug, "tmrecovercl test...");
0778     /**************************************************************************/
0779     
0780     sql_delete();
0781     
0782     if (EXSUCCEED!=tpbegin(90, 0))
0783     {
0784         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0785         EXFAIL_OUT(ret);
0786     }
0787     
0788     for (i=0; i<900; i++)
0789     {
0790         if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0791         {
0792             NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0793             EXFAIL_OUT(ret);
0794         }    
0795 
0796         if (EXFAIL == tpcall("TESTSV", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0))
0797         {
0798             NDRX_LOG(log_error, "TESTERROR: TESTSV failed: %s", tpstrerror(tperrno));
0799             EXFAIL_OUT(ret);
0800         }
0801     }
0802     
0803     /* test that we have 0 records here... */
0804     if (EXSUCCEED!=(ret=(int)sql_count()))
0805     {
0806         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0807         EXFAIL_OUT(ret);
0808     }
0809     
0810     /* run recover here...
0811      * shall recover 0 transactions... as all of them are alive...
0812      */
0813     
0814     if (EXSUCCEED!=(ret=system("tmrecovercl")))
0815     {
0816         NDRX_LOG(log_error, "TESTERROR: Failed to tmrecovercl: %d", ret);
0817         EXFAIL_OUT(ret);
0818     }
0819     
0820     /* set larger timeout, as in slow machines we might get timeout here...*/
0821     if (EXSUCCEED!=tpcommit(0))
0822     {
0823         NDRX_LOG(log_error, "TESTERROR: Failed to commit: %s", tpstrerror(tperrno));
0824         EXFAIL_OUT(ret);
0825     }
0826     
0827     if (900!=(ret=(int)sql_count()))
0828     {
0829         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 900", ret);
0830         EXFAIL_OUT(ret);
0831     }
0832     
0833     /**************************************************************************/
0834     NDRX_LOG(log_debug, "tmrecovercl test (lost logs)");
0835     /**************************************************************************/
0836     
0837     sql_delete();
0838     
0839     if (EXSUCCEED!=tpbegin(90, 0))
0840     {
0841         NDRX_LOG(log_error, "TESTERROR: Failed to begin: %s", tpstrerror(tperrno));
0842         EXFAIL_OUT(ret);
0843     }
0844     
0845     for (i=0; i<900; i++)
0846     {
0847         if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&i, 0))
0848         {
0849             NDRX_LOG(log_debug, "Failed to set T_STRING_FLD[0]: %s", Bstrerror(Berror));
0850             EXFAIL_OUT(ret);
0851         }    
0852 
0853         if (EXFAIL == tpcall("TESTSV", (char *)p_ub, 0L, (char **)&p_ub, &rsplen,0))
0854         {
0855             NDRX_LOG(log_error, "TESTERROR: TESTSV failed: %s", tpstrerror(tperrno));
0856             EXFAIL_OUT(ret);
0857         }
0858     }
0859     
0860     /* test that we have 0 records here... */
0861     if (EXSUCCEED!=(ret=(int)sql_count()))
0862     {
0863         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0864         EXFAIL_OUT(ret);
0865     }
0866     
0867     if (EXSUCCEED!=(ret=system("rm -f ./RM1/*")))
0868     {
0869         NDRX_LOG(log_error, "TESTERROR: Failed to remove RM1: %d", ret);
0870         EXFAIL_OUT(ret);
0871     }
0872     
0873     if (EXSUCCEED!=(ret=system("rm -f ./RM2/*")))
0874     {
0875         NDRX_LOG(log_error, "TESTERROR: Failed to remove RM1: %d", ret);
0876         EXFAIL_OUT(ret);
0877     }
0878     
0879     /* restart tmsrv... now it does not know anything about transactions */
0880     if (EXSUCCEED!=(ret=system("xadmin stop -s tmsrv; xadmin start -s tmsrv")))
0881     {
0882         NDRX_LOG(log_error, "TESTERROR: tmsrv restart failed.: %d", ret);
0883         EXFAIL_OUT(ret);
0884     }
0885     
0886     if (EXSUCCEED!=(ret=system("tmrecovercl")))
0887     {
0888         NDRX_LOG(log_error, "TESTERROR: Failed to tmrecovercl: %d", ret);
0889         EXFAIL_OUT(ret);
0890     }
0891     
0892     /* set larger timeout, as in slow machines we might get timeout here...*/
0893     if (EXSUCCEED==tpcommit(0))
0894     {
0895         NDRX_LOG(log_error, "TESTERROR: Commit must fail!");
0896         EXFAIL_OUT(ret);
0897     }
0898     
0899     if (0!=(ret=(int)sql_count()))
0900     {
0901         NDRX_LOG(log_error, "TESTERROR: Got count: %d, expected 0", ret);
0902         EXFAIL_OUT(ret);
0903     }
0904     
0905     ret = EXSUCCEED;
0906     
0907 out:
0908     
0909     if (EXSUCCEED!=ret)
0910     {
0911         tpabort(0);
0912     }
0913 
0914     tpclose();
0915     tpterm();
0916     fprintf(stderr, "Exit with %d\n", ret);
0917 
0918     return ret;
0919 }
0920 
0921 /* vim: set ts=4 sw=4 et smartindent: */