Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Standard header tests
0003  *
0004  * @file test_nstd_standard.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 #ifndef _GNU_SOURCE
0036 #define _GNU_SOURCE
0037 #endif
0038 
0039 #include <stdio.h>
0040 #include <stdlib.h>
0041 #include <cgreen/cgreen.h>
0042 #include <ubf.h>
0043 #include <ndrstandard.h>
0044 #include <string.h>
0045 #include <ndebug.h>
0046 #include <exbase64.h>
0047 #include "test.fd.h"
0048 #include "ubfunit1.h"
0049 #include "xatmi.h"
0050 #include <utlist.h>
0051 #include <nstdutil.h>
0052 /**
0053  * Test NDRX_STRCPY_S macro
0054  */
0055 Ensure(test_nstd_ndrx_strcpy_s)
0056 {
0057     char tmp[16] = {EXEOS};
0058     
0059     NDRX_STRCAT_S(tmp, sizeof(tmp), "HELLO");
0060     assert_string_equal(tmp, "HELLO");
0061     
0062     NDRX_STRCAT_S(tmp, sizeof(tmp), " WORLD");
0063     assert_string_equal(tmp, "HELLO WORLD");
0064     
0065     NDRX_STRCAT_S(tmp, sizeof(tmp), " THIS");
0066 
0067     /* on C11 / solaris 11.4 this might be stripped to empty */
0068     if (EXEOS!=tmp[0])
0069     {
0070         assert_string_equal(tmp, "HELLO WORLD THI");
0071     }
0072 }
0073 
0074 /**
0075  * Test NDRX_ASPRINTF
0076  */
0077 Ensure(test_nstd_ndrx_asprintf)
0078 {
0079     char *p = (char *)123;
0080     long len;
0081     
0082     NDRX_ASPRINTF(&p, &len, "Hello %d %s", 1, "world");
0083     
0084     assert_not_equal(p, NULL);
0085     assert_not_equal(p, 123);
0086     assert_equal(len, 13);
0087     
0088     assert_string_equal(p, "Hello 1 world");
0089     
0090     NDRX_FREE(p);
0091     
0092 }
0093 
0094 /**
0095  * Test split add
0096  */
0097 Ensure(test_ndrx_string_list_splitadd)
0098 {
0099     string_list_t *list = NULL;
0100     string_list_t *el = NULL;
0101     int i = 0;
0102     
0103     assert_equal(ndrx_string_list_splitadd(&list, "\tHELLO: WORLD:22", ":"), EXSUCCEED);
0104     
0105     /* Check the entries in list: */
0106     LL_FOREACH(list, el)
0107     {
0108         i++;
0109         
0110         switch (i)
0111         {
0112             case 1:
0113                 assert_equal(el->qname, "HELLO");
0114                 break;
0115             case 2:
0116                 assert_equal(el->qname, "WORLD");
0117                 break;
0118             case 3:
0119                 assert_equal(el->qname, "22");
0120                 break;
0121             default:
0122                 /* Too many entries! */
0123                 NDRX_LOG(log_error, "Too many entries! [%s]", el->qname);
0124                 assert_equal(EXFALSE, EXTRUE);
0125                 break;
0126         }
0127     }
0128     
0129     ndrx_string_list_free(list);
0130 }
0131 
0132 
0133 /*
0134  * Ensure(test_nstd_ndrx_strcpy_s)
0135  * - NDRX_STRCPY_SAFE
0136  * - NDRX_STRCPY_SAFE_DST
0137  * - NDRX_STRNCPY
0138  * - NDRX_STRNCPY_EOS
0139  * - NDRX_STRNCPY_SRC
0140  * - NDRX_STRCPY_LAST_SAFE
0141  */
0142 
0143 /**
0144  * Copy to test dest string with using target size as sizeof(DST)
0145  */
0146 Ensure(test_nstd_NDRX_STRCPY_SAFE)
0147 {
0148     char dst[6];
0149     
0150     /* check normal copy */
0151     memset(dst, 1, sizeof(dst));
0152     NDRX_STRCPY_SAFE(dst, "ABCD");
0153     assert_string_equal(dst, "ABCD");
0154     
0155     /* check full copy */
0156     memset(dst, 1, sizeof(dst));
0157     NDRX_STRCPY_SAFE(dst, "ABCDE");
0158     assert_string_equal(dst, "ABCDE");
0159     
0160     /* check truncate copy */
0161     memset(dst, 1, sizeof(dst));
0162     NDRX_STRCPY_SAFE(dst, "HELLO WORLD");
0163     assert_string_equal(dst, "HELLO");
0164     
0165 }
0166 
0167 /**
0168  * The dest buffer space is given then parameter..
0169  * used for pointer buffers
0170  */
0171 Ensure(test_nstd_NDRX_STRCPY_SAFE_DST)
0172 {
0173     char dst[6];
0174     char *p = dst;
0175     
0176     /* check normal copy */
0177     memset(p, 1, sizeof(dst));
0178     NDRX_STRCPY_SAFE_DST(p, "ABCD", 6);
0179     assert_string_equal(p, "ABCD");
0180     assert_string_equal(dst, "ABCD");
0181     
0182     /* check full copy */
0183     memset(dst, 1, sizeof(dst));
0184     NDRX_STRCPY_SAFE_DST(dst, "ABCDE", 6);
0185     assert_string_equal(p, "ABCDE");
0186     assert_string_equal(dst, "ABCDE");
0187     
0188     /* check truncate copy */
0189     memset(dst, 1, sizeof(dst));
0190     NDRX_STRCPY_SAFE_DST(dst, "HELLO WORLD", 6);
0191     assert_string_equal(p, "HELLO");
0192     assert_string_equal(dst, "HELLO");
0193 }
0194 
0195 /**
0196  * This is same as strncpy, but instead it does not fill the non-copied
0197  * left overs with zeros..
0198  * Generally this is not safe, but faster version.
0199  */
0200 Ensure(test_nstd_NDRX_STRNCPY)
0201 {
0202     char dst[7];
0203     
0204     /* zero is copied from src.. */
0205     memset(dst, 1, sizeof(dst));
0206     NDRX_STRNCPY(dst, "ABCD", 6);
0207     assert_equal(dst[0], 'A');
0208     assert_equal(dst[1], 'B');
0209     assert_equal(dst[2], 'C');
0210     assert_equal(dst[3], 'D');
0211     assert_equal(dst[4], 0);
0212     assert_equal(dst[5], 1);
0213     assert_equal(dst[6], 1);
0214     
0215     /* full copied, no zero space */
0216     memset(dst, 1, sizeof(dst));
0217     NDRX_STRNCPY(dst, "ABCDEF", 6);
0218     assert_equal(dst[0], 'A');
0219     assert_equal(dst[1], 'B');
0220     assert_equal(dst[2], 'C');
0221     assert_equal(dst[3], 'D');
0222     assert_equal(dst[4], 'E');
0223     assert_equal(dst[5], 'F');
0224     assert_equal(dst[6], 1);
0225     
0226     /* check truncate copy */
0227     memset(dst, 1, sizeof(dst));
0228     NDRX_STRNCPY(dst, "ABCDEF", 3);
0229     assert_equal(dst[0], 'A');
0230     assert_equal(dst[1], 'B');
0231     assert_equal(dst[2], 'C');
0232     assert_equal(dst[3], 1);
0233     assert_equal(dst[4], 1);
0234     assert_equal(dst[5], 1);
0235     assert_equal(dst[6], 1);
0236 }
0237 
0238 /**
0239  * This is same as NDRX_STRNCPY, but ensure that string is terminated.
0240  * Thus we give dest buffer size + how much to copy.
0241  */
0242 Ensure(test_nstd_NDRX_STRNCPY_EOS)
0243 {
0244     char dst[7];
0245     
0246     /* zero is copied from src.. */
0247     memset(dst, 1, sizeof(dst));
0248     NDRX_STRNCPY_EOS(dst, "ABCD", 4, 6);
0249     assert_equal(dst[0], 'A');
0250     assert_equal(dst[1], 'B');
0251     assert_equal(dst[2], 'C');
0252     assert_equal(dst[3], 'D');
0253     assert_equal(dst[4], 0);
0254     assert_equal(dst[5], 1);
0255     assert_equal(dst[6], 1);
0256     
0257     /* try copy som more */
0258     memset(dst, 1, sizeof(dst));
0259     NDRX_STRNCPY_EOS(dst, "ABCDE", 6, 6);
0260     assert_equal(dst[0], 'A');
0261     assert_equal(dst[1], 'B');
0262     assert_equal(dst[2], 'C');
0263     assert_equal(dst[3], 'D');
0264     assert_equal(dst[4], 'E');
0265     assert_equal(dst[5], 0);
0266     assert_equal(dst[6], 1);
0267     
0268     memset(dst, 1, sizeof(dst));
0269     NDRX_STRNCPY_EOS(dst, "ABCDEG", 6, 4);
0270     assert_equal(dst[0], 'A');
0271     assert_equal(dst[1], 'B');
0272     assert_equal(dst[2], 'C');
0273     assert_equal(dst[3], 0);
0274     assert_equal(dst[4], 1);
0275     assert_equal(dst[5], 1);
0276     assert_equal(dst[6], 1);
0277     
0278     /* just full */
0279     memset(dst, 1, sizeof(dst));
0280     NDRX_STRNCPY_EOS(dst, "ABCDEG", 3, 4);
0281     assert_equal(dst[0], 'A');
0282     assert_equal(dst[1], 'B');
0283     assert_equal(dst[2], 'C');
0284     assert_equal(dst[3], 0);
0285     assert_equal(dst[4], 1);
0286     assert_equal(dst[5], 1);
0287     assert_equal(dst[6], 1); 
0288 }
0289 
0290 /**
0291  * Do not check the dest buffer, but check source indead.
0292  * This will ensure that strlen does not go into unknown memories
0293  */
0294 Ensure(test_nstd_NDRX_STRNCPY_SRC)
0295 {
0296     char src[6]={1, 2, 3, 4, 5, 6};
0297     char dst[6]={6, 7, 8, 9, 10, 11};
0298     char result[6]={1, 2, 3, 9, 10, 11};
0299     
0300     NDRX_STRNCPY_SRC(dst, src, 3);
0301     assert_equal(memcmp(dst, result, 6), 0);
0302 }
0303 
0304 /**
0305  * Copy last bytes from dest to source.
0306  * This is SAFE, thus target buffer must be static sized.
0307  * EOS is placed in result string.
0308  */
0309 Ensure(test_nstd_NDRX_STRCPY_LAST_SAFE)
0310 {
0311     char dst[7];
0312     
0313     memset(dst, 1, sizeof(dst));
0314     NDRX_STRCPY_LAST_SAFE(dst, "ABCFFFFFABC", 3);
0315     assert_string_equal(dst, "ABC");
0316     
0317     /* last 10, trunc to 6 for EOS */
0318     memset(dst, 1, sizeof(dst));
0319     NDRX_STRCPY_LAST_SAFE(dst, "ABCFFFFFABC", 10);
0320     assert_string_equal(dst, "BCFFFF");
0321     
0322     /* full size */
0323     memset(dst, 1, sizeof(dst));
0324     NDRX_STRCPY_LAST_SAFE(dst, "ABCDEF", 6);
0325     assert_string_equal(dst, "ABCDEF");
0326 }
0327 
0328 
0329 exprivate void chk_token(char *str, char **tokens, int num_tokens)
0330 {
0331     char *tok;
0332     int i=0;
0333     
0334     UBF_LOG(log_debug, "Splitting [%s]", str);
0335     for (tok = ndrx_strtokblk ( str, " \t\n", "'\""), i=0; NULL!=tok; tok = ndrx_strtokblk (NULL, " \t\n", "'\""), i++)
0336     {
0337         assert_string_equal(tok, tokens[i]);
0338     }
0339     assert_equal(i, num_tokens);
0340 }
0341 
0342 /**
0343  * Check the ndrx_strtokblk engine
0344  */
0345 Ensure(test_nstd_strtokblk)
0346 {
0347     do {
0348     char test1[]="HELLO WORLD";
0349     chk_token(test1, (char*[]){ "HELLO", "WORLD"}, 2);
0350     }while(0);
0351     
0352     do {
0353         char test1[]="HELLO' WORLD '1 OK";
0354         chk_token(test1, (char*[]){ "HELLO WORLD 1", "OK"}, 2);
0355     }while(0);
0356     
0357     
0358     do {
0359         char test1[]="-e\t\"HELLO";
0360         chk_token(test1, (char*[]){ "-e", "HELLO"}, 2);
0361     }while(0);
0362     
0363     do {
0364         char test1[]="\"THIS IS SIGNER\\\\\\\"QUOTE 'RIGHT?'\"";
0365         chk_token(test1, (char*[]){"THIS IS SIGNER\\\"QUOTE 'RIGHT?'"}, 1);
0366     }while(0);
0367     
0368     do {
0369         char test1[]="-e\\' -z\\\"";
0370         chk_token(test1, (char*[]){"-e'", "-z\""}, 2);
0371     }while(0);
0372     
0373     do {
0374         char test1[]="test string '\t inside double\"OK \"?'";
0375         chk_token(test1, (char*[]){"test", "string", "\t inside double\"OK \"?"}, 3);
0376     }while(0);
0377     
0378     do {
0379         char test1[]="\\X \"\\'\" ";
0380         chk_token(test1, (char*[]){"\\X", "\\'"}, 2);
0381     }while(0);
0382     
0383     do {
0384         char test1[]="\"\\'";
0385         chk_token(test1, (char*[]){"\\'"}, 1);
0386     }while(0);
0387     
0388     
0389     do {
0390         char test1[]="'\\\"'";
0391         chk_token(test1, (char*[]){"\\\""}, 1);
0392     }while(0);
0393     
0394     
0395     do {
0396         char test1[]="arg1  arg2";
0397         chk_token(test1, (char*[]){"arg1", "arg2"}, 2);
0398     }while(0);
0399     
0400     do {
0401         char test1[]="some \\\\ arg3";
0402         chk_token(test1, (char*[]){"some", "\\", "arg3"}, 3);
0403     }while(0);
0404     
0405     /* nothing to escape... */
0406     do {
0407         char test1[]="some \\ arg4";
0408         chk_token(test1, (char*[]){"some", "arg4"}, 2);
0409     }while(0);
0410     
0411     
0412     do {
0413         char test1[]="some '\\\\' arg";
0414         chk_token(test1, (char*[]){"some", "\\", "arg"}, 3);
0415     }while(0);
0416     
0417     
0418     do {
0419         char test1[]="    ";
0420         chk_token(test1, NULL, 0);
0421     }while(0);
0422 
0423     do {
0424         char test1[]="HELLO ''";
0425         chk_token(test1, (char*[]){"HELLO", ""}, 2);
0426     }while(0);
0427     
0428 
0429     do {
0430         char test1[]="''";
0431         chk_token(test1, (char*[]){""}, 1);
0432     }while(0);
0433     
0434     
0435     do {
0436         char test1[]="''a''";
0437         chk_token(test1, (char*[]){"a"}, 1);
0438     }while(0);
0439     
0440 }
0441 
0442 /**
0443  * Check format string escaping function
0444  */
0445 Ensure(test_nstd_str_fmtesc)
0446 {
0447     char buf[16+1];
0448     
0449     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), ""), "");
0450     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "%"), "%%");
0451     
0452     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "%ABC"), "%%ABC");
0453     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "ABC%"), "ABC%%");
0454     
0455     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "0123456789123456"), "0123456789123456");
0456     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "012345678912345%"), "012345678912345");
0457     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "%123456789123456"), "%%12345678912345");
0458     assert_string_equal(ndrx_str_fmtesc(buf, sizeof(buf), "%123456789123%%"), "%%123456789123%%");
0459     
0460 }
0461 
0462 /**
0463  * Check standard settings string parser
0464  */
0465 Ensure(test_nstd_stdcfgstr)
0466 {
0467     ndrx_stdcfgstr_t *parsed;
0468     ndrx_stdcfgstr_t *cur;
0469     
0470     assert_equal(ndrx_stdcfgstr_parse("HELLO,WORLD,,,,  THIS=VALUE", &parsed), EXSUCCEED);
0471     
0472     cur = parsed;
0473     
0474     assert_string_equal(cur->key, "HELLO");
0475     assert_equal(cur->value, NULL);
0476     
0477     cur=cur->next;
0478     
0479     assert_string_equal(cur->key, "WORLD");
0480     assert_equal(cur->value, NULL);
0481 
0482     cur=cur->next;
0483     
0484     assert_string_equal(cur->key, "THIS");
0485     assert_string_equal(cur->value, "VALUE");
0486 
0487     cur=cur->next;
0488     assert_equal(cur, NULL);
0489     
0490     ndrx_stdcfgstr_free(parsed);
0491     
0492     
0493     assert_equal(ndrx_stdcfgstr_parse(",,,\nIS\tANOTHER=SETTING", &parsed), EXSUCCEED);
0494     
0495     cur = parsed;
0496     
0497     assert_string_equal(cur->key, "IS");
0498     assert_equal(cur->value, NULL);
0499     
0500     cur=cur->next;
0501     
0502     assert_string_equal(cur->key, "ANOTHER");
0503     assert_string_equal(cur->value, "SETTING");
0504     
0505     cur=cur->next;
0506     assert_equal(cur, NULL);
0507     
0508     ndrx_stdcfgstr_free(parsed);
0509     
0510     
0511     assert_equal(ndrx_stdcfgstr_parse("X='=HELLO WORLD INSIDE\"' Y=\"HELO\\\" EHLO\" ndrx=5", &parsed), EXSUCCEED);
0512     
0513     cur = parsed;
0514     
0515     assert_string_equal(cur->key, "X");
0516     assert_string_equal(cur->value, "=HELLO WORLD INSIDE\"");
0517     
0518     cur=cur->next;
0519     
0520     assert_string_equal(cur->key, "Y");
0521     assert_string_equal(cur->value, "HELO\" EHLO");
0522     
0523     cur=cur->next;
0524     
0525     assert_string_equal(cur->key, "ndrx");
0526     assert_string_equal(cur->value, "5");
0527     
0528     cur=cur->next;
0529     assert_equal(cur, NULL);
0530     
0531     ndrx_stdcfgstr_free(parsed);
0532 }
0533 
0534 /**
0535  * Standard header tests
0536  * @return
0537  */
0538 TestSuite *ubf_nstd_standard(void)
0539 {
0540     TestSuite *suite = create_test_suite();
0541 
0542     add_test(suite, test_nstd_ndrx_strcpy_s);
0543     add_test(suite, test_nstd_ndrx_asprintf);
0544     add_test(suite, test_nstd_NDRX_STRCPY_SAFE);
0545     add_test(suite, test_nstd_NDRX_STRCPY_SAFE_DST);
0546     add_test(suite, test_nstd_NDRX_STRNCPY);
0547     add_test(suite, test_nstd_NDRX_STRNCPY_EOS);
0548     add_test(suite, test_nstd_NDRX_STRNCPY_SRC);
0549     add_test(suite, test_nstd_NDRX_STRCPY_LAST_SAFE);
0550     add_test(suite, test_nstd_strtokblk);
0551     add_test(suite, test_nstd_str_fmtesc);
0552     add_test(suite, test_nstd_stdcfgstr);
0553     
0554     return suite;
0555 }
0556 /* vim: set ts=4 sw=4 et smartindent: */