From 26dfa76faa883c35fe3e5ff4b2b33f4102059a81 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov <0x7fffff@guattari.ru> Date: Fri, 5 Aug 2022 21:17:16 +0400 Subject: Async function & unit-testing --- source/test/CMakeLists.txt | 1 + source/test/integration/fetch_content/.gitignore | 1 + .../test/integration/fetch_content/CMakeLists.txt | 19 ++ source/test/integration/fetch_content/main.c | 5 + source/test/integration/find_package/.gitignore | 2 + .../test/integration/find_package/CMakeLists.txt | 34 ++++ .../integration/find_package/source/CMakeLists.txt | 10 ++ source/test/integration/find_package/source/main.c | 5 + source/test/unittests/CMakeLists.txt | 4 + source/test/unittests/async_function.test.c | 200 +++++++++++++++++++++ source/test/unittests/main.test.c | 5 + 11 files changed, 286 insertions(+) create mode 100644 source/test/CMakeLists.txt create mode 100644 source/test/integration/fetch_content/.gitignore create mode 100644 source/test/integration/fetch_content/CMakeLists.txt create mode 100644 source/test/integration/fetch_content/main.c create mode 100644 source/test/integration/find_package/.gitignore create mode 100644 source/test/integration/find_package/CMakeLists.txt create mode 100644 source/test/integration/find_package/source/CMakeLists.txt create mode 100644 source/test/integration/find_package/source/main.c create mode 100644 source/test/unittests/CMakeLists.txt create mode 100644 source/test/unittests/async_function.test.c create mode 100644 source/test/unittests/main.test.c (limited to 'source/test') diff --git a/source/test/CMakeLists.txt b/source/test/CMakeLists.txt new file mode 100644 index 0000000..740981e --- /dev/null +++ b/source/test/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(unittests) diff --git a/source/test/integration/fetch_content/.gitignore b/source/test/integration/fetch_content/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/source/test/integration/fetch_content/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/source/test/integration/fetch_content/CMakeLists.txt b/source/test/integration/fetch_content/CMakeLists.txt new file mode 100644 index 0000000..efa83d0 --- /dev/null +++ b/source/test/integration/fetch_content/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.16) +set(NAME kit-integration-fetch-content) +project(${NAME} C) + +include(FetchContent) +FetchContent_Declare( + kit + GIT_REPOSITORY https://github.com/automainint/kit.git + GIT_TAG dev) +set(KIT_ENABLE_TESTING OFF) +FetchContent_MakeAvailable(kit) + +add_executable(${NAME}) +target_sources(${NAME} PRIVATE main.c) +target_link_libraries(${NAME} PRIVATE kit::kit) + +enable_testing() +add_test(NAME ${NAME}-run COMMAND ${NAME}) +set_tests_properties(${NAME}-run PROPERTIES TIMEOUT "15") diff --git a/source/test/integration/fetch_content/main.c b/source/test/integration/fetch_content/main.c new file mode 100644 index 0000000..c9dc882 --- /dev/null +++ b/source/test/integration/fetch_content/main.c @@ -0,0 +1,5 @@ +#include + +int main() { + return 0; +} diff --git a/source/test/integration/find_package/.gitignore b/source/test/integration/find_package/.gitignore new file mode 100644 index 0000000..0ba45dd --- /dev/null +++ b/source/test/integration/find_package/.gitignore @@ -0,0 +1,2 @@ +/build/ +/install/ diff --git a/source/test/integration/find_package/CMakeLists.txt b/source/test/integration/find_package/CMakeLists.txt new file mode 100644 index 0000000..f21cdae --- /dev/null +++ b/source/test/integration/find_package/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.16) +set(NAME kit-integration-find-package) +project(${NAME}-root) + +include(ExternalProject) + +ExternalProject_Add( + kit + GIT_REPOSITORY https://github.com/automainint/kit.git + GIT_TAG dev + CMAKE_ARGS + -D CMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/install + -D KIT_ENABLE_TESTING=OFF) + +ExternalProject_Add( + ${NAME} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/source + CMAKE_ARGS + -D CMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/install) + +ExternalProject_Add_StepDependencies(${NAME} build kit) + +include(GNUInstallDirs) + +enable_testing() + +add_test( + NAME ${NAME}-run + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/install/${CMAKE_INSTALL_BINDIR}/${NAME}${CMAKE_EXECUTABLE_SUFFIX}) + +set_tests_properties( + ${NAME}-run + PROPERTIES + TIMEOUT "15") diff --git a/source/test/integration/find_package/source/CMakeLists.txt b/source/test/integration/find_package/source/CMakeLists.txt new file mode 100644 index 0000000..2dc34a1 --- /dev/null +++ b/source/test/integration/find_package/source/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.16) +set(NAME kit-integration-find-package) +project(${NAME} C) + +find_package(kit REQUIRED) + +add_executable(${NAME}) +target_sources(${NAME} PRIVATE main.c) +target_link_libraries(${NAME} PRIVATE kit::kit) +install(TARGETS ${NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/source/test/integration/find_package/source/main.c b/source/test/integration/find_package/source/main.c new file mode 100644 index 0000000..c9dc882 --- /dev/null +++ b/source/test/integration/find_package/source/main.c @@ -0,0 +1,5 @@ +#include + +int main() { + return 0; +} diff --git a/source/test/unittests/CMakeLists.txt b/source/test/unittests/CMakeLists.txt new file mode 100644 index 0000000..d5cc573 --- /dev/null +++ b/source/test/unittests/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources( + ${KIT_TEST_SUITE} + PRIVATE + async_function.test.c main.test.c) diff --git a/source/test/unittests/async_function.test.c b/source/test/unittests/async_function.test.c new file mode 100644 index 0000000..1f50445 --- /dev/null +++ b/source/test/unittests/async_function.test.c @@ -0,0 +1,200 @@ +#include "../../kit/async_function.h" + +#define KIT_TEST_FILE async_function_test +#include "../../kit_test/test.h" + +CORO(int, test_foo) { + AF_RETURN(42); +} +CORO_END + +CORO(int, test_bar) { + AF_YIELD_VOID; + AF_RETURN(42); +} +CORO_END + +CORO(int, test_gen, int i; int min; int max;) { + for (af i = af min; af i < af max; af i++) AF_YIELD(af i); + AF_RETURN(af max); +} +CORO_END + +CORO_VOID(test_task) { + AF_YIELD_VOID; + AF_YIELD_VOID; + AF_RETURN_VOID; +} +CORO_END + +CORO_VOID(test_nest_task, AF_TYPE(test_task) promise;) { + AF_INIT(af promise, test_task); + AF_AWAIT(af promise); + AF_AWAIT(af promise); + AF_AWAIT(af promise); +} +CORO_END + +CORO(int, test_nest_generator, AF_TYPE(test_gen) promise;) { + AF_INIT(af promise, test_gen, .min = 1, .max = 3); + AF_YIELD_AWAIT(af promise); +} +CORO_END + +CORO(int, test_join_multiple, AF_TYPE(test_bar) promises[3];) { + for (int i = 0; i < 3; i++) + AF_INIT(af promises[i], test_bar, .return_value = 0); + AF_RESUME_AND_JOIN_ALL(af promises); + AF_RETURN(af promises[0].return_value + + af promises[1].return_value + + af promises[2].return_value); +} +CORO_END + +CORO(int, test_await_multiple, AF_TYPE(test_bar) promises[3];) { + for (int i = 0; i < 3; i++) + AF_INIT(af promises[i], test_bar, .return_value = 0); + AF_AWAIT_ALL(af promises); + AF_RETURN(af promises[0].return_value + + af promises[1].return_value + + af promises[2].return_value); +} +CORO_END + +void test_execute_lazy(void *_, void *coro, int request) { + if (request == af_request_resume) + return; + AF_EXECUTE(coro); +} + +void test_execute_immediate(void *_, void *coro, int request) { + if (request == af_request_join) + return; + AF_EXECUTE(coro); +} + +TEST("coroutine create") { + AF_CREATE(promise, test_foo); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine init") { + AF_TYPE(test_foo) promise; + AF_INIT(promise, test_foo); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine init with value") { + AF_TYPE(test_foo) promise; + AF_INIT(promise, test_foo, .return_value = 42); + REQUIRE(promise.return_value == 42); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine resume") { + AF_CREATE(promise, test_foo, .return_value = -1); + AF_RESUME(promise); + REQUIRE(promise.return_value == -1); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine resume and join") { + AF_CREATE(promise, test_foo); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 42); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine resume and join manually") { + AF_CREATE(promise, test_foo); + AF_RESUME(promise); + REQUIRE(AF_JOIN(promise) == 42); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine suspend") { + AF_CREATE(promise, test_bar, .return_value = 0); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 0); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 42); +} + +TEST("coroutine generator") { + AF_CREATE(promise, test_gen, .min = 10, .max = 15); + for (int i = 0; i <= 5; i++) + REQUIRE(AF_RESUME_AND_JOIN(promise) == 10 + i); +} + +TEST("coroutine status finished") { + AF_CREATE(promise, test_bar); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine task") { + AF_CREATE(promise, test_task); + AF_RESUME_AND_JOIN(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine nested task") { + AF_CREATE(promise, test_nest_task); + AF_RESUME_AND_JOIN(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine nested generator") { + AF_CREATE(promise, test_nest_generator); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 1); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 2); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 3); + REQUIRE(!AF_FINISHED(promise)); + AF_RESUME_AND_JOIN(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine join multiple") { + AF_CREATE(promise, test_join_multiple); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 0); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine await multiple") { + AF_CREATE(promise, test_await_multiple); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 0); + REQUIRE(AF_RESUME_AND_JOIN(promise) == 42 * 3); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine custom execution context lazy") { + AF_CREATE(promise, test_foo, .return_value = 0); + AF_EXECUTION_CONTEXT(promise, .state = NULL, + .execute = test_execute_lazy); + AF_RESUME(promise); + REQUIRE(promise.return_value == 0); + REQUIRE(!AF_FINISHED(promise)); + AF_JOIN(promise); + REQUIRE(promise.return_value == 42); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine custom execution context immediate") { + AF_CREATE(promise, test_foo, .return_value = 0); + AF_EXECUTION_CONTEXT(promise, .state = NULL, + .execute = test_execute_immediate); + AF_RESUME(promise); + REQUIRE(promise.return_value == 42); + REQUIRE(AF_FINISHED(promise)); + AF_JOIN(promise); + REQUIRE(promise.return_value == 42); + REQUIRE(AF_FINISHED(promise)); +} diff --git a/source/test/unittests/main.test.c b/source/test/unittests/main.test.c new file mode 100644 index 0000000..b072c67 --- /dev/null +++ b/source/test/unittests/main.test.c @@ -0,0 +1,5 @@ +#include "../../kit_test/test.h" + +int main(int argc, char **argv) { + return kit_run_tests(argc, argv); +} -- cgit v1.2.3