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


syntax highlighted by Code2HTML, v. 0.9.1