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