Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Cluster Identifier tests
0003  *
0004  * @file test_nstd_cid.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 
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <cgreen/cgreen.h>
0038 #include <ndrstandard.h>
0039 #include <exhash.h>
0040 #include <nstdutil.h>
0041 #include <thlock.h>
0042 #include <ndebug.h>
0043 #include <sys/time.h>
0044 /*---------------------------Externs------------------------------------*/
0045 /*---------------------------Macros-------------------------------------*/
0046 /*---------------------------Enums--------------------------------------*/
0047 /*---------------------------Typedefs-----------------------------------*/
0048 
0049 typedef struct
0050 {
0051     exuuid_t cid;
0052     EX_hash_handle hh;         /* makes this structure hashable */    
0053 } cid_hash_t;
0054 
0055 
0056 /*---------------------------Globals------------------------------------*/
0057 /*---------------------------Statics------------------------------------*/
0058 exprivate cid_hash_t *M_hash = NULL;
0059 exprivate MUTEX_LOCKDECL(M_lock);
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 /**
0063  * Return true if found
0064  */
0065 exprivate cid_hash_t * do_lookup(exuuid_t cid)
0066 {
0067     cid_hash_t *ent=NULL;
0068     
0069     MUTEX_LOCK_V(M_lock);
0070     
0071     EXHASH_FIND(hh, M_hash, cid, sizeof(exuuid_t), ent);
0072 
0073     
0074     MUTEX_UNLOCK_V(M_lock);
0075     
0076     return ent;
0077 }
0078 
0079 /**
0080  * Add entry
0081  * @param 0
0082  */
0083 exprivate void do_add(exuuid_t cid)
0084 {
0085     cid_hash_t *add=NDRX_MALLOC(sizeof(cid_hash_t));
0086     if (NULL==add)
0087     {
0088         abort();
0089     }
0090     memcpy(add->cid, cid, sizeof(exuuid_t));
0091     MUTEX_LOCK_V(M_lock);
0092     EXHASH_ADD(hh, M_hash, cid, sizeof(exuuid_t), add);
0093     MUTEX_UNLOCK_V(M_lock);
0094 }
0095 
0096 /**
0097  * Dynamic work with some blocks
0098  */
0099 static void * thread_start(void *arg)
0100 {
0101     int i, j;
0102     exuuid_t cid;
0103             
0104     /* for 1 M CIDs... ever 1x sec.. */
0105     for (i=0; i<2; i++)
0106     {
0107         for (j=0; j<100000; j++)
0108         {
0109             ndrx_cid_generate(129, cid);
0110             
0111             /* lookup */
0112             if (NULL!=do_lookup(cid))
0113             {
0114                 fail_test("Geneate 0 exists!");
0115                 break;
0116             }
0117             /* add */
0118             do_add(cid);
0119         }
0120         sleep(1);
0121     }
0122 
0123     return NULL;
0124 }
0125 
0126 /**
0127  * Check that 0 is unique accorss the threads
0128  */
0129 Ensure(test_nstd_cid_unq)
0130 {
0131     pthread_t th1;
0132     pthread_t th2;
0133     pthread_t th3;
0134     pthread_t th4;
0135  
0136     int ret;
0137     
0138     ret=pthread_create(&th1, NULL, thread_start, NULL);
0139     assert_equal(ret, EXSUCCEED);
0140     
0141     ret=pthread_create(&th2, NULL, thread_start, NULL);
0142     assert_equal(ret, EXSUCCEED);
0143     
0144     ret=pthread_create(&th3, NULL, thread_start, NULL);
0145     assert_equal(ret, EXSUCCEED);
0146     
0147     ret=pthread_create(&th4, NULL, thread_start, NULL);
0148     assert_equal(ret, EXSUCCEED);
0149     
0150     pthread_join(th1, NULL);
0151     pthread_join(th2, NULL);
0152     pthread_join(th3, NULL);
0153     pthread_join(th4, NULL);
0154 }
0155 
0156 /**
0157  * Analyze the CID format, shall match the desired one.
0158  */
0159 Ensure(test_nstd_cid_fmt)
0160 {
0161     exuuid_t cid, cid2;
0162     unsigned seq1=0, seq2=0;
0163     pid_t pid;
0164     struct timeval tv, tv2, tvt;
0165     int i, got_diff;
0166 
0167     memset(cid, 0, sizeof(exuuid_t));
0168     memset(cid2, 0, sizeof(exuuid_t));
0169   
0170     ndrx_cid_generate(129, cid);
0171     sleep(2);
0172     ndrx_cid_generate(4, cid2);
0173     
0174     /* node id: */
0175     assert_equal((unsigned char)129, cid[0]);
0176     assert_equal((unsigned char)4, cid2[0]);
0177     
0178     pid=getpid();
0179     
0180     assert_equal( (pid>>24 & 0xff), cid[1]);
0181     assert_equal( (pid>>16 & 0xff), cid[2]);
0182     assert_equal( (pid>>8 & 0xff), cid[3]);
0183     assert_equal( (pid & 0xff), cid[4]);
0184         
0185 /*
0186     seq1 |= cid[5];
0187     seq1<<=8;
0188 */
0189     seq1 |= cid[6];
0190     seq1<<=8;
0191     seq1 |= cid[7];
0192     seq1<<=8;
0193     seq1 |= cid[8];
0194     
0195 /*
0196     seq2 |= cid2[5];
0197     seq2<<=8;
0198 */
0199     seq2 |= cid2[6];
0200     seq2<<=8;
0201     seq2 |= cid2[7];
0202     seq2<<=8;
0203     seq2 |= cid2[8];
0204     
0205     /* sequence counters: */
0206     assert_not_equal(seq1, seq2);
0207     
0208     if ((seq1+1)!=seq2 )
0209     {
0210         fail_test("Sequence not incremented!");
0211     }
0212     
0213     gettimeofday(&tvt, 0);
0214     
0215     memset(&tv, 0, sizeof(tv));
0216     memset(&tv2, 0, sizeof(tv2));
0217     
0218     tv.tv_sec |= (cid[9] & 0x01);
0219     tv.tv_sec<<=8;
0220     tv.tv_sec |= cid[10];
0221     tv.tv_sec<<=8;
0222     tv.tv_sec |= cid[11];
0223     tv.tv_sec<<=8;
0224     tv.tv_sec |= cid[12];
0225     tv.tv_sec<<=8;
0226     tv.tv_sec |= cid[13];
0227     
0228     /* strip off leading usec: */
0229     tv2.tv_sec |= (cid2[9] & 0x01);
0230     tv2.tv_sec<<=8;
0231     tv2.tv_sec |= cid2[10];
0232     tv2.tv_sec<<=8;
0233     tv2.tv_sec |= cid2[11];
0234     tv2.tv_sec<<=8;
0235     tv2.tv_sec |= cid2[12];
0236     tv2.tv_sec<<=8;
0237     tv2.tv_sec |= cid2[13];
0238     
0239     assert_not_equal(tv.tv_sec, tv2.tv_sec);
0240     
0241     if (tv2.tv_sec - tv.tv_sec > 10)
0242     {
0243         fail_test("Time difference too large");
0244     }
0245     
0246     if (labs(tv.tv_sec - tvt.tv_sec) > 10)
0247     {
0248         UBF_LOG(log_error, "Time difference too large (from clock): %ld vs %ld",
0249                 (long)tv.tv_sec, (long)tvt.tv_sec);
0250         fail_test("Time difference too large (from clock)");
0251     }
0252     
0253     got_diff=EXFALSE;
0254     for (i=0; i<1000; i++)
0255     {
0256         ndrx_cid_generate(129, cid);
0257         ndrx_cid_generate(4, cid2);
0258         
0259         if (0!=memcmp(cid+14, cid2+14, 2))
0260         {
0261             got_diff=EXTRUE;
0262         }
0263     }
0264     
0265     assert_equal(got_diff, EXTRUE);
0266     
0267 }
0268 
0269 /**
0270  * Standard library tests
0271  * @return
0272  */
0273 TestSuite *ubf_nstd_cid(void)
0274 {
0275     TestSuite *suite = create_test_suite();
0276 
0277     add_test(suite, test_nstd_cid_unq);
0278     add_test(suite, test_nstd_cid_fmt);
0279     
0280     return suite;
0281 }
0282 /* vim: set ts=4 sw=4 et smartindent: */