Newer
Older
libkc / modules / test / src / test_queue.c
Nomura Kei on 24 May 2024 7 KB add queue
  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <threads.h>
  4.  
  5. #include <kc.h>
  6. #include <kc_ut.h>
  7. #include <kc_assert.h>
  8. #include <kc_queue.h>
  9. #include <kc_memory.h>
  10.  
  11. #include "ut.h"
  12.  
  13. // プロトタイプ宣言
  14. static void test_queue_new(void);
  15. static void test_queue_offer(void);
  16. static void test_queue_put(void);
  17. static void test_queue_size(void);
  18. static void test_queue_offer_ng(void);
  19. static void test_queue_malloc_error(void);
  20.  
  21. /**
  22. * KcQueue 単体テストスイート
  23. */
  24. void suite_queue(void)
  25. {
  26. KcUt *ut = KcUt_get_instance();
  27. ut->add(ut, UT_TESTCASE, "queue new/delete", test_queue_new);
  28. ut->add(ut, UT_TESTCASE, "queue offer/peek/poll", test_queue_offer);
  29. ut->add(ut, UT_TESTCASE, "queue put/take", test_queue_put);
  30. ut->add(ut, UT_TESTCASE, "queue size", test_queue_size);
  31. ut->add(ut, UT_TESTCASE, "queue offer ng", test_queue_offer_ng);
  32. ut->add(ut, UT_TESTCASE, "queue malloc error", test_queue_malloc_error);
  33. }
  34.  
  35. /**
  36. * Queue 生成/破棄。
  37. *
  38. * @process KcQueue_new を実行する。。
  39. * @result KcQueue が生成されること。
  40. *
  41. * @process KcQueue_delete にて Queue を破棄する。
  42. * @result Queue が破棄されること。
  43. */
  44. static void test_queue_new(void)
  45. {
  46. KcQueue *queue = KcQueue_new(0);
  47. assert_not_null(queue);
  48. KcQueue_delete(queue);
  49.  
  50. // リストが残った状態での削除
  51. queue = KcQueue_new(0);
  52. queue->offer(queue, "ABC", 4);
  53. assert_not_null(queue);
  54. KcQueue_delete(queue);
  55. }
  56.  
  57. // for offer thread
  58. static int test_queue_offer_thread(void *arg)
  59. {
  60. KcQueue *queue = (KcQueue *)arg;
  61. struct timespec spec;
  62. spec.tv_sec = 0;
  63. spec.tv_nsec = 1;
  64. for (int i = 0; i < 100; i++)
  65. {
  66. printf("offer: %d\n", i);
  67. queue->offer(queue, &i, sizeof(int));
  68. thrd_sleep(&spec, NULL);
  69. }
  70. return 0;
  71. }
  72.  
  73. // for poll thread
  74. static int test_queue_poll_thread(void *arg)
  75. {
  76. struct timespec spec;
  77. spec.tv_sec = 0;
  78. spec.tv_nsec = 1;
  79. KcQueue *queue = (KcQueue *)arg;
  80. for (int i = 0; i < 100; i++)
  81. {
  82. int *val = queue->peek(queue, NULL);
  83. if (val == NULL)
  84. {
  85. printf("peek: (null)\n");
  86. }
  87. else
  88. {
  89. printf("peek: %d\n", *val);
  90. }
  91.  
  92. int element;
  93. size_t size = sizeof(int);
  94. bool is_success = queue->poll(queue, &element, &size);
  95. if (is_success)
  96. {
  97. printf("poll: %d\n", element);
  98. }
  99. else
  100. {
  101. printf("poll: (null)\n");
  102. }
  103. thrd_sleep(&spec, NULL);
  104. }
  105. return 0;
  106. }
  107.  
  108. /**
  109. * キューへの値追加/取得。
  110. */
  111. static void test_queue_offer(void)
  112. {
  113. KcQueue *queue = KcQueue_new(10);
  114.  
  115. thrd_t offer_thread, poll_thread;
  116.  
  117. thrd_create(&offer_thread, test_queue_offer_thread, queue);
  118. thrd_create(&poll_thread, test_queue_poll_thread, queue);
  119.  
  120. thrd_join(offer_thread, NULL);
  121. thrd_join(poll_thread, NULL);
  122. KcQueue_delete(queue);
  123. }
  124.  
  125. // for put thread
  126. static int test_queue_put_thread(void *arg)
  127. {
  128. KcQueue *queue = (KcQueue *)arg;
  129. struct timespec spec;
  130. spec.tv_sec = 0;
  131. spec.tv_nsec = 1 * 1000;
  132. for (int i = 0; i < 100; i++)
  133. {
  134. queue->put(queue, &i, sizeof(int));
  135. thrd_sleep(&spec, NULL);
  136. }
  137. return 0;
  138. }
  139.  
  140. // for take thread
  141. static int test_queue_take_thread(void *arg)
  142. {
  143. struct timespec spec;
  144. spec.tv_sec = 0;
  145. spec.tv_nsec = 1;
  146. KcQueue *queue = (KcQueue *)arg;
  147. for (int i = 0; i < 100; i++)
  148. {
  149. int element;
  150. size_t size = sizeof(int);
  151. queue->take(queue, &element, &size);
  152. assert_equals(i, element);
  153. thrd_sleep(&spec, NULL);
  154. }
  155. return 0;
  156. }
  157.  
  158. // for take thread
  159. static int test_queue_take2_thread(void *arg)
  160. {
  161. struct timespec spec;
  162. spec.tv_sec = 0;
  163. spec.tv_nsec = 100 * 1000;
  164. KcQueue *queue = (KcQueue *)arg;
  165. for (int i = 0; i < 100; i++)
  166. {
  167. int element;
  168. size_t size = sizeof(int);
  169. queue->take(queue, &element, &size);
  170. assert_equals(i, element);
  171. thrd_sleep(&spec, NULL);
  172. }
  173. return 0;
  174. }
  175.  
  176. /**
  177. * キューへの値追加/取得。
  178. */
  179. static void test_queue_put(void)
  180. {
  181. {
  182. KcQueue *queue = KcQueue_new(0);
  183. thrd_t put_thread, take_thread;
  184. thrd_create(&put_thread, test_queue_put_thread, queue);
  185. thrd_create(&take_thread, test_queue_take_thread, queue);
  186. thrd_join(put_thread, NULL);
  187. thrd_join(take_thread, NULL);
  188. KcQueue_delete(queue);
  189. }
  190.  
  191. // PUT ブロックパターン
  192. {
  193. KcQueue *queue = KcQueue_new(5);
  194. thrd_t put_thread, take_thread;
  195. thrd_create(&put_thread, test_queue_put_thread, queue);
  196. thrd_create(&take_thread, test_queue_take2_thread, queue);
  197. thrd_join(put_thread, NULL);
  198. thrd_join(take_thread, NULL);
  199. KcQueue_delete(queue);
  200. }
  201. }
  202.  
  203. /**
  204. * キューサイズ取得
  205. */
  206. static void test_queue_size(void)
  207. {
  208. KcQueue *queue = KcQueue_new(0);
  209.  
  210. // キューへ追加
  211. bool ret = queue->offer(queue, "ABC", 4);
  212. assert_true(ret);
  213. ret = queue->offer(queue, "DEFG", 5);
  214. int size = queue->size(queue);
  215. assert_equals(2, size);
  216. bool is_empty = queue->is_empty(queue);
  217. assert_false(is_empty);
  218.  
  219. bool is_contains = queue->contains(queue, "ABC", 4);
  220. assert_true(is_contains);
  221. is_contains = queue->contains(queue, "DEFG", 5);
  222. assert_true(is_contains);
  223.  
  224. char buffer[10];
  225. size_t element_size;
  226. // 取り出し [peek]
  227. const char *val = (const char *)queue->peek(queue, &element_size);
  228. assert_equals(4, element_size);
  229. assert_equals("ABC", val);
  230. size = queue->size(queue);
  231. assert_equals(2, size);
  232. is_empty = queue->is_empty(queue);
  233. assert_false(is_empty);
  234. // 取り出し [poll] (サイズ不足)
  235. for (int i = 0; i < 10; i++)
  236. {
  237. buffer[i] = 'X';
  238. }
  239. buffer[9] = '\0';
  240. element_size = 2;
  241. queue->poll(queue, buffer, &element_size);
  242. assert_equals("ABXXXXXXX", buffer);
  243. assert_equals(4, element_size);
  244. size = queue->size(queue);
  245. assert_equals(1, size);
  246. is_empty = queue->is_empty(queue);
  247. assert_false(is_empty);
  248. is_contains = queue->contains(queue, "ABC", 4);
  249. assert_false(is_contains);
  250. is_contains = queue->contains(queue, "DEFG", 5);
  251. assert_true(is_contains);
  252.  
  253. // 取り出し [poll]
  254. for (int i = 0; i < 10; i++)
  255. {
  256. buffer[i] = 'X';
  257. }
  258. buffer[9] = '\0';
  259. element_size = 10;
  260. queue->poll(queue, buffer, &element_size);
  261. assert_equals("DEFG", buffer);
  262. assert_equals(5, element_size);
  263. size = queue->size(queue);
  264. assert_equals(0, size);
  265. is_empty = queue->is_empty(queue);
  266. assert_true(is_empty);
  267. is_contains = queue->contains(queue, "ABC", 4);
  268. assert_false(is_contains);
  269. is_contains = queue->contains(queue, "DEFG", 5);
  270. assert_false(is_contains);
  271.  
  272. KcQueue_delete(queue);
  273. }
  274.  
  275. /**
  276. * offer 失敗。
  277. */
  278. static void test_queue_offer_ng(void)
  279. {
  280. KcQueue *queue = KcQueue_new(3);
  281.  
  282. bool ret;
  283. ret = queue->offer(queue, "ABC", 4);
  284. assert_true(ret);
  285. ret = queue->offer(queue, "DEF", 4);
  286. assert_true(ret);
  287. ret = queue->offer(queue, "GHI", 4);
  288. assert_true(ret);
  289. ret = queue->offer(queue, "JKL", 4);
  290. assert_false(ret);
  291.  
  292. queue->clear(queue);
  293. ret = queue->is_empty(queue);
  294. assert_true(ret);
  295.  
  296. KcQueue_delete(queue);
  297. }
  298.  
  299. /**
  300. * Queue メモリ確保失敗。
  301. */
  302. static void test_queue_malloc_error(void)
  303. {
  304. // メモリ確保失敗
  305. KcQueue *queue;
  306. ut_alloc_control(0)
  307. {
  308. queue = KcQueue_new(0);
  309. }
  310. assert_null(queue);
  311.  
  312. // 内部管理のリストメモリ確保失敗
  313. ut_alloc_control(1)
  314. {
  315. queue = KcQueue_new(0);
  316. }
  317. assert_null(queue);
  318.  
  319. // 追加時のメモリ確保失敗
  320.  
  321. queue = KcQueue_new(10);
  322. ut_alloc_control(0)
  323. {
  324. bool ret = queue->offer(queue, "XYZ", 4);
  325. assert_false(ret);
  326. }
  327. KcQueue_delete(queue);
  328. }