- #include <stdio.h>
- #include <errno.h>
- #include <threads.h>
-
- #include <kc.h>
- #include <kc_ut.h>
- #include <kc_assert.h>
- #include <kc_queue.h>
- #include <kc_memory.h>
-
- #include "ut.h"
-
- // プロトタイプ宣言
- static void test_queue_new(void);
- static void test_queue_offer(void);
- static void test_queue_put(void);
- static void test_queue_size(void);
- static void test_queue_offer_ng(void);
- static void test_queue_malloc_error(void);
-
- /**
- * KcQueue 単体テストスイート
- */
- void suite_queue(void)
- {
- KcUt *ut = KcUt_get_instance();
- ut->add(ut, UT_TESTCASE, "queue new/delete", test_queue_new);
- ut->add(ut, UT_TESTCASE, "queue offer/peek/poll", test_queue_offer);
- ut->add(ut, UT_TESTCASE, "queue put/take", test_queue_put);
- ut->add(ut, UT_TESTCASE, "queue size", test_queue_size);
- ut->add(ut, UT_TESTCASE, "queue offer ng", test_queue_offer_ng);
- ut->add(ut, UT_TESTCASE, "queue malloc error", test_queue_malloc_error);
- }
-
- /**
- * Queue 生成/破棄。
- *
- * @process KcQueue_new を実行する。。
- * @result KcQueue が生成されること。
- *
- * @process KcQueue_delete にて Queue を破棄する。
- * @result Queue が破棄されること。
- */
- static void test_queue_new(void)
- {
- KcQueue *queue = KcQueue_new(0);
- assert_not_null(queue);
- KcQueue_delete(queue);
-
- // リストが残った状態での削除
- queue = KcQueue_new(0);
- queue->offer(queue, "ABC", 4);
- assert_not_null(queue);
- KcQueue_delete(queue);
- }
-
- // for offer thread
- static int test_queue_offer_thread(void *arg)
- {
- KcQueue *queue = (KcQueue *)arg;
- struct timespec spec;
- spec.tv_sec = 0;
- spec.tv_nsec = 1;
- for (int i = 0; i < 100; i++)
- {
- printf("offer: %d\n", i);
- queue->offer(queue, &i, sizeof(int));
- thrd_sleep(&spec, NULL);
- }
- return 0;
- }
-
- // for poll thread
- static int test_queue_poll_thread(void *arg)
- {
- struct timespec spec;
- spec.tv_sec = 0;
- spec.tv_nsec = 1;
- KcQueue *queue = (KcQueue *)arg;
- for (int i = 0; i < 100; i++)
- {
- int *val = queue->peek(queue, NULL);
- if (val == NULL)
- {
- printf("peek: (null)\n");
- }
- else
- {
- printf("peek: %d\n", *val);
- }
-
- int element;
- size_t size = sizeof(int);
- bool is_success = queue->poll(queue, &element, &size);
- if (is_success)
- {
- printf("poll: %d\n", element);
- }
- else
- {
- printf("poll: (null)\n");
- }
- thrd_sleep(&spec, NULL);
- }
- return 0;
- }
-
- /**
- * キューへの値追加/取得。
- */
- static void test_queue_offer(void)
- {
- KcQueue *queue = KcQueue_new(10);
-
- thrd_t offer_thread, poll_thread;
-
- thrd_create(&offer_thread, test_queue_offer_thread, queue);
- thrd_create(&poll_thread, test_queue_poll_thread, queue);
-
- thrd_join(offer_thread, NULL);
- thrd_join(poll_thread, NULL);
- KcQueue_delete(queue);
- }
-
- // for put thread
- static int test_queue_put_thread(void *arg)
- {
- KcQueue *queue = (KcQueue *)arg;
- struct timespec spec;
- spec.tv_sec = 0;
- spec.tv_nsec = 1 * 1000;
- for (int i = 0; i < 100; i++)
- {
- queue->put(queue, &i, sizeof(int));
- thrd_sleep(&spec, NULL);
- }
- return 0;
- }
-
- // for take thread
- static int test_queue_take_thread(void *arg)
- {
- struct timespec spec;
- spec.tv_sec = 0;
- spec.tv_nsec = 1;
- KcQueue *queue = (KcQueue *)arg;
- for (int i = 0; i < 100; i++)
- {
- int element;
- size_t size = sizeof(int);
- queue->take(queue, &element, &size);
- assert_equals(i, element);
- thrd_sleep(&spec, NULL);
- }
- return 0;
- }
-
- // for take thread
- static int test_queue_take2_thread(void *arg)
- {
- struct timespec spec;
- spec.tv_sec = 0;
- spec.tv_nsec = 100 * 1000;
- KcQueue *queue = (KcQueue *)arg;
- for (int i = 0; i < 100; i++)
- {
- int element;
- size_t size = sizeof(int);
- queue->take(queue, &element, &size);
- assert_equals(i, element);
- thrd_sleep(&spec, NULL);
- }
- return 0;
- }
-
- /**
- * キューへの値追加/取得。
- */
- static void test_queue_put(void)
- {
- {
- KcQueue *queue = KcQueue_new(0);
- thrd_t put_thread, take_thread;
- thrd_create(&put_thread, test_queue_put_thread, queue);
- thrd_create(&take_thread, test_queue_take_thread, queue);
- thrd_join(put_thread, NULL);
- thrd_join(take_thread, NULL);
- KcQueue_delete(queue);
- }
-
- // PUT ブロックパターン
- {
- KcQueue *queue = KcQueue_new(5);
- thrd_t put_thread, take_thread;
- thrd_create(&put_thread, test_queue_put_thread, queue);
- thrd_create(&take_thread, test_queue_take2_thread, queue);
- thrd_join(put_thread, NULL);
- thrd_join(take_thread, NULL);
- KcQueue_delete(queue);
- }
- }
-
- /**
- * キューサイズ取得
- */
- static void test_queue_size(void)
- {
- KcQueue *queue = KcQueue_new(0);
-
- // キューへ追加
- bool ret = queue->offer(queue, "ABC", 4);
- assert_true(ret);
- ret = queue->offer(queue, "DEFG", 5);
- int size = queue->size(queue);
- assert_equals(2, size);
- bool is_empty = queue->is_empty(queue);
- assert_false(is_empty);
-
- bool is_contains = queue->contains(queue, "ABC", 4);
- assert_true(is_contains);
- is_contains = queue->contains(queue, "DEFG", 5);
- assert_true(is_contains);
-
- char buffer[10];
- size_t element_size;
- // 取り出し [peek]
- const char *val = (const char *)queue->peek(queue, &element_size);
- assert_equals(4, element_size);
- assert_equals("ABC", val);
- size = queue->size(queue);
- assert_equals(2, size);
- is_empty = queue->is_empty(queue);
- assert_false(is_empty);
- // 取り出し [poll] (サイズ不足)
- for (int i = 0; i < 10; i++)
- {
- buffer[i] = 'X';
- }
- buffer[9] = '\0';
- element_size = 2;
- queue->poll(queue, buffer, &element_size);
- assert_equals("ABXXXXXXX", buffer);
- assert_equals(4, element_size);
- size = queue->size(queue);
- assert_equals(1, size);
- is_empty = queue->is_empty(queue);
- assert_false(is_empty);
- is_contains = queue->contains(queue, "ABC", 4);
- assert_false(is_contains);
- is_contains = queue->contains(queue, "DEFG", 5);
- assert_true(is_contains);
-
- // 取り出し [poll]
- for (int i = 0; i < 10; i++)
- {
- buffer[i] = 'X';
- }
- buffer[9] = '\0';
- element_size = 10;
- queue->poll(queue, buffer, &element_size);
- assert_equals("DEFG", buffer);
- assert_equals(5, element_size);
- size = queue->size(queue);
- assert_equals(0, size);
- is_empty = queue->is_empty(queue);
- assert_true(is_empty);
- is_contains = queue->contains(queue, "ABC", 4);
- assert_false(is_contains);
- is_contains = queue->contains(queue, "DEFG", 5);
- assert_false(is_contains);
-
- KcQueue_delete(queue);
- }
-
- /**
- * offer 失敗。
- */
- static void test_queue_offer_ng(void)
- {
- KcQueue *queue = KcQueue_new(3);
-
- bool ret;
- ret = queue->offer(queue, "ABC", 4);
- assert_true(ret);
- ret = queue->offer(queue, "DEF", 4);
- assert_true(ret);
- ret = queue->offer(queue, "GHI", 4);
- assert_true(ret);
- ret = queue->offer(queue, "JKL", 4);
- assert_false(ret);
-
- queue->clear(queue);
- ret = queue->is_empty(queue);
- assert_true(ret);
-
- KcQueue_delete(queue);
- }
-
- /**
- * Queue メモリ確保失敗。
- */
- static void test_queue_malloc_error(void)
- {
- // メモリ確保失敗
- KcQueue *queue;
- ut_alloc_control(0)
- {
- queue = KcQueue_new(0);
- }
- assert_null(queue);
-
- // 内部管理のリストメモリ確保失敗
- ut_alloc_control(1)
- {
- queue = KcQueue_new(0);
- }
- assert_null(queue);
-
- // 追加時のメモリ確保失敗
-
- queue = KcQueue_new(10);
- ut_alloc_control(0)
- {
- bool ret = queue->offer(queue, "XYZ", 4);
- assert_false(ret);
- }
- KcQueue_delete(queue);
- }