function(add_store_test name)
  add_executable(${name} ${ARGN})
  target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
  target_link_libraries(
    ${name}
    PUBLIC mooncake_store
           transfer_engine
           cachelib_memory_allocator
           ${ETCD_WRAPPER_LIB}
           glog
           ibverbs
           gtest
           gtest_main
           pthread)
  add_test(NAME ${name} COMMAND ${name})
endfunction()

function(add_ha_test name)
  add_executable(${name} ${ARGN})
  target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
  target_link_libraries(
    ${name}
    PUBLIC mooncake_store
           transfer_engine
           cachelib_memory_allocator
           ${ETCD_WRAPPER_LIB}
           glog
           gflags
           ibverbs
           gtest
           gtest_main
           pthread)
  add_test(NAME ${name} COMMAND ${name})
endfunction()

add_store_test(buffer_allocator_test buffer_allocator_test.cpp)
add_store_test(allocation_strategy_test allocation_strategy_test.cpp)
add_store_test(eviction_strategy_test eviction_strategy_test.cpp)
add_store_test(master_service_test master_service_test.cpp)
add_store_test(batch_remove_test batch_remove_test.cpp)
add_store_test(master_service_ssd_test master_service_ssd_test.cpp)
add_store_test(master_service_ssd_test_for_snapshot
               ha/snapshot/master_service_ssd_test_for_snapshot.cpp)
add_store_test(client_integration_test client_integration_test.cpp)
if(USE_CXL)
  add_store_test(cxl_client_integration_test cxl_client_integration_test.cpp)
endif()
add_store_test(master_metrics_test master_metrics_test.cpp)
add_store_test(posix_file_test posix_file_test.cpp)
add_store_test(thread_pool_test thread_pool_test.cpp)
add_store_test(transfer_task_test transfer_task_test.cpp)
add_store_test(segment_test segment_test.cpp)
add_store_test(offset_allocator_test offset_allocator_test.cpp)
add_store_test(utils_test utils_test.cpp)
add_store_test(client_buffer_test client_buffer_test.cpp)
add_store_test(client_local_hot_cache_test client_local_hot_cache_test.cpp)
add_store_test(pybind_client_test pybind_client_test.cpp)
add_store_test(ipv6_client_test ipv6_client_test.cpp)
add_store_test(client_metrics_test client_metrics_test.cpp)
add_store_test(ssd_metrics_test ssd_metrics_test.cpp)
add_store_test(serializer_test serializer_test.cpp)
add_store_test(embedded_snapshot_catalog_store_test
               ha/snapshot/catalog/backends/embedded/embedded_snapshot_catalog_store_test.cpp)
add_store_test(zstd_util_test zstd_util_test.cpp)
add_store_test(local_file_snapshot_object_store_test
               ha/snapshot/object/backends/local/local_file_snapshot_object_store_test.cpp)
add_store_test(file_util_test file_util_test.cpp)
add_store_test(snapshot_child_process_test
               ha/snapshot/snapshot_child_process_test.cpp)
add_store_test(master_service_test_for_snapshot
               ha/snapshot/master_service_test_for_snapshot.cpp)
add_store_test(non_ha_reconnect_test non_ha_reconnect_test.cpp)
add_store_test(storage_backend_test storage_backend_test.cpp)
add_store_test(mutex_test mutex_test.cpp)
add_store_test(file_storage_test file_storage_test.cpp)
add_store_test(task_manager_test task_manager_test.cpp)
add_store_test(task_executor_test task_executor_test.cpp)
add_store_test(task_integration_test task_integration_test.cpp)
add_store_test(dummy_client_get_buffer_test dummy_client_get_buffer_test.cpp)
add_store_test(health_check_test health_check_test.cpp)
add_subdirectory(e2e)

add_executable(high_availability_test ha/leadership/high_availability_test.cpp)
target_include_directories(high_availability_test PRIVATE
                           ${CMAKE_CURRENT_SOURCE_DIR})
if(STORE_USE_REDIS)
    target_sources(high_availability_test PRIVATE
        ha/leadership/backends/redis/high_availability_redis_test.cpp)
    target_include_directories(high_availability_test PRIVATE
        ${MOONCAKE_STORE_HIREDIS_INCLUDE_DIR})
    target_link_libraries(high_availability_test PRIVATE
        ${MOONCAKE_STORE_HIREDIS_LIBRARY})

    add_executable(redis_snapshot_catalog_store_test
                   ha/snapshot/catalog/backends/redis/redis_snapshot_catalog_store_test.cpp)
    target_include_directories(redis_snapshot_catalog_store_test PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${MOONCAKE_STORE_HIREDIS_INCLUDE_DIR})
    target_link_libraries(redis_snapshot_catalog_store_test
        PUBLIC mooncake_store transfer_engine cachelib_memory_allocator
               ${ETCD_WRAPPER_LIB} glog gflags ibverbs gtest pthread
        PRIVATE ${MOONCAKE_STORE_HIREDIS_LIBRARY})
    add_test(NAME redis_snapshot_catalog_store_test
             COMMAND redis_snapshot_catalog_store_test)
endif()
target_link_libraries(high_availability_test PUBLIC mooncake_store transfer_engine cachelib_memory_allocator ${ETCD_WRAPPER_LIB} glog gtest gtest_main pthread)
if (STORE_USE_ETCD OR STORE_USE_REDIS)
    add_test(NAME high_availability_test COMMAND high_availability_test)
endif()

add_executable(stress_workload_test stress_workload_test.cpp)
target_link_libraries(
  stress_workload_test
  PUBLIC mooncake_store
         transfer_engine
         cachelib_memory_allocator
         ${ETCD_WRAPPER_LIB}
         mooncake_common
         glog
         gflags
         pthread)

# HA tests
add_ha_test(standby_state_machine_test
            ha/standby/standby_state_machine_test.cpp)
add_ha_test(ha_metric_manager_test
            ha/standby/ha_metric_manager_test.cpp)
add_ha_test(hot_standby_service_test
            ha/standby/hot_standby_service_test.cpp)
add_ha_test(hot_standby_snapshot_bootstrap_test
            ha/standby/hot_standby_snapshot_bootstrap_test.cpp)
add_ha_test(oplog_applier_test ha/oplog/oplog_applier_test.cpp)
add_ha_test(oplog_manager_test ha/oplog/oplog_manager_test.cpp)
add_ha_test(etcd_oplog_store_test ha/oplog/etcd_oplog_store_test.cpp)
add_ha_test(oplog_replicator_test ha/oplog/oplog_replicator_test.cpp)
add_ha_test(oplog_serializer_test ha/oplog/oplog_serializer_test.cpp)
add_ha_test(localfs_oplog_store_test ha/oplog/localfs_oplog_store_test.cpp)
add_ha_test(ha_recovery_test ha/oplog/ha_recovery_test.cpp)
add_ha_test(localfs_hot_standby_integration_test
            ha/oplog/localfs_hot_standby_integration_test.cpp)
add_ha_test(catalog_backed_snapshot_provider_test
            ha/snapshot/catalog_backed_snapshot_provider_test.cpp)
if(STORE_USE_REDIS)
  foreach(target catalog_backed_snapshot_provider_test
                 hot_standby_snapshot_bootstrap_test)
    target_include_directories(${target} PRIVATE
                               ${MOONCAKE_STORE_HIREDIS_INCLUDE_DIR})
    target_link_libraries(${target}
                          PRIVATE ${MOONCAKE_STORE_HIREDIS_LIBRARY})
  endforeach()
endif()
