summaryrefslogtreecommitdiff
path: root/src/testbed/test_testbed_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testbed/test_testbed_api.c')
-rw-r--r--src/testbed/test_testbed_api.c359
1 files changed, 182 insertions, 177 deletions
diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c
index 00d53dc25..37dc362ea 100644
--- a/src/testbed/test_testbed_api.c
+++ b/src/testbed/test_testbed_api.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -33,14 +33,14 @@
33/** 33/**
34 * Generic logging shortcut 34 * Generic logging shortcut
35 */ 35 */
36#define LOG(kind,...) \ 36#define LOG(kind, ...) \
37 GNUNET_log (kind, __VA_ARGS__) 37 GNUNET_log(kind, __VA_ARGS__)
38 38
39/** 39/**
40 * Relative time seconds shorthand 40 * Relative time seconds shorthand
41 */ 41 */
42#define TIME_REL_SECS(sec) \ 42#define TIME_REL_SECS(sec) \
43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) 43 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, sec)
44 44
45/** 45/**
46 * Our localhost 46 * Our localhost
@@ -101,8 +101,7 @@ static int result;
101/** 101/**
102 * Enumeration of sub testcases 102 * Enumeration of sub testcases
103 */ 103 */
104enum Test 104enum Test {
105{
106 /** 105 /**
107 * Test cases which are not covered by the below ones 106 * Test cases which are not covered by the below ones
108 */ 107 */
@@ -136,23 +135,23 @@ static enum Test sub_test;
136 * @param tc the task context 135 * @param tc the task context
137 */ 136 */
138static void 137static void
139do_shutdown (void *cls) 138do_shutdown(void *cls)
140{ 139{
141 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down...\n"); 140 LOG(GNUNET_ERROR_TYPE_DEBUG, "Shutting down...\n");
142 if (NULL != abort_task) 141 if (NULL != abort_task)
143 GNUNET_SCHEDULER_cancel (abort_task); 142 GNUNET_SCHEDULER_cancel(abort_task);
144 if (NULL != reg_handle) 143 if (NULL != reg_handle)
145 GNUNET_TESTBED_cancel_registration (reg_handle); 144 GNUNET_TESTBED_cancel_registration(reg_handle);
146 if (NULL != controller) 145 if (NULL != controller)
147 GNUNET_TESTBED_controller_disconnect (controller); 146 GNUNET_TESTBED_controller_disconnect(controller);
148 if (NULL != cfg) 147 if (NULL != cfg)
149 GNUNET_CONFIGURATION_destroy (cfg); 148 GNUNET_CONFIGURATION_destroy(cfg);
150 if (NULL != cp) 149 if (NULL != cp)
151 GNUNET_TESTBED_controller_stop (cp); 150 GNUNET_TESTBED_controller_stop(cp);
152 if (NULL != neighbour) 151 if (NULL != neighbour)
153 GNUNET_TESTBED_host_destroy (neighbour); 152 GNUNET_TESTBED_host_destroy(neighbour);
154 if (NULL != host) 153 if (NULL != host)
155 GNUNET_TESTBED_host_destroy (host); 154 GNUNET_TESTBED_host_destroy(host);
156} 155}
157 156
158 157
@@ -160,14 +159,14 @@ do_shutdown (void *cls)
160 * shortcut to exit during failure 159 * shortcut to exit during failure
161 */ 160 */
162#define FAIL_TEST(cond, ret) do { \ 161#define FAIL_TEST(cond, ret) do { \
163 if (!(cond)) { \ 162 if (!(cond)) { \
164 GNUNET_break(0); \ 163 GNUNET_break(0); \
165 if (NULL != abort_task) \ 164 if (NULL != abort_task) \
166 GNUNET_SCHEDULER_cancel (abort_task); \ 165 GNUNET_SCHEDULER_cancel (abort_task); \
167 abort_task = NULL; \ 166 abort_task = NULL; \
168 GNUNET_SCHEDULER_add_now (do_shutdown, NULL); \ 167 GNUNET_SCHEDULER_add_now(do_shutdown, NULL); \
169 ret; \ 168 ret; \
170 } \ 169 } \
171 } while (0) 170 } while (0)
172 171
173 172
@@ -178,11 +177,11 @@ do_shutdown (void *cls)
178 * @param tc the task context 177 * @param tc the task context
179 */ 178 */
180static void 179static void
181do_abort (void *cls) 180do_abort(void *cls)
182{ 181{
183 LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n"); 182 LOG(GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
184 abort_task = NULL; 183 abort_task = NULL;
185 do_shutdown (cls); 184 do_shutdown(cls);
186} 185}
187 186
188 187
@@ -197,13 +196,13 @@ do_abort (void *cls)
197 * @return service handle to return in 'op_result', NULL on error 196 * @return service handle to return in 'op_result', NULL on error
198 */ 197 */
199static void * 198static void *
200arm_connect_adapter (void *cls, 199arm_connect_adapter(void *cls,
201 const struct GNUNET_CONFIGURATION_Handle *cfg) 200 const struct GNUNET_CONFIGURATION_Handle *cfg)
202{ 201{
203 FAIL_TEST (NULL == cls, return NULL); 202 FAIL_TEST(NULL == cls, return NULL);
204 FAIL_TEST (OTHER == sub_test, return NULL); 203 FAIL_TEST(OTHER == sub_test, return NULL);
205 sub_test = PEER_SERVICE_CONNECT; 204 sub_test = PEER_SERVICE_CONNECT;
206 arm_handle = GNUNET_ARM_connect (cfg, NULL, NULL); 205 arm_handle = GNUNET_ARM_connect(cfg, NULL, NULL);
207 return arm_handle; 206 return arm_handle;
208} 207}
209 208
@@ -216,17 +215,17 @@ arm_connect_adapter (void *cls,
216 * @param op_result service handle returned from the connect adapter 215 * @param op_result service handle returned from the connect adapter
217 */ 216 */
218static void 217static void
219arm_disconnect_adapter (void *cls, 218arm_disconnect_adapter(void *cls,
220 void *op_result) 219 void *op_result)
221{ 220{
222 FAIL_TEST (NULL != op_result, return); 221 FAIL_TEST(NULL != op_result, return );
223 FAIL_TEST (op_result == arm_handle, return); 222 FAIL_TEST(op_result == arm_handle, return );
224 GNUNET_ARM_disconnect (arm_handle); 223 GNUNET_ARM_disconnect(arm_handle);
225 arm_handle = NULL; 224 arm_handle = NULL;
226 FAIL_TEST (PEER_SERVICE_CONNECT == sub_test, return); 225 FAIL_TEST(PEER_SERVICE_CONNECT == sub_test, return );
227 FAIL_TEST (NULL != operation, return); 226 FAIL_TEST(NULL != operation, return );
228 operation = GNUNET_TESTBED_peer_stop (NULL, peer, NULL, NULL); 227 operation = GNUNET_TESTBED_peer_stop(NULL, peer, NULL, NULL);
229 FAIL_TEST (NULL != operation, return); 228 FAIL_TEST(NULL != operation, return );
230} 229}
231 230
232 231
@@ -240,24 +239,25 @@ arm_disconnect_adapter (void *cls,
240 * operation has executed successfully. 239 * operation has executed successfully.
241 */ 240 */
242static void 241static void
243service_connect_comp_cb (void *cls, 242service_connect_comp_cb(void *cls,
244 struct GNUNET_TESTBED_Operation *op, 243 struct GNUNET_TESTBED_Operation *op,
245 void *ca_result, 244 void *ca_result,
246 const char *emsg) 245 const char *emsg)
247{ 246{
248 switch (sub_test) 247 switch (sub_test)
249 { 248 {
250 case PEER_SERVICE_CONNECT: 249 case PEER_SERVICE_CONNECT:
251 FAIL_TEST (operation == op, return); 250 FAIL_TEST(operation == op, return );
252 FAIL_TEST (NULL == emsg, return); 251 FAIL_TEST(NULL == emsg, return );
253 FAIL_TEST (NULL == cls, return); 252 FAIL_TEST(NULL == cls, return );
254 FAIL_TEST (ca_result == arm_handle, return); 253 FAIL_TEST(ca_result == arm_handle, return );
255 GNUNET_TESTBED_operation_done (operation); /* This results in call to 254 GNUNET_TESTBED_operation_done(operation); /* This results in call to
256 * disconnect adapter */ 255 * disconnect adapter */
257 break; 256 break;
258 default: 257
259 FAIL_TEST (0, return); 258 default:
260 } 259 FAIL_TEST(0, return );
260 }
261} 261}
262 262
263 263
@@ -272,27 +272,28 @@ service_connect_comp_cb (void *cls,
272 * operation is successfull 272 * operation is successfull
273 */ 273 */
274static void 274static void
275peerinfo_cb (void *cb_cls, 275peerinfo_cb(void *cb_cls,
276 struct GNUNET_TESTBED_Operation *op, 276 struct GNUNET_TESTBED_Operation *op,
277 const struct GNUNET_TESTBED_PeerInformation *pinfo, 277 const struct GNUNET_TESTBED_PeerInformation *pinfo,
278 const char *emsg) 278 const char *emsg)
279{ 279{
280 switch (sub_test) 280 switch (sub_test)
281 { 281 {
282 case PEER_GETCONFIG: 282 case PEER_GETCONFIG:
283 FAIL_TEST (NULL != pinfo, return); 283 FAIL_TEST(NULL != pinfo, return );
284 FAIL_TEST (NULL == emsg, return); 284 FAIL_TEST(NULL == emsg, return );
285 FAIL_TEST (NULL == cb_cls, return); 285 FAIL_TEST(NULL == cb_cls, return );
286 FAIL_TEST (operation == op, return); 286 FAIL_TEST(operation == op, return );
287 FAIL_TEST (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit, return); 287 FAIL_TEST(GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit, return );
288 FAIL_TEST (NULL != pinfo->result.cfg, return); 288 FAIL_TEST(NULL != pinfo->result.cfg, return );
289 sub_test = PEER_DESTROY; 289 sub_test = PEER_DESTROY;
290 GNUNET_TESTBED_operation_done (operation); 290 GNUNET_TESTBED_operation_done(operation);
291 operation = GNUNET_TESTBED_peer_destroy (peer); 291 operation = GNUNET_TESTBED_peer_destroy(peer);
292 break; 292 break;
293 default: 293
294 FAIL_TEST (0, return); 294 default:
295 } 295 FAIL_TEST(0, return );
296 }
296} 297}
297 298
298 299
@@ -304,60 +305,65 @@ peerinfo_cb (void *cb_cls,
304 * @param event information about the event 305 * @param event information about the event
305 */ 306 */
306static void 307static void
307controller_cb (void *cls, 308controller_cb(void *cls,
308 const struct GNUNET_TESTBED_EventInformation *event) 309 const struct GNUNET_TESTBED_EventInformation *event)
309{ 310{
310 switch (event->type) 311 switch (event->type)
311 {
312 case GNUNET_TESTBED_ET_OPERATION_FINISHED:
313 switch (sub_test)
314 { 312 {
315 case PEER_DESTROY: 313 case GNUNET_TESTBED_ET_OPERATION_FINISHED:
316 FAIL_TEST (event->op == operation, return); 314 switch (sub_test)
317 FAIL_TEST (NULL == event->op_cls, return); 315 {
318 FAIL_TEST (NULL == event->details.operation_finished.emsg, return); 316 case PEER_DESTROY:
319 FAIL_TEST (NULL == event->details.operation_finished.generic, return); 317 FAIL_TEST(event->op == operation, return );
320 GNUNET_TESTBED_operation_done (operation); 318 FAIL_TEST(NULL == event->op_cls, return );
321 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 319 FAIL_TEST(NULL == event->details.operation_finished.emsg, return );
320 FAIL_TEST(NULL == event->details.operation_finished.generic, return );
321 GNUNET_TESTBED_operation_done(operation);
322 GNUNET_SCHEDULER_add_now(&do_shutdown, NULL);
323 break;
324
325 case PEER_SERVICE_CONNECT:
326 FAIL_TEST(event->op == operation, return );
327 FAIL_TEST(NULL == event->op_cls, return );
328 FAIL_TEST(NULL == event->details.operation_finished.emsg, return );
329 FAIL_TEST(NULL != arm_handle, return );
330 FAIL_TEST(event->details.operation_finished.generic == arm_handle, return );
331 break;
332
333 default:
334 FAIL_TEST(0, return );
335 break;
336 }
322 break; 337 break;
323 case PEER_SERVICE_CONNECT: 338
324 FAIL_TEST (event->op == operation, return); 339 case GNUNET_TESTBED_ET_PEER_START:
325 FAIL_TEST (NULL == event->op_cls, return); 340 FAIL_TEST(event->details.peer_start.host == host, return );
326 FAIL_TEST (NULL == event->details.operation_finished.emsg, return); 341 FAIL_TEST(event->details.peer_start.peer == peer, return );
327 FAIL_TEST (NULL != arm_handle, return); 342 FAIL_TEST(OTHER == sub_test, return );
328 FAIL_TEST (event->details.operation_finished.generic == arm_handle, return); 343 GNUNET_TESTBED_operation_done(operation);
344 operation =
345 GNUNET_TESTBED_service_connect(NULL, peer, "dht",
346 &service_connect_comp_cb, NULL,
347 &arm_connect_adapter,
348 &arm_disconnect_adapter, NULL);
349 FAIL_TEST(NULL != operation, return );
329 break; 350 break;
330 default: 351
331 FAIL_TEST (0, return); 352 case GNUNET_TESTBED_ET_PEER_STOP:
353 FAIL_TEST(event->details.peer_stop.peer == peer, return );
354 FAIL_TEST(PEER_SERVICE_CONNECT == sub_test, return );
355 result = GNUNET_YES;
356 sub_test = PEER_GETCONFIG;
357 GNUNET_TESTBED_operation_done(operation);
358 operation =
359 GNUNET_TESTBED_peer_get_information(peer,
360 GNUNET_TESTBED_PIT_CONFIGURATION,
361 &peerinfo_cb, NULL);
332 break; 362 break;
363
364 default:
365 FAIL_TEST(0, return ); /* We should never reach this state */
333 } 366 }
334 break;
335 case GNUNET_TESTBED_ET_PEER_START:
336 FAIL_TEST (event->details.peer_start.host == host, return);
337 FAIL_TEST (event->details.peer_start.peer == peer, return);
338 FAIL_TEST (OTHER == sub_test, return);
339 GNUNET_TESTBED_operation_done (operation);
340 operation =
341 GNUNET_TESTBED_service_connect (NULL, peer, "dht",
342 &service_connect_comp_cb, NULL,
343 &arm_connect_adapter,
344 &arm_disconnect_adapter, NULL);
345 FAIL_TEST (NULL != operation, return);
346 break;
347 case GNUNET_TESTBED_ET_PEER_STOP:
348 FAIL_TEST (event->details.peer_stop.peer == peer, return);
349 FAIL_TEST (PEER_SERVICE_CONNECT == sub_test, return);
350 result = GNUNET_YES;
351 sub_test = PEER_GETCONFIG;
352 GNUNET_TESTBED_operation_done (operation);
353 operation =
354 GNUNET_TESTBED_peer_get_information (peer,
355 GNUNET_TESTBED_PIT_CONFIGURATION,
356 &peerinfo_cb, NULL);
357 break;
358 default:
359 FAIL_TEST (0, return); /* We should never reach this state */
360 }
361} 367}
362 368
363 369
@@ -371,22 +377,22 @@ controller_cb (void *cls,
371 * @param emsg NULL if peer is not NULL; else MAY contain the error description 377 * @param emsg NULL if peer is not NULL; else MAY contain the error description
372 */ 378 */
373static void 379static void
374peer_create_cb (void *cls, 380peer_create_cb(void *cls,
375 struct GNUNET_TESTBED_Peer *peer, 381 struct GNUNET_TESTBED_Peer *peer,
376 const char *emsg) 382 const char *emsg)
377{ 383{
378 struct GNUNET_TESTBED_Peer **peer_ptr; 384 struct GNUNET_TESTBED_Peer **peer_ptr;
379 385
380 peer_ptr = cls; 386 peer_ptr = cls;
381 FAIL_TEST (NULL != peer, return); 387 FAIL_TEST(NULL != peer, return );
382 FAIL_TEST (NULL != peer_ptr, return); 388 FAIL_TEST(NULL != peer_ptr, return );
383 *peer_ptr = peer; 389 *peer_ptr = peer;
384 GNUNET_TESTBED_operation_done (operation); 390 GNUNET_TESTBED_operation_done(operation);
385 operation = GNUNET_TESTBED_peer_start (NULL, 391 operation = GNUNET_TESTBED_peer_start(NULL,
386 peer, 392 peer,
387 NULL, 393 NULL,
388 NULL); 394 NULL);
389 FAIL_TEST (NULL != operation, return); 395 FAIL_TEST(NULL != operation, return );
390} 396}
391 397
392 398
@@ -397,18 +403,18 @@ peer_create_cb (void *cls,
397 * @param emsg the error message; NULL if host registration is successful 403 * @param emsg the error message; NULL if host registration is successful
398 */ 404 */
399static void 405static void
400registration_comp (void *cls, 406registration_comp(void *cls,
401 const char *emsg) 407 const char *emsg)
402{ 408{
403 FAIL_TEST (cls == neighbour, return); 409 FAIL_TEST(cls == neighbour, return );
404 reg_handle = NULL; 410 reg_handle = NULL;
405 operation = 411 operation =
406 GNUNET_TESTBED_peer_create (controller, 412 GNUNET_TESTBED_peer_create(controller,
407 host, 413 host,
408 cfg, 414 cfg,
409 &peer_create_cb, 415 &peer_create_cb,
410 &peer); 416 &peer);
411 FAIL_TEST (NULL != operation, return); 417 FAIL_TEST(NULL != operation, return );
412} 418}
413 419
414 420
@@ -422,33 +428,33 @@ registration_comp (void *cls,
422 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case 428 * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
423 */ 429 */
424static void 430static void
425status_cb (void *cls, 431status_cb(void *cls,
426 const struct GNUNET_CONFIGURATION_Handle *cfg_, 432 const struct GNUNET_CONFIGURATION_Handle *cfg_,
427 int status) 433 int status)
428{ 434{
429 uint64_t event_mask; 435 uint64_t event_mask;
430 436
431 if (GNUNET_OK != status) 437 if (GNUNET_OK != status)
432 { 438 {
433 cp = NULL; 439 cp = NULL;
434 FAIL_TEST (0, return); 440 FAIL_TEST(0, return );
435 return; 441 return;
436 } 442 }
437 event_mask = 0; 443 event_mask = 0;
438 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START); 444 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
439 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP); 445 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
440 event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT); 446 event_mask |= (1L << GNUNET_TESTBED_ET_CONNECT);
441 event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED); 447 event_mask |= (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED);
442 controller = 448 controller =
443 GNUNET_TESTBED_controller_connect (host, event_mask, &controller_cb, 449 GNUNET_TESTBED_controller_connect(host, event_mask, &controller_cb,
444 NULL); 450 NULL);
445 FAIL_TEST (NULL != controller, return); 451 FAIL_TEST(NULL != controller, return );
446 neighbour = GNUNET_TESTBED_host_create ("localhost", NULL, cfg, 0); 452 neighbour = GNUNET_TESTBED_host_create("localhost", NULL, cfg, 0);
447 FAIL_TEST (NULL != neighbour, return); 453 FAIL_TEST(NULL != neighbour, return );
448 reg_handle = 454 reg_handle =
449 GNUNET_TESTBED_register_host (controller, neighbour, &registration_comp, 455 GNUNET_TESTBED_register_host(controller, neighbour, &registration_comp,
450 neighbour); 456 neighbour);
451 FAIL_TEST (NULL != reg_handle, return); 457 FAIL_TEST(NULL != reg_handle, return );
452} 458}
453 459
454 460
@@ -462,22 +468,22 @@ status_cb (void *cls,
462 * @param cfg the configuration file handle 468 * @param cfg the configuration file handle
463 */ 469 */
464static void 470static void
465run (void *cls, 471run(void *cls,
466 char *const *args, 472 char *const *args,
467 const char *cfgfile, 473 const char *cfgfile,
468 const struct GNUNET_CONFIGURATION_Handle *config) 474 const struct GNUNET_CONFIGURATION_Handle *config)
469{ 475{
470 cfg = GNUNET_CONFIGURATION_dup (config); 476 cfg = GNUNET_CONFIGURATION_dup(config);
471 host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); 477 host = GNUNET_TESTBED_host_create(NULL, NULL, cfg, 0);
472 FAIL_TEST (NULL != host, return); 478 FAIL_TEST(NULL != host, return );
473 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, 479 cp = GNUNET_TESTBED_controller_start("127.0.0.1", host,
474 &status_cb, 480 &status_cb,
475 NULL); 481 NULL);
476 abort_task = 482 abort_task =
477 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 483 GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply
478 (GNUNET_TIME_UNIT_MINUTES, 5), 484 (GNUNET_TIME_UNIT_MINUTES, 5),
479 &do_abort, 485 &do_abort,
480 NULL); 486 NULL);
481} 487}
482 488
483 489
@@ -485,22 +491,21 @@ run (void *cls,
485 * Main function 491 * Main function
486 */ 492 */
487int 493int
488main (int argc, char **argv) 494main(int argc, char **argv)
489{ 495{
490 int ret; 496 int ret;
491 497
492 char *const argv2[] = { "test_testbed_api", 498 char *const argv2[] = { "test_testbed_api",
493 "-c", "test_testbed_api.conf", 499 "-c", "test_testbed_api.conf",
494 NULL 500 NULL };
495 };
496 struct GNUNET_GETOPT_CommandLineOption options[] = { 501 struct GNUNET_GETOPT_CommandLineOption options[] = {
497 GNUNET_GETOPT_OPTION_END 502 GNUNET_GETOPT_OPTION_END
498 }; 503 };
499 504
500 result = GNUNET_SYSERR; 505 result = GNUNET_SYSERR;
501 ret = 506 ret =
502 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, 507 GNUNET_PROGRAM_run((sizeof(argv2) / sizeof(char *)) - 1, argv2,
503 "test_testbed_api", "nohelp", options, &run, NULL); 508 "test_testbed_api", "nohelp", options, &run, NULL);
504 if ((GNUNET_OK != ret) || (GNUNET_OK != result)) 509 if ((GNUNET_OK != ret) || (GNUNET_OK != result))
505 return 1; 510 return 1;
506 return 0; 511 return 0;