123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #include <atomic>
- #include <esp_log.h>
- #include "kbf.h"
- #include "kbf/task.h"
- #include <unity.h>
- /** delay between cycles */
- #define KBF_TASK_TEST_DELAY 200
- /** counter increase factor for the "runner" task */
- #define KBF_TASK_TEST_RUNNER_INC 10
- /** counter increase factor for the "quitter" task */
- #define KBF_TASK_TEST_QUITTER_INC 1
- /** number of cycles to run for each testing stage */
- #define KBF_TASK_TEST_CYCLES 5
- using namespace std;
- using namespace kbf;
- static atomic<int> counter{0};
- /** runs until stopped */
- class Runner : public Task {
- public:
- Runner(const string &name, void *arg, const uint32_t stackSize, const uint32_t priority) :
- Task(name, arg, stackSize, priority) {}
- static constexpr const char *const TAG = "Runner";
- protected:
- [[noreturn]] void run(void *arg) override {
- auto delay = static_cast<int *>(arg);
- TEST_ASSERT_EQUAL(KBF_TASK_TEST_DELAY, *delay);
- int i = 0;
- while (true) {
- ESP_LOGI(TAG, "cycle %d", i++);
- counter += KBF_TASK_TEST_RUNNER_INC;
- kbf::sleep(*delay);
- }
- }
- };
- struct QuitterArg {
- int delay;
- int cycles;
- };
- /** stops after KBF_TASK_TEST_CYCLES cycles */
- class Quitter : public Task {
- public:
- Quitter(const string &name, void *arg, const uint32_t stackSize, const uint32_t priority) :
- Task(name, arg, stackSize, priority) {}
- static constexpr const char *const TAG = "Quitter";
- protected:
- void run(void *arg) override {
- auto argData = static_cast<QuitterArg *>(arg);
- TEST_ASSERT_EQUAL(KBF_TASK_TEST_DELAY, argData->delay);
- TEST_ASSERT_EQUAL(KBF_TASK_TEST_CYCLES, argData->cycles);
- int i;
- for (i = 0; i < argData->cycles; i++) {
- ESP_LOGI(TAG, "cycle %d/%d", i, argData->cycles);
- counter += KBF_TASK_TEST_QUITTER_INC;
- kbf::sleep(argData->delay);
- }
- ESP_LOGI(TAG, "done: %d/%d", i, argData->cycles);
- }
- };
- TEST_CASE("Task", "[kbf_task]") {
- counter = 0;
- uint32_t delay = KBF_TASK_TEST_DELAY;
- QuitterArg quitterArg = {KBF_TASK_TEST_DELAY, KBF_TASK_TEST_CYCLES};
- auto runnerTask = task::start<Runner>("test_runner", &delay);
- auto quitterTask = task::start<Quitter>("test_quitter", &quitterArg);
- kbf::sleep(40); // make sure the tasks have started
- int expected = 0;
- // both tasks are running
- for (int i = 0; i < KBF_TASK_TEST_CYCLES; i++) {
- expected += KBF_TASK_TEST_RUNNER_INC + KBF_TASK_TEST_QUITTER_INC;
- TEST_ASSERT_EQUAL(expected, counter);
- TEST_ASSERT_TRUE(runnerTask->running())
- TEST_ASSERT_TRUE(quitterTask->running())
- kbf::sleep(KBF_TASK_TEST_DELAY);
- }
- // quitter has quit, only runner is left
- for (int i = 0; i < KBF_TASK_TEST_CYCLES; i++) {
- expected += KBF_TASK_TEST_RUNNER_INC;
- TEST_ASSERT_EQUAL(expected, counter);
- TEST_ASSERT_TRUE(runnerTask->running())
- TEST_ASSERT_FALSE(quitterTask->running())
- kbf::sleep(KBF_TASK_TEST_DELAY);
- }
- // stop runner; no more updates
- runnerTask->stop();
- TEST_ASSERT_FALSE(runnerTask->running());
- expected += KBF_TASK_TEST_RUNNER_INC; // runner went another cycle while we were sleeping
- for (int i = 0; i < KBF_TASK_TEST_CYCLES; i++) {
- TEST_ASSERT_EQUAL(expected, counter);
- kbf::sleep(KBF_TASK_TEST_DELAY);
- }
- }
- static QuitterArg scopeTestArg = {KBF_TASK_TEST_DELAY, KBF_TASK_TEST_CYCLES};
- void createTask() {
- task::start<Quitter>("test_task_scope", &scopeTestArg);
- }
- TEST_CASE("Task out of scope", "[kbf_task]") {
- counter = 0;
- createTask();
- kbf::sleep(KBF_TASK_TEST_DELAY * KBF_TASK_TEST_CYCLES);
- TEST_ASSERT_EQUAL(KBF_TASK_TEST_CYCLES * KBF_TASK_TEST_QUITTER_INC, counter);
- }
- TEST_CASE("Task out of memory", "[kbf_task]") {
- QuitterArg quitterArg = {KBF_TASK_TEST_DELAY, KBF_TASK_TEST_CYCLES};
- counter = 0;
- bool caught = false;
- try {
- task::start<Quitter>("test_task_oom", &quitterArg, 2 << 24);
- } catch (kbf::exception::OutOfMemoryError &e) {
- caught = true;
- }
- TEST_ASSERT_TRUE(caught)
- }
|