diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5466bdc..6f23d06 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,7 @@ jobs: sudo apt-get update sudo apt-get install -qq libgflags-dev \ libprotobuf-dev libprotoc-dev protobuf-compiler \ - libleveldb-dev libgoogle-perftools-dev + libleveldb-dev libgoogle-perftools-dev lcov sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo env "PATH=$PATH" cmake . && sudo make && sudo mv ./lib/libgtest* /usr/lib/ - name: Install bazel if: ${{ matrix.build_tool == 'bazel' }} @@ -62,13 +62,15 @@ jobs: - name: Build with cmake if: ${{ matrix.build_tool == 'cmake' }} run: | - cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -DWITH_TESTS=ON + cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -DWITH_TESTS=ON -DWITH_COVERAGE=ON cmake --build bld --parallel 16 -- brpc-static cmake --build "${{ env.CMAKE_BUILD_DIR }}" --parallel 16 + - name: Build with bazel if: ${{ matrix.build_tool == 'bazel' }} run: | ~/.bazel/bin/bazel build -c opt --copt -DHAVE_ZLIB=1 //... + - name: Run Tests if: ${{ matrix.with_test }} id: test-braft @@ -76,6 +78,27 @@ jobs: run: | ulimit -c unlimited -S sh ../../test/run_tests.sh + + - name: Coverage + if: ${{ matrix.with_test && matrix.compiler == 'gcc' }} + working-directory: ${{ github.workspace }} + run: | + # generate coverage report + lcov --capture --directory . --output-file coverage.info --no-external + # only keep braft/src files + lcov --extract coverage.info '*/src/braft/*' --output-file coverage.info + # report + lcov --list coverage.info + + - uses: codecov/codecov-action@v4 + if: ${{ matrix.with_test && matrix.compiler == 'gcc' }} + with: + fail_ci_if_error: true # optional (default = false) + files: ./coverage.info # optional + name: codecov-umbrella # optional + token: ${{ secrets.CODECOV_TOKEN }} # required + verbose: true # optional (default = false) + - name: Collect failure info if: ${{ steps.test-braft.conclusion == 'failure'}} run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b161e..6872786 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ option(WITH_DEBUG_SYMBOLS "With debug symbols" ON) # suppress this CMP0058 warning cmake_policy(SET CMP0058 OLD) option(WITH_TESTS "Whether to build unit tests" OFF) +option(WITH_COVERAGE "Whether build with coverage report" OFF) set(WITH_GLOG_VAL "0") if(BRPC_WITH_GLOG) @@ -232,7 +233,7 @@ add_subdirectory(src) if(WITH_TESTS) add_subdirectory(test) endif() -add_subdirectory(tools) +# add_subdirectory(tools) file(COPY ${CMAKE_CURRENT_BINARY_DIR}/braft/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/output/include/braft/ diff --git a/README.md b/README.md index 3c1e621..bf6d20d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://travis-ci.org/baidu/braft.svg?branch=master)](https://travis-ci.org/baidu/braft) +![build status](https://github.com/ehds/mbraft/actions/workflows/build.yml/badge.svg\?branch=main) +[![codecov](https://codecov.io/gh/ehds/mbraft/graph/badge.svg?token=TCS003M7RA)](https://codecov.io/gh/ehds/mbraft) --- @@ -47,7 +48,3 @@ It's widely used inside Baidu to build highly-available systems, such as: * [Paxos](./docs/cn/paxos_protocol.md) * [ZAB](./docs/cn/zab_protocol.md) * [QJM](./docs/cn/qjm.md) - -# Discussion - -* Add Weixin id ***zhengpf__87*** or ***xiongk_2049*** with a verification message '**braft**', then you will be invited into the discussion group. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 59c8498..cf4515c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,11 @@ include_directories(${CMAKE_SOURCE_DIR}/src) add_library(OBJ_LIB OBJECT ${SOURCES}) set_property(TARGET ${OBJ_LIB} PROPERTY POSITION_INDEPENDENT_CODE 1) + +if(WITH_TESTS AND WITH_COVERAGE) + target_compile_options(OBJ_LIB PRIVATE -g -O0 --coverage -fprofile-arcs -ftest-coverage) +endif() + add_library(braft-shared SHARED $) add_library(braft-static STATIC $) target_link_libraries(braft-shared ${DYNAMIC_LIB}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c5e67f..c258168 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,26 +8,42 @@ include_directories(${CMAKE_SOURCE_DIR}/test) set(CMAKE_CPP_FLAGS "-DGFLAGS_NS=${GFLAGS_NS}") set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -D__const__=__unused__ -D_GNU_SOURCE -DUSE_SYMBOLIZE -DNO_TCMALLOC -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DUNIT_TEST -g -Dprivate=public -Dprotected=public -D__STRICT_ANSI__ -include sstream_workaround.h") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CPP_FLAGS} -O2 -pipe -Wall -W -fPIC -fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter -fno-omit-frame-pointer -Wno-unused-result") -use_cxx11() + +if (WITH_COVERAGE) + if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + link_libraries(gcov) + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + endif() + +endif() # bthread_* functions are used in logging.cc, and they need to be marked as # weak symbols explicitly in Darwin system. if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(DYNAMIC_LIB ${DYNAMIC_LIB} - "-Wl,-U,_bthread_getspecific" - "-Wl,-U,_bthread_setspecific" - "-Wl,-U,_bthread_key_create") + pthread + "-framework CoreFoundation" + "-framework CoreGraphics" + "-framework CoreData" + "-framework CoreText" + "-framework Security" + "-framework Foundation" + "-Wl,-U,_MallocExtension_ReleaseFreeMemory" + "-Wl,-U,_ProfilerStart" + "-Wl,-U,_ProfilerStop" + "-Wl,-U,__Z13GetStackTracePPvii") endif() file(GLOB TEST_BRAFT_SRCS "test_*.cpp") foreach(BRAFT_UT ${TEST_BRAFT_SRCS}) get_filename_component(BRAFT_UT_WE ${BRAFT_UT} NAME_WE) - add_executable(${BRAFT_UT_WE} ${BRAFT_UT} - $) + add_executable(${BRAFT_UT_WE} ${BRAFT_UT}) target_link_libraries(${BRAFT_UT_WE} ${GTEST_MAIN_LIB} ${GTEST_LIB} ${GPERFTOOLS_LIBRARY} ${DYNAMIC_LIB} + $ ) endforeach() diff --git a/test/test_route_table.cpp b/test/test_route_table.cpp new file mode 100644 index 0000000..a05b26b --- /dev/null +++ b/test/test_route_table.cpp @@ -0,0 +1,60 @@ +#include "braft/configuration.h" +#include "braft/route_table.h" +#include +#include +#include +#include "../test/util.h" + +class RouteTableTest : public testing::Test { + void SetUp() { + GFLAGS_NS::SetCommandLineOption("minloglevel", "1"); + + ::system("rm -rf data"); + } + void TearDown() { ::system("rm -rf data"); } +}; + +TEST_F(RouteTableTest, BasicTest) { + std::string group = "unittest"; + std::vector peers; + Configuration conf; + for (int i = 0; i < 3; i++) { + braft::PeerId peer; + peer.addr.ip = butil::my_ip(); + peer.addr.port = 5011 + i; + peer.idx = 0; + peers.push_back(peer); + conf.add_peer(peer); + } + + // start cluster + Cluster cluster(group, peers); + for (size_t i = 0; i < peers.size(); i++) { + ASSERT_EQ(0, cluster.start(peers[i].addr)); + } + cluster.wait_leader(); + braft::Node* leader = cluster.leader(); + + PeerId leader_id; + braft::rtb::update_configuration("unittest", conf); + braft::rtb::select_leader(group, &leader_id); + ASSERT_EQ(PeerId(), leader_id); // unvalid peerid. + + braft::rtb::refresh_leader(group, 3000 /*timeout ms*/); + braft::rtb::select_leader(group, &leader_id); + ASSERT_EQ(leader->node_id().peer_id, leader_id); // leader id. + + braft::rtb::update_leader(group, peers[1]); + braft::rtb::select_leader(group, &leader_id); + ASSERT_EQ(peers[1], leader_id); // leader id. + + braft::rtb::remove_group(group); + ASSERT_EQ(braft::rtb::select_leader(group, &leader_id), -1); +} + +int main(int argc, char *argv[]) { + ::testing::InitGoogleTest(&argc, argv); + GFLAGS_NS::SetCommandLineOption("minloglevel", "1"); + GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true); + return RUN_ALL_TESTS(); +}