diff --git a/CHANGES b/CHANGES index bfc303bd7..7a62cbe70 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Bugfixes: Misc: - SDL: Remove scancode key input - GBA Video: Clean up unused timers + - Test: Add a basic test suite 0.5.1: (2016-10-05) Bugfixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index 11b0b1d2f..c39f06551 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ if(APPLE) endif() set(BUILD_PERF OFF CACHE BOOL "Build performance profiling tool") set(BUILD_TEST OFF CACHE BOOL "Build testing harness") +set(BUILD_SUITE OFF CACHE BOOL "Build test suite") set(BUILD_EXAMPLE OFF CACHE BOOL "Build example frontends") set(BUILD_STATIC OFF CACHE BOOL "Build a static library") set(BUILD_SHARED ON CACHE BOOL "Build a shared library") @@ -330,6 +331,7 @@ endif() set(WANT_ZLIB ${USE_ZLIB}) set(WANT_PNG ${USE_PNG}) set(WANT_LIBZIP ${USE_LIBZIP}) +set(USE_CMOCKA ${BUILD_SUITE}) find_feature(USE_FFMPEG "libavcodec;libavformat;libavresample;libavutil;libswscale") find_feature(USE_ZLIB "ZLIB") @@ -338,6 +340,7 @@ find_feature(USE_PNG "PNG") find_feature(USE_LIBZIP "libzip") find_feature(USE_MAGICK "MagickWand") find_feature(USE_EPOXY "epoxy") +find_feature(USE_CMOCKA "cmocka") # Features set(DEBUGGER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/debugger.c) @@ -633,6 +636,7 @@ else() set(DISABLE_FRONTENDS ON) set(BUILD_PERF OFF) set(BUILD_TEST OFF) + set(BUILD_SUITE OFF) endif() endif() @@ -701,6 +705,16 @@ if(BUILD_TEST) install(TARGETS ${BINARY_NAME}-fuzz DESTINATION bin COMPONENT ${BINARY_NAME}-test) endif() +if(NOT USE_CMOCKA) + set(BUILD_SUITE OFF) +endif() +if(USE_CMOCKA) + enable_testing() + include_directories(AFTER ${CMOCKA_INCLUDE_DIRS}) + link_directories(${CMOCKA_LIBRARY_DIRS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/test/suite ${CMAKE_CURRENT_BINARY_DIR}/suite) +endif() + if(BUILD_EXAMPLE) add_executable(${BINARY_NAME}-example-server ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/example/client-server/server.c) target_link_libraries(${BINARY_NAME}-example-server ${BINARY_NAME}) @@ -782,6 +796,7 @@ if(NOT QUIET) message(STATUS " SDL (${SDL_VERSION}): ${BUILD_SDL}") message(STATUS " Profiling: ${BUILD_PERF}") message(STATUS " Test harness: ${BUILD_TEST}") + message(STATUS " Test suite: ${BUILD_SUITE}") message(STATUS " Examples: ${BUILD_EXAMPLE}") message(STATUS "Cores:") message(STATUS " Libretro core: ${BUILD_LIBRETRO}") diff --git a/src/platform/test/suite-main.c b/src/platform/test/suite-main.c new file mode 100644 index 000000000..c655c4ab7 --- /dev/null +++ b/src/platform/test/suite-main.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "platform/test/suite/suite.h" + +#include "platform/test/suite/common/common.h" + +int main() { + return mTestRunCommon() != 0; +} diff --git a/src/platform/test/suite/CMakeLists.txt b/src/platform/test/suite/CMakeLists.txt new file mode 100644 index 000000000..05d7520b7 --- /dev/null +++ b/src/platform/test/suite/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB SUITE_COMMON_SRC ${CMAKE_CURRENT_SOURCE_DIR}/common/*.c) +add_executable(${BINARY_NAME}-suite ${SUITE_COMMON_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/../suite-main.c) +target_link_libraries(${BINARY_NAME}-suite ${BINARY_NAME} ${PLATFORM_LIBRARY} cmocka) +add_test(${BINARY_NAME}-suite ${BINARY_NAME}-suite) \ No newline at end of file diff --git a/src/platform/test/suite/common/common.c b/src/platform/test/suite/common/common.c new file mode 100644 index 000000000..3997dbb9d --- /dev/null +++ b/src/platform/test/suite/common/common.c @@ -0,0 +1,16 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "platform/test/suite/suite.h" + +M_TEST_SUITE_DECLARE(mCore); +M_TEST_SUITE_DECLARE(VFS); + +int mTestRunCommon(void) { + int failures = 0; + failures += M_TEST_SUITE_RUN(mCore); + failures += M_TEST_SUITE_RUN(VFS); + return failures; +} diff --git a/src/platform/test/suite/common/common.h b/src/platform/test/suite/common/common.h new file mode 100644 index 000000000..19453c156 --- /dev/null +++ b/src/platform/test/suite/common/common.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef SUITE_COMMON_H +#define SUITE_COMMON_H +#include "util/common.h" + +int mTestRunCommon(void); + +#endif \ No newline at end of file diff --git a/src/platform/test/suite/common/core.c b/src/platform/test/suite/common/core.c new file mode 100644 index 000000000..df008079b --- /dev/null +++ b/src/platform/test/suite/common/core.c @@ -0,0 +1,36 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "platform/test/suite/suite.h" + +#include "core/core.h" +#include "util/vfs.h" + +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +M_TEST_DEFINE(findNullPath) { + struct mCore* core = mCoreFind(NULL); + assert_null(core); +} +#endif + +M_TEST_DEFINE(findNullVF) { + struct mCore* core = mCoreFindVF(NULL); + assert_null(core); +} + +M_TEST_DEFINE(findEmpty) { + struct VFile* vf = VFileMemChunk(NULL, 0); + assert_non_null(vf); + struct mCore* core = mCoreFindVF(vf); + assert_null(core); + vf->close(vf); +} + +M_TEST_SUITE_DEFINE(mCore, +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 + cmocka_unit_test(findNullPath), +#endif + cmocka_unit_test(findNullVF), + cmocka_unit_test(findEmpty)) \ No newline at end of file diff --git a/src/platform/test/suite/common/vfs.c b/src/platform/test/suite/common/vfs.c new file mode 100644 index 000000000..14122d01b --- /dev/null +++ b/src/platform/test/suite/common/vfs.c @@ -0,0 +1,87 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "platform/test/suite/suite.h" + +#include "util/vfs.h" + +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +M_TEST_DEFINE(openNullPathR) { + struct VFile* vf = VFileOpen(NULL, O_RDONLY); + assert_null(vf); +} + +M_TEST_DEFINE(openNullPathW) { + struct VFile* vf = VFileOpen(NULL, O_WRONLY); + assert_null(vf); +} + +M_TEST_DEFINE(openNullPathCreate) { + struct VFile* vf = VFileOpen(NULL, O_CREAT); + assert_null(vf); +} + +M_TEST_DEFINE(openNullPathWCreate) { + struct VFile* vf = VFileOpen(NULL, O_WRONLY | O_CREAT); + assert_null(vf); +} +#endif + +M_TEST_DEFINE(openNullMem0) { + struct VFile* vf = VFileFromMemory(NULL, 0); + assert_null(vf); +} + +M_TEST_DEFINE(openNullMemNonzero) { + struct VFile* vf = VFileFromMemory(NULL, 32); + assert_null(vf); +} + +M_TEST_DEFINE(openNullConstMem0) { + struct VFile* vf = VFileFromConstMemory(NULL, 0); + assert_null(vf); +} + +M_TEST_DEFINE(openNullConstMemNonzero) { + struct VFile* vf = VFileFromConstMemory(NULL, 32); + assert_null(vf); +} + +M_TEST_DEFINE(openNullMemChunk0) { + struct VFile* vf = VFileMemChunk(NULL, 0); + assert_non_null(vf); + assert_int_equal(vf->size(vf), 0); + vf->close(vf); +} + +M_TEST_DEFINE(openNonNullMemChunk0) { + const uint8_t bytes[32] = {}; + struct VFile* vf = VFileMemChunk(bytes, 0); + assert_non_null(vf); + assert_int_equal(vf->size(vf), 0); + vf->close(vf); +} + +M_TEST_DEFINE(openNullMemChunkNonzero) { + struct VFile* vf = VFileMemChunk(NULL, 32); + assert_non_null(vf); + assert_int_equal(vf->size(vf), 32); + vf->close(vf); +} + +M_TEST_SUITE_DEFINE(VFS, +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 + cmocka_unit_test(openNullPathR), + cmocka_unit_test(openNullPathW), + cmocka_unit_test(openNullPathCreate), + cmocka_unit_test(openNullPathWCreate), +#endif + cmocka_unit_test(openNullMem0), + cmocka_unit_test(openNullMemNonzero), + cmocka_unit_test(openNullConstMem0), + cmocka_unit_test(openNullConstMemNonzero), + cmocka_unit_test(openNullMemChunk0), + cmocka_unit_test(openNonNullMemChunk0), + cmocka_unit_test(openNullMemChunkNonzero)) diff --git a/src/platform/test/suite/suite.h b/src/platform/test/suite/suite.h new file mode 100644 index 000000000..041633e01 --- /dev/null +++ b/src/platform/test/suite/suite.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef SUITE_H +#define SUITE_H +#include "util/common.h" + +#include +#include + +#define M_TEST_DEFINE(NAME) static void NAME (void **state ATTRIBUTE_UNUSED) + +#define M_TEST_SUITE(NAME) _testSuite_ ## NAME +#define M_TEST_SUITE_RUN(NAME) M_TEST_SUITE(NAME)() +#define M_TEST_SUITE_DEFINE(NAME, ...) \ + int M_TEST_SUITE(NAME) (void) { \ + const static struct CMUnitTest tests[] = { \ + __VA_ARGS__ \ + }; \ + return cmocka_run_group_tests_name(# NAME, tests, NULL, NULL); \ + } + +#define M_TEST_SUITE_DECLARE(NAME) extern int M_TEST_SUITE(NAME) (void) + +#endif \ No newline at end of file