1 /*----------------------------------------------------------------------------
  2 Name:      xmlBlaster/testsuite/src/c/TestMethods.c
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Test C client library
  6 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
  7 Compile:   cd xmlBlaster; build c
  8 Invoke:    Start 'java org.xmlBlaster.Main' and then 'TestMethods'
  9 See:       http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.socket.html
 10 See:       http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html
 11 -----------------------------------------------------------------------------*/
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <string.h>
 15 #include <XmlBlasterAccessUnparsed.h>
 16 #include "test.h"
 17 
 18 static int argc = 0;
 19 static char** argv = 0;
 20 #define  ERRORSTR_LEN 4096
 21 static char errorString[ERRORSTR_LEN+1];
 22 static char *updateContent = 0;
 23 static void *updateUserData;
 24 static const char *CONTENT = "Some message payload";
 25 
 26 /**
 27  * Here we receive the callback messages from xmlBlaster
 28  * mu_assert() does not help here as it is another thread
 29  */
 30 static bool myUpdate(MsgUnitArr *msgUnitArr, void *userData, XmlBlasterException *xmlBlasterException)
 31 {
 32    size_t i;
 33    XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData;
 34    if (xmlBlasterException != 0) ;  /* Supress compiler warning */
 35    updateUserData = xa;
 36    for (i=0; i<msgUnitArr->len; i++) {
 37       MsgUnit *msg = 0;
 38       if (updateContent != 0) {
 39          xmlBlasterFree(updateContent);
 40          updateContent = 0;
 41       }
 42       msg = &msgUnitArr->msgUnitArr[i];
 43       printf("[client] CALLBACK update(): Asynchronous message update arrived\n");
 44       updateContent = strFromBlobAlloc(msg->content, msg->contentLen);
 45       msgUnitArr->msgUnitArr[i].responseQos = strcpyAlloc("<qos><state id='OK'/></qos>");
 46    }
 47    return true;
 48 }
 49 
 50 /**
 51  * Invoke: TestMethods -logLevel TRACE
 52  */
 53 static const char * test_methods()
 54 {
 55    int iarg;
 56    char *response = (char *)0;
 57    /*
 58       * callbackSessionId:
 59       * Is created by the client and used to validate callback messages in update. 
 60       * This is sent on connect in ConnectQos.
 61       * (Is different from the xmlBlaster secret session ID)
 62       */
 63    const char *callbackSessionId = "topSecret";
 64    XmlBlasterException xmlBlasterException;
 65    XmlBlasterAccessUnparsed *xa = 0;
 66    bool retBool;
 67 
 68    printf("[client] Try option '-help' if you need usage informations\n");
 69 
 70    for (iarg=0; iarg < argc; iarg++) {
 71       if (strcmp(argv[iarg], "-help") == 0 || strcmp(argv[iarg], "--help") == 0) {
 72          char usage[XMLBLASTER_MAX_USAGE_LEN];
 73          const char *pp =
 74          "\n  -logLevel            ERROR | WARN | INFO | TRACE [WARN]"
 75          "\n\nExample:"
 76          "\n  TestMethods -logLevel TRACE"
 77          " -dispatch/connection/plugin/socket/hostname 192.168.2.9";
 78          printf("Usage:\nXmlBlaster C SOCKET client %s\n%s%s\n",
 79                   getXmlBlasterVersion(), xmlBlasterAccessUnparsedUsage(usage), pp);
 80          exit(EXIT_FAILURE);
 81       }
 82    }
 83 
 84    xa = getXmlBlasterAccessUnparsed(argc, (const char* const*)argv);
 85    if (xa->initialize(xa, myUpdate, &xmlBlasterException) == false) {
 86       xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_ERROR, __FILE__,
 87          "Connection to xmlBlaster failed, please start the server or check your configuration");
 88       freeXmlBlasterAccessUnparsed(xa);
 89       mu_assert("Connection to xmlBlaster failed, please start the server or check your configuration",
 90                 false);
 91    }
 92 
 93    xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_INFO, __FILE__, "Connected to xmlBlaster");
 94 
 95    {  /* connect */
 96       char connectQos[2048];
 97       char callbackQos[1024];
 98       sprintf(callbackQos,
 99                "<queue relating='callback' maxEntries='100' maxEntriesCache='100'>"
100                "  <callback type='SOCKET' sessionId='%s'>"
101                "    socket://%.120s:%d"
102                "  </callback>"
103                "</queue>",
104                callbackSessionId, xa->callbackP->hostCB, xa->callbackP->portCB);
105       sprintf(connectQos,
106                "<qos>"
107                " <securityService type='htpasswd' version='1.0'>"
108                "  <![CDATA["
109                "   <user>fritz</user>"
110                "   <passwd>secret</passwd>"
111                "  ]]>"
112                " </securityService>"
113                "%.1024s"
114                "</qos>", callbackQos);
115 
116       response = xa->connect(xa, connectQos, myUpdate, &xmlBlasterException);
117       if (*xmlBlasterException.errorCode != '\0') {
118          SNPRINTF(errorString, ERRORSTR_LEN, "Caught exception during connect errorCode=%s, message=%s\n",
119                   xmlBlasterException.errorCode, xmlBlasterException.message);
120          freeXmlBlasterAccessUnparsed(xa);
121          mu_assert(errorString, false);
122       }
123       xmlBlasterFree(response);
124       printf("[client] Connected to xmlBlaster, do some tests ...\n");
125    }
126 
127    response = xa->ping(xa, 0, &xmlBlasterException);
128    mu_assert("Pinging a connected server failed", response != (char *)0);
129    mu_assert("Pinging a connected server failed", *xmlBlasterException.errorCode == 0);
130    printf("[client] Pinging a connected server, response=%s\n", response);
131    xmlBlasterFree(response);
132 
133    { /* subscribe ... */
134       const char *key = "<key oid='HelloWorld'/>";
135       const char *qos = "<qos/>";
136       printf("[client] Subscribe message 'HelloWorld' ...\n");
137       response = xa->subscribe(xa, key, qos, &xmlBlasterException);
138       if (*xmlBlasterException.errorCode != 0) {
139          SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in subscribe errorCode=%s, message=%s\n",
140                   xmlBlasterException.errorCode, xmlBlasterException.message);
141          freeXmlBlasterAccessUnparsed(xa);
142          mu_assert(errorString, false);
143       }
144       printf("[client] Subscribe success\n");
145       mu_assert("Subscribe response is invalid", strstr(response, "subscribe id=")!=0);
146       mu_assert("Subscribe response is invalid", strstr(response, "WARNING")==0);
147       mu_assert("Subscribe response is invalid", strstr(response, "ERROR")==0);
148       xmlBlasterFree(response);
149    }
150 
151    {  /* publish ... */
152       MsgUnit msgUnit;
153       memset(&msgUnit, 0, sizeof(MsgUnit));
154       printf("[client] Publishing message 'HelloWorld' ...\n");
155       msgUnit.key = strcpyAlloc("<key oid='HelloWorld'/>");
156       msgUnit.content = strcpyAlloc(CONTENT);
157       msgUnit.contentLen = strlen(msgUnit.content);
158       msgUnit.qos =strcpyAlloc("<qos><persistent/></qos>");
159       response = xa->publish(xa, &msgUnit, &xmlBlasterException);
160       freeMsgUnitData(&msgUnit);
161       if (*xmlBlasterException.errorCode != '\0') {
162          SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in publish errorCode=%s, message=%s\n",
163                   xmlBlasterException.errorCode, xmlBlasterException.message);
164          freeXmlBlasterAccessUnparsed(xa);
165          mu_assert(errorString, false);
166       }
167       printf("[client] Publish success");
168       mu_assert("Publish response is invalid", strstr(response, "rcvTimestamp nanos=")!=0);
169       xmlBlasterFree(response);
170    }
171 
172    sleepMillis(1000);
173    mu_assert("No update arrived", updateContent != 0);
174    mu_assert("Received wrong message in update()", strcmp(CONTENT, updateContent) == 0);
175    xmlBlasterFree(updateContent);
176    updateContent = 0;
177 
178    mu_assert("UserData from update() is invalid", updateUserData == xa);
179 
180 
181    {  /* unSubscribe ... */
182       QosArr* responseArrP;
183       const char *key = "<key oid='HelloWorld'/>";
184       const char *qos = "<qos/>";
185       printf("[client] UnSubscribe message 'HelloWorld' ...\n");
186       responseArrP = xa->unSubscribe(xa, key, qos, &xmlBlasterException);
187       if (*xmlBlasterException.errorCode != '\0') {
188          SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in unSubscribe errorCode=%s, message=%s\n",
189                   xmlBlasterException.errorCode, xmlBlasterException.message);
190          freeXmlBlasterAccessUnparsed(xa);
191          mu_assert(errorString, false);
192       }
193       printf("[client] Unsubscribe success\n");
194       freeQosArr(responseArrP);
195    }
196 
197    {  /* get synchronous ... */
198       size_t i;
199       const char *key = "<key queryType='XPATH'>//key</key>";
200       const char *qos = "<qos/>";
201       MsgUnitArr *msgUnitArr;
202       printf("[client] Get synchronous messages with XPath '//key' ...\n");
203       msgUnitArr = xa->get(xa, key, qos, &xmlBlasterException);
204       if (*xmlBlasterException.errorCode != 0) {
205          printf("[TEST FAIL] Caught exception in get errorCode=%s, message=%s\n",
206                   xmlBlasterException.errorCode, xmlBlasterException.message);
207          xa->disconnect(xa, 0, &xmlBlasterException);
208          freeXmlBlasterAccessUnparsed(xa);
209          exit(EXIT_FAILURE);
210       }
211       if (*xmlBlasterException.errorCode != '\0') {
212          SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in get() errorCode=%s, message=%s\n",
213                   xmlBlasterException.errorCode, xmlBlasterException.message);
214          freeXmlBlasterAccessUnparsed(xa);
215          mu_assert(errorString, false);
216       }
217       mu_assert("Empty get() return", msgUnitArr != (MsgUnitArr *)0);
218       for (i=0; i<msgUnitArr->len; i++) {
219          char *contentStr = strFromBlobAlloc(msgUnitArr->msgUnitArr[i].content,
220                                           msgUnitArr->msgUnitArr[i].contentLen);
221          printf("[client] Received message#%lu/%lu\n", (unsigned long)(i+1), (unsigned long)msgUnitArr->len);
222          xmlBlasterFree(contentStr);
223       }
224       freeMsgUnitArr(msgUnitArr);
225    }
226 
227 
228    {  /* erase ... */
229       QosArr* responseArrP;
230       const char *key = "<key oid='HelloWorld'/>";
231       const char *qos = "<qos/>";
232       printf("[client] Erasing message 'HelloWorld' ...\n");
233       responseArrP = xa->erase(xa, key, qos, &xmlBlasterException);
234       if (*xmlBlasterException.errorCode != '\0') {
235          SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in erase() errorCode=%s, message=%s\n",
236                   xmlBlasterException.errorCode, xmlBlasterException.message);
237          freeXmlBlasterAccessUnparsed(xa);
238          mu_assert(errorString, false);
239       }
240       printf("[client] Erase success\n");
241       freeQosArr(responseArrP);
242    }
243 
244    sleepMillis(1000);
245 
246    retBool = xa->disconnect(xa, 0, &xmlBlasterException);
247    if (*xmlBlasterException.errorCode != '\0') {
248       SNPRINTF(errorString, ERRORSTR_LEN, "[TEST FAIL] Caught exception in erase() errorCode=%s, message=%s\n",
249                xmlBlasterException.errorCode, xmlBlasterException.message);
250       freeXmlBlasterAccessUnparsed(xa);
251       mu_assert(errorString, false);
252    }
253    mu_assert("disconnect() returned false", retBool == true);
254 
255    if (updateContent != 0) { /* The erase event is sent as update as well */
256       xmlBlasterFree(updateContent);
257       updateContent = 0;
258    }
259 
260    freeXmlBlasterAccessUnparsed(xa);
261    printf("[client] Good bye.\n");
262    return 0;
263 }
264 
265 
266 static const char *all_tests()
267 {
268    mu_run_test(test_methods);
269    return 0;
270 }
271 
272 int main(int argc_, char **argv_)
273 {
274    const char *result;
275    argc = argc_;
276    argv = argv_;
277 
278    result = all_tests();
279 
280    if (result != 0) {
281       printf("%s\n", result);
282    }
283    else {
284       printf("ALL TESTS PASSED\n");
285    }
286    printf("Tests run: %d\n", tests_run);
287 
288    return result != 0;
289 }


syntax highlighted by Code2HTML, v. 0.9.1