diff --git a/.gitignore b/.gitignore index 51529d9..6c83480 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ vendor/ *.dot *.png *.o +#*.pb.cc +#*.pb.h diff --git a/.travis.yml b/.travis.yml index 75b7c4e..b731474 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ jobs: - cd ${TRAVIS_BUILD_DIR}/spec/cpp - mkdir build - cd build - - cmake -Dtest=ON -DCOVERAGE=1 .. + - cmake -DBUILD_TESTS=ON -DCOVERAGE=1 .. - make - GTEST_COLOR=1 ctest --extra-verbose @@ -66,7 +66,7 @@ jobs: # - cd ${TRAVIS_BUILD_DIR}/spec/cpp # - mkdir build # - cd build -# - cmake -Dtest=ON .. +# - cmake -DBUILD_TESTS=ON .. # - make # - GTEST_COLOR=1 ctest --extra-verbose diff --git a/spec/cpp/CMakeLists.txt b/spec/cpp/CMakeLists.txt index f4073dd..22c7e0b 100644 --- a/spec/cpp/CMakeLists.txt +++ b/spec/cpp/CMakeLists.txt @@ -7,86 +7,36 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build") project(${PROJECT_NAME} VERSION ${PROJECT_VERSION}) -# https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc/ -# https://caiorss.github.io/C-Cpp-Notes/compiler-flags-options.html -add_definitions(-std=c++17) -#add_definitions(-fconcepts) -add_definitions(-fpermissive) -add_definitions(-fasynchronous-unwind-tables) +if (EXISTS /usr/bin/gcc-9) + if (EXISTS /usr/bin/g++-9) + set(CMAKE_C_COMPILER /usr/bin/gcc-9) + set(CMAKE_CXX_COMPILER /usr/bin/g++-9) + endif() +endif() -#add_definitions(-fno-rtti) -add_definitions(-pedantic-errors) -add_definitions(-pipe) -add_definitions(-W) -add_definitions(-Wall) -add_definitions(-Wconversion) -add_definitions(-Wcast-align) -add_definitions(-Wextra) -#add_definitions(-Werror) -add_definitions(-Werror=format-security) -add_definitions(-Werror=implicit-function-declaration) -add_definitions(-Wpedantic) -add_definitions(-Wno-long-long) -add_definitions(-Wno-missing-braces) -add_definitions(-Wno-parentheses) -add_definitions(-Wno-switch) -add_definitions(-Wno-unused-parameter) -add_definitions(-Wold-style-cast) -add_definitions(-Wpointer-arith) -add_definitions(-Wshadow) -#add_definitions(-Wswitch-default) -#add_definitions(-Wswitch-enum) -add_definitions(-Wcast-qual) -#add_definitions(-Wundef) -add_definitions(-Wunused) -add_definitions(-Wunreachable-code) -add_definitions(-Wunused-function) -add_definitions(-Wunused-variable) -add_definitions(-Wwrite-strings) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake") +find_package(Definitions REQUIRED) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes") +ADD_MY_DEFINITIONS() #set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS "${CMAKE_CXX_SOURCE_FILE_EXTENSIONS};hpp;HPP") #message(STATUS "Ignoring extensios ${CMAKE_CXX_IGNORE_EXTENSIONS}") #list(REMOVE_ITEM CMAKE_CXX_IGNORE_EXTENSIONS HPP hpp) #message(STATUS "Ignoring extensios ${CMAKE_CXX_IGNORE_EXTENSIONS}") -string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type) -if (build_type STREQUAL "debug") - message(STATUS "--- Debug build ---") - add_definitions(-g) - add_definitions(-grecord-gcc-switches) -# add_definitions(-D_GLIBCXX_DEBUG) # Not sure why it's breaking the mainRPC.cpp build -# add_definitions(-D_GLIBCXX_DEBUG_PEDANTIC) # Not sure why it's breaking the mainRPC.cpp build - add_definitions(-D_FORTIFY_SOURCE=2) - add_definitions(-D_GLIBCXX_ASSERTIONS) - add_definitions(-ggdb) - add_definitions(-O0) - add_definitions(-fstack-protector-all) - - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") -else () - message(STATUS "--- Release build ---") - add_definitions(-O3) -# add_definitions(-Ofast) - add_definitions(-finline-functions) - add_definitions(-funroll-loops) - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -frecursive") -endif () - #set(PROTOBUF_GENERATED_PATH src CACHE STRING proto_gen) set(GRPC_PLUGIN_CPP /usr/local/bin/grpc_cpp_plugin CACHE STRING grpc_bin) +option(BUILD_TESTS "Build test programs" ON) message(STATUS "BUILD_TESTS = ${BUILD_TESTS}") -option(BUILD_TESTS "Build test programs" ON) set(CMAKE_CXX_CPPCHECK "cppcheck") include_directories(src) add_subdirectory(src) -if (test) +if (BUILD_TESTS) + message(STATUS "Building the tests") enable_testing() SET(COVERAGE OFF CACHE BOOL "Coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") @@ -96,4 +46,6 @@ if (test) #find_package(GTest REQUIRED) #include_directories(${GTEST_INCLUDE_DIRS}) add_subdirectory(tests) +else() + message(STATUS "Ignoring the tests") endif() diff --git a/spec/cpp/cmake/FindDefinitions.cmake b/spec/cpp/cmake/FindDefinitions.cmake new file mode 100644 index 0000000..88fbab3 --- /dev/null +++ b/spec/cpp/cmake/FindDefinitions.cmake @@ -0,0 +1,105 @@ +MACRO(ADD_MY_DEFINITIONS) + message(STATUS "Adding definitiions") + # https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc/ + # https://caiorss.github.io/C-Cpp-Notes/compiler-flags-options.html + add_definitions(-std=c++17) + #add_definitions(-fconcepts) + add_definitions(-fpermissive) + add_definitions(-fasynchronous-unwind-tables) + + #add_definitions(-fno-rtti) + add_definitions(-pedantic-errors) + add_definitions(-pipe) + + add_definitions(-W) + add_definitions(-Wall) + add_definitions(-Wconversion) + add_definitions(-Wcast-align) + add_definitions(-Wextra) + #add_definitions(-Werror) + add_definitions(-Werror=format-security) + add_definitions(-Werror=implicit-function-declaration) + add_definitions(-Wpedantic) + add_definitions(-Wno-long-long) + add_definitions(-Wno-missing-braces) + add_definitions(-Wno-parentheses) + add_definitions(-Wno-switch) + add_definitions(-Wno-unused-parameter) + add_definitions(-Wold-style-cast) + add_definitions(-Wpointer-arith) + add_definitions(-Wshadow) + #add_definitions(-Wswitch-default) + #add_definitions(-Wswitch-enum) + add_definitions(-Wcast-qual) + #add_definitions(-Wundef) + add_definitions(-Wunused) + add_definitions(-Wunreachable-code) + add_definitions(-Wunused-function) + add_definitions(-Wunused-variable) + add_definitions(-Wwrite-strings) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes") + + string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type) + if (build_type STREQUAL "debug") + message(STATUS "--- Debug build ---") + add_definitions(-g) + add_definitions(-grecord-gcc-switches) + # add_definitions(-D_GLIBCXX_DEBUG) # Not sure why it's breaking the mainRPC.cpp build + # add_definitions(-D_GLIBCXX_DEBUG_PEDANTIC) # Not sure why it's breaking the mainRPC.cpp build + add_definitions(-D_FORTIFY_SOURCE=2) + add_definitions(-D_GLIBCXX_ASSERTIONS) + add_definitions(-ggdb) + add_definitions(-O0) + add_definitions(-fstack-protector-all) + + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined") + else () + message(STATUS "--- Release build ---") + add_definitions(-O3) + # add_definitions(-Ofast) + add_definitions(-finline-functions) + add_definitions(-funroll-loops) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -frecursive") + endif () +ENDMACRO() + +MACRO(ADD_TEST_DEFINITIONS) + message(STATUS "Adding test definitions") + + string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type) + if (build_type STREQUAL "debug") + message(STATUS "--- Debug build ---") + message(STATUS "Adding sanitizer") + add_definitions(-fsanitize=address) + add_definitions(-fsanitize=alignment) + add_definitions(-fsanitize=bool) + add_definitions(-fsanitize=bounds) + add_definitions(-fsanitize=bounds-strict) + add_definitions(-fsanitize=builtin) + add_definitions(-fsanitize=enum) + add_definitions(-fsanitize=float-divide-by-zero) + add_definitions(-fsanitize=float-cast-overflow) + add_definitions(-fsanitize=integer-divide-by-zero) + add_definitions(-fsanitize=leak) + # add_definitions(-fsanitize=kernel-address) + add_definitions(-fsanitize=nonnull-attribute) + add_definitions(-fsanitize=null) + add_definitions(-fsanitize=object-size) + add_definitions(-fsanitize=pointer-compare) + add_definitions(-fsanitize=pointer-overflow) + add_definitions(-fsanitize=pointer-subtract) + add_definitions(-fsanitize=return) + add_definitions(-fsanitize=returns-nonnull-attribute) + add_definitions(-fsanitize=signed-integer-overflow) + add_definitions(-fsanitize=shift) + add_definitions(-fsanitize=shift-base) + add_definitions(-fsanitize=shift-exponent) + # add_definitions(-fsanitize=thread) + add_definitions(-fsanitize=undefined) + add_definitions(-fsanitize=unreachable) + add_definitions(-fsanitize=vla-bound) + add_definitions(-fsanitize=vptr) + endif () +ENDMACRO() diff --git a/spec/cpp/cmake/FindHelper.cmake b/spec/cpp/cmake/FindHelper.cmake new file mode 100644 index 0000000..f068724 --- /dev/null +++ b/spec/cpp/cmake/FindHelper.cmake @@ -0,0 +1,10 @@ +MACRO(SUBDIRLIST result curdir) + FILE(GLOB children RELATIVE ${curdir} ${curdir}/*) + SET(dirlist "") + FOREACH (child ${children}) + IF (IS_DIRECTORY ${curdir}/${child} AND EXISTS ${curdir}/${child}/CMakeLists.txt) + LIST(APPEND dirlist ${child}) + ENDIF () + ENDFOREACH () + SET(${result} ${dirlist}) +ENDMACRO() diff --git a/spec/cpp/cmake/FindProtobufHelper.cmake b/spec/cpp/cmake/FindProtobufHelper.cmake new file mode 100644 index 0000000..f322ca9 --- /dev/null +++ b/spec/cpp/cmake/FindProtobufHelper.cmake @@ -0,0 +1,50 @@ +#================================================================# +# Protobuf code generation +#================================================================# +find_package(Protobuf REQUIRED) + +#include_directories(protos) + +#file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PROTOMODEL_PATH) +#file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${PROTOBUF_GENERATED_PATH} PROTOBINDING_PATH) + +MACRO(GENERATE_PROTO proto) + file(TO_NATIVE_PATH ${proto} proto_native) + message(STATUS "Generating Protobuf ${proto}") + execute_process( + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + # --proto_path=${PROTOMODEL_PATH} + --proto_path=${CMAKE_CURRENT_SOURCE_DIR} + # --cpp_out=${PROTOBINDING_PATH} ${proto_native} + --cpp_out=${CMAKE_CURRENT_SOURCE_DIR} ${proto_native} + RESULT_VARIABLE rv + ) + + execute_process( + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + # --proto_path=${PROTOMODEL_PATH} + --proto_path=${CMAKE_CURRENT_SOURCE_DIR} + # --grpc_out=${PROTOBINDING_PATH} + --grpc_out=${CMAKE_CURRENT_SOURCE_DIR} + --plugin=protoc-gen-grpc=${GRPC_PLUGIN_CPP} ${proto_native} + RESULT_VARIABLE rv + ) +ENDMACRO() + +MACRO(target_link_libraries_proto name) +# find_package(gRPC CONFIG REQUIRED) +# find_package(Protobuf REQUIRED) + target_link_libraries( + ${name} + protobuf + pthread +# gRPC::grpc++ + grpc++ + grpc++_reflection + dl + m + rt + ${_GRPC_GRPCPP_UNSECURE} + ${_PROTOBUF_LIBPROTOBUF} + ) +ENDMACRO() diff --git a/spec/cpp/cmake/FindTestHelper.cmake b/spec/cpp/cmake/FindTestHelper.cmake new file mode 100644 index 0000000..0c3478d --- /dev/null +++ b/spec/cpp/cmake/FindTestHelper.cmake @@ -0,0 +1,42 @@ +MACRO(ADD_TEST_ALL_FILES asan) + get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) + + if (${asan} STREQUAL "ON") + message(STATUS "Adding address sanitizer to ${test_name}") + ADD_TEST_DEFINITIONS() + else () + message(STATUS "No address sanitizer to ${test_name}") + endif () + message(STATUS "Creating test ${test_name}") + + file(GLOB_RECURSE test_sources *) + list(FILTER test_sources INCLUDE REGEX "cpp$") + + set(lib_name "${PROJECT_NAME}_${PROJECT_VERSION}") + + add_executable( + "${test_name}_test" + ${test_sources} + ) + + target_link_libraries( + "${test_name}_test" + ${lib_name} + gtest + gtest_main + ${CMAKE_THREAD_LIBS_INIT} + ) + + if (${asan} STREQUAL "ON") + target_link_libraries("${test_name}_test" asan) + endif () + + target_link_libraries("${test_name}_test" ${lib_name}) + include_directories(${CMAKE_SOURCE_DIR}/src) + + message(STATUS "Adding test: ${test_name}_test") + add_test(NAME "${test_name}_test_caller" COMMAND "${test_name}_test") + + target_compile_options("${test_name}_test" PRIVATE --coverage) + target_link_libraries("${test_name}_test" --coverage) +ENDMACRO() diff --git a/spec/cpp/src/CMakeLists.txt b/spec/cpp/src/CMakeLists.txt index be44ce6..259df35 100644 --- a/spec/cpp/src/CMakeLists.txt +++ b/spec/cpp/src/CMakeLists.txt @@ -1,25 +1,31 @@ +find_package(ProtobufHelper REQUIRED) + file(GLOB_RECURSE project_sources *) list(FILTER project_sources EXCLUDE REGEX "main.*\\.cpp$") -list(FILTER project_sources INCLUDE REGEX "pp$") +list(FILTER project_sources EXCLUDE REGEX "main.*\\.cc$") +list(FILTER project_sources EXCLUDE REGEX "\\.txt$") +list(FILTER project_sources EXCLUDE REGEX "\\.h$") +list(FILTER project_sources EXCLUDE REGEX "\\.gitignore$") +list(FILTER project_sources EXCLUDE REGEX "Makefile$") +list(FILTER project_sources EXCLUDE REGEX "\\.proto$") +#list(FILTER project_sources INCLUDE REGEX "pp$") set(lib_name "${PROJECT_NAME}_${PROJECT_VERSION}") message(STATUS "${lib_name} - ${project_sources}") -add_library(${lib_name} ${project_sources} utils/Pointer.hpp) +add_library(${lib_name} ${project_sources}) +target_link_libraries_proto(${lib_name}) #set_source_files_properties(${project_sources} PROPERTIES LANGUAGE CXX) set_target_properties(${lib_name} PROPERTIES LINKER_LANGUAGE CXX) add_executable(app_test main.cpp ${project_sources}) +target_link_libraries_proto(app_test) target_link_libraries( app_test ${lib_name} - protobuf - grpc++ - grpc++_reflection - dl - pthread ) +add_subdirectory(p2p) add_subdirectory(bftevents-grpc) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/lib") @@ -31,14 +37,7 @@ add_executable( ${project_sources} ) -target_link_libraries( - app_RPCtest - protobuf - pthread - grpc++ - grpc++_reflection - dl -) +target_link_libraries_proto(app_RPCtest) if (build_type STREQUAL "debug") # Fix asan diff --git a/spec/cpp/src/bftevents-grpc/.gitignore b/spec/cpp/src/bftevents-grpc/.gitignore deleted file mode 100644 index 7a78db6..0000000 --- a/spec/cpp/src/bftevents-grpc/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -bftserver -bftclient diff --git a/spec/cpp/src/bftevents-grpc/CMakeLists.txt b/spec/cpp/src/bftevents-grpc/CMakeLists.txt index b146a20..6b68c94 100644 --- a/spec/cpp/src/bftevents-grpc/CMakeLists.txt +++ b/spec/cpp/src/bftevents-grpc/CMakeLists.txt @@ -1,35 +1,26 @@ -#================================================================# -# Protobuf code generation -#================================================================# -find_package(Protobuf REQUIRED) +find_package(ProtobufHelper REQUIRED) -#include_directories(protos) +file(GLOB DATAMODEL_PROTOS bftevent.proto) -file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PROTOMODEL_PATH) -#file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${PROTOBUF_GENERATED_PATH} PROTOBINDING_PATH) +foreach(proto ${DATAMODEL_PROTOS}) + GENERATE_PROTO(${proto}) +endforeach(proto) -file(GLOB DATAMODEL_PROTOS ${CMAKE_CURRENT_SOURCE_DIR}/bftevent.proto) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/lib") +add_executable( + bftclient + mainBftclient.cc + bftevent.pb.cc + bftevent.grpc.pb.cc +) -foreach(proto ${DATAMODEL_PROTOS}) - file(TO_NATIVE_PATH ${proto} proto_native) - message(STATUS "Generating ${proto}") +target_link_libraries_proto(bftclient) - execute_process( - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} -# --proto_path=${PROTOMODEL_PATH} - --proto_path=${CMAKE_CURRENT_SOURCE_DIR} -# --cpp_out=${PROTOBINDING_PATH} ${proto_native} - --cpp_out=${CMAKE_CURRENT_SOURCE_DIR} ${proto_native} - RESULT_VARIABLE rv - ) +add_executable( + bftserver + mainBftserver.cc + bftevent.pb.cc + bftevent.grpc.pb.cc +) - execute_process( - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} -# --proto_path=${PROTOMODEL_PATH} - --proto_path=${CMAKE_CURRENT_SOURCE_DIR} -# --grpc_out=${PROTOBINDING_PATH} - --grpc_out=${CMAKE_CURRENT_SOURCE_DIR} - --plugin=protoc-gen-grpc=${GRPC_PLUGIN_CPP} ${proto_native} - RESULT_VARIABLE rv - ) -endforeach(proto) +target_link_libraries_proto(bftserver) diff --git a/spec/cpp/src/bftevents-grpc/Makefile b/spec/cpp/src/bftevents-grpc/Makefile deleted file mode 100644 index 01fbbb8..0000000 --- a/spec/cpp/src/bftevents-grpc/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -LDFLAGS = -L/usr/local/lib `pkg-config --libs protobuf grpc++`\ - -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ - -ldl - -CXX = g++ -CPPFLAGS1 += `pkg-config --cflags protobuf grpc` -CXXFLAGS1 += -std=c++17 - -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -all: bftclient bftserver - -bftclient: bftevent.pb.o bftevent.grpc.pb.o bftclient.o - $(CXX) $^ $(LDFLAGS) -o $@ - -bftserver: bftevent.pb.o bftevent.grpc.pb.o bftserver.o - $(CXX) $^ $(LDFLAGS) -o $@ - -%.grpc.pb.cc: %.proto - protoc --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -%.pb.cc: %.proto - protoc --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h bftclient bftserver diff --git a/spec/cpp/src/bftevents-grpc/bftevent.pb.cc b/spec/cpp/src/bftevents-grpc/bftevent.pb.cc index 711f596..a4ea26e 100644 --- a/spec/cpp/src/bftevents-grpc/bftevent.pb.cc +++ b/spec/cpp/src/bftevents-grpc/bftevent.pb.cc @@ -90,7 +90,8 @@ const char descriptor_table_protodef_bftevent_2eproto[] = "args\030\003 \003(\t\022\r\n\005delay\030\004 \001(\005\"\033\n\nEventReply\022" "\r\n\005gotit\030\001 \001(\0052H\n\010BFTEvent\022<\n\013informEven" "t\022\025.bftevent.EventInform\032\024.bftevent.Even" - "tReply\"\000B\t\n\007ex.grpcb\006proto3" + "tReply\"\000B,\n*com.github.com.neoresearch.l" + "ibbft.bfteventb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_bftevent_2eproto_deps[1] = { }; @@ -101,7 +102,7 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_bft static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_bftevent_2eproto_once; static bool descriptor_table_bftevent_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_bftevent_2eproto = { - &descriptor_table_bftevent_2eproto_initialized, descriptor_table_protodef_bftevent_2eproto, "bftevent.proto", 227, + &descriptor_table_bftevent_2eproto_initialized, descriptor_table_protodef_bftevent_2eproto, "bftevent.proto", 262, &descriptor_table_bftevent_2eproto_once, descriptor_table_bftevent_2eproto_sccs, descriptor_table_bftevent_2eproto_deps, 2, 0, schemas, file_default_instances, TableStruct_bftevent_2eproto::offsets, file_level_metadata_bftevent_2eproto, 2, file_level_enum_descriptors_bftevent_2eproto, file_level_service_descriptors_bftevent_2eproto, diff --git a/spec/cpp/src/bftevents-grpc/bftevent.proto b/spec/cpp/src/bftevents-grpc/bftevent.proto index 158b495..98cc809 100644 --- a/spec/cpp/src/bftevents-grpc/bftevent.proto +++ b/spec/cpp/src/bftevents-grpc/bftevent.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option java_package = "ex.grpc"; +option java_package = "com.github.com.neoresearch.libbft.bftevent"; package bftevent; diff --git a/spec/cpp/src/bftevents-grpc/bftclient.cc b/spec/cpp/src/bftevents-grpc/mainBftclient.cc similarity index 100% rename from spec/cpp/src/bftevents-grpc/bftclient.cc rename to spec/cpp/src/bftevents-grpc/mainBftclient.cc diff --git a/spec/cpp/src/bftevents-grpc/bftserver.cc b/spec/cpp/src/bftevents-grpc/mainBftserver.cc similarity index 100% rename from spec/cpp/src/bftevents-grpc/bftserver.cc rename to spec/cpp/src/bftevents-grpc/mainBftserver.cc diff --git a/spec/cpp/src/p2p/CMakeLists.txt b/spec/cpp/src/p2p/CMakeLists.txt new file mode 100644 index 0000000..da6b5c1 --- /dev/null +++ b/spec/cpp/src/p2p/CMakeLists.txt @@ -0,0 +1,28 @@ +find_package(ProtobufHelper REQUIRED) + +file(GLOB DATAMODEL_PROTOS bftp2p.proto) + +foreach(proto ${DATAMODEL_PROTOS}) + GENERATE_PROTO(${proto}) +endforeach(proto) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/local/lib") +add_executable( + p2p + mainP2P.cpp + bftp2p.pb.cc + bftp2p.grpc.pb.cc + P2PServer.cpp + ../utils/CLI.cpp +) + +target_link_libraries_proto(p2p) + +set(lib_name "${PROJECT_NAME}_${PROJECT_VERSION}") +message(STATUS "p2p - ${lib_name}") + +# TODO Check why it does not link the CLI.cpp +target_link_libraries( + ${name} + ${lib_name} +) diff --git a/spec/cpp/src/p2p/P2PServer.cpp b/spec/cpp/src/p2p/P2PServer.cpp new file mode 100644 index 0000000..860264e --- /dev/null +++ b/spec/cpp/src/p2p/P2PServer.cpp @@ -0,0 +1,37 @@ +#include "P2PServer.h" +#include + +using namespace std; + +P2PServiceImpl::P2PServiceImpl(const ::p2p::Url *urlMe) { + me = urlToString(urlMe); +} + +grpc::Status P2PServiceImpl::register_me( + ::grpc::ServerContext *context, const ::p2p::Url *request, ::grpc::ServerWriter<::p2p::Url> *writer) { + const string registered = urlToString(request); + servers.emplace(registered); + cout << me << " is registering: " << registered << endl; + + writer->Write(stringToUrl(me)); + for (auto &server : servers) { + writer->Write(stringToUrl(server)); + } + + return grpc::Status::OK; +} + +grpc::Status P2PServiceImpl::update_services( + ::grpc::ServerContext *context, ::grpc::ServerReaderWriter<::p2p::Url, ::p2p::Url> *stream) { + cout << me << " is updating its services " << endl; + p2p::Url url; + while (stream->Read(&url)) { + servers.emplace(urlToString(&url)); + } + + stream->Write(stringToUrl(me)); + for (auto &server : servers) { + stream->Write(stringToUrl(server)); + } + return grpc::Status::OK; +} diff --git a/spec/cpp/src/p2p/P2PServer.h b/spec/cpp/src/p2p/P2PServer.h new file mode 100644 index 0000000..40b050c --- /dev/null +++ b/spec/cpp/src/p2p/P2PServer.h @@ -0,0 +1,38 @@ +#ifndef LIBBFT_P2P_P2P_SERVER +#define LIBBFT_P2P_P2P_SERVER + +#include +#include + +#include "bftp2p.pb.h" +#include "bftp2p.grpc.pb.h" + +inline std::string urlToString(const ::p2p::Url *url) { + return url->domain() + ":" + std::to_string(url->port()); +} + +inline ::p2p::Url stringToUrl(const std::string& server) { + p2p::Url resp; + auto pos = server.find(':'); + resp.set_domain(server.substr(0, pos)); + resp.set_port(std::stoi(server.substr(pos + 1))); + return resp; +} + +class P2PServiceImpl final : public p2p::P2P::Service { +private: + std::string me; + std::unordered_set servers; +public: + explicit P2PServiceImpl(const ::p2p::Url *urlMe); + + virtual ~P2PServiceImpl() {} + + grpc::Status register_me( + ::grpc::ServerContext *context, const ::p2p::Url *request, ::grpc::ServerWriter<::p2p::Url> *writer); + + grpc::Status update_services( + ::grpc::ServerContext *context, ::grpc::ServerReaderWriter<::p2p::Url, ::p2p::Url> *stream); +}; + +#endif diff --git a/spec/cpp/src/p2p/bftp2p.grpc.pb.cc b/spec/cpp/src/p2p/bftp2p.grpc.pb.cc new file mode 100644 index 0000000..178481d --- /dev/null +++ b/spec/cpp/src/p2p/bftp2p.grpc.pb.cc @@ -0,0 +1,100 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: bftp2p.proto + +#include "bftp2p.pb.h" +#include "bftp2p.grpc.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace p2p { + +static const char* P2P_method_names[] = { + "/p2p.P2P/register_me", + "/p2p.P2P/update_services", +}; + +std::unique_ptr< P2P::Stub> P2P::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { + (void)options; + std::unique_ptr< P2P::Stub> stub(new P2P::Stub(channel)); + return stub; +} + +P2P::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) + : channel_(channel), rpcmethod_register_me_(P2P_method_names[0], ::grpc::internal::RpcMethod::SERVER_STREAMING, channel) + , rpcmethod_update_services_(P2P_method_names[1], ::grpc::internal::RpcMethod::BIDI_STREAMING, channel) + {} + +::grpc::ClientReader< ::p2p::Url>* P2P::Stub::register_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request) { + return ::grpc::internal::ClientReaderFactory< ::p2p::Url>::Create(channel_.get(), rpcmethod_register_me_, context, request); +} + +void P2P::Stub::experimental_async::register_me(::grpc::ClientContext* context, ::p2p::Url* request, ::grpc::experimental::ClientReadReactor< ::p2p::Url>* reactor) { + ::grpc::internal::ClientCallbackReaderFactory< ::p2p::Url>::Create(stub_->channel_.get(), stub_->rpcmethod_register_me_, context, request, reactor); +} + +::grpc::ClientAsyncReader< ::p2p::Url>* P2P::Stub::Asyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq, void* tag) { + return ::grpc::internal::ClientAsyncReaderFactory< ::p2p::Url>::Create(channel_.get(), cq, rpcmethod_register_me_, context, request, true, tag); +} + +::grpc::ClientAsyncReader< ::p2p::Url>* P2P::Stub::PrepareAsyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncReaderFactory< ::p2p::Url>::Create(channel_.get(), cq, rpcmethod_register_me_, context, request, false, nullptr); +} + +::grpc::ClientReaderWriter< ::p2p::Url, ::p2p::Url>* P2P::Stub::update_servicesRaw(::grpc::ClientContext* context) { + return ::grpc::internal::ClientReaderWriterFactory< ::p2p::Url, ::p2p::Url>::Create(channel_.get(), rpcmethod_update_services_, context); +} + +void P2P::Stub::experimental_async::update_services(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::p2p::Url,::p2p::Url>* reactor) { + ::grpc::internal::ClientCallbackReaderWriterFactory< ::p2p::Url,::p2p::Url>::Create(stub_->channel_.get(), stub_->rpcmethod_update_services_, context, reactor); +} + +::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>* P2P::Stub::Asyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return ::grpc::internal::ClientAsyncReaderWriterFactory< ::p2p::Url, ::p2p::Url>::Create(channel_.get(), cq, rpcmethod_update_services_, context, true, tag); +} + +::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>* P2P::Stub::PrepareAsyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncReaderWriterFactory< ::p2p::Url, ::p2p::Url>::Create(channel_.get(), cq, rpcmethod_update_services_, context, false, nullptr); +} + +P2P::Service::Service() { + AddMethod(new ::grpc::internal::RpcServiceMethod( + P2P_method_names[0], + ::grpc::internal::RpcMethod::SERVER_STREAMING, + new ::grpc::internal::ServerStreamingHandler< P2P::Service, ::p2p::Url, ::p2p::Url>( + std::mem_fn(&P2P::Service::register_me), this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + P2P_method_names[1], + ::grpc::internal::RpcMethod::BIDI_STREAMING, + new ::grpc::internal::BidiStreamingHandler< P2P::Service, ::p2p::Url, ::p2p::Url>( + std::mem_fn(&P2P::Service::update_services), this))); +} + +P2P::Service::~Service() { +} + +::grpc::Status P2P::Service::register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) { + (void) context; + (void) request; + (void) writer; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status P2P::Service::update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) { + (void) context; + (void) stream; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + + +} // namespace p2p + diff --git a/spec/cpp/src/p2p/bftp2p.grpc.pb.h b/spec/cpp/src/p2p/bftp2p.grpc.pb.h new file mode 100644 index 0000000..e49ee2d --- /dev/null +++ b/spec/cpp/src/p2p/bftp2p.grpc.pb.h @@ -0,0 +1,364 @@ +// Generated by the gRPC C++ plugin. +// If you make any local change, they will be lost. +// source: bftp2p.proto +#ifndef GRPC_bftp2p_2eproto__INCLUDED +#define GRPC_bftp2p_2eproto__INCLUDED + +#include "bftp2p.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class Channel; +class ServerCompletionQueue; +class ServerContext; +} // namespace grpc + +namespace p2p { + +// Defines the service +class P2P final { + public: + static constexpr char const* service_full_name() { + return "p2p.P2P"; + } + class StubInterface { + public: + virtual ~StubInterface() {} + // Function invoked to send the request + std::unique_ptr< ::grpc::ClientReaderInterface< ::p2p::Url>> register_me(::grpc::ClientContext* context, const ::p2p::Url& request) { + return std::unique_ptr< ::grpc::ClientReaderInterface< ::p2p::Url>>(register_meRaw(context, request)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::p2p::Url>> Asyncregister_me(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::p2p::Url>>(Asyncregister_meRaw(context, request, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::p2p::Url>> PrepareAsyncregister_me(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< ::p2p::Url>>(PrepareAsyncregister_meRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::p2p::Url, ::p2p::Url>> update_services(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::p2p::Url, ::p2p::Url>>(update_servicesRaw(context)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>> Asyncupdate_services(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>>(Asyncupdate_servicesRaw(context, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>> PrepareAsyncupdate_services(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>>(PrepareAsyncupdate_servicesRaw(context, cq)); + } + class experimental_async_interface { + public: + virtual ~experimental_async_interface() {} + // Function invoked to send the request + virtual void register_me(::grpc::ClientContext* context, ::p2p::Url* request, ::grpc::experimental::ClientReadReactor< ::p2p::Url>* reactor) = 0; + virtual void update_services(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::p2p::Url,::p2p::Url>* reactor) = 0; + }; + virtual class experimental_async_interface* experimental_async() { return nullptr; } + private: + virtual ::grpc::ClientReaderInterface< ::p2p::Url>* register_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::p2p::Url>* Asyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderInterface< ::p2p::Url>* PrepareAsyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientReaderWriterInterface< ::p2p::Url, ::p2p::Url>* update_servicesRaw(::grpc::ClientContext* context) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>* Asyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0; + virtual ::grpc::ClientAsyncReaderWriterInterface< ::p2p::Url, ::p2p::Url>* PrepareAsyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) = 0; + }; + class Stub final : public StubInterface { + public: + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + std::unique_ptr< ::grpc::ClientReader< ::p2p::Url>> register_me(::grpc::ClientContext* context, const ::p2p::Url& request) { + return std::unique_ptr< ::grpc::ClientReader< ::p2p::Url>>(register_meRaw(context, request)); + } + std::unique_ptr< ::grpc::ClientAsyncReader< ::p2p::Url>> Asyncregister_me(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::p2p::Url>>(Asyncregister_meRaw(context, request, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReader< ::p2p::Url>> PrepareAsyncregister_me(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReader< ::p2p::Url>>(PrepareAsyncregister_meRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientReaderWriter< ::p2p::Url, ::p2p::Url>> update_services(::grpc::ClientContext* context) { + return std::unique_ptr< ::grpc::ClientReaderWriter< ::p2p::Url, ::p2p::Url>>(update_servicesRaw(context)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>> Asyncupdate_services(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>>(Asyncupdate_servicesRaw(context, cq, tag)); + } + std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>> PrepareAsyncupdate_services(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>>(PrepareAsyncupdate_servicesRaw(context, cq)); + } + class experimental_async final : + public StubInterface::experimental_async_interface { + public: + void register_me(::grpc::ClientContext* context, ::p2p::Url* request, ::grpc::experimental::ClientReadReactor< ::p2p::Url>* reactor) override; + void update_services(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::p2p::Url,::p2p::Url>* reactor) override; + private: + friend class Stub; + explicit experimental_async(Stub* stub): stub_(stub) { } + Stub* stub() { return stub_; } + Stub* stub_; + }; + class experimental_async_interface* experimental_async() override { return &async_stub_; } + + private: + std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; + ::grpc::ClientReader< ::p2p::Url>* register_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request) override; + ::grpc::ClientAsyncReader< ::p2p::Url>* Asyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReader< ::p2p::Url>* PrepareAsyncregister_meRaw(::grpc::ClientContext* context, const ::p2p::Url& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientReaderWriter< ::p2p::Url, ::p2p::Url>* update_servicesRaw(::grpc::ClientContext* context) override; + ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>* Asyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc::ClientAsyncReaderWriter< ::p2p::Url, ::p2p::Url>* PrepareAsyncupdate_servicesRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) override; + const ::grpc::internal::RpcMethod rpcmethod_register_me_; + const ::grpc::internal::RpcMethod rpcmethod_update_services_; + }; + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + + class Service : public ::grpc::Service { + public: + Service(); + virtual ~Service(); + // Function invoked to send the request + virtual ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer); + virtual ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream); + }; + template + class WithAsyncMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithAsyncMethod_register_me() { + ::grpc::Service::MarkMethodAsync(0); + } + ~WithAsyncMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void Requestregister_me(::grpc::ServerContext* context, ::p2p::Url* request, ::grpc::ServerAsyncWriter< ::p2p::Url>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(0, context, request, writer, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_update_services : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithAsyncMethod_update_services() { + ::grpc::Service::MarkMethodAsync(1); + } + ~WithAsyncMethod_update_services() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void Requestupdate_services(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::p2p::Url, ::p2p::Url>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(1, context, stream, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_register_me > AsyncService; + template + class ExperimentalWithCallbackMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + ExperimentalWithCallbackMethod_register_me() { + ::grpc::Service::experimental().MarkMethodCallback(0, + new ::grpc::internal::CallbackServerStreamingHandler< ::p2p::Url, ::p2p::Url>( + [this] { return this->register_me(); })); + } + ~ExperimentalWithCallbackMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::experimental::ServerWriteReactor< ::p2p::Url, ::p2p::Url>* register_me() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::p2p::Url, ::p2p::Url>;} + }; + template + class ExperimentalWithCallbackMethod_update_services : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + ExperimentalWithCallbackMethod_update_services() { + ::grpc::Service::experimental().MarkMethodCallback(1, + new ::grpc::internal::CallbackBidiHandler< ::p2p::Url, ::p2p::Url>( + [this] { return this->update_services(); })); + } + ~ExperimentalWithCallbackMethod_update_services() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::experimental::ServerBidiReactor< ::p2p::Url, ::p2p::Url>* update_services() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::p2p::Url, ::p2p::Url>;} + }; + typedef ExperimentalWithCallbackMethod_register_me > ExperimentalCallbackService; + template + class WithGenericMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithGenericMethod_register_me() { + ::grpc::Service::MarkMethodGeneric(0); + } + ~WithGenericMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_update_services : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithGenericMethod_update_services() { + ::grpc::Service::MarkMethodGeneric(1); + } + ~WithGenericMethod_update_services() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithRawMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithRawMethod_register_me() { + ::grpc::Service::MarkMethodRaw(0); + } + ~WithRawMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void Requestregister_me(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncServerStreaming(0, context, request, writer, new_call_cq, notification_cq, tag); + } + }; + template + class WithRawMethod_update_services : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithRawMethod_update_services() { + ::grpc::Service::MarkMethodRaw(1); + } + ~WithRawMethod_update_services() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void Requestupdate_services(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncBidiStreaming(1, context, stream, new_call_cq, notification_cq, tag); + } + }; + template + class ExperimentalWithRawCallbackMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + ExperimentalWithRawCallbackMethod_register_me() { + ::grpc::Service::experimental().MarkMethodRawCallback(0, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->register_me(); })); + } + ~ExperimentalWithRawCallbackMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* register_me() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} + }; + template + class ExperimentalWithRawCallbackMethod_update_services : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + ExperimentalWithRawCallbackMethod_update_services() { + ::grpc::Service::experimental().MarkMethodRawCallback(1, + new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->update_services(); })); + } + ~ExperimentalWithRawCallbackMethod_update_services() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status update_services(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::p2p::Url, ::p2p::Url>* stream) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* update_services() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} + }; + typedef Service StreamedUnaryService; + template + class WithSplitStreamingMethod_register_me : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithSplitStreamingMethod_register_me() { + ::grpc::Service::MarkMethodStreamed(0, + new ::grpc::internal::SplitServerStreamingHandler< ::p2p::Url, ::p2p::Url>(std::bind(&WithSplitStreamingMethod_register_me::Streamedregister_me, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithSplitStreamingMethod_register_me() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status register_me(::grpc::ServerContext* context, const ::p2p::Url* request, ::grpc::ServerWriter< ::p2p::Url>* writer) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with split streamed + virtual ::grpc::Status Streamedregister_me(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::p2p::Url,::p2p::Url>* server_split_streamer) = 0; + }; + typedef WithSplitStreamingMethod_register_me SplitStreamedService; + typedef WithSplitStreamingMethod_register_me StreamedService; +}; + +} // namespace p2p + + +#endif // GRPC_bftp2p_2eproto__INCLUDED diff --git a/spec/cpp/src/p2p/bftp2p.pb.cc b/spec/cpp/src/p2p/bftp2p.pb.cc new file mode 100644 index 0000000..8a5a893 --- /dev/null +++ b/spec/cpp/src/p2p/bftp2p.pb.cc @@ -0,0 +1,415 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: bftp2p.proto + +#include "bftp2p.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) +#include +namespace p2p { +class UrlDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _Url_default_instance_; +} // namespace p2p +static void InitDefaultsscc_info_Url_bftp2p_2eproto() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::p2p::_Url_default_instance_; + new (ptr) ::p2p::Url(); + ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); + } + ::p2p::Url::InitAsDefaultInstance(); +} + +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Url_bftp2p_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsscc_info_Url_bftp2p_2eproto}, {}}; + +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_bftp2p_2eproto[1]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_bftp2p_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_bftp2p_2eproto = nullptr; + +const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_bftp2p_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::p2p::Url, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + PROTOBUF_FIELD_OFFSET(::p2p::Url, domain_), + PROTOBUF_FIELD_OFFSET(::p2p::Url, port_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, sizeof(::p2p::Url)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast(&::p2p::_Url_default_instance_), +}; + +const char descriptor_table_protodef_bftp2p_2eproto[] = + "\n\014bftp2p.proto\022\003p2p\"#\n\003Url\022\016\n\006domain\030\001 \001" + "(\t\022\014\n\004port\030\002 \001(\0052Y\n\003P2P\022%\n\013register_me\022\010" + ".p2p.Url\032\010.p2p.Url\"\0000\001\022+\n\017update_service" + "s\022\010.p2p.Url\032\010.p2p.Url\"\000(\0010\001B\'\n%com.githu" + "b.com.neoresearch.libbft.p2pb\006proto3" + ; +static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_bftp2p_2eproto_deps[1] = { +}; +static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_bftp2p_2eproto_sccs[1] = { + &scc_info_Url_bftp2p_2eproto.base, +}; +static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_bftp2p_2eproto_once; +static bool descriptor_table_bftp2p_2eproto_initialized = false; +const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_bftp2p_2eproto = { + &descriptor_table_bftp2p_2eproto_initialized, descriptor_table_protodef_bftp2p_2eproto, "bftp2p.proto", 196, + &descriptor_table_bftp2p_2eproto_once, descriptor_table_bftp2p_2eproto_sccs, descriptor_table_bftp2p_2eproto_deps, 1, 0, + schemas, file_default_instances, TableStruct_bftp2p_2eproto::offsets, + file_level_metadata_bftp2p_2eproto, 1, file_level_enum_descriptors_bftp2p_2eproto, file_level_service_descriptors_bftp2p_2eproto, +}; + +// Force running AddDescriptors() at dynamic initialization time. +static bool dynamic_init_dummy_bftp2p_2eproto = ( ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_bftp2p_2eproto), true); +namespace p2p { + +// =================================================================== + +void Url::InitAsDefaultInstance() { +} +class Url::HasBitSetters { + public: +}; + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int Url::kDomainFieldNumber; +const int Url::kPortFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +Url::Url() + : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { + SharedCtor(); + // @@protoc_insertion_point(constructor:p2p.Url) +} +Url::Url(const Url& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _internal_metadata_(nullptr) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + domain_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (from.domain().size() > 0) { + domain_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.domain_); + } + port_ = from.port_; + // @@protoc_insertion_point(copy_constructor:p2p.Url) +} + +void Url::SharedCtor() { + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Url_bftp2p_2eproto.base); + domain_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + port_ = 0; +} + +Url::~Url() { + // @@protoc_insertion_point(destructor:p2p.Url) + SharedDtor(); +} + +void Url::SharedDtor() { + domain_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} + +void Url::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const Url& Url::default_instance() { + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_Url_bftp2p_2eproto.base); + return *internal_default_instance(); +} + + +void Url::Clear() { +// @@protoc_insertion_point(message_clear_start:p2p.Url) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + domain_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + port_ = 0; + _internal_metadata_.Clear(); +} + +#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER +const char* Url::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + ::PROTOBUF_NAMESPACE_ID::uint32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + CHK_(ptr); + switch (tag >> 3) { + // string domain = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParserUTF8(mutable_domain(), ptr, ctx, "p2p.Url.domain"); + CHK_(ptr); + } else goto handle_unusual; + continue; + // int32 port = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { + port_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; + default: { + handle_unusual: + if ((tag & 7) == 4 || tag == 0) { + ctx->SetLastTag(tag); + goto success; + } + ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + CHK_(ptr != nullptr); + continue; + } + } // switch + } // while +success: + return ptr; +failure: + ptr = nullptr; + goto success; +#undef CHK_ +} +#else // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER +bool Url::MergePartialFromCodedStream( + ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure + ::PROTOBUF_NAMESPACE_ID::uint32 tag; + // @@protoc_insertion_point(parse_start:p2p.Url) + for (;;) { + ::std::pair<::PROTOBUF_NAMESPACE_ID::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // string domain = 1; + case 1: { + if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (10 & 0xFF)) { + DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadString( + input, this->mutable_domain())); + DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->domain().data(), static_cast(this->domain().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::PARSE, + "p2p.Url.domain")); + } else { + goto handle_unusual; + } + break; + } + + // int32 port = 2; + case 2: { + if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) { + + DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive< + ::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>( + input, &port_))); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:p2p.Url) + return true; +failure: + // @@protoc_insertion_point(parse_failure:p2p.Url) + return false; +#undef DO_ +} +#endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + +void Url::SerializeWithCachedSizes( + ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:p2p.Url) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string domain = 1; + if (this->domain().size() > 0) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->domain().data(), static_cast(this->domain().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "p2p.Url.domain"); + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->domain(), output); + } + + // int32 port = 2; + if (this->port() != 0) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(2, this->port(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SerializeUnknownFields( + _internal_metadata_.unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:p2p.Url) +} + +::PROTOBUF_NAMESPACE_ID::uint8* Url::InternalSerializeWithCachedSizesToArray( + ::PROTOBUF_NAMESPACE_ID::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:p2p.Url) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // string domain = 1; + if (this->domain().size() > 0) { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( + this->domain().data(), static_cast(this->domain().length()), + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, + "p2p.Url.domain"); + target = + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteStringToArray( + 1, this->domain(), target); + } + + // int32 port = 2; + if (this->port() != 0) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->port(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::SerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:p2p.Url) + return target; +} + +size_t Url::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:p2p.Url) + size_t total_size = 0; + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::ComputeUnknownFieldsSize( + _internal_metadata_.unknown_fields()); + } + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // string domain = 1; + if (this->domain().size() > 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->domain()); + } + + // int32 port = 2; + if (this->port() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + this->port()); + } + + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void Url::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:p2p.Url) + GOOGLE_DCHECK_NE(&from, this); + const Url* source = + ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated( + &from); + if (source == nullptr) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:p2p.Url) + ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:p2p.Url) + MergeFrom(*source); + } +} + +void Url::MergeFrom(const Url& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:p2p.Url) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.domain().size() > 0) { + + domain_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.domain_); + } + if (from.port() != 0) { + set_port(from.port()); + } +} + +void Url::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:p2p.Url) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Url::CopyFrom(const Url& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:p2p.Url) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Url::IsInitialized() const { + return true; +} + +void Url::Swap(Url* other) { + if (other == this) return; + InternalSwap(other); +} +void Url::InternalSwap(Url* other) { + using std::swap; + _internal_metadata_.Swap(&other->_internal_metadata_); + domain_.Swap(&other->domain_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + swap(port_, other->port_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata Url::GetMetadata() const { + return GetMetadataStatic(); +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace p2p +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::p2p::Url* Arena::CreateMaybeMessage< ::p2p::Url >(Arena* arena) { + return Arena::CreateInternal< ::p2p::Url >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include diff --git a/spec/cpp/src/p2p/bftp2p.pb.h b/spec/cpp/src/p2p/bftp2p.pb.h new file mode 100644 index 0000000..e6b405c --- /dev/null +++ b/spec/cpp/src/p2p/bftp2p.pb.h @@ -0,0 +1,293 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: bftp2p.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_bftp2p_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_bftp2p_2eproto + +#include +#include + +#include +#if PROTOBUF_VERSION < 3008000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3008000 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +#include +#define PROTOBUF_INTERNAL_EXPORT_bftp2p_2eproto +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct TableStruct_bftp2p_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[]; +}; +extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_bftp2p_2eproto; +namespace p2p { +class Url; +class UrlDefaultTypeInternal; +extern UrlDefaultTypeInternal _Url_default_instance_; +} // namespace p2p +PROTOBUF_NAMESPACE_OPEN +template<> ::p2p::Url* Arena::CreateMaybeMessage<::p2p::Url>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +namespace p2p { + +// =================================================================== + +class Url : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:p2p.Url) */ { + public: + Url(); + virtual ~Url(); + + Url(const Url& from); + Url(Url&& from) noexcept + : Url() { + *this = ::std::move(from); + } + + inline Url& operator=(const Url& from) { + CopyFrom(from); + return *this; + } + inline Url& operator=(Url&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return GetMetadataStatic().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return GetMetadataStatic().reflection; + } + static const Url& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const Url* internal_default_instance() { + return reinterpret_cast( + &_Url_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + void Swap(Url* other); + friend void swap(Url& a, Url& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline Url* New() const final { + return CreateMaybeMessage(nullptr); + } + + Url* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void CopyFrom(const Url& from); + void MergeFrom(const Url& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + #else + bool MergePartialFromCodedStream( + ::PROTOBUF_NAMESPACE_ID::io::CodedInputStream* input) final; + #endif // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + void SerializeWithCachedSizes( + ::PROTOBUF_NAMESPACE_ID::io::CodedOutputStream* output) const final; + ::PROTOBUF_NAMESPACE_ID::uint8* InternalSerializeWithCachedSizesToArray( + ::PROTOBUF_NAMESPACE_ID::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + inline void SharedCtor(); + inline void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(Url* other); + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "p2p.Url"; + } + private: + inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { + return nullptr; + } + inline void* MaybeArenaPtr() const { + return nullptr; + } + public: + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + private: + static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_bftp2p_2eproto); + return ::descriptor_table_bftp2p_2eproto.file_level_metadata[kIndexInFileMessages]; + } + + public: + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // string domain = 1; + void clear_domain(); + static const int kDomainFieldNumber = 1; + const std::string& domain() const; + void set_domain(const std::string& value); + void set_domain(std::string&& value); + void set_domain(const char* value); + void set_domain(const char* value, size_t size); + std::string* mutable_domain(); + std::string* release_domain(); + void set_allocated_domain(std::string* domain); + + // int32 port = 2; + void clear_port(); + static const int kPortFieldNumber = 2; + ::PROTOBUF_NAMESPACE_ID::int32 port() const; + void set_port(::PROTOBUF_NAMESPACE_ID::int32 value); + + // @@protoc_insertion_point(class_scope:p2p.Url) + private: + class HasBitSetters; + + ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr domain_; + ::PROTOBUF_NAMESPACE_ID::int32 port_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_bftp2p_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// Url + +// string domain = 1; +inline void Url::clear_domain() { + domain_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline const std::string& Url::domain() const { + // @@protoc_insertion_point(field_get:p2p.Url.domain) + return domain_.GetNoArena(); +} +inline void Url::set_domain(const std::string& value) { + + domain_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:p2p.Url.domain) +} +inline void Url::set_domain(std::string&& value) { + + domain_.SetNoArena( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:p2p.Url.domain) +} +inline void Url::set_domain(const char* value) { + GOOGLE_DCHECK(value != nullptr); + + domain_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:p2p.Url.domain) +} +inline void Url::set_domain(const char* value, size_t size) { + + domain_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:p2p.Url.domain) +} +inline std::string* Url::mutable_domain() { + + // @@protoc_insertion_point(field_mutable:p2p.Url.domain) + return domain_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline std::string* Url::release_domain() { + // @@protoc_insertion_point(field_release:p2p.Url.domain) + + return domain_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline void Url::set_allocated_domain(std::string* domain) { + if (domain != nullptr) { + + } else { + + } + domain_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), domain); + // @@protoc_insertion_point(field_set_allocated:p2p.Url.domain) +} + +// int32 port = 2; +inline void Url::clear_port() { + port_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::int32 Url::port() const { + // @@protoc_insertion_point(field_get:p2p.Url.port) + return port_; +} +inline void Url::set_port(::PROTOBUF_NAMESPACE_ID::int32 value) { + + port_ = value; + // @@protoc_insertion_point(field_set:p2p.Url.port) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +} // namespace p2p + +// @@protoc_insertion_point(global_scope) + +#include +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_bftp2p_2eproto diff --git a/spec/cpp/src/p2p/bftp2p.proto b/spec/cpp/src/p2p/bftp2p.proto new file mode 100644 index 0000000..c4182a9 --- /dev/null +++ b/spec/cpp/src/p2p/bftp2p.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option java_package = "com.github.com.neoresearch.libbft.p2p"; + +package p2p; + +message Url { + string domain = 1; + int32 port = 2; +} + +// Defines the service +service P2P { + // Function invoked to send the request + rpc register_me (Url) returns (stream Url) {} + rpc update_services (stream Url) returns (stream Url) {} +} diff --git a/spec/cpp/src/p2p/mainP2P.cpp b/spec/cpp/src/p2p/mainP2P.cpp new file mode 100644 index 0000000..937664c --- /dev/null +++ b/spec/cpp/src/p2p/mainP2P.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "utils/CLI.h" +#include "P2PServer.h" +#include "bftp2p.grpc.pb.h" +#include "bftp2p.pb.h" + +using namespace grpc; +using namespace libbft; +using namespace p2p; +using namespace std; + +using grpc::Server; +using grpc::ServerBuilder; + + +int main(int argc, char **argv) { + ArgumentParser parser(argc, argv); + auto domain = Argument('d', true, "domain", "0.0.0.0"); + auto port = Argument('p', true, "port", "50051"); + auto peers = Argument('e', true, "peers"); + parser.addArguments(std::vector{domain, port, peers}); + parser.parse(); + + string serverAddress(parser.getValue(domain) + ":" + parser.getValue(port)); + const p2p::Url url = stringToUrl(serverAddress); + + P2PServiceImpl p2p(&url); + + thread serverThread([&serverAddress, &p2p] { + ServerBuilder builder; + builder.AddListeningPort(serverAddress, grpc::InsecureServerCredentials()); + builder.RegisterService(&p2p); + unique_ptr server(builder.BuildAndStart()); + cout << "Starting server: " << serverAddress << endl; + server->Wait(); + }); + + thread clientThread([&parser, &peers, &url, &serverAddress] { + if (parser.isPresent(peers)) { + auto thePeers = parser.getValue(peers); + unordered_set peersSet; + queue peersQueue; + const unsigned long thePeersSize = thePeers.size(); + + auto addPeer = [&peersSet, &peersQueue, &serverAddress](string name) { + if (name != serverAddress) { + if (peersSet.emplace(name).second) { + peersQueue.emplace(name); + } + } + }; + + for (unsigned long i = 0; i < thePeersSize;) { + auto comma = thePeers.find(',', i); + bool shouldBreak = false; + string thePeerName; + if (comma != -1ul) { + thePeerName = thePeers.substr(i, comma - i); + } else { + thePeerName = thePeers.substr(i); + shouldBreak = true; + } + + addPeer(thePeerName); + if (shouldBreak) { + break; + } + i = comma + 1; + } + + cout << "Connecting to " << peersSet.size() << " addresses" << endl; + while (!peersQueue.empty()) { + auto &peerName = peersQueue.front(); + peersQueue.pop(); + cout << "Connecting to " << peerName << endl; + + auto stub = P2P::NewStub(CreateChannel(peerName, InsecureChannelCredentials())); + ClientContext context; + auto reader = stub->register_me(&context, url); + p2p::Url peerUrl; + while (reader->Read(&peerUrl)) { + addPeer(urlToString(&peerUrl)); + } + if (!reader->Finish().ok()) { + cout << "There was a problem connecting to " << peerName << endl; + peersSet.erase(peerName); + } + } + + if (!peersSet.empty()) { + auto stub = P2P::NewStub(CreateChannel(serverAddress, InsecureChannelCredentials())); + ClientContext context; + auto stream = stub->update_services(&context); + for (auto &peerName: peersSet) { + stream->Write(stringToUrl(peerName)); + } + stream->Finish(); + } + } + }); + + serverThread.join(); + clientThread.join(); + + return 0; +} diff --git a/spec/cpp/src/utils/CLI.cpp b/spec/cpp/src/utils/CLI.cpp new file mode 100644 index 0000000..e7578f1 --- /dev/null +++ b/spec/cpp/src/utils/CLI.cpp @@ -0,0 +1,118 @@ +#include +#include +#include + +#include "CLI.h" + +using namespace libbft; + +Argument::Argument(char _shortName, bool _itHasValue, std::string _longName, std::string _defaultValue) + : shortName(_shortName), itHasValue(_itHasValue), longName(std::move(_longName)), + defaultValue(std::move(_defaultValue)) { +} + +char Argument::getShortName() const { + return shortName; +} + +bool Argument::hasValue() const { + return itHasValue; +} + +std::string Argument::getLongName() const { + return longName; +} + +bool Argument::hasLongName() const { + return !getLongName().empty(); +} + +std::string Argument::getDefaultValue() const { + return defaultValue; +} + +bool Argument::hasDefaultValue() const { + return !getDefaultValue().empty(); +} + +std::string Argument::getShortNameParam() const { + std::stringstream ss; + ss << "-" << getShortName(); + return ss.str(); +} + +std::string Argument::getLongNameParam() const { + return "--" + getLongName(); +} + +ArgumentParser::ArgumentParser(int argc, char **argv) { + for (auto i = 0; i < argc; ++i) { + args.emplace_back(std::string(argv[i])); + } +} + +ArgumentParser::ArgumentParser(std::vector &argv) { + for (auto &arg: argv) { + args.emplace_back(arg); + } +} + +void ArgumentParser::addArguments(const std::vector &arguments) { + for (auto &arg: arguments) { + addArgument(arg); + } +} + +void ArgumentParser::addArgument(const Argument &arg) { + shortArgument[arg.getShortNameParam()] = arg; + if (arg.hasLongName()) { + longArgument[arg.getLongNameParam()] = arg; + } +} + +void ArgumentParser::parse() { + for (auto &kv: shortArgument) { + if (kv.second.hasDefaultValue()) { + argumentValue[kv.first] = kv.second.getDefaultValue(); + } + } + + auto size = args.size(); + for (auto i = 0ul; i < size; ++i) { + if (shortArgument.find(args[i]) != shortArgument.end()) { + auto arg = shortArgument.find(args[i]); + if (arg->second.hasValue()) { + if (i < size - 1) { + argumentValue[arg->second.getShortNameParam()] = args[i++ + 1]; + } else { + // It should treat the error + } + } else { + argumentValue[arg->second.getShortNameParam()] = ""; + } + } else if (longArgument.find(args[i]) != longArgument.end()) { + auto arg = longArgument.find(args[i]); + if (arg->second.hasValue()) { + if (i < size - 1) { + argumentValue[arg->second.getShortNameParam()] = args[i++ + 1]; + } else { + // It should treat the error + } + } else { + argumentValue[arg->second.getShortNameParam()] = ""; + } + } else { + // It was not found + } + } +} + +std::string ArgumentParser::getValue(const Argument &arg) const { + const auto &iterator = argumentValue.find(arg.getShortNameParam()); + return iterator->second; +} + +bool ArgumentParser::isPresent(const Argument &arg) const { + const auto &iterator = argumentValue.find(arg.getShortNameParam()); + return iterator != argumentValue.end(); +} diff --git a/spec/cpp/src/utils/CLI.h b/spec/cpp/src/utils/CLI.h new file mode 100644 index 0000000..f5aaa85 --- /dev/null +++ b/spec/cpp/src/utils/CLI.h @@ -0,0 +1,48 @@ +#ifndef LIBBFT_UTILS_CLI +#define LIBBFT_UTILS_CLI + +#include +#include +#include + +namespace libbft { + class Argument { + private: + char shortName; + bool itHasValue; + std::string longName; + std::string defaultValue; + public: + explicit Argument( + char shortName = '\0', bool itHasValue = false, std::string longName = "", std::string defaultValue = ""); + + char getShortName() const; + bool hasValue() const; + std::string getLongName() const; + bool hasLongName() const; + std::string getDefaultValue() const; + bool hasDefaultValue() const; + + std::string getShortNameParam() const; + std::string getLongNameParam() const; + }; + + class ArgumentParser { + private: + std::vector args; + std::unordered_map shortArgument; + std::unordered_map longArgument; + std::unordered_map argumentValue; + public: + explicit ArgumentParser(int argc, char **argv); + explicit ArgumentParser(std::vector &argv); + + void addArguments(const std::vector &arguments); + void addArgument(const Argument &arg); + void parse(); + std::string getValue(const Argument &arg) const; + bool isPresent(const Argument &arg) const; + }; +} + +#endif diff --git a/spec/cpp/tests/CMakeLists.txt b/spec/cpp/tests/CMakeLists.txt index 3ca2087..ef458a3 100644 --- a/spec/cpp/tests/CMakeLists.txt +++ b/spec/cpp/tests/CMakeLists.txt @@ -1,76 +1,6 @@ -if (build_type STREQUAL "debug") - message(STATUS "--- Debug build ---") - add_definitions(-fsanitize=address) - add_definitions(-fsanitize=alignment) - add_definitions(-fsanitize=bool) - add_definitions(-fsanitize=bounds) - add_definitions(-fsanitize=bounds-strict) - add_definitions(-fsanitize=builtin) - add_definitions(-fsanitize=enum) - add_definitions(-fsanitize=float-divide-by-zero) - add_definitions(-fsanitize=float-cast-overflow) - add_definitions(-fsanitize=integer-divide-by-zero) - add_definitions(-fsanitize=leak) - # add_definitions(-fsanitize=kernel-address) - add_definitions(-fsanitize=nonnull-attribute) - add_definitions(-fsanitize=null) - add_definitions(-fsanitize=object-size) - add_definitions(-fsanitize=pointer-compare) - add_definitions(-fsanitize=pointer-overflow) - add_definitions(-fsanitize=pointer-subtract) - add_definitions(-fsanitize=return) - add_definitions(-fsanitize=returns-nonnull-attribute) - add_definitions(-fsanitize=signed-integer-overflow) - add_definitions(-fsanitize=shift) - add_definitions(-fsanitize=shift-base) - add_definitions(-fsanitize=shift-exponent) - # add_definitions(-fsanitize=thread) - add_definitions(-fsanitize=undefined) - add_definitions(-fsanitize=unreachable) - add_definitions(-fsanitize=vla-bound) - add_definitions(-fsanitize=vptr) -endif () - add_subdirectory(libgtest) -MACRO(SUBDIRLIST result curdir) - FILE(GLOB children RELATIVE ${curdir} ${curdir}/*) - SET(dirlist "") - FOREACH (child ${children}) - IF (IS_DIRECTORY ${curdir}/${child} AND EXISTS ${curdir}/${child}/CMakeLists.txt) - LIST(APPEND dirlist ${child}) - ENDIF () - ENDFOREACH () - SET(${result} ${dirlist}) -ENDMACRO() - -MACRO(ADD_TEST_ALL_FILES) - get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) - message(STATUS "Creating test ${test_name}") - - file(GLOB_RECURSE test_sources *) - list(FILTER test_sources INCLUDE REGEX "cpp$") - - add_executable("${test_name}_test" ${test_sources}) - - target_link_libraries( - "${test_name}_test" - gtest - gtest_main - ${CMAKE_THREAD_LIBS_INIT} - ) - if (build_type STREQUAL "debug") - target_link_libraries("${test_name}_test" asan) - endif() - target_link_libraries("${test_name}_test" ${lib_name}) - include_directories(${CMAKE_SOURCE_DIR}/src) - - message(STATUS "Adding test: ${test_name}_test") - add_test(NAME "${test_name}_test_caller" COMMAND "${test_name}_test") - - target_compile_options("${test_name}_test" PRIVATE --coverage) - target_link_libraries("${test_name}_test" --coverage) -ENDMACRO() +find_package(Helper REQUIRED) include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/src) diff --git a/spec/cpp/tests/dbft2/CMakeLists.txt b/spec/cpp/tests/dbft2/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/dbft2/CMakeLists.txt +++ b/spec/cpp/tests/dbft2/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/events/CMakeLists.txt b/spec/cpp/tests/events/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/events/CMakeLists.txt +++ b/spec/cpp/tests/events/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/machine/CMakeLists.txt b/spec/cpp/tests/machine/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/machine/CMakeLists.txt +++ b/spec/cpp/tests/machine/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/replicated/CMakeLists.txt b/spec/cpp/tests/replicated/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/replicated/CMakeLists.txt +++ b/spec/cpp/tests/replicated/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/single/CMakeLists.txt b/spec/cpp/tests/single/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/single/CMakeLists.txt +++ b/spec/cpp/tests/single/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/timing/CMakeLists.txt b/spec/cpp/tests/timing/CMakeLists.txt index cee6771..923a6ea 100644 --- a/spec/cpp/tests/timing/CMakeLists.txt +++ b/spec/cpp/tests/timing/CMakeLists.txt @@ -1 +1,2 @@ -ADD_TEST_ALL_FILES() +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/utils/CMakeLists.txt b/spec/cpp/tests/utils/CMakeLists.txt new file mode 100644 index 0000000..923a6ea --- /dev/null +++ b/spec/cpp/tests/utils/CMakeLists.txt @@ -0,0 +1,2 @@ +find_package(TestHelper REQUIRED) +ADD_TEST_ALL_FILES(ON) diff --git a/spec/cpp/tests/utils/CliTests.cpp b/spec/cpp/tests/utils/CliTests.cpp new file mode 100644 index 0000000..b36912b --- /dev/null +++ b/spec/cpp/tests/utils/CliTests.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "utils/CLI.h" + +using namespace std; +using namespace libbft; + +TEST(Utils, Parse) { + auto argv = std::vector{ + "--oi", + "2", + "-a", + "--dado", + "12" + }; + ArgumentParser parser(argv); + auto oi = Argument('o', true, "oi"); + auto a = Argument('a'); + auto b = Argument('b'); + auto c = Argument('c', true, "casa", "casinha"); + auto d = Argument('d', true, "dado", "123"); + parser.addArguments(std::vector{oi, a, b, c, d}); + parser.parse(); + + EXPECT_TRUE(parser.isPresent(oi)); + EXPECT_EQ("2", parser.getValue(oi)); + EXPECT_TRUE(parser.isPresent(a)); + EXPECT_FALSE(parser.isPresent(b)); + + EXPECT_TRUE(parser.isPresent(c)); + EXPECT_EQ("casinha", parser.getValue(c)); + + EXPECT_TRUE(parser.isPresent(d)); + EXPECT_EQ("12", parser.getValue(d)); +}