206 #include "../../utilities/utilities.h"
207 #include "../../json/json.h"
214 static char* cpMakeFileName(
char* cpBuffer,
const char* cpBase,
const char* cpDivider,
const char* cpName){
215 strcpy(cpBuffer, cpBase);
216 strcat(cpBuffer, cpDivider);
217 strcat(cpBuffer, cpName);
221 static char s_caBuf[2*PATH_MAX];
222 static char s_caBufTests[4*PATH_MAX];
224 static char* s_cpDescription =
225 "Illustrate parsing and time tests for SIP messages.";
227 static char* s_cppCases[] = {
228 "Display application information.",
229 "Build the JSON composite file of all SIP torture test messages.",
230 "Parse and trace all valid SIP messages, with and without UDTs..",
231 "Parse and trace all invalid SIP messages, with and without UDTs..",
232 "Parse and trace all semantically invalid SIP messages, with and without UDTs..",
233 "Parse all SIP messages and measure the times, with and without UDTs.",
234 "Parse all SIP messages and display the node-hit statistics, with and without UDTs.",
236 static long int s_iCaseCount = (
long int)(
sizeof(s_cppCases) /
sizeof(s_cppCases[0]));
238 static int iHelp(
void){
241 printf(
"description: %s\n", s_cpDescription);
242 printf(
" usage: ex-api arg\n");
243 printf(
" arg = n, 1 <= n <= %ld\n", s_iCaseCount);
244 printf(
" execute case number n\n");
245 printf(
" arg = anthing else\n");
246 printf(
" print this help screen\n");
248 printf(
" NOTE: Case 2 must be run before any of the other cases.\n");
249 printf(
" It constructs a JSON file of tests that is used by all other cases.\n");
251 for(; i < s_iCaseCount; i++){
252 printf(
"case %ld %s\n", (i + 1), s_cppCases[i]);
300 static char caBuf[PATH_MAX];
301 sCtx.
cpOutObject = cpMakeFileName(caBuf, SOURCE_DIR,
"/../output/",
"sip-tests.json");
313 static void vMakeList(
json_context* spCtx,
const char* cpDirName){
316 struct dirent* spEnt;
317 char* cpDat =
".dat";
319 aint uiChars, uiIndex, uiCount;
322 DIR* spDir = opendir(cpDirName);
325 snprintf(caBuf,
sizeof(caBuf),
"can't open directory: %s", cpDirName);
328 printf(
"directory name: %s\n", cpDirName);
330 while((spEnt = readdir(spDir)) != NULL){
331 if(spEnt->d_type == DT_REG){
332 cpExt = strstr(spEnt->d_name, cpDat);
334 uiChars = (
aint)(cpExt - &spEnt->d_name[0]);
341 printf(
"%d: file name found: %s\n", (
int)uiCount, (
char*)vpName);
356 static aint uiMakeObject(
json_context* spCtx,
void* vpB,
const char* cpDirName){
357 aint ui, uii, uiCount, uiObjRoot, uiObjTest;
358 aint uiKeyName, uiKeyDesc, uiKeyData;
359 char caFileName[PATH_MAX];
360 char* cpFile = caFileName;
361 char* cpDat =
".dat";
362 char* cpTxt =
".txt";
373 vMakeList(spCtx, cpDirName);
384 for(ui = 0; ui < uiCount; ui++){
389 cpName = &cpNames[uipIndexes[ui]];
393 strcpy(cpFile, cpDirName);
394 strcat(cpFile, cpName);
395 strcat(cpFile, cpTxt);
402 uiInLen = (uint32_t)
uiVecLen(vpVec);
406 for(uii = 0; uii < uiInLen; uii++){
407 uipIn32[uii] = (uint32_t)ucpIn8[uii];
412 strcpy(cpFile, cpDirName);
413 strcat(cpFile, cpName);
414 strcat(cpFile, cpDat);
420 uiInLen = (uint32_t)
uiVecLen(vpVec);
424 for(uii = 0; uii < uiInLen; uii++){
425 uipIn32[uii] = (uint32_t)ucpIn8[uii];
435 static int iBuilder() {
436 int iReturn = EXIT_SUCCESS;
437 static void* vpMem = NULL;
438 static void* vpJson = NULL;
439 static void* vpB = NULL;
451 "This function will read the text and data SIP torture test files and\n"
452 "wrap them all into a single JSON file for later use by other example cases.\n";
453 printf(
"\n%s", cpHeader);
456 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
457 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
461 sCtx = sSetup(&e, vpMem);
488 printf(
"JSON file created: %s\n", sCtx.
cpOutObject);
493 iReturn = EXIT_FAILURE;
511 #define SECTION_VALID 0
512 #define SECTION_INVALID 1
513 #define SECTION_SEMANTICS 2
524 static char s_cZero = 0;
534 void* vpItRoot, *vpItSection, *vpItTests, *vpItContent;
535 json_value* spValue, *spTest;
550 XTHROW(spEx,
"expected key not found");
561 spPhrase = spTest->spKey;
563 for(ui = 0; ui < spPhrase->
uiLength; ui++){
566 XTHROW(spEx,
"test names must be ASCII characters only");
574 printf(
"\n%2d: test name: %s\n", (
int)spSection->
uiCount, cpTest);
581 spPhrase = spValue->spString;
584 for(ui = 0; ui < spPhrase->
uiLength; ui++){
587 XTHROW(spEx,
"test descriptions must be ASCII characters only");
595 printf(
"\n%2d test description: %s\n", (
int)spSection->
uiCount, cpTest);
600 spPhrase = spValue->spString;
606 for(ui = 0; ui < spPhrase->
uiLength; ui++){
609 XTHROW(spEx,
"test messages must be octets only");
620 printf(
"number of msgs: %d\n", (
int)spSection->
uiCount);
630 char caTraceName[1024];
632 char* cpTraceConfig =
"trace-config.txt";
634 void* vpParser = NULL;
641 cpTraceConfig = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/", cpTraceConfig);
644 printf(
"\nParse the Messages without UDTs\n");
648 spOffset = spOffsetBeg;
649 for(ui = 0; ui < spSection->
uiCount; ui++){
651 snprintf(caTraceName,
sizeof(caTraceName),
"%s-%d-%s.out", cpPrefix, (
int)(ui + 1), cpTestName);
658 printf(
"%2d: test name: %s: success\n", (
int)(ui + 1), cpTestName);
660 printf(
"%2d: test name: %s: failure\n", (
int)(ui + 1), cpTestName);
667 printf(
"\nParse the Messages with UDTs\n");
673 spOffset = spOffsetBeg;
674 for(ui = 0; ui < spSection->
uiCount; ui++){
676 snprintf(caTraceName,
sizeof(caTraceName),
"%s-udt-%d-%s.out", cpPrefix, (
int)(ui + 1), cpTestName);
683 printf(
"%2d: test name: %s: success\n", (
int)(ui + 1), cpTestName);
685 printf(
"%2d: test name: %s: failure\n", (
int)(ui + 1), cpTestName);
693 static int iValid() {
694 int iReturn = EXIT_SUCCESS;
695 static void* vpMem = NULL;
696 static void* vpJson = NULL;
698 const char* cpOutPrefix;
708 "This function will read the SIP torture test valid messages and parse them,\n"
709 "with and without UDTs, displaying the test name and parsing result.\n"
710 "The parse is traced to the ../output folder.\n"
711 "To test without PPPTs, compile with APG_NO_PPPT defined.\n"
712 "To test with PPPTs, leave APG_NO_PPPT undefined.\n";
713 printf(
"\n%s", cpHeader);
716 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
717 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
723 vGetMsgs(vpMem, &sSection,
APG_TRUE);
726 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"valid-trace");
728 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"valid-trace-pppt");
730 vParseTheMsgs(&e, &sSection, cpOutPrefix);
735 iReturn = EXIT_FAILURE;
744 static int iInvalid() {
745 int iReturn = EXIT_SUCCESS;
746 static void* vpMem = NULL;
747 static void* vpJson = NULL;
749 const char* cpOutPrefix;
759 "This function will read the SIP torture test invalid messages and parse them,\n"
760 "with and without UDTs, displaying the test name and parsing result.\n"
761 "The parse is traced to the ../output folder.\n"
762 "To test without PPPTs, compile with APG_NO_PPPT defined.\n"
763 "To test with PPPTs, leave APG_NO_PPPT undefined.\n";
764 printf(
"\n%s", cpHeader);
767 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
768 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
774 vGetMsgs(vpMem, &sSection,
APG_TRUE);
777 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"invalid-trace");
779 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"invalid-trace-pppt");
781 vParseTheMsgs(&e, &sSection, cpOutPrefix);
786 iReturn = EXIT_FAILURE;
795 static int iSemantics() {
796 int iReturn = EXIT_SUCCESS;
797 static void* vpMem = NULL;
798 static void* vpJson = NULL;
800 const char* cpOutPrefix;
810 "This function will read the SIP torture test semantics messages and parse them,\n"
811 "with and without UDTs, displaying the test name and parsing result.\n"
812 "The parse is traced to the ../output folder.\n"
813 "To test without PPPTs, compile with APG_NO_PPPT defined.\n"
814 "To test with PPPTs, leave APG_NO_PPPT undefined.\n"
815 "Note that all of these tests are syntactically correct and parse successfully.\n"
816 "Since the errors are in the semantics no attempt at critiquing them is done.\n";
817 printf(
"\n%s", cpHeader);
820 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
821 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
827 vGetMsgs(vpMem, &sSection,
APG_TRUE);
829 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"semantic-trace");
831 cpOutPrefix = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"semantic-trace-pppt");
834 vParseTheMsgs(&e, &sSection, cpOutPrefix);
839 iReturn = EXIT_FAILURE;
855 int iReturn = EXIT_SUCCESS;
856 static void* vpMem = NULL;
857 static void* vpVecConfig = NULL;
858 static void* vpJson = NULL;
859 static void* vpParser = NULL;
860 static FILE* spFp = NULL;
861 static FILE* spFpUdt = NULL;
862 const char* cpOut, *cpOutUdt;
865 aint ui, uj, uiTests;
866 clock_t tStartTime, tEndTime;
867 double dMSec, dMsgsPerMSec;
868 luint uiMsgs, uiCharCount, uiMsgCount;
880 "This function will read all the SIP torture tests and parse them all multiple times.\n"
881 "Timing results will be collected and written to the ../output folder\n"
882 "To test without PPPTs, compile with APG_NO_PPPT defined.\n"
883 "To test with PPPTs, leave APG_NO_PPPT undefined.\n";
884 printf(
"\n%s", cpHeader);
887 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
888 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
893 cpOut = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"time.out");
894 cpOutUdt = cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR,
"/../output/",
"time-udt.out");
896 cpOut = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"time-pppt.out");
897 cpOutUdt = cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR,
"/../output/",
"time-pppt-udt.out");
899 spFp = fopen(cpOut,
"wb");
901 snprintf(caBuf,
sizeof(caBuf),
"can't open output file %s", cpOut);
904 spFpUdt = fopen(cpOutUdt,
"wb");
906 snprintf(caBuf,
sizeof(caBuf),
"can't open output file %s", cpOutUdt);
912 vGetMsgs(vpMem, &sSection[0],
APG_FALSE);
915 vGetMsgs(vpMem, &sSection[1],
APG_FALSE);
918 vGetMsgs(vpMem, &sSection[2],
APG_FALSE);
921 for(uj = 0; uj < 3; uj++){
924 for(ui = 0; ui < sSection[uj].
uiCount; ui++){
937 spEnd = spStart + uiMsgs;
943 printf(
"\nBeginning Tests without UDTs: be patient\n");
944 tStartTime = clock();
945 for(ui = 0; ui < uiTests; ui++){
946 for(spConfig = spStart; spConfig < spEnd; spConfig++){
950 uiMsgCount += uiMsgs;
953 dMSec = (double)((tEndTime - tStartTime) * 1000) / (
double)CLOCKS_PER_SEC;
954 dMsgsPerMSec = (double)uiMsgCount / dMSec;
955 fprintf(spFp,
"Timing Tests without UDTs\n");
956 fprintf(spFp,
" Messages: %"PRIuMAX
"\n", uiMsgCount);
957 fprintf(spFp,
"Characters: %"PRIuMAX
"\n", uiCharCount);
958 fprintf(spFp,
" msec: %e\n", dMSec);
959 fprintf(spFp,
" msec/msg: %e\n", (1.0 / dMsgsPerMSec));
960 fprintf(spFp,
" msgs/msec: %e\n", dMsgsPerMSec);
961 printf(
"Results written to %s\n", cpOut);
968 printf(
"\nBeginning Tests with UDTs: be patient\n");
969 tStartTime = clock();
970 for(ui = 0; ui < uiTests; ui++){
971 for(spConfig = spStart; spConfig < spEnd; spConfig++){
975 uiMsgCount += uiMsgs;
978 dMSec = (double)((tEndTime - tStartTime) * 1000) / (
double)CLOCKS_PER_SEC;
979 dMsgsPerMSec = (double)uiMsgCount /dMSec;
980 fprintf(spFpUdt,
"Timing Tests with UDTs\n");
981 fprintf(spFpUdt,
" Messages: %"PRIuMAX
"\n", uiMsgCount);
982 fprintf(spFpUdt,
"Characters: %"PRIuMAX
"\n", uiCharCount);
983 fprintf(spFpUdt,
" msec: %e\n", dMSec);
984 fprintf(spFpUdt,
" msec/msg: %e\n", (1.0 / dMsgsPerMSec));
985 fprintf(spFpUdt,
" msgs/msec: %e\n", dMsgsPerMSec);
986 printf(
"Results written to %s\n", cpOutUdt);
991 iReturn = EXIT_FAILURE;
1007 static int iStats() {
1008 int iReturn = EXIT_SUCCESS;
1009 static void* vpMem = NULL;
1010 static void* vpStats = NULL;
1011 static void* vpVecConfig = NULL;
1012 static void* vpJson = NULL;
1013 static void* vpParser = NULL;
1014 const char* cpOut, *cpOutUdt;
1028 "This function will parse all of the SIP torture tests and display the node-hit statistics.\n"
1029 "Comparisons will show the differences between parsing with and without PPPTs,\n"
1030 " and with and without UDTs.\n";
1031 printf(
"\n%s", cpHeader);
1034 s_sTestsCtx.
cpValidIn = cpMakeFileName(s_caBufTests, SOURCE_DIR,
"/", s_sTestsCtx.
cpValidIn);
1035 s_sTestsCtx.
cpInvalidIn = cpMakeFileName(&s_caBufTests[PATH_MAX], SOURCE_DIR,
"/", s_sTestsCtx.
cpInvalidIn);
1041 vGetMsgs(vpMem, &sSection[0],
APG_FALSE);
1044 vGetMsgs(vpMem, &sSection[1],
APG_FALSE);
1047 vGetMsgs(vpMem, &sSection[2],
APG_FALSE);
1050 for(uj = 0; uj < 3; uj++){
1053 for(ui = 0; ui < sSection[uj].
uiCount; ui++){
1064 cpOut = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"stats.out");
1065 cpOutUdt = cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR,
"/../output/",
"stats-udt.out");
1067 cpOut = cpMakeFileName(s_caBuf, SOURCE_DIR,
"/../output/",
"stats-pppt.out");
1068 cpOutUdt = cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR,
"/../output/",
"stats-pppt-udt.out");
1072 spEnd = spStart + uiMsgs;
1076 printf(
"\nStats without UDTs: cumulative for %d messages\n", (
int)uiMsgs);
1077 for(; spConfig < spEnd; spConfig++){
1081 printf(
"Results written to %s\n", cpOut);
1088 printf(
"\nStats with UDTs: cumulative for %d messages\n", (
int)uiMsgs);
1089 for(; spConfig < spEnd; spConfig++){
1093 printf(
"Results written to %s\n", cpOutUdt);
1098 iReturn = EXIT_FAILURE;
1118 iCase = atol(argv[1]);
1120 if((iCase > 0) && (iCase <= s_iCaseCount)){
1121 printf(
"%s\n", s_cppCases[iCase -1]);
1133 return iSemantics();