PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/liblo-0.26/src/testlo.c

#
C | 1193 lines | 971 code | 159 blank | 63 comment | 335 complexity | 9d4d96a30c22302d6bb96bec1d07ff31 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /*
  2. * Copyright (C) 2004 Steve Harris
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as
  6. * published by the Free Software Foundation; either version 2.1 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * $Id$
  15. */
  16. /*
  17. * This is some testcase code - it exercises the internals of liblo, so its not
  18. * a good example to learn from, see examples/ for example code
  19. */
  20. #include <math.h>
  21. #include <float.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #ifdef _MSC_VER
  26. #define snprintf _snprintf
  27. #else
  28. #include <unistd.h>
  29. #endif
  30. #include "lo_types_internal.h"
  31. #include "lo_internal.h"
  32. #include "lo/lo.h"
  33. #include "config.h"
  34. #ifdef WIN32
  35. #define PATHDELIM "\\"
  36. #else
  37. #define PATHDELIM "/"
  38. #endif
  39. #ifndef MSG_NOSIGNAL
  40. #define MSG_NOSIGNAL 0
  41. #endif
  42. #define TEST(cond) if (!(cond)) { fprintf(stderr, "FAILED " #cond \
  43. " at %s:%d\n", __FILE__, __LINE__); \
  44. exit(1); } \
  45. else { printf("passed " #cond "\n"); }
  46. union end_test32 {
  47. uint32_t i;
  48. char c[4];
  49. };
  50. union end_test64 {
  51. uint64_t i;
  52. char c[8];
  53. };
  54. static int done = 0;
  55. static int bundle_count = 0;
  56. static int pattern_count = 0;
  57. static int reply_count = 0;
  58. static int subtest_count = 0;
  59. static int subtest_reply_count = 0;
  60. static int error_okay = 0;
  61. char testdata[5] = "ABCDE";
  62. static int jitter_count = 0;
  63. static float jitter_total = 0.0f;
  64. static float jitter_max = 0.0f;
  65. static float jitter_min = 1000.0f;
  66. void exitcheck(void);
  67. void test_deserialise(void);
  68. void test_validation(lo_address a);
  69. void test_multicast(lo_server_thread st);
  70. void error(int num, const char *m, const char *path);
  71. void rep_error(int num, const char *m, const char *path);
  72. int generic_handler(const char *path, const char *types, lo_arg **argv,
  73. int argc, lo_message data, void *user_data);
  74. int foo_handler(const char *path, const char *types, lo_arg **argv, int argc,
  75. lo_message data, void *user_data);
  76. int reply_handler(const char *path, const char *types, lo_arg **argv, int argc,
  77. lo_message data, void *user_data);
  78. int lots_handler(const char *path, const char *types, lo_arg **argv, int argc,
  79. lo_message data, void *user_data);
  80. int coerce_handler(const char *path, const char *types, lo_arg **argv, int argc,
  81. lo_message data, void *user_data);
  82. int bundle_handler(const char *path, const char *types, lo_arg **argv, int argc,
  83. lo_message data, void *user_data);
  84. int timestamp_handler(const char *path, const char *types, lo_arg **argv,
  85. int argc, lo_message data, void *user_data);
  86. int jitter_handler(const char *path, const char *types, lo_arg **argv, int argc,
  87. lo_message data, void *user_data);
  88. int pattern_handler(const char *path, const char *types, lo_arg **argv,
  89. int argc, lo_message data, void *user_data);
  90. int subtest_handler(const char *path, const char *types, lo_arg **argv,
  91. int argc, lo_message data, void *user_data);
  92. int subtest_reply_handler(const char *path, const char *types, lo_arg **argv,
  93. int argc, lo_message data, void *user_data);
  94. int quit_handler(const char *path, const char *types, lo_arg **argv, int argc,
  95. lo_message data, void *user_data);
  96. int test_varargs(lo_address a, const char *path, const char *types, ...);
  97. int main()
  98. {
  99. lo_blob btest = lo_blob_new(sizeof(testdata), testdata);
  100. lo_server_thread st, sta, stb;
  101. lo_server s = lo_server_new(NULL, error);
  102. lo_bundle b;
  103. lo_message m1, m2;
  104. char *server_url, *path, *protocol, *host, *port;
  105. const char *host2, *port2;
  106. lo_address a;
  107. uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00};
  108. union end_test32 et32;
  109. union end_test64 et64;
  110. lo_timetag tt = {0x1, 0x80000000}, sched;
  111. int count;
  112. int proto;
  113. char cmd[256];
  114. test_deserialise();
  115. sta = lo_server_thread_new("7591", error);
  116. stb = lo_server_thread_new("7591", rep_error);
  117. if (stb) {
  118. fprintf(stderr, "FAILED: create bad server thread object!\n");
  119. exit(1);
  120. }
  121. lo_server_thread_free(sta);
  122. /* leak check */
  123. st = lo_server_thread_new(NULL, error);
  124. lo_server_thread_start(st);
  125. #ifdef WIN32
  126. Sleep(4);
  127. #else
  128. usleep(4000);
  129. #endif
  130. lo_server_thread_stop(st);
  131. lo_server_thread_free(st);
  132. st = lo_server_thread_new(NULL, error);
  133. lo_server_thread_start(st);
  134. lo_server_thread_stop(st);
  135. lo_server_thread_free(st);
  136. st = lo_server_thread_new(NULL, error);
  137. lo_server_thread_free(st);
  138. st = lo_server_thread_new(NULL, error);
  139. lo_server_thread_free(st);
  140. st = lo_server_thread_new(NULL, error);
  141. a = lo_address_new_from_url("osc://localhost/");
  142. TEST(a != NULL);
  143. lo_address_free(a);
  144. a = lo_address_new_from_url("osc.://localhost/");
  145. TEST(a == NULL);
  146. atexit(exitcheck);
  147. printf("type tests\n");
  148. TEST(sizeof(float) == sizeof(int32_t));
  149. TEST(sizeof(double) == sizeof(int64_t));
  150. et32.i = 0x23242526U;
  151. et32.i = lo_htoo32(et32.i);
  152. if (et32.c[0] != 0x23 || et32.c[1] != 0x24 || et32.c[2] != 0x25 ||
  153. et32.c[3] != 0x26) {
  154. fprintf(stderr, "failed 32bit endian conversion test\n");
  155. fprintf(stderr, "0x23242526 -> %X\n", et32.i);
  156. exit(1);
  157. } else {
  158. printf("passed 32bit endian conversion test\n");
  159. }
  160. et64.i = 0x232425262728292AULL;
  161. et64.i = lo_htoo64(et64.i);
  162. if (et64.c[0] != 0x23 || et64.c[1] != 0x24 || et64.c[2] != 0x25 ||
  163. et64.c[3] != 0x26 || et64.c[4] != 0x27 || et64.c[5] != 0x28 ||
  164. et64.c[6] != 0x29 || et64.c[7] != 0x2A) {
  165. fprintf(stderr, "failed 64bit endian conversion\n");
  166. fprintf(stderr, "0x232425262728292A -> %llX\n", (long long unsigned int)et64.i);
  167. exit(1);
  168. } else {
  169. printf("passed 64bit endian conversion\n");
  170. }
  171. printf("\n");
  172. /* OSC URL tests */
  173. path = lo_url_get_path("osc.udp://localhost:9999/a/path/is/here");
  174. if (strcmp(path, "/a/path/is/here")) {
  175. printf("failed lo_url_get_path() test1\n");
  176. printf("'%s' != '/a/path/is/here'\n", path);
  177. exit(1);
  178. } else {
  179. printf("passed lo_url_get_path() test1\n");
  180. }
  181. free(path);
  182. protocol = lo_url_get_protocol("osc.udp://localhost:9999/a/path/is/here");
  183. if (strcmp(protocol, "udp")) {
  184. printf("failed lo_url_get_protocol() test1\n");
  185. printf("'%s' != 'udp'\n", protocol);
  186. exit(1);
  187. } else {
  188. printf("passed lo_url_get_protocol() test1\n");
  189. }
  190. free(protocol);
  191. protocol = lo_url_get_protocol("osc.tcp://localhost:9999/a/path/is/here");
  192. if (strcmp(protocol, "tcp")) {
  193. printf("failed lo_url_get_protocol() test2\n");
  194. printf("'%s' != 'tcp'\n", protocol);
  195. exit(1);
  196. } else {
  197. printf("passed lo_url_get_protocol() test2\n");
  198. }
  199. free(protocol);
  200. protocol = lo_url_get_protocol("osc.udp://[::ffff:localhost]:9999/a/path/is/here");
  201. if (strcmp(protocol, "udp")) {
  202. printf("failed lo_url_get_protocol() test1 (IPv6)\n");
  203. printf("'%s' != 'udp'\n", protocol);
  204. exit(1);
  205. } else {
  206. printf("passed lo_url_get_protocol() test1 (IPv6)\n");
  207. }
  208. free(protocol);
  209. proto = lo_url_get_protocol_id("osc.udp://localhost:9999/a/path/is/here");
  210. if (proto != LO_UDP) {
  211. printf("failed lo_url_get_protocol_id() test1\n");
  212. printf("'%d' != LO_UDP\n", proto);
  213. exit(1);
  214. } else {
  215. printf("passed lo_url_get_protocol_id() test1\n");
  216. }
  217. proto = lo_url_get_protocol_id("osc.tcp://localhost:9999/a/path/is/here");
  218. if (proto != LO_TCP) {
  219. printf("failed lo_url_get_protocol_id() test2\n");
  220. printf("'%d' != LO_TCP\n", proto);
  221. exit(1);
  222. } else {
  223. printf("passed lo_url_get_protocol_id() test2\n");
  224. }
  225. proto = lo_url_get_protocol_id("osc.invalid://localhost:9999/a/path/is/here");
  226. if (proto != -1) {
  227. printf("failed lo_url_get_protocol_id() test3\n");
  228. printf("'%d' != -1\n", proto);
  229. exit(1);
  230. } else {
  231. printf("passed lo_url_get_protocol_id() test3\n");
  232. }
  233. proto = lo_url_get_protocol_id("osc.udp://[::ffff:localhost]:9999/a/path/is/here");
  234. if (proto != LO_UDP) {
  235. printf("failed lo_url_get_protocol_id() test1 (IPv6)\n");
  236. printf("'%d' != LO_UDP\n", proto);
  237. exit(1);
  238. } else {
  239. printf("passed lo_url_get_protocol_id() test1 (IPv6)\n");
  240. }
  241. host = lo_url_get_hostname("osc.udp://foo.example.com:9999/a/path/is/here");
  242. if (strcmp(host, "foo.example.com")) {
  243. printf("failed lo_url_get_hostname() test1\n");
  244. printf("'%s' != 'foo.example.com'\n", host);
  245. exit(1);
  246. } else {
  247. printf("passed lo_url_get_hostname() test1\n");
  248. }
  249. free(host);
  250. host = lo_url_get_hostname("osc.udp://[0000::::0001]:9999/a/path/is/here");
  251. if (strcmp(host, "0000::::0001")) {
  252. printf("failed lo_url_get_hostname() test2 (IPv6)\n");
  253. printf("'%s' != '0000::::0001'\n", host);
  254. exit(1);
  255. } else {
  256. printf("passed lo_url_get_hostname() test2 (IPv6)\n");
  257. }
  258. free(host);
  259. port = lo_url_get_port("osc.udp://localhost:9999/a/path/is/here");
  260. if (strcmp(port, "9999")) {
  261. printf("failed lo_url_get_port() test1\n");
  262. printf("'%s' != '9999'\n", port);
  263. exit(1);
  264. } else {
  265. printf("passed lo_url_get_port() test1\n");
  266. }
  267. free(port);
  268. port = lo_url_get_port("osc.udp://[::ffff:127.0.0.1]:9999/a/path/is/here");
  269. if (strcmp(port, "9999")) {
  270. printf("failed lo_url_get_port() test1 (IPv6)\n");
  271. printf("'%s' != '9999'\n", port);
  272. exit(1);
  273. } else {
  274. printf("passed lo_url_get_port() test1 (IPv6)\n");
  275. }
  276. free(port);
  277. printf("\n");
  278. a = lo_address_new_from_url("osc.tcp://foo.example.com:9999/");
  279. host2 = lo_address_get_hostname(a);
  280. if (strcmp(host2, "foo.example.com")) {
  281. printf("failed lo_address_get_hostname() test\n");
  282. printf("'%s' != 'foo.example.com'\n", host2);
  283. exit(1);
  284. } else {
  285. printf("passed lo_address_get_hostname() test\n");
  286. }
  287. port2 = lo_address_get_port(a);
  288. if (strcmp(port2, "9999")) {
  289. printf("failed lo_address_get_port() test\n");
  290. printf("'%s' != '9999'\n", port2);
  291. exit(1);
  292. } else {
  293. printf("passed lo_address_get_port() test\n");
  294. }
  295. proto = lo_address_get_protocol(a);
  296. if (proto != LO_TCP) {
  297. printf("failed lo_address_get_protocol() test\n");
  298. printf("'%d' != '%d'\n", proto, LO_TCP);
  299. exit(1);
  300. } else {
  301. printf("passed lo_address_get_protocol() test\n");
  302. }
  303. server_url = lo_address_get_url(a);
  304. if (strcmp(server_url, "osc.tcp://foo.example.com:9999/")) {
  305. printf("failed lo_address_get_url() test\n");
  306. printf("'%s' != '%s'\n", server_url, "osc.tcp://foo.example.com:9999/");
  307. exit(1);
  308. } else {
  309. printf("passed lo_address_get_url() test\n");
  310. }
  311. free(server_url);
  312. lo_address_free( a );
  313. printf("\n");
  314. /* Test blod sizes */
  315. if (lo_blob_datasize(btest) != 5 || lo_blobsize(btest) != 12) {
  316. printf("blob is %d (%d) bytes long, should be 5 (12)\n",
  317. lo_blob_datasize(btest), lo_blobsize(btest));
  318. lo_arg_pp(LO_BLOB, btest);
  319. printf(" <- blob\n");
  320. exit(1);
  321. }
  322. /* Server method handler tests */
  323. server_url = lo_server_thread_get_url(st);
  324. a = lo_address_new_from_url(server_url);
  325. printf("Server URL: %s\n", server_url);
  326. free(server_url);
  327. /* add method that will match the path /foo/bar, with two numbers, coerced
  328. * to float and int */
  329. lo_server_thread_add_method(st, "/foo/bar", "fi", foo_handler, lo_server_thread_get_server(st));
  330. lo_server_thread_add_method(st, "/reply", "s", reply_handler, NULL);
  331. lo_server_thread_add_method(st, "/lotsofformats", "fisbmhtdSccTFNI",
  332. lots_handler, NULL);
  333. lo_server_thread_add_method(st, "/coerce", "dfhiSs",
  334. coerce_handler, NULL);
  335. lo_server_thread_add_method(st, "/bundle", NULL,
  336. bundle_handler, NULL);
  337. lo_server_thread_add_method(st, "/timestamp", NULL,
  338. timestamp_handler, NULL);
  339. lo_server_thread_add_method(st, "/jitter", "ti",
  340. jitter_handler, NULL);
  341. lo_server_thread_add_method(st, "/pattern/foo", NULL,
  342. pattern_handler, "foo");
  343. lo_server_thread_add_method(st, "/pattern/bar", NULL,
  344. pattern_handler, "bar");
  345. lo_server_thread_add_method(st, "/pattern/baz", NULL,
  346. pattern_handler, "baz");
  347. lo_server_thread_add_method(st, "/subtest", "i",
  348. subtest_handler, st);
  349. lo_server_thread_add_method(st, "/subtest-reply", "i",
  350. subtest_reply_handler, NULL);
  351. /* add method that will match any path and args */
  352. lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL);
  353. /* add method that will match the path /quit with no args */
  354. lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL);
  355. /* check that the thread restarts */
  356. lo_server_thread_start(st);
  357. lo_server_thread_stop(st);
  358. lo_server_thread_start(st);
  359. if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) {
  360. printf("OSC error A %d: %s\n", lo_address_errno(a), lo_address_errstr(a));
  361. exit(1);
  362. }
  363. if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) {
  364. printf("OSC error B %d: %s\n", lo_address_errno(a), lo_address_errstr(a));
  365. exit(1);
  366. }
  367. test_validation(a);
  368. test_multicast(st);
  369. lo_send(a, "/", "i", 242);
  370. lo_send(a, "/pattern/", "i", 243);
  371. #ifndef _MSC_VER /* MS compiler refuses to compile this case */
  372. lo_send(a, "/bar", "ff", 0.12345678f, 1.0/0.0);
  373. #endif
  374. lo_send(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123",
  375. btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym",
  376. 'X', 'Y');
  377. lo_send(a, "/coerce", "fdihsS", 0.1f, 0.2, 123, 124LL, "aaa", "bbb");
  378. lo_send(a, "/coerce", "ffffss", 0.1f, 0.2f, 123.0, 124.0, "aaa", "bbb");
  379. lo_send(a, "/coerce", "ddddSS", 0.1, 0.2, 123.0, 124.0, "aaa", "bbb");
  380. lo_send(a, "/a/b/c/d", "sfsff", "one", 0.12345678f, "three",
  381. -0.00000023001f, 1.0);
  382. lo_send(a, "/a/b/c/d", "b", btest);
  383. TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123,
  384. "123", btest, midi_data, 0x0123456789abcdefULL, tt,
  385. 0.9999, "sym", 'X', 'Y', LO_ARGS_END) == 0);
  386. #ifdef __GNUC__
  387. // Note: Lack of support for variable-argument macros in non-GCC compilers
  388. // does not allow us to test for these conditions.
  389. // too many args
  390. TEST(test_varargs(a, "/lotsofformats", "f", 0.12345678f, 123,
  391. "123", btest, midi_data, 0x0123456789abcdefULL, tt,
  392. 0.9999, "sym", 'X', 'Y', LO_ARGS_END) != 0);
  393. // too many types
  394. TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123,
  395. "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.5,
  396. LO_ARGS_END) != 0);
  397. #endif
  398. // test lo_message_add
  399. m1 = lo_message_new();
  400. TEST(lo_message_add(m1, "fisbmhtdSccTFNI", 0.12345678f, 123, "123",
  401. btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym",
  402. 'X', 'Y') == 0);
  403. lo_send_message(a, "/lotsofformats", m1);
  404. lo_message_free(m1);
  405. lo_blob_free(btest);
  406. lo_send(a, "/pattern/*", "s", "a");
  407. lo_send(a, "/pattern/ba[rz]", "s", "b");
  408. server_url = lo_server_thread_get_url(st);
  409. sprintf(cmd, "." PATHDELIM "subtest %s &", server_url);
  410. if (system(cmd) != 0) {
  411. fprintf(stderr, "Cannot execute subtest command\n");
  412. exit(1);
  413. }
  414. system(cmd);
  415. free(server_url);
  416. #ifdef WIN32
  417. Sleep(2000);
  418. #else
  419. sleep(2);
  420. #endif
  421. TEST(reply_count == 3);
  422. TEST(pattern_count == 5);
  423. TEST(subtest_count == 2);
  424. TEST(subtest_reply_count == 22);
  425. printf("\n");
  426. {
  427. lo_timetag t = {10,0xFFFFFFFC};
  428. b = lo_bundle_new(t);
  429. }
  430. m1 = lo_message_new();
  431. lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz");
  432. lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  433. lo_bundle_add_message(b, "/bundle", m1);
  434. lo_send_bundle(a, b);
  435. /* This should be safe for multiple copies of the same message. */
  436. lo_bundle_free_messages(b);
  437. {
  438. lo_timetag t = {1,2};
  439. b = lo_bundle_new(t);
  440. }
  441. m1 = lo_message_new();
  442. lo_message_add_int32(m1, 23);
  443. lo_message_add_string(m1, "23");
  444. lo_bundle_add_message(b, "/bundle", m1);
  445. m2 = lo_message_new();
  446. lo_message_add_string(m2, "24");
  447. lo_message_add_int32(m2, 24);
  448. lo_bundle_add_message(b, "/bundle", m2);
  449. lo_bundle_add_message(b, "/bundle", m1);
  450. /*
  451. lo_send_bundle(a, b);
  452. if (a->errnum) {
  453. printf("error %d: %s\n", a->errnum, a->errstr);
  454. exit(1);
  455. }
  456. */
  457. TEST(lo_send_bundle(a, b) == 88);
  458. /* Test freeing out-of-order copies of messages in a bundle. */
  459. lo_bundle_free_messages(b);
  460. {
  461. lo_timetag t = {10,0xFFFFFFFE};
  462. b = lo_bundle_new(t);
  463. }
  464. m1 = lo_message_new();
  465. lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz");
  466. lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  467. lo_bundle_add_message(b, "/bundle", m1);
  468. lo_send_bundle(a, b);
  469. lo_message_free(m1);
  470. lo_bundle_free(b);
  471. lo_timetag_now(&sched);
  472. sched.sec += 5;
  473. b = lo_bundle_new(sched);
  474. m1 = lo_message_new();
  475. lo_message_add_string(m1, "future");
  476. lo_message_add_string(m1, "time");
  477. lo_message_add_string(m1, "test");
  478. lo_bundle_add_message(b, "/bundle", m1);
  479. lo_send_bundle(a, b);
  480. lo_message_free(m1);
  481. lo_bundle_free(b);
  482. lo_send_timestamped(a, sched, "/bundle", "s", "lo_send_timestamped() test");
  483. /* test bundle timestamp ends up in message struct (and doesn't end up in
  484. unbundled messages) */
  485. lo_timetag_now(&sched);
  486. lo_send_timestamped(a, sched, "/timestamp", "it", 1, sched);
  487. lo_send(a, "/timestamp", "it", 0, sched);
  488. #define JITTER_ITS 25
  489. /* jitter tests */
  490. {
  491. lo_timetag stamps[JITTER_ITS];
  492. lo_timetag now;
  493. int i;
  494. for (i=0; i<JITTER_ITS; i++) {
  495. lo_timetag_now(&now);
  496. stamps[i] = now;
  497. stamps[i].sec += 1;
  498. stamps[i].frac = rand();
  499. lo_send_timestamped(a, stamps[i], "/jitter", "ti", stamps[i], i);
  500. }
  501. }
  502. #ifdef WIN32
  503. Sleep(2000);
  504. #else
  505. sleep(2);
  506. #endif
  507. lo_address_free(a);
  508. TEST(lo_server_thread_events_pending(st));
  509. while (lo_server_thread_events_pending(st)) {
  510. printf("pending events, wait...\n");
  511. #ifdef WIN32
  512. fflush(stdout);
  513. Sleep(1000);
  514. #else
  515. sleep(1);
  516. #endif
  517. }
  518. TEST(bundle_count == 7);
  519. printf("\n");
  520. printf("bundle timing jitter results:\n"
  521. "max jitter = %fs\n"
  522. "avg jitter = %fs\n"
  523. "min jitter = %fs\n\n",
  524. jitter_max, jitter_total/(float)jitter_count, jitter_min);
  525. server_url = lo_server_get_url(s);
  526. lo_server_add_method(s, NULL, NULL, generic_handler, NULL);
  527. a = lo_address_new_from_url(server_url);
  528. TEST(lo_server_recv_noblock(s, 0) == 0);
  529. printf("Testing noblock API on %s\n", server_url);
  530. lo_send(a, "/non-block-test", "f", 23.0);
  531. count = 0;
  532. while (!lo_server_recv_noblock(s, 10) && count++ < 1000) { }
  533. if (count >= 1000) {
  534. printf("lo_server_recv_noblock() test failed\n");
  535. exit(1);
  536. }
  537. /* Delete methods */
  538. lo_server_thread_del_method(st, "/coerce", "dfhiSs");
  539. lo_server_del_method(s, NULL, NULL);
  540. lo_address_free(a);
  541. lo_server_free(s);
  542. free(server_url);
  543. #ifndef WIN32
  544. { /* UNIX domain tests */
  545. lo_address ua;
  546. lo_server us;
  547. char *addr;
  548. unlink("/tmp/testlo.osc");
  549. us = lo_server_new_with_proto("/tmp/testlo.osc", LO_UNIX, error);
  550. ua = lo_address_new_from_url("osc.unix:///tmp/testlo.osc");
  551. TEST(lo_server_get_protocol(us) == LO_UNIX);
  552. TEST(lo_send(ua, "/unix", "f", 23.0) == 16);
  553. TEST(lo_server_recv(us) == 16);
  554. addr = lo_server_get_url(us);
  555. TEST(!strcmp("osc.unix:////tmp/testlo.osc", addr));
  556. free(addr);
  557. lo_address_free(ua);
  558. ua = lo_address_new_with_proto(LO_UNIX, NULL, "/tmp/testlo.osc");
  559. TEST(lo_send(ua, "/unix", "f", 23.0) == 16);
  560. TEST(lo_server_recv(us) == 16);
  561. lo_server_free(us);
  562. lo_address_free(ua);
  563. }
  564. #endif
  565. { /* TCP tests */
  566. lo_address ta;
  567. lo_server ts;
  568. char *addr;
  569. ts = lo_server_new_with_proto(NULL, LO_TCP, error);
  570. addr = lo_server_get_url(ts);
  571. ta = lo_address_new_from_url(addr);
  572. if (lo_address_errno(ta)) {
  573. printf("err: %s\n", lo_address_errstr(ta));
  574. exit(1);
  575. }
  576. TEST(lo_server_get_protocol(ts) == LO_TCP);
  577. TEST(lo_send(ta, "/tcp", "f", 23.0) == 16);
  578. TEST(lo_send(ta, "/tcp", "f", 23.0) == 16);
  579. TEST(lo_server_recv(ts) == 16);
  580. TEST(lo_server_recv(ts) == 16);
  581. free(addr);
  582. lo_server_free(ts);
  583. lo_address_free(ta);
  584. }
  585. server_url = lo_server_thread_get_url(st);
  586. a = lo_address_new_from_url(server_url);
  587. /* exit */
  588. lo_send(a, "/quit", NULL);
  589. lo_address_free(a);
  590. while (!done) {
  591. #ifdef WIN32
  592. Sleep(1);
  593. #else
  594. usleep(1000);
  595. #endif
  596. }
  597. lo_server_thread_free(st);
  598. free(server_url);
  599. return 0;
  600. }
  601. void exitcheck(void)
  602. {
  603. if (!done) {
  604. fprintf(stderr, "\ntest run not completed\n" PACKAGE_NAME
  605. " test FAILED\n");
  606. } else {
  607. printf(PACKAGE_NAME " test PASSED\n");
  608. }
  609. }
  610. void error(int num, const char *msg, const char *path)
  611. {
  612. printf("liblo server error %d in %s: %s", num, path, msg);
  613. if (!error_okay)
  614. exit(1);
  615. else
  616. printf(" (expected)\n");
  617. }
  618. void rep_error(int num, const char *msg, const char *path)
  619. {
  620. if (num != 9904) {
  621. error(num, msg, path);
  622. }
  623. }
  624. int generic_handler(const char *path, const char *types, lo_arg **argv,
  625. int argc, lo_message data, void *user_data)
  626. {
  627. int i;
  628. printf("path: <%s>\n", path);
  629. for (i=0; i<argc; i++) {
  630. printf("arg %d '%c' ", i, types[i]);
  631. lo_arg_pp(types[i], argv[i]);
  632. printf("\n");
  633. }
  634. printf("\n");
  635. return 1;
  636. }
  637. int foo_handler(const char *path, const char *types, lo_arg **argv, int argc,
  638. lo_message data, void *user_data)
  639. {
  640. lo_server serv = (lo_server)user_data;
  641. lo_address src = lo_message_get_source(data);
  642. char *url = lo_address_get_url(src);
  643. char *server_url = lo_server_get_url(serv);
  644. printf("Address of us: %s\n", server_url);
  645. printf("%s <- f:%f, i:%d\n", path, argv[0]->f, argv[1]->i);
  646. if (lo_send_from(src, serv, LO_TT_IMMEDIATE, "/reply", "s", "a reply") == -1) {
  647. printf("OSC reply error %d: %s\nSending to %s\n", lo_address_errno(src), lo_address_errstr(src), url);
  648. exit(1);
  649. } else {
  650. printf("Reply sent to %s\n\n", url);
  651. }
  652. free(server_url);
  653. free(url);
  654. return 0;
  655. }
  656. int reply_handler(const char *path, const char *types, lo_arg **argv, int argc,
  657. lo_message data, void *user_data)
  658. {
  659. lo_address src = lo_message_get_source(data);
  660. char *url = lo_address_get_url(src);
  661. printf("Reply received from %s\n", url);
  662. free(url);
  663. reply_count++;
  664. return 0;
  665. }
  666. int lots_handler(const char *path, const char *types, lo_arg **argv, int argc,
  667. lo_message data, void *user_data)
  668. {
  669. lo_blob b;
  670. unsigned char *d;
  671. if (strcmp(path, "/lotsofformats")) {
  672. fprintf(stderr, "path != /lotsofformats\n");
  673. exit(1);
  674. }
  675. printf("path = %s\n", path);
  676. TEST(types[0] == 'f' && argv[0]->f == 0.12345678f);
  677. TEST(types[1] == 'i' && argv[1]->i == 123);
  678. TEST(types[2] == 's' && !strcmp(&argv[2]->s, "123"));
  679. b = (lo_blob)argv[3];
  680. d = lo_blob_dataptr(b);
  681. TEST(types[3] == 'b' && lo_blob_datasize(b) == 5);
  682. TEST(d[0] == 'A' && d[1] == 'B' && d[2] == 'C' && d[3] == 'D' &&
  683. d[4] == 'E');
  684. d = argv[4]->m;
  685. TEST(d[0] == 0xff && d[1] == 0xf7 && d[2] == 0xaa && d[3] == 0x00);
  686. TEST(types[5] == 'h' && argv[5]->h == 0x0123456789ABCDEFULL);
  687. TEST(types[6] == 't' && argv[6]->t.sec == 1 && \
  688. argv[6]->t.frac == 0x80000000);
  689. TEST(types[7] == 'd' && argv[7]->d == 0.9999);
  690. TEST(types[8] == 'S' && !strcmp(&argv[8]->S, "sym"));
  691. printf("char: %d\n", argv[9]->c);
  692. TEST(types[9] == 'c' && argv[9]->c == 'X');
  693. TEST(types[10] == 'c' && argv[10]->c == 'Y');
  694. TEST(types[11] == 'T');
  695. TEST(types[12] == 'F');
  696. TEST(types[13] == 'N');
  697. TEST(types[14] == 'I');
  698. printf("\n");
  699. return 0;
  700. }
  701. int coerce_handler(const char *path, const char *types, lo_arg **argv, int argc,
  702. lo_message data, void *user_data)
  703. {
  704. printf("path = %s\n", path);
  705. TEST(types[0] == 'd' && fabs(argv[0]->d - 0.1) < FLT_EPSILON);
  706. TEST(types[1] == 'f' && fabs(argv[1]->f - 0.2) < FLT_EPSILON);
  707. TEST(types[2] == 'h' && argv[2]->h == 123);
  708. TEST(types[3] == 'i' && argv[3]->i == 124);
  709. TEST(types[4] == 'S' && !strcmp(&argv[4]->S, "aaa"));
  710. TEST(types[5] == 's' && !strcmp(&argv[5]->s, "bbb"));
  711. printf("\n");
  712. return 0;
  713. }
  714. int bundle_handler(const char *path, const char *types, lo_arg **argv, int argc,
  715. lo_message data, void *user_data)
  716. {
  717. bundle_count++;
  718. printf("received bundle\n");
  719. return 0;
  720. }
  721. int timestamp_handler(const char *path, const char *types, lo_arg **argv,
  722. int argc, lo_message data, void *user_data)
  723. {
  724. int bundled = argv[0]->i;
  725. lo_timetag ts, arg_ts;
  726. ts = lo_message_get_timestamp(data);
  727. arg_ts = argv[1]->t;
  728. if (bundled) {
  729. TEST((ts.sec == arg_ts.sec) && (ts.frac == arg_ts.frac));
  730. }
  731. else {
  732. TEST(ts.sec == LO_TT_IMMEDIATE.sec && ts.frac == LO_TT_IMMEDIATE.frac);
  733. }
  734. return 0;
  735. }
  736. int jitter_handler(const char *path, const char *types, lo_arg **argv, int argc,
  737. lo_message data, void *user_data)
  738. {
  739. lo_timetag now;
  740. float jitter;
  741. lo_timetag_now(&now);
  742. jitter = fabs(lo_timetag_diff(now, argv[0]->t));
  743. jitter_count++;
  744. //printf("jitter: %f\n", jitter);
  745. printf("%d expected: %x:%x received %x:%x\n", argv[1]->i, argv[0]->t.sec,
  746. argv[0]->t.frac, now.sec, now.frac);
  747. jitter_total += jitter;
  748. if (jitter > jitter_max) jitter_max = jitter;
  749. if (jitter < jitter_min) jitter_min = jitter;
  750. return 0;
  751. }
  752. int pattern_handler(const char *path, const char *types, lo_arg **argv,
  753. int argc, lo_message data, void *user_data)
  754. {
  755. pattern_count++;
  756. printf("pattern matched %s\n", (char *)user_data);
  757. return 0;
  758. }
  759. int subtest_handler(const char *path, const char *types, lo_arg **argv,
  760. int argc, lo_message data, void *user_data)
  761. {
  762. lo_address a = lo_message_get_source(data);
  763. subtest_count++;
  764. printf("got subtest message %d\n", subtest_count);
  765. lo_send_from(a, lo_server_thread_get_server(user_data),
  766. LO_TT_IMMEDIATE, "/subtest", "i", subtest_count);
  767. return 0;
  768. }
  769. int subtest_reply_handler(const char *path, const char *types, lo_arg **argv,
  770. int argc, lo_message data, void *user_data)
  771. {
  772. subtest_reply_count++;
  773. //printf("got subtest reply message %d\n", subtest_reply_count);
  774. return 0;
  775. }
  776. int quit_handler(const char *path, const char *types, lo_arg **argv, int argc,
  777. lo_message data, void *user_data)
  778. {
  779. done = 1;
  780. return 0;
  781. }
  782. int test_varargs(lo_address a, const char *path, const char *types, ...)
  783. {
  784. va_list ap;
  785. lo_message m = lo_message_new();
  786. int error;
  787. va_start(ap, types);
  788. if ((error=lo_message_add_varargs(m, types, ap))==0)
  789. lo_send_message(a, path, m);
  790. else
  791. printf("lo_message_add_varargs returned %d\n", error);
  792. lo_message_free(m);
  793. return error<0;
  794. }
  795. void replace_char(char *str, size_t size, const char find, const char replace)
  796. {
  797. char *p = str;
  798. while(size--)
  799. {
  800. if (find == *p) { *p = replace; }
  801. ++p;
  802. }
  803. }
  804. void test_deserialise()
  805. {
  806. char *buf, *buf2, *tmp;
  807. const char *types = NULL, *path;
  808. lo_arg **argv = NULL;
  809. size_t len, size;
  810. char data[256];
  811. int result = 0;
  812. lo_blob btest = lo_blob_new(sizeof(testdata), testdata);
  813. uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00};
  814. lo_timetag tt = {0x1, 0x80000000};
  815. lo_blob b = NULL;
  816. // build a message
  817. lo_message msg = lo_message_new();
  818. TEST(0 == lo_message_get_argc(msg));
  819. lo_message_add_float(msg, 0.12345678f); // 0 f
  820. lo_message_add_int32(msg, 123); // 1 i
  821. lo_message_add_string(msg, "123"); // 2 s
  822. lo_message_add_blob(msg, btest); // 3 b
  823. lo_message_add_midi(msg, midi_data); // 4 m
  824. lo_message_add_int64(msg, 0x0123456789abcdefULL); // 5 h
  825. lo_message_add_timetag(msg, tt); // 6 t
  826. lo_message_add_double(msg, 0.9999); // 7 d
  827. lo_message_add_symbol(msg, "sym"); // 8 S
  828. lo_message_add_char(msg, 'X'); // 9 c
  829. lo_message_add_char(msg, 'Y'); // 10 c
  830. lo_message_add_true(msg); // 11 T
  831. lo_message_add_false(msg); // 12 F
  832. lo_message_add_nil(msg); // 13 N
  833. lo_message_add_infinitum(msg); // 14 I
  834. // test types, args
  835. TEST(15 == lo_message_get_argc(msg));
  836. types = lo_message_get_types(msg);
  837. TEST(NULL != types);
  838. argv = lo_message_get_argv(msg);
  839. TEST(NULL != argv);
  840. TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
  841. TEST('i' == types[1] && 123 == argv[1]->i);
  842. TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
  843. TEST('b' == types[3]);
  844. b = (lo_blob)argv[3];
  845. TEST(lo_blob_datasize(b) == sizeof(testdata));
  846. TEST(12 == lo_blobsize(b));
  847. TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
  848. TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4));
  849. TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h);
  850. TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
  851. TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
  852. TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym"));
  853. TEST('c' == types[9] && 'X' == argv[9]->c);
  854. TEST('c' == types[10] && 'Y' == argv[10]->c);
  855. TEST('T' == types[11] && NULL == argv[11]);
  856. TEST('F' == types[12] && NULL == argv[12]);
  857. TEST('N' == types[13] && NULL == argv[13]);
  858. TEST('I' == types[14] && NULL == argv[14]);
  859. // serialise it
  860. len = lo_message_length(msg, "/foo");
  861. printf("serialise message_length=%d\n", (int)len);
  862. buf = calloc(len, sizeof(char));
  863. size = 0;
  864. tmp = lo_message_serialise(msg, "/foo", buf, &size);
  865. TEST(tmp == buf && size == len && 92 == len);
  866. lo_message_free(msg);
  867. // deserialise it
  868. printf("deserialise\n");
  869. path = lo_get_path(buf, len);
  870. TEST(NULL != path && !strcmp(path, "/foo"));
  871. msg = lo_message_deserialise(buf, size, NULL);
  872. TEST(NULL != msg);
  873. // repeat same test as above
  874. TEST(15 == lo_message_get_argc(msg));
  875. types = lo_message_get_types(msg);
  876. TEST(NULL != types);
  877. argv = lo_message_get_argv(msg);
  878. TEST(NULL != argv);
  879. TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
  880. TEST('i' == types[1] && 123 == argv[1]->i);
  881. TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
  882. TEST('b' == types[3]);
  883. b = (lo_blob)argv[3];
  884. TEST(lo_blob_datasize(b) == sizeof(testdata));
  885. TEST(12 == lo_blobsize(b));
  886. TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
  887. TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4));
  888. TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h);
  889. TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
  890. TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
  891. TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym"));
  892. TEST('c' == types[9] && 'X' == argv[9]->c);
  893. TEST('c' == types[10] && 'Y' == argv[10]->c);
  894. TEST('T' == types[11] && NULL == argv[11]);
  895. TEST('F' == types[12] && NULL == argv[12]);
  896. TEST('N' == types[13] && NULL == argv[13]);
  897. TEST('I' == types[14] && NULL == argv[14]);
  898. // serialise it again, compare
  899. len = lo_message_length(msg, "/foo");
  900. printf("serialise message_length=%d\n", (int)len);
  901. buf2 = calloc(len, sizeof(char));
  902. size = 0;
  903. tmp = lo_message_serialise(msg, "/foo", buf2, &size);
  904. TEST(tmp == buf2 && size == len && 92 == len);
  905. TEST(!memcmp(buf, buf2, len));
  906. lo_message_free(msg);
  907. lo_blob_free(btest);
  908. free(buf);
  909. free(buf2);
  910. // deserialise failure tests with invalid message data
  911. msg = lo_message_deserialise(data, 0, &result); // 0 size
  912. TEST(NULL == msg && LO_ESIZE == result);
  913. snprintf(data, 256, "%s", "/foo"); // unterminated path string
  914. msg = lo_message_deserialise(data, 4, &result);
  915. TEST(NULL == msg && LO_EINVALIDPATH == result);
  916. snprintf(data, 256, "%s", "/f_o"); // non-0 in pad area
  917. msg = lo_message_deserialise(data, 4, &result);
  918. TEST(NULL == msg && LO_EINVALIDPATH == result);
  919. snprintf(data, 256, "%s", "/t__"); // types missing
  920. replace_char(data, 4, '_', '\0');
  921. msg = lo_message_deserialise(data, 4, &result);
  922. TEST(NULL == msg && LO_ENOTYPE == result);
  923. snprintf(data, 256, "%s%s", "/t__", "____"); // types empty
  924. replace_char(data, 8, '_', '\0');
  925. msg = lo_message_deserialise(data, 8, &result);
  926. TEST(NULL == msg && LO_EBADTYPE == result);
  927. snprintf(data, 256, "%s%s", "/t__", ",f_"); // short message
  928. replace_char(data, 7, '_', '\0');
  929. msg = lo_message_deserialise(data, 7, &result);
  930. TEST(NULL == msg && LO_EINVALIDTYPE == result);
  931. snprintf(data, 256, "%s%s", "/t__", "ifi_"); // types missing comma
  932. replace_char(data, 8, '_', '\0');
  933. msg = lo_message_deserialise(data, 8, &result);
  934. TEST(NULL == msg && LO_EBADTYPE == result);
  935. snprintf(data, 256, "%s%s", "/t__", ",ifi"); // types unterminated
  936. replace_char(data, 8, '_', '\0');
  937. msg = lo_message_deserialise(data, 8, &result);
  938. TEST(NULL == msg && LO_EINVALIDTYPE == result);
  939. snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data
  940. replace_char(data, 8, '_', '\0');
  941. msg = lo_message_deserialise(data, 12, &result);
  942. TEST(NULL == msg && LO_EINVALIDARG == result);
  943. snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data again
  944. replace_char(data, 8, '_', '\0');
  945. msg = lo_message_deserialise(data, 15, &result);
  946. TEST(NULL == msg && LO_EINVALIDARG == result);
  947. snprintf(data, 256, "%s%s", "/t__", ",f__"); // too much arg data
  948. replace_char(data, 8, '_', '\0');
  949. msg = lo_message_deserialise(data, 16, &result);
  950. TEST(NULL == msg && LO_ESIZE == result);
  951. snprintf(data, 256, "%s%s", "/t__", ",bs_"); // blob longer than msg length
  952. replace_char(data, 8, '_', '\0');
  953. *(uint32_t *)(data + 8) = lo_htoo32((uint32_t)99999);
  954. msg = lo_message_deserialise(data, 256, &result);
  955. TEST(NULL == msg && LO_EINVALIDARG == result);
  956. }
  957. void test_validation(lo_address a)
  958. {
  959. /* packet crafted to crash a lo_server when no input validation is performed */
  960. char mem[] = {"/\0\0\0,bs\0,\x00\x0F\x42\x3F"}; // OSC: "/" ",bs" 999999
  961. int eok = error_okay;
  962. int sock = a->socket;
  963. /* This code won't work with MSVC because the lo_client_sockets data structure
  964. * is not explicitly made available to external programs. We could expose it
  965. * in debug mode, perhaps, but let's just skip this test for now. (Can be tested
  966. * on Windows using MingW.) */
  967. #ifdef _MSC_VER
  968. return;
  969. #else
  970. printf("validation\n");
  971. if (sock == -1)
  972. sock = lo_client_sockets.udp;
  973. if (sock == -1) {
  974. fprintf(stderr, "Couldn't get socket in test_validation(), %s:%d\n", __FILE__, __LINE__);
  975. exit(1);
  976. }
  977. error_okay = 1;
  978. if (sendto(sock, &mem, sizeof(mem), MSG_NOSIGNAL,
  979. a->ai->ai_addr, a->ai->ai_addrlen)==-1) {
  980. fprintf(stderr, "Error sending packet in test_validation(), %s:%d\n", __FILE__, __LINE__);
  981. }
  982. #ifndef WIN32
  983. usleep(10000);
  984. #else
  985. Sleep(10);
  986. #endif
  987. error_okay = eok;
  988. #endif
  989. }
  990. void test_multicast(lo_server_thread st)
  991. {
  992. /* test multicast server and sender */
  993. /* message is sent from st otherwise reply doesn't work */
  994. lo_server ms = lo_server_new_multicast("224.0.1.1", "15432", error);
  995. lo_address ma = lo_address_new("224.0.1.1", "15432");
  996. lo_address_set_ttl(ma, 1);
  997. lo_server_add_method(ms, "/foo/bar", "fi", foo_handler, ms);
  998. lo_server_add_method(ms, "/reply", "s", reply_handler, NULL);
  999. if (lo_send_from(ma, lo_server_thread_get_server(st), LO_TT_IMMEDIATE,
  1000. "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) {
  1001. printf("multicast send error %d: %s\n", lo_address_errno(ma), lo_address_errstr(ma));
  1002. exit(1);
  1003. }
  1004. TEST(lo_server_recv(ms)==24);
  1005. lo_server_free(ms);
  1006. lo_address_free(ma);
  1007. }
  1008. /* vi:set ts=8 sts=4 sw=4: */