From cb5f269b13429f0e1ffbc41426227983e5ccaeba Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 20 Sep 2021 17:31:54 +0200 Subject: Simplify/fix task dependency calculation. And tasks unit-tests. --- test/ctor.cc | 18 +++- test/execute_test.cc | 2 +- test/tasks_test.cc | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 test/tasks_test.cc (limited to 'test') diff --git a/test/ctor.cc b/test/ctor.cc index aed3ee5..caa00ee 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -1,4 +1,4 @@ -#include "libctor.h" +#include namespace { @@ -19,7 +19,21 @@ BuildConfigurations ctorTestConfigs() "-I../src", "-Iuunit", "-DOUTPUT=\"execute\"", }, - } + }, + { + .type = TargetType::UnitTest, + .target = "tasks_test", + .sources = { + "tasks_test.cc", + "uunit/uunit.cc", + }, + .depends = {"libctor.a"}, + .cxxflags = { + "-std=c++17", "-O3", "-s", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"tasks\"", + }, + }, }; } } diff --git a/test/execute_test.cc b/test/execute_test.cc index e055757..9da18dc 100644 --- a/test/execute_test.cc +++ b/test/execute_test.cc @@ -1,6 +1,6 @@ #include -#include "../src/execute.h" +#include class ExecuteTest : public uUnit diff --git a/test/tasks_test.cc b/test/tasks_test.cc new file mode 100644 index 0000000..d6515b8 --- /dev/null +++ b/test/tasks_test.cc @@ -0,0 +1,253 @@ +#include + +#include +#include +#include + +namespace +{ +BuildConfigurations ctorTestConfigs1() +{ + return + { + { + .target = "target1", + .sources = {"foo.cc", "bar.c"}, + }, + { + .target = "target2", + }, + }; +} + +BuildConfigurations ctorTestConfigs2() +{ + return + { + { + .target = "target3", + }, + { + .target = "target4", + }, + }; +} +} + +REG(ctorTestConfigs1); +REG(ctorTestConfigs2); + + +class TestTask + : public Task +{ +public: + TestTask(const std::string& name, bool dirty, + const std::vector& deps = {}) + : Task({}) + , task_name(name) + , task_dirty(dirty) + , task_deps(deps) + { + } + + std::string name() const override { return task_name; } + int clean() override { return 0; } + std::vector depends() const override { return task_deps; } + std::string target() const override { return task_name; } + bool dirtyInner() override { return task_dirty; } + +private: + std::string task_name; + bool task_dirty; + std::vector task_deps; +}; + +class TasksTest + : public uUnit +{ +public: + TasksTest() + { + uTEST(TasksTest::getTargets_test); + uTEST(TasksTest::getTasks_test); + uTEST(TasksTest::getNextTask_test); + } + + void getTargets_test() + { + using namespace std::string_literals; + Settings settings{}; + const auto& targets = getTargets(settings); + uASSERT_EQUAL(4u, targets.size()); + + uASSERT_EQUAL("target1"s, targets[0].config.target); + uASSERT_EQUAL("target2"s, targets[1].config.target); + uASSERT_EQUAL("target3"s, targets[2].config.target); + uASSERT_EQUAL("target4"s, targets[3].config.target); + + uASSERT_EQUAL("test"s, targets[0].path); + uASSERT_EQUAL("test"s, targets[1].path); + uASSERT_EQUAL("test"s, targets[2].path); + uASSERT_EQUAL("test"s, targets[3].path); + } + + void getTasks_test() + { + using namespace std::string_literals; + Settings settings{}; + { + auto tasks = getTasks(settings); + uASSERT_EQUAL(6u, tasks.size()); + auto task = tasks.begin(); + uASSERT_EQUAL("target1-foo_cc.o"s, (*task)->target()); + task++; + uASSERT_EQUAL("target1-bar_c.o"s, (*task)->target()); + task++; + uASSERT_EQUAL("target1"s, (*task)->target()); + task++; + uASSERT_EQUAL("target2"s, (*task)->target()); + task++; + uASSERT_EQUAL("target3"s, (*task)->target()); + task++; + uASSERT_EQUAL("target4"s, (*task)->target()); + } + { + auto tasks = getTasks(settings, {"target1", "target3"}); + uASSERT_EQUAL(4u, tasks.size()); + auto task = tasks.begin(); + uASSERT_EQUAL("target1-foo_cc.o"s, (*task)->target()); + task++; + uASSERT_EQUAL("target1-bar_c.o"s, (*task)->target()); + task++; + uASSERT_EQUAL("target1"s, (*task)->target()); + task++; + uASSERT_EQUAL("target3"s, (*task)->target()); + } + { + auto tasks = getTasks(settings, {"no-such-target"}); + uASSERT_EQUAL(0u, tasks.size()); + } + } + + void getNextTask_test() + { + using namespace std::string_literals; + Settings settings{}; + + { // Zero (Empty) + std::list> allTasks; + std::list> dirtyTasks; + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); + } + + { // Zero (One task, no dirty) + auto task1 = std::make_shared("task1", false); + + std::list> allTasks; + allTasks.push_back(task1); + + std::list> dirtyTasks; + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); + } + + { // One (One task, one dirty) + auto task1 = std::make_shared("task1", true); + + std::list> allTasks; + allTasks.push_back(task1); + + std::list> dirtyTasks; + dirtyTasks.push_back(task1); + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); + uASSERT_EQUAL(0u, dirtyTasks.size()); + } + + { // One (Two tasks, one dirty) + auto task1 = std::make_shared("task1", false); + auto task2 = std::make_shared("task2", true); + + std::list> allTasks; + allTasks.push_back(task1); + allTasks.push_back(task2); + + std::list> dirtyTasks; + dirtyTasks.push_back(task2); + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); + uASSERT_EQUAL(0u, dirtyTasks.size()); + } + + { // One (Two tasks, one dirty which depends on the other) + auto task1 = std::make_shared("task1", false); + + std::vector deps = {"task1"}; + auto task2 = std::make_shared("task2", true, deps); + + std::list> allTasks; + allTasks.push_back(task1); + allTasks.push_back(task2); + + std::list> dirtyTasks; + dirtyTasks.push_back(task2); + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); + uASSERT_EQUAL(0u, dirtyTasks.size()); + } + + { // One (Two tasks, Both dirty, one depends on the other) + auto task1 = std::make_shared("task1", true); + + std::vector deps = {"task1"}; + auto task2 = std::make_shared("task2", true, deps); + + std::list> allTasks; + allTasks.push_back(task2); + allTasks.push_back(task1); + + std::list> dirtyTasks; + dirtyTasks.push_back(task2); + dirtyTasks.push_back(task1); + + for(auto& task : dirtyTasks) + { + uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); + } + + uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); + uASSERT_EQUAL(1u, dirtyTasks.size()); + } + + } +}; + +// Registers the fixture into the 'registry' +static TasksTest test; -- cgit v1.2.3