util_topic_test.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #include <CUnit/CUnit.h>
  2. #include <CUnit/Basic.h>
  3. #include <util_mosq.h>
  4. static void match_helper(const char *sub, const char *topic)
  5. {
  6. int rc;
  7. bool match;
  8. rc = mosquitto_topic_matches_sub(sub, topic, &match);
  9. CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
  10. CU_ASSERT_EQUAL(match, true);
  11. }
  12. static void no_match_helper(int rc_expected, const char *sub, const char *topic)
  13. {
  14. int rc;
  15. bool match;
  16. rc = mosquitto_topic_matches_sub(sub, topic, &match);
  17. CU_ASSERT_EQUAL(rc, rc_expected);
  18. if(rc != rc_expected){
  19. printf("%d:%d %s:%s\n", rc, rc_expected, sub, topic);
  20. }
  21. CU_ASSERT_EQUAL(match, false);
  22. }
  23. /* ========================================================================
  24. * EMPTY INPUT
  25. * ======================================================================== */
  26. static void TEST_empty_input(void)
  27. {
  28. int rc;
  29. bool match;
  30. rc = mosquitto_topic_matches_sub("sub", NULL, &match);
  31. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  32. CU_ASSERT_EQUAL(match, false);
  33. rc = mosquitto_topic_matches_sub(NULL, "topic", &match);
  34. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  35. CU_ASSERT_EQUAL(match, false);
  36. rc = mosquitto_topic_matches_sub(NULL, NULL, &match);
  37. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  38. CU_ASSERT_EQUAL(match, false);
  39. rc = mosquitto_topic_matches_sub("sub", "", &match);
  40. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  41. CU_ASSERT_EQUAL(match, false);
  42. rc = mosquitto_topic_matches_sub("", "topic", &match);
  43. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  44. CU_ASSERT_EQUAL(match, false);
  45. rc = mosquitto_topic_matches_sub("", "", &match);
  46. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  47. CU_ASSERT_EQUAL(match, false);
  48. rc = mosquitto_topic_matches_sub2("sub", 3, NULL, 0, &match);
  49. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  50. CU_ASSERT_EQUAL(match, false);
  51. rc = mosquitto_topic_matches_sub2(NULL, 0, "topic", 5, &match);
  52. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  53. CU_ASSERT_EQUAL(match, false);
  54. rc = mosquitto_topic_matches_sub2(NULL, 0, NULL, 0, &match);
  55. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  56. CU_ASSERT_EQUAL(match, false);
  57. rc = mosquitto_topic_matches_sub2("sub", 3, "", 0, &match);
  58. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  59. CU_ASSERT_EQUAL(match, false);
  60. rc = mosquitto_topic_matches_sub2("", 0, "topic", 5, &match);
  61. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  62. CU_ASSERT_EQUAL(match, false);
  63. rc = mosquitto_topic_matches_sub2("", 0, "", 0, &match);
  64. CU_ASSERT_EQUAL(rc, MOSQ_ERR_INVAL);
  65. CU_ASSERT_EQUAL(match, false);
  66. }
  67. /* ========================================================================
  68. * VALID MATCHING AND NON-MATCHING
  69. * ======================================================================== */
  70. static void TEST_valid_matching(void)
  71. {
  72. match_helper("foo/#", "foo/");
  73. match_helper("foo/#", "foo");
  74. match_helper("foo//bar", "foo//bar");
  75. match_helper("foo//+", "foo//bar");
  76. match_helper("foo/+/+/baz", "foo///baz");
  77. match_helper("foo/bar/+", "foo/bar/");
  78. match_helper("foo/bar", "foo/bar");
  79. match_helper("foo/+", "foo/bar");
  80. match_helper("foo/+/baz", "foo/bar/baz");
  81. match_helper("A/B/+/#", "A/B/B/C");
  82. match_helper("foo/+/#", "foo/bar/baz");
  83. match_helper("foo/+/#", "foo/bar");
  84. match_helper("#", "foo/bar/baz");
  85. match_helper("#", "foo/bar/baz");
  86. match_helper("#", "/foo/bar");
  87. match_helper("/#", "/foo/bar");
  88. }
  89. static void TEST_invalid_but_matching(void)
  90. {
  91. /* Matching here is "naive treatment of the wildcards would produce a
  92. * match". They shouldn't really match, they should fail. */
  93. no_match_helper(MOSQ_ERR_INVAL, "+foo", "+foo");
  94. no_match_helper(MOSQ_ERR_INVAL, "fo+o", "fo+o");
  95. no_match_helper(MOSQ_ERR_INVAL, "foo+", "foo+");
  96. no_match_helper(MOSQ_ERR_INVAL, "+foo/bar", "+foo/bar");
  97. no_match_helper(MOSQ_ERR_INVAL, "foo+/bar", "foo+/bar");
  98. no_match_helper(MOSQ_ERR_INVAL, "foo/+bar", "foo/+bar");
  99. no_match_helper(MOSQ_ERR_INVAL, "foo/bar+", "foo/bar+");
  100. no_match_helper(MOSQ_ERR_INVAL, "+foo", "afoo");
  101. no_match_helper(MOSQ_ERR_INVAL, "fo+o", "foao");
  102. no_match_helper(MOSQ_ERR_INVAL, "foo+", "fooa");
  103. no_match_helper(MOSQ_ERR_INVAL, "+foo/bar", "afoo/bar");
  104. no_match_helper(MOSQ_ERR_INVAL, "foo+/bar", "fooa/bar");
  105. no_match_helper(MOSQ_ERR_INVAL, "foo/+bar", "foo/abar");
  106. no_match_helper(MOSQ_ERR_INVAL, "foo/bar+", "foo/bara");
  107. no_match_helper(MOSQ_ERR_INVAL, "#foo", "#foo");
  108. no_match_helper(MOSQ_ERR_INVAL, "fo#o", "fo#o");
  109. no_match_helper(MOSQ_ERR_INVAL, "foo#", "foo#");
  110. no_match_helper(MOSQ_ERR_INVAL, "#foo/bar", "#foo/bar");
  111. no_match_helper(MOSQ_ERR_INVAL, "foo#/bar", "foo#/bar");
  112. no_match_helper(MOSQ_ERR_INVAL, "foo/#bar", "foo/#bar");
  113. no_match_helper(MOSQ_ERR_INVAL, "foo/bar#", "foo/bar#");
  114. no_match_helper(MOSQ_ERR_INVAL, "foo+", "fooa");
  115. no_match_helper(MOSQ_ERR_INVAL, "foo/+", "foo/+");
  116. no_match_helper(MOSQ_ERR_INVAL, "foo/#", "foo/+");
  117. no_match_helper(MOSQ_ERR_INVAL, "foo/+", "foo/bar/+");
  118. no_match_helper(MOSQ_ERR_INVAL, "foo/#", "foo/bar/+");
  119. no_match_helper(MOSQ_ERR_INVAL, "foo/+", "foo/#");
  120. no_match_helper(MOSQ_ERR_INVAL, "foo/#", "foo/#");
  121. no_match_helper(MOSQ_ERR_INVAL, "foo/+", "foo/bar/#");
  122. no_match_helper(MOSQ_ERR_INVAL, "foo/#", "foo/bar/#");
  123. }
  124. static void TEST_valid_no_matching(void)
  125. {
  126. no_match_helper(MOSQ_ERR_SUCCESS, "test/6/#", "test/3");
  127. no_match_helper(MOSQ_ERR_SUCCESS, "foo/bar", "foo");
  128. no_match_helper(MOSQ_ERR_SUCCESS, "foo/+", "foo/bar/baz");
  129. no_match_helper(MOSQ_ERR_SUCCESS, "foo/+/baz", "foo/bar/bar");
  130. no_match_helper(MOSQ_ERR_SUCCESS, "foo/+/#", "fo2/bar/baz");
  131. no_match_helper(MOSQ_ERR_SUCCESS, "/#", "foo/bar");
  132. no_match_helper(MOSQ_ERR_SUCCESS, "#", "$SYS/bar");
  133. no_match_helper(MOSQ_ERR_SUCCESS, "$BOB/bar", "$SYS/bar");
  134. }
  135. static void TEST_invalid(void)
  136. {
  137. no_match_helper(MOSQ_ERR_INVAL, "foo#", "foo");
  138. no_match_helper(MOSQ_ERR_INVAL, "fo#o/", "foo");
  139. no_match_helper(MOSQ_ERR_INVAL, "foo#", "fooa");
  140. no_match_helper(MOSQ_ERR_INVAL, "foo+", "foo");
  141. no_match_helper(MOSQ_ERR_INVAL, "foo/#a", "foo");
  142. no_match_helper(MOSQ_ERR_INVAL, "#a", "foo");
  143. no_match_helper(MOSQ_ERR_INVAL, "foo/#abc", "foo");
  144. no_match_helper(MOSQ_ERR_INVAL, "#abc", "foo");
  145. no_match_helper(MOSQ_ERR_INVAL, "/#a", "foo/bar");
  146. }
  147. /* ========================================================================
  148. * PUB TOPIC CHECK
  149. * ======================================================================== */
  150. static void pub_topic_helper(const char *topic, int rc_expected)
  151. {
  152. int rc;
  153. rc = mosquitto_pub_topic_check(topic);
  154. CU_ASSERT_EQUAL(rc, rc_expected);
  155. rc = mosquitto_pub_topic_check2(topic, strlen(topic));
  156. CU_ASSERT_EQUAL(rc, rc_expected);
  157. }
  158. static void TEST_pub_topic_valid(void)
  159. {
  160. pub_topic_helper("pub/topic", MOSQ_ERR_SUCCESS);
  161. pub_topic_helper("pub//topic", MOSQ_ERR_SUCCESS);
  162. pub_topic_helper("pub/ /topic", MOSQ_ERR_SUCCESS);
  163. }
  164. static void TEST_pub_topic_invalid(void)
  165. {
  166. pub_topic_helper("+pub/topic", MOSQ_ERR_INVAL);
  167. pub_topic_helper("pub+/topic", MOSQ_ERR_INVAL);
  168. pub_topic_helper("pub/+topic", MOSQ_ERR_INVAL);
  169. pub_topic_helper("pub/topic+", MOSQ_ERR_INVAL);
  170. pub_topic_helper("pub/topic/+", MOSQ_ERR_INVAL);
  171. pub_topic_helper("#pub/topic", MOSQ_ERR_INVAL);
  172. pub_topic_helper("pub#/topic", MOSQ_ERR_INVAL);
  173. pub_topic_helper("pub/#topic", MOSQ_ERR_INVAL);
  174. pub_topic_helper("pub/topic#", MOSQ_ERR_INVAL);
  175. pub_topic_helper("pub/topic/#", MOSQ_ERR_INVAL);
  176. pub_topic_helper("+/pub/topic", MOSQ_ERR_INVAL);
  177. }
  178. /* ========================================================================
  179. * SUB TOPIC CHECK
  180. * ======================================================================== */
  181. static void sub_topic_helper(const char *topic, int rc_expected)
  182. {
  183. int rc;
  184. rc = mosquitto_sub_topic_check(topic);
  185. CU_ASSERT_EQUAL(rc, rc_expected);
  186. rc = mosquitto_sub_topic_check2(topic, strlen(topic));
  187. CU_ASSERT_EQUAL(rc, rc_expected);
  188. }
  189. static void TEST_sub_topic_valid(void)
  190. {
  191. sub_topic_helper("sub/topic", MOSQ_ERR_SUCCESS);
  192. sub_topic_helper("sub//topic", MOSQ_ERR_SUCCESS);
  193. sub_topic_helper("sub/ /topic", MOSQ_ERR_SUCCESS);
  194. sub_topic_helper("sub/+/topic", MOSQ_ERR_SUCCESS);
  195. sub_topic_helper("+/+/+", MOSQ_ERR_SUCCESS);
  196. sub_topic_helper("+", MOSQ_ERR_SUCCESS);
  197. sub_topic_helper("sub/topic/#", MOSQ_ERR_SUCCESS);
  198. sub_topic_helper("sub//topic/#", MOSQ_ERR_SUCCESS);
  199. sub_topic_helper("sub/ /topic/#", MOSQ_ERR_SUCCESS);
  200. sub_topic_helper("sub/+/topic/#", MOSQ_ERR_SUCCESS);
  201. sub_topic_helper("+/+/+/#", MOSQ_ERR_SUCCESS);
  202. sub_topic_helper("#", MOSQ_ERR_SUCCESS);
  203. }
  204. static void TEST_sub_topic_invalid(void)
  205. {
  206. sub_topic_helper("+sub/topic", MOSQ_ERR_INVAL);
  207. sub_topic_helper("sub+/topic", MOSQ_ERR_INVAL);
  208. sub_topic_helper("sub/+topic", MOSQ_ERR_INVAL);
  209. sub_topic_helper("sub/topic+", MOSQ_ERR_INVAL);
  210. sub_topic_helper("#sub/topic", MOSQ_ERR_INVAL);
  211. sub_topic_helper("sub#/topic", MOSQ_ERR_INVAL);
  212. sub_topic_helper("sub/#topic", MOSQ_ERR_INVAL);
  213. sub_topic_helper("sub/topic#", MOSQ_ERR_INVAL);
  214. sub_topic_helper("#/sub/topic", MOSQ_ERR_INVAL);
  215. }
  216. /* ========================================================================
  217. * TEST SUITE SETUP
  218. * ======================================================================== */
  219. int init_util_topic_tests(void)
  220. {
  221. CU_pSuite test_suite = NULL;
  222. test_suite = CU_add_suite("Util topic", NULL, NULL);
  223. if(!test_suite){
  224. printf("Error adding CUnit util topic test suite.\n");
  225. return 1;
  226. }
  227. if(0
  228. || !CU_add_test(test_suite, "Matching: Empty input", TEST_empty_input)
  229. || !CU_add_test(test_suite, "Matching: Valid matching", TEST_valid_matching)
  230. || !CU_add_test(test_suite, "Matching: Valid no matching", TEST_valid_no_matching)
  231. || !CU_add_test(test_suite, "Matching: Invalid but matching", TEST_invalid_but_matching)
  232. || !CU_add_test(test_suite, "Matching: Invalid", TEST_invalid)
  233. || !CU_add_test(test_suite, "Pub topic: Valid", TEST_pub_topic_valid)
  234. || !CU_add_test(test_suite, "Pub topic: Invalid", TEST_pub_topic_invalid)
  235. || !CU_add_test(test_suite, "Sub topic: Valid", TEST_sub_topic_valid)
  236. || !CU_add_test(test_suite, "Sub topic: Invalid", TEST_sub_topic_invalid)
  237. ){
  238. printf("Error adding util topic CUnit tests.\n");
  239. return 1;
  240. }
  241. return 0;
  242. }