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