Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief xadmin down tests
0003  *
0004  * @file atmiclt38.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 
0039 #include <atmi.h>
0040 #include <ubf.h>
0041 #include <ndebug.h>
0042 #include <test.fd.h>
0043 #include <ndrstandard.h>
0044 #include <ubfutil.h>
0045 /*---------------------------Externs------------------------------------*/
0046 /*---------------------------Macros-------------------------------------*/
0047 #define MAX_CALLS       10000
0048 /*---------------------------Enums--------------------------------------*/
0049 /*---------------------------Typedefs-----------------------------------*/
0050 /*---------------------------Globals------------------------------------*/
0051 /*---------------------------Statics------------------------------------*/
0052 int M_replies_got = 0;
0053 int M_notifs_got = 0;
0054 int M_calls_made = 0;
0055 /*---------------------------Prototypes---------------------------------*/
0056 
0057 /**
0058  * Set notification handler 
0059  * @return 
0060  */
0061 void notification_callback (char *data, long len, long flags)
0062 {
0063     UBFH *p_ub = (UBFH *)data;
0064     NDRX_LOG(log_info, "Got notification...");
0065     /* Dump UBF buffer... */
0066     ndrx_debug_dump_UBF(log_error, "notification_callback", p_ub);
0067     M_notifs_got++;
0068 }
0069 
0070 /**
0071  * Read the replies from ATMI subsystem.
0072  * @return SUCCEED/FAIL
0073  */
0074 int handle_replies(UBFH **pp_ub, int num)
0075 {
0076     int ret = EXSUCCEED;
0077     long len;
0078     int cd;
0079     int i;
0080     
0081     /* Process notifs... */
0082     if (0==num)
0083     {
0084         while (EXSUCCEED==tpgetrply(&cd, (char **)pp_ub, &len, TPGETANY | TPNOBLOCK) 
0085                 && 0!=cd)
0086         {
0087             ndrx_debug_dump_UBF(log_error, "Got reply", *pp_ub);
0088             M_replies_got++;
0089         }
0090     }
0091     else
0092     {
0093         for (i=0; i<num; i++)
0094         {
0095             if (EXSUCCEED!=tpgetrply(&cd, (char **)pp_ub, &len, TPGETANY))
0096             {
0097                     NDRX_LOG(log_error, "TESTERROR! Failed to get rply!");
0098                     EXFAIL_OUT(ret);
0099             }
0100             ndrx_debug_dump_UBF(log_error, "Got reply", *pp_ub);
0101             M_replies_got++;
0102         }
0103     }
0104     
0105 out:
0106     return ret;
0107 }
0108 
0109 /**
0110  * Do the test call to the server
0111  */
0112 int main(int argc, char** argv) 
0113 {
0114     int ret = EXSUCCEED;
0115     int i;
0116     char tmp[20];
0117     UBFH *p_ub = NULL;
0118     void (*prev_handler) (char *data, long len, long flags);
0119     
0120     if (EXSUCCEED!=tpinit(NULL))
0121     {
0122         NDRX_LOG(log_error, "TESTERROR: Failed to init!!!!");
0123         EXFAIL_OUT(ret);
0124     }
0125     
0126     if (NULL!=(prev_handler = tpsetunsol(notification_callback)))
0127     {
0128         NDRX_LOG(log_error, "TESTERRORR: Previous handler must be NULL!");
0129         EXFAIL_OUT(ret);
0130     }
0131     
0132     if (notification_callback!= tpsetunsol(notification_callback))
0133     {
0134         NDRX_LOG(log_error, "TESTERRORR: Previous handler must be "
0135                 "notification_callback()!");
0136         EXFAIL_OUT(ret);
0137     }
0138     
0139     /* Allocate some buffer */
0140     if (NULL==(p_ub = (UBFH *)tpalloc("UBF", NULL, 1024)))
0141     {
0142         NDRX_LOG(log_error, "TESTERROR: Failed to allocate test buffer!");
0143         EXFAIL_OUT(ret);
0144     }
0145     
0146     /* So we will call lots of local and remote services,
0147      * The service must send back notification.
0148      */
0149     for (i=1; i<MAX_CALLS+1; i++)
0150     {
0151         /* Let servers to provide back replies... */
0152         /* Have a fixed buffer len, so that we do not need to realloc... */
0153         
0154         snprintf(tmp, sizeof(tmp), "AA%02ld%08d", tpgetnodeid(), i);
0155         
0156 restart:
0157         if (EXSUCCEED!=Bchg(p_ub, T_STRING_FLD, 0, tmp, 0L))
0158         {
0159             NDRX_LOG(log_error, "TESTERROR: Failed to set T_STRING_FLD to [%s]: %s", 
0160                     tmp, Bstrerror(Berror));
0161             EXFAIL_OUT(ret);
0162         }
0163         
0164         /* Do Some A calls... */
0165         
0166         /* Remote service & local services */
0167         /* maybe async call, with retry? 
0168          * as we get deadlock here: atmisv38 does tpnotify -> tpbrdcstsv does send to us
0169          * but we try to send to atmisv38. Our Q gets full and we are stuck..
0170          */
0171 
0172         if (tpacall("SVC38_01", (char *)p_ub, 0L, TPNOBLOCK)<=0)
0173         {
0174             if (TPEBLOCK==tperrno || TPELIMIT==tperrno)
0175             {
0176                 NDRX_LOG(log_error, "Additional handle_replies %d", tperrno);
0177                 if (EXSUCCEED!=handle_replies(&p_ub, 0))
0178                 {
0179                     NDRX_LOG(log_error, "handle_replies() failed");
0180                     EXFAIL_OUT(ret);
0181                 }
0182                 /* also restart the value */
0183                 goto restart;
0184             }
0185             else
0186             {
0187                 NDRX_LOG(log_error, "TESTERROR: Failed to call [SVC38_01]: %s",
0188                     tpstrerror(tperrno));
0189                 EXFAIL_OUT(ret);
0190             }
0191         }
0192 
0193         M_calls_made++;
0194 
0195 restart2:
0196         /* in case of blocked receive, we shall process the messages
0197          * from the Q, thus do non block too.
0198          */
0199         if (tpacall("SVC38_02", (char *)p_ub, 0L, TPNOBLOCK)<=0)
0200         {
0201             /* try to receive something if we got limit... */
0202             if (TPELIMIT==tperrno || TPEBLOCK==tperrno)
0203             {
0204                 NDRX_LOG(log_error, "Additional handle_replies %d", tperrno);
0205                 if (EXSUCCEED!=handle_replies(&p_ub, 0))
0206                 {
0207                     NDRX_LOG(log_error, "handle_replies() failed");
0208                     EXFAIL_OUT(ret);
0209                 }
0210                 goto restart2;
0211             }
0212             else
0213             {
0214                 NDRX_LOG(log_error, "TESTERROR: Failed to call [SVC38_02]: %s",
0215                         tpstrerror(tperrno));
0216                 EXFAIL_OUT(ret);
0217             }
0218         }
0219         M_calls_made++;
0220     }
0221     
0222     i=0; /* try for 30 sec... */
0223     while (i<1000000 && (M_replies_got < M_calls_made || M_notifs_got < M_calls_made))
0224     {
0225         /* Let all replies come in... */
0226         NDRX_LOG(log_warn, "Waiting for replies...");
0227         usleep(1000); /* 0.01 sec */
0228         if (EXSUCCEED!=handle_replies(&p_ub,  0))
0229         {
0230              NDRX_LOG(log_error, "TESTERROR: handle_replies() failed");
0231              EXFAIL_OUT(ret);
0232         }
0233     
0234         i++;
0235     }
0236     
0237     /* Reply from both domains */
0238     if (M_calls_made!=M_notifs_got)
0239     {
0240         NDRX_LOG(log_error, "TESTERROR: M_notifs_got = %d, expected: %d", 
0241                 M_notifs_got, M_calls_made);
0242         EXFAIL_OUT(ret);
0243     }
0244     
0245     /* Reply from both domains */
0246     if (M_calls_made!=M_replies_got)
0247     {
0248         NDRX_LOG(log_error, "TESTERROR: M_replies_got = %d, expected: %d", 
0249                 M_replies_got, M_calls_made);
0250         EXFAIL_OUT(ret);
0251     }
0252     
0253 out:
0254 
0255     if (NULL!=p_ub)
0256     {
0257         tpfree((char *)p_ub);
0258     }
0259 
0260     return ret;
0261     
0262 }
0263 
0264 
0265 /* vim: set ts=4 sw=4 et smartindent: */