diff --git a/librepomgr/testfiles/test-config/presets.json b/librepomgr/testfiles/test-config/presets.json new file mode 100644 index 0000000..2761b87 --- /dev/null +++ b/librepomgr/testfiles/test-config/presets.json @@ -0,0 +1,74 @@ +{ + "templates": { + "foo": { + "directory": "foo", + "packageNames": [], + "sourceDbs": [], + "destinationDbs": [], + "settings": { + "cmd": "echo foo" + }, + "flags": 0, + "type": 13 + }, + "bar-1": { + "directory": "bar", + "packageNames": [], + "sourceDbs": [], + "destinationDbs": [], + "settings": { + "cmd": "echo bar-1" + }, + "flags": 0, + "type": 13 + }, + "bar-2": { + "directory": "bar", + "packageNames": [], + "sourceDbs": [], + "destinationDbs": [], + "settings": { + "cmd": "echo bar-2" + }, + "flags": 0, + "type": 13 + }, + "baz": { + "directory": "baz", + "packageNames": [], + "sourceDbs": [], + "destinationDbs": [], + "settings": { + "cmd": "echo baz" + }, + "flags": 0, + "type": 13 + }, + "buz": { + "directory": "buz", + "packageNames": [], + "sourceDbs": [], + "destinationDbs": [], + "settings": { + "cmd": "echo buz" + }, + "flags": 0, + "type": 13 + } + }, + "tasks": { + "foobarbaz": { + "name": "Test task", + "desc": "Task used by WebAPITests::testPostingBuildActionsFromTask()", + "category": "Testing", + "actions": [ + "foo", + { + "actions": [["bar-1", "bar-2"], "baz"], + "concurrent": true + }, + "buz" + ] + } + } +} diff --git a/librepomgr/tests/webapi.cpp b/librepomgr/tests/webapi.cpp index 7e1c005..78145a4 100644 --- a/librepomgr/tests/webapi.cpp +++ b/librepomgr/tests/webapi.cpp @@ -36,6 +36,7 @@ class WebAPITests : public TestFixture { CPPUNIT_TEST_SUITE(WebAPITests); CPPUNIT_TEST(testBasicNetworking); CPPUNIT_TEST(testPostingBuildAction); + CPPUNIT_TEST(testPostingBuildActionsFromTask); CPPUNIT_TEST_SUITE_END(); public: @@ -48,6 +49,7 @@ public: std::shared_ptr invokeRouteHandler( void (*handler)(const Params ¶ms, ResponseHandler &&handler), std::vector> &&queryParams); void testPostingBuildAction(); + void testPostingBuildActionsFromTask(); private: ServiceSetup m_setup; @@ -188,13 +190,23 @@ static void parseBuildAction(BuildAction &buildAction, std::string_view json) CPPUNIT_FAIL("json document is no object"); } auto errors = ReflectiveRapidJSON::JsonDeserializationErrors(); + errors.throwOn = ReflectiveRapidJSON::JsonDeserializationErrors::ThrowOn::All; ReflectiveRapidJSON::JsonReflector::pull(buildAction, doc.GetObject(), &errors); - CPPUNIT_ASSERT_EQUAL_MESSAGE("response is valid json", 0_st, errors.size()); +} + +/*! + * \brief Parses the specified \a json as build actions storing results in \a buildActions. + */ +static auto parseBuildActions(std::string_view json) +{ + auto errors = ReflectiveRapidJSON::JsonDeserializationErrors(); + errors.throwOn = ReflectiveRapidJSON::JsonDeserializationErrors::ThrowOn::All; + return ReflectiveRapidJSON::JsonReflector::fromJson>(json.data(), json.size(), &errors); } /*! * \brief Tests the handler to post a build action. - * \remarks Only covers a very basic use so far. + * \remarks Only covers a very basic use so far; tasks are handled in the next test function. */ void WebAPITests::testPostingBuildAction() { @@ -223,3 +235,50 @@ void WebAPITests::testPostingBuildAction() CPPUNIT_ASSERT_EQUAL_MESSAGE("response ok", boost::beast::http::status::ok, response->result()); } } + +/*! + * \brief Tests the handler to post build actions from a pre-defined task. + */ +void WebAPITests::testPostingBuildActionsFromTask() +{ + auto &building = m_setup.building; + building.presets = decltype(building.presets)::fromJson(readFile(testFilePath("test-config/presets.json"))); + CPPUNIT_ASSERT_MESSAGE("templates parsed from JSON", !building.presets.templates.empty()); + CPPUNIT_ASSERT_MESSAGE("task parsed from JSON", building.presets.tasks.contains("foobarbaz")); + CPPUNIT_ASSERT_MESSAGE("no build actions present before", building.actions.empty()); + + const auto response = invokeRouteHandler(&WebAPI::Routes::postBuildAction, + { + { "task"sv, "foobarbaz"sv }, + { "start-condition"sv, "manually"sv }, + }); + CPPUNIT_ASSERT_MESSAGE("got response", response); + + const auto buildActions = parseBuildActions(response->body()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("expected number of build actions created", 5_st, buildActions.size()); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("build actions actually present", 5_st, building.actions.size()); + for (const auto &action : building.actions) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(argsToString("build action ", action->id, " not started yet"), BuildActionStatus::Created, action->status); + CPPUNIT_ASSERT_EQUAL_MESSAGE(argsToString("build action ", action->id, " has no result yet"), BuildActionResult::None, action->result); + CPPUNIT_ASSERT_EQUAL_MESSAGE(argsToString("build action ", action->id, " has task name assigned"), "foobarbaz"s, action->taskName); + } + CPPUNIT_ASSERT_EQUAL_MESSAGE("foo is 1st action", "foo"s, building.actions[0]->templateName); + CPPUNIT_ASSERT_EQUAL_MESSAGE("foo has dir assigned", "foo"s, building.actions[0]->directory); + CPPUNIT_ASSERT_EQUAL_MESSAGE("foo has correct deps", std::vector{}, building.actions[0]->startAfter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-1 is 2nd action", "bar-1"s, building.actions[1]->templateName); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-1 has dir assigned", "bar"s, building.actions[1]->directory); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-1 has correct deps", std::vector{ 0 }, building.actions[1]->startAfter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-2 is 3rd action", "bar-2"s, building.actions[2]->templateName); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-2 has dir assigned", "bar"s, building.actions[2]->directory); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bar-2 has correct deps", std::vector{ 1 }, building.actions[2]->startAfter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("baz is 4th action", "baz"s, building.actions[3]->templateName); + CPPUNIT_ASSERT_EQUAL_MESSAGE("baz has dir assigned", "baz"s, building.actions[3]->directory); + CPPUNIT_ASSERT_EQUAL_MESSAGE("baz has correct deps", std::vector{ 0 }, building.actions[3]->startAfter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("buz is 5th action", "buz"s, building.actions[4]->templateName); + CPPUNIT_ASSERT_EQUAL_MESSAGE("buz has dir assigned", "buz"s, building.actions[4]->directory); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + "buz has correct deps", std::vector{ 2 CPP_UTILITIES_PP_COMMA 3 }, building.actions[4]->startAfter); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("response ok", boost::beast::http::status::ok, response->result()); +} diff --git a/librepomgr/webapi/routes.cpp b/librepomgr/webapi/routes.cpp index abc9b1f..ad983ea 100644 --- a/librepomgr/webapi/routes.cpp +++ b/librepomgr/webapi/routes.cpp @@ -678,6 +678,7 @@ static std::string allocateNewBuildAction(const BuildActionMetaInfo &metaInfo, c auto &allocatedBuildAction = allocatedActions.emplace_back(std::make_shared()); auto *const buildAction = std::get>(newActionSequence.actions.emplace_back(allocatedBuildAction)).get(); buildAction->taskName = taskName; + buildAction->templateName = actionTemplateToAllocate; buildAction->directory = !typeInfo.directory || directory.empty() ? actionTemplate.directory : directory; buildAction->type = buildActionType; buildAction->sourceDbs = actionTemplate.sourceDbs;