test_queue.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <vector>
  2. #include <string>
  3. #include "kbf.h"
  4. #include "kbf/exception.h"
  5. #include "kbf/queue.h"
  6. #include "kbf/task.h"
  7. #include <unity.h>
  8. #define DELAY 500 // milliseconds to sleep between pushes
  9. using namespace kbf;
  10. using std::vector;
  11. using std::string;
  12. template<typename T>
  13. struct PusherArg {
  14. vector<T> &values;
  15. Queue<T> &queue;
  16. };
  17. template<typename T>
  18. class Pusher : public Task {
  19. public:
  20. Pusher(const std::string &name, void *arg, uint32_t stackSize, uint32_t priority) :
  21. Task(name, arg, stackSize, priority) {}
  22. protected:
  23. void run(void *rawArgs) override {
  24. auto args = static_cast<PusherArg<T> *>(rawArgs);
  25. for (const auto &item : args->values) {
  26. kbf::sleep(DELAY);
  27. TEST_ASSERT_TRUE(args->queue.push(item));
  28. }
  29. }
  30. };
  31. TEST_CASE("Queue<int>", "[kbf_queue]") {
  32. Queue<int> queue(2);
  33. TEST_ASSERT_EQUAL(2, queue.maxSize);
  34. TEST_ASSERT_EQUAL(0, queue.size());
  35. TEST_ASSERT_TRUE(queue.empty());
  36. vector<int> values = {10, 20};
  37. PusherArg<int> arg = {values, queue};
  38. task::start<Pusher<int>>("test_queue", (void *) &arg);
  39. kbf::sleep(DELAY * values.size() + 100);
  40. TEST_ASSERT_EQUAL(values.size(), queue.size());
  41. for (const auto &value : values) {
  42. TEST_ASSERT_FALSE(queue.empty());
  43. TEST_ASSERT_EQUAL(value, queue.pop().value());
  44. }
  45. TEST_ASSERT_TRUE(queue.pop(0) == std::nullopt);
  46. TEST_ASSERT_TRUE(queue.empty());
  47. }
  48. //TEST_CASE("Queue<string>", "[kbf_queue]") {
  49. // Queue<string> queue(3);
  50. // TEST_ASSERT_EQUAL(0, queue.size());
  51. // TEST_ASSERT_TRUE(queue.empty());
  52. //
  53. // vector<string> values = {"first", "second", "third"};
  54. // PusherArg<string> arg = {values, queue};
  55. // task::start<Pusher<string>>("test_queue", (void *) &arg);
  56. //
  57. // kbf::sleep(DELAY * values.size() + 100);
  58. // TEST_ASSERT_EQUAL(values.size(), queue.size());
  59. //
  60. // for (const auto &value : values) {
  61. // TEST_ASSERT_FALSE(queue.empty());
  62. // TEST_ASSERT_EQUAL_STRING(value.c_str(), queue.pop().value().c_str());
  63. // }
  64. //
  65. // TEST_ASSERT_TRUE(queue.empty());
  66. //}
  67. TEST_CASE("Queue<struct>", "[kbf_queue]") {
  68. struct Foo {
  69. int a;
  70. int b;
  71. };
  72. Queue<Foo> queue(2);
  73. TEST_ASSERT_EQUAL(0, queue.size());
  74. TEST_ASSERT_TRUE(queue.empty());
  75. vector<Foo> values = {{10, 20}, {30, 40}};
  76. PusherArg<Foo> arg = {values, queue};
  77. task::start<Pusher<Foo>>("test_queue", &arg);
  78. kbf::sleep(DELAY * values.size() + 100);
  79. TEST_ASSERT_EQUAL(values.size(), queue.size());
  80. for (const auto &value : values) {
  81. TEST_ASSERT_FALSE(queue.empty());
  82. const std::optional<Foo> &current = queue.pop();
  83. TEST_ASSERT_FALSE(current == std::nullopt);
  84. TEST_ASSERT_EQUAL(value.a, current.value().a);
  85. TEST_ASSERT_EQUAL(value.b, current.value().b);
  86. }
  87. TEST_ASSERT_TRUE(queue.empty());
  88. }
  89. TEST_CASE("Queue timeout", "[kbf_queue]") {
  90. Queue<int> queue(2);
  91. TEST_ASSERT_EQUAL(0, queue.size());
  92. TEST_ASSERT_TRUE(queue.empty());
  93. vector<int> values = {10, 20};
  94. PusherArg<int> arg = {values, queue};
  95. task::start<Pusher<int>>("test_queue", (void *) &arg);
  96. TEST_ASSERT_TRUE(queue.empty());
  97. std::optional<int> current = queue.pop(DELAY + 100);
  98. TEST_ASSERT_FALSE(current == std::nullopt);
  99. TEST_ASSERT_EQUAL(values[0], current.value());
  100. TEST_ASSERT_TRUE(queue.empty());
  101. TEST_ASSERT_TRUE(queue.pop(DELAY / 2) == std::nullopt);
  102. kbf::sleep(DELAY);
  103. TEST_ASSERT_FALSE(queue.empty());
  104. current = queue.pop();
  105. TEST_ASSERT_FALSE(current == std::nullopt);
  106. TEST_ASSERT_EQUAL(values[1], current.value());
  107. TEST_ASSERT_TRUE(queue.empty());
  108. TEST_ASSERT_TRUE(queue.pop(DELAY / 2) == std::nullopt);
  109. }
  110. TEST_CASE("Queue clear", "[kbf_queue]") {
  111. Queue<int> queue(2);
  112. TEST_ASSERT_EQUAL(0, queue.size());
  113. TEST_ASSERT_TRUE(queue.push(10));
  114. TEST_ASSERT_EQUAL(1, queue.size());
  115. TEST_ASSERT_TRUE(queue.push(20));
  116. TEST_ASSERT_EQUAL(2, queue.size());
  117. queue.clear();
  118. TEST_ASSERT_EQUAL(0, queue.size());
  119. }
  120. TEST_CASE("Queue overflow", "[kbf_queue]") {
  121. Queue<int> queue(1);
  122. TEST_ASSERT_EQUAL(1, queue.maxSize);
  123. TEST_ASSERT_TRUE(queue.push(10));
  124. TEST_ASSERT_FALSE(queue.push(20));
  125. }
  126. TEST_CASE("Queue out of memory", "[kbf_queue]") {
  127. try {
  128. [[maybe_unused]] Queue<int> queue(2 << 16);
  129. TEST_FAIL();
  130. } catch (exception::OutOfMemoryError &) {
  131. return;
  132. }
  133. }