123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include <vector>
- #include <string>
- #include "kbf.h"
- #include "kbf/exception.h"
- #include "kbf/queue.h"
- #include "kbf/task.h"
- #include <unity.h>
- #define DELAY 500 // milliseconds to sleep between pushes
- using namespace kbf;
- using std::vector;
- using std::string;
- template<typename T>
- struct PusherArg {
- vector<T> &values;
- Queue<T> &queue;
- };
- template<typename T>
- class Pusher : public Task {
- public:
- Pusher(const std::string &name, void *arg, uint32_t stackSize, uint32_t priority) :
- Task(name, arg, stackSize, priority) {}
- protected:
- void run(void *rawArgs) override {
- auto args = static_cast<PusherArg<T> *>(rawArgs);
- for (const auto &item : args->values) {
- kbf::sleep(DELAY);
- TEST_ASSERT_TRUE(args->queue.push(item));
- }
- }
- };
- TEST_CASE("Queue<int>", "[kbf_queue]") {
- Queue<int> queue(2);
- TEST_ASSERT_EQUAL(2, queue.maxSize);
- TEST_ASSERT_EQUAL(0, queue.size());
- TEST_ASSERT_TRUE(queue.empty());
- vector<int> values = {10, 20};
- PusherArg<int> arg = {values, queue};
- task::start<Pusher<int>>("test_queue", (void *) &arg);
- kbf::sleep(DELAY * values.size() + 100);
- TEST_ASSERT_EQUAL(values.size(), queue.size());
- for (const auto &value : values) {
- TEST_ASSERT_FALSE(queue.empty());
- TEST_ASSERT_EQUAL(value, queue.pop().value());
- }
- TEST_ASSERT_TRUE(queue.pop(0) == std::nullopt);
- TEST_ASSERT_TRUE(queue.empty());
- }
- //TEST_CASE("Queue<string>", "[kbf_queue]") {
- // Queue<string> queue(3);
- // TEST_ASSERT_EQUAL(0, queue.size());
- // TEST_ASSERT_TRUE(queue.empty());
- //
- // vector<string> values = {"first", "second", "third"};
- // PusherArg<string> arg = {values, queue};
- // task::start<Pusher<string>>("test_queue", (void *) &arg);
- //
- // kbf::sleep(DELAY * values.size() + 100);
- // TEST_ASSERT_EQUAL(values.size(), queue.size());
- //
- // for (const auto &value : values) {
- // TEST_ASSERT_FALSE(queue.empty());
- // TEST_ASSERT_EQUAL_STRING(value.c_str(), queue.pop().value().c_str());
- // }
- //
- // TEST_ASSERT_TRUE(queue.empty());
- //}
- TEST_CASE("Queue<struct>", "[kbf_queue]") {
- struct Foo {
- int a;
- int b;
- };
- Queue<Foo> queue(2);
- TEST_ASSERT_EQUAL(0, queue.size());
- TEST_ASSERT_TRUE(queue.empty());
- vector<Foo> values = {{10, 20}, {30, 40}};
- PusherArg<Foo> arg = {values, queue};
- task::start<Pusher<Foo>>("test_queue", &arg);
- kbf::sleep(DELAY * values.size() + 100);
- TEST_ASSERT_EQUAL(values.size(), queue.size());
- for (const auto &value : values) {
- TEST_ASSERT_FALSE(queue.empty());
- const std::optional<Foo> ¤t = queue.pop();
- TEST_ASSERT_FALSE(current == std::nullopt);
- TEST_ASSERT_EQUAL(value.a, current.value().a);
- TEST_ASSERT_EQUAL(value.b, current.value().b);
- }
- TEST_ASSERT_TRUE(queue.empty());
- }
- TEST_CASE("Queue timeout", "[kbf_queue]") {
- Queue<int> queue(2);
- TEST_ASSERT_EQUAL(0, queue.size());
- TEST_ASSERT_TRUE(queue.empty());
- vector<int> values = {10, 20};
- PusherArg<int> arg = {values, queue};
- task::start<Pusher<int>>("test_queue", (void *) &arg);
- TEST_ASSERT_TRUE(queue.empty());
- std::optional<int> current = queue.pop(DELAY + 100);
- TEST_ASSERT_FALSE(current == std::nullopt);
- TEST_ASSERT_EQUAL(values[0], current.value());
- TEST_ASSERT_TRUE(queue.empty());
- TEST_ASSERT_TRUE(queue.pop(DELAY / 2) == std::nullopt);
- kbf::sleep(DELAY);
- TEST_ASSERT_FALSE(queue.empty());
- current = queue.pop();
- TEST_ASSERT_FALSE(current == std::nullopt);
- TEST_ASSERT_EQUAL(values[1], current.value());
- TEST_ASSERT_TRUE(queue.empty());
- TEST_ASSERT_TRUE(queue.pop(DELAY / 2) == std::nullopt);
- }
- TEST_CASE("Queue clear", "[kbf_queue]") {
- Queue<int> queue(2);
- TEST_ASSERT_EQUAL(0, queue.size());
- TEST_ASSERT_TRUE(queue.push(10));
- TEST_ASSERT_EQUAL(1, queue.size());
- TEST_ASSERT_TRUE(queue.push(20));
- TEST_ASSERT_EQUAL(2, queue.size());
- queue.clear();
- TEST_ASSERT_EQUAL(0, queue.size());
- }
- TEST_CASE("Queue overflow", "[kbf_queue]") {
- Queue<int> queue(1);
- TEST_ASSERT_EQUAL(1, queue.maxSize);
- TEST_ASSERT_TRUE(queue.push(10));
- TEST_ASSERT_FALSE(queue.push(20));
- }
- TEST_CASE("Queue out of memory", "[kbf_queue]") {
- try {
- [[maybe_unused]] Queue<int> queue(2 << 16);
- TEST_FAIL();
- } catch (exception::OutOfMemoryError &) {
- return;
- }
- }
|