if(BUILD_TESTING)
    include(${CMAKE_SOURCE_DIR}/cmake/BuildboxGTestSetup.cmake)

    # Every directory containing a source file needed by the tests, must be added here.
    include_directories(.. fixtures/)

    macro(add_casd_test TEST_NAME TEST_SOURCE)
        # Create a separate test executable per test source.
        add_executable(casd_${TEST_NAME} ${TEST_SOURCE} buildboxcasd_tests.m.cpp)
        target_precompile_headers(casd_${TEST_NAME} REUSE_FROM common)

        # This allows us to pass an optional argument if the cwd for the test is not the default.
        set(ExtraMacroArgs ${ARGN})
        list(LENGTH ExtraMacroArgs NumExtraArgs)
        if(${NumExtraArgs} GREATER 0)
            list(GET ExtraMacroArgs 0 TEST_WORKING_DIRECTORY)
        else()
            set(TEST_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
        endif()

        add_test(NAME casd_${TEST_NAME} COMMAND casd_${TEST_NAME} WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
        target_link_libraries(casd_${TEST_NAME} PUBLIC casd ${GMOCK_TARGET})
    endmacro()

    add_casd_test(server_tests buildboxcasd_casserver.t.cpp)
    add_casd_test(casproxy_findmissingblobscache buildboxcasd_casproxy_findmissingblobscache.t.cpp)
    add_casd_test(casproxy_unreachable_remote buildboxcasd_casproxy_unreachable_remote.t.cpp)
    add_casd_test(casproxy_static_instance_fmb_off buildboxcasd_casproxy_static_instance_fmb_off.t.cpp)
    add_casd_test(casproxy_static_instance_fmb_on buildboxcasd_casproxy_static_instance_fmb_on.t.cpp)
    add_casd_test(casproxy_dynamic_instance_fmb_off buildboxcasd_casproxy_dynamic_instance_fmb_off.t.cpp)
    add_casd_test(casproxy_dynamic_instance_fmb_on buildboxcasd_casproxy_dynamic_instance_fmb_on.t.cpp)
    add_casd_test(local_service_static_instance_tests buildboxcasd_localcasservice_static_instance.t.cpp)
    add_casd_test(local_service_dynamic_instance_tests buildboxcasd_localcasservice_dynamic_instance.t.cpp)
    add_casd_test(local_service_static_instance_unreachable_tests buildboxcasd_localcasservice_static_instance_unreachable.t.cpp)
    add_casd_test(local_service_dynamic_instance_unreachable_tests buildboxcasd_localcasservice_dynamic_instance_unreachable.t.cpp)
    add_casd_test(local_service_remote_server_static_instance_tests buildboxcasd_localcasservice_remote_server_static_instance.t.cpp)
    add_casd_test(local_service_remote_server_dynamic_instance_tests buildboxcasd_localcasservice_remote_server_dynamic_instance.t.cpp)
    add_casd_test(merge_tests buildboxcasd_merge.t.cpp)
    add_casd_test(ra_server_tests buildboxcasd_raserver.t.cpp)
    add_casd_test(expiring_unordered_set buildboxcasd_expiringunorderedset.t.cpp)
    add_casd_test(digest_cache_tests buildboxcasd_digestcache.t.cpp)
    add_casd_test(findmissingblobs_client_tests buildboxcasd_findmissingblobsclient.t.cpp)
    add_casd_test(cmdlinespec_tests buildboxcasd_cmdlinespec.t.cpp)
    add_casd_test(digestoperationqueue_tests buildboxcasd_digestoperationqueue.t.cpp)
    add_casd_test(fetch_tree_cache buildboxcasd_fetchtreecache.t.cpp)
    add_casd_test(actioncache_fs_tests buildboxcasd_fslocalactionstorage.t.cpp)
    add_casd_test(actioncache_tests buildboxcasd_localacinstance.t.cpp)
    add_casd_test(actioncache_proxy_tests buildboxcasd_localacproxyinstance.t.cpp)
    add_casd_test(actioncache_proxy_noupdate_tests buildboxcasd_localacproxyinstancenoupdate.t.cpp)
    add_casd_test(ra_instance_tests buildboxcasd_localrainstance.t.cpp)
    add_casd_test(ra_proxy_instance_tests buildboxcasd_localraproxyinstance.t.cpp)
    add_casd_test(server_noupdate_tests buildboxcasd_casproxynoupdate.t.cpp)
    add_casd_test(instance_tests buildboxcasd_casinstance.t.cpp)
    add_casd_test(execution_proxy_instance_tests buildboxcasd_executionproxyinstance.t.cpp)
    add_casd_test(execution_service_tests buildboxcasd_executionservice.t.cpp)
    add_casd_test(local_execution_service_tests buildboxcasd_localexecutionservice.t.cpp)
    add_casd_test(hybrid_execution_service_tests buildboxcasd_hybridexecutionservice.t.cpp)
    add_casd_test(requestcontextmanager_tests buildboxcasd_requestcontextmanager.t.cpp)
    add_casd_test(hybrid_fallback_execution_service_tests_1 buildboxcasd_hybridfallbackexecutionservice_part1.t.cpp)
    add_casd_test(hybrid_fallback_execution_service_tests_2 buildboxcasd_hybridfallbackexecutionservice_part2.t.cpp)
    add_casd_test(hybrid_fallback_execution_service_tests_3 buildboxcasd_hybridfallbackexecutionservice_part3.t.cpp)
    add_casd_test(get_server_details_tests buildboxcasd_get_server_details.t.cpp)
    add_casd_test(nested_server_tests buildboxcasd_nestedserver.t.cpp)
    add_casd_test(inode_cache_tests buildboxcasd_inodecache.t.cpp)

    add_executable(casd_testrunner buildboxcasd_testrunner.m.cpp)
    target_precompile_headers(casd_testrunner REUSE_FROM common)
    target_link_libraries(casd_testrunner common)
    set_tests_properties(casd_local_execution_service_tests casd_hybrid_execution_service_tests casd_hybrid_fallback_execution_service_tests_1 casd_hybrid_fallback_execution_service_tests_2 casd_hybrid_fallback_execution_service_tests_3
        PROPERTIES ENVIRONMENT "BUILDBOX_RUN=${CMAKE_CURRENT_BINARY_DIR}/casd_testrunner")
endif()

#
# These utilities are used by e2e tests,
# so they should be built even if unit tests are disabled
#

add_executable(cli_stager buildboxcasd_clistager.m.cpp)
target_precompile_headers(cli_stager REUSE_FROM common)
add_dependencies(cli_stager buildbox-casd)
target_link_libraries(cli_stager casd)

add_executable(cli_uploader buildboxcasd_cliuploader.m.cpp)
target_precompile_headers(cli_uploader REUSE_FROM common)
add_dependencies(cli_uploader buildbox-casd)
target_link_libraries(cli_uploader casd)

add_executable(cli_downloader buildboxcasd_clidownloader.m.cpp)
target_precompile_headers(cli_downloader REUSE_FROM common)
add_dependencies(cli_downloader buildbox-casd)
target_link_libraries(cli_downloader casd)

add_executable(cli_tree_fetcher buildboxcasd_clitreefetcher.m.cpp)
target_precompile_headers(cli_tree_fetcher REUSE_FROM common)
add_dependencies(cli_tree_fetcher buildbox-casd)
target_link_libraries(cli_tree_fetcher casd)
