Fixes for windows (vcpkg environment) compatibility.
Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
parent
eee2ea2d14
commit
e286c36926
|
|
@ -8,9 +8,6 @@ set(etcd-cpp-api_VERSION_MINOR 1)
|
||||||
|
|
||||||
option(BUILD_ETCD_TESTS "Build test cases" OFF)
|
option(BUILD_ETCD_TESTS "Build test cases" OFF)
|
||||||
|
|
||||||
find_library(CPPREST_LIB NAMES cpprest)
|
|
||||||
find_path(CPPREST_INCLUDE_DIR NAMES cpprest/http_client.h)
|
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS system thread locale random)
|
find_package(Boost REQUIRED COMPONENTS system thread locale random)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# If we're on OS X check for Homebrew's copy of OpenSSL instead of Apple's
|
# If we're on OS X check for Homebrew's copy of OpenSSL instead of Apple's
|
||||||
|
|
@ -28,22 +25,31 @@ if (APPLE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
find_package(Protobuf REQUIRED)
|
find_package(Protobuf REQUIRED)
|
||||||
|
find_package(cpprestsdk REQUIRED)
|
||||||
|
|
||||||
|
find_package(gRPC)
|
||||||
|
if(gRPC_FOUND)
|
||||||
|
set(GRPC_LIBRARIES gRPC::gpr gRPC::grpc gRPC::grpc++)
|
||||||
|
else()
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindGRPC.cmake)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindGRPC.cmake)
|
||||||
set(GRPC_LIBRARIES ${GPR_LIBRARY} ${GRPC_LIBRARY} ${GRPC_GRPC++_LIBRARY})
|
set(GRPC_LIBRARIES ${GPR_LIBRARY} ${GRPC_LIBRARY} ${GRPC_GRPC++_LIBRARY})
|
||||||
|
endif()
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobufGRPC.cmake)
|
||||||
|
|
||||||
# will set `PROTOBUF_GENERATES`, indicates all generated .cc files, and a target `protobuf_generates`.
|
# will set `PROTOBUF_GENERATES`, indicates all generated .cc files, and a target `protobuf_generates`.
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobuf.cmake)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobuf.cmake)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/proto)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/proto)
|
||||||
|
|
||||||
include_directories(SYSTEM ${CPPREST_INCLUDE_DIR}
|
include_directories(SYSTEM ${Boost_INCLUDE_DIR}
|
||||||
${Boost_INCLUDE_DIR}
|
|
||||||
${PROTOBUF_INCLUDE_DIRS}
|
${PROTOBUF_INCLUDE_DIRS}
|
||||||
${OPENSSL_INCLUDE_DIR})
|
${OPENSSL_INCLUDE_DIR})
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-string-compare -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-string-compare -std=c++11")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#
|
#
|
||||||
# The original repository is open-sourced with the MIT license.
|
# The original repository is open-sourced with the MIT license.
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# Locate and configure the gRPC library
|
# Locate and configure the gRPC library
|
||||||
#
|
#
|
||||||
# Adds the following targets:
|
# Adds the following targets:
|
||||||
|
|
@ -16,76 +15,6 @@
|
||||||
# gRPC::grpc_cpp_plugin - C++ generator plugin for Protocol Buffers
|
# gRPC::grpc_cpp_plugin - C++ generator plugin for Protocol Buffers
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
|
||||||
# Generates C++ sources from the .proto files
|
|
||||||
#
|
|
||||||
# grpc_generate_cpp (<SRCS> <HDRS> <DEST> [<ARGN>...])
|
|
||||||
#
|
|
||||||
# SRCS - variable to define with autogenerated source files
|
|
||||||
# HDRS - variable to define with autogenerated header files
|
|
||||||
# DEST - directory where the source files will be created
|
|
||||||
# ARGN - .proto files
|
|
||||||
#
|
|
||||||
function(GRPC_GENERATE_CPP SRCS HDRS DEST)
|
|
||||||
if(NOT ARGN)
|
|
||||||
message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(GRPC_GENERATE_CPP_APPEND_PATH)
|
|
||||||
# Create an include path for each file specified
|
|
||||||
foreach(FIL ${ARGN})
|
|
||||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
|
||||||
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
|
||||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
|
||||||
if(${_contains_already} EQUAL -1)
|
|
||||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
else()
|
|
||||||
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEFINED PROTOBUF_IMPORT_DIRS)
|
|
||||||
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
|
|
||||||
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
|
||||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
|
||||||
if(${_contains_already} EQUAL -1)
|
|
||||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${SRCS})
|
|
||||||
set(${HDRS})
|
|
||||||
foreach(FIL ${ARGN})
|
|
||||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
|
||||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
|
||||||
|
|
||||||
list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc")
|
|
||||||
list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h")
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc"
|
|
||||||
"${DEST}/${FIL_WE}.grpc.pb.h"
|
|
||||||
COMMAND protobuf::protoc
|
|
||||||
ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL}
|
|
||||||
DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin
|
|
||||||
COMMENT "Running C++ gRPC compiler on ${FIL}"
|
|
||||||
VERBATIM )
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
|
|
||||||
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
|
||||||
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# By default have GRPC_GENERATE_CPP macro pass -I to protoc
|
|
||||||
# for each directory where a proto file is referenced.
|
|
||||||
if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH)
|
|
||||||
set(GRPC_GENERATE_CPP_APPEND_PATH TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find gRPC include directory
|
# Find gRPC include directory
|
||||||
find_path(GRPC_INCLUDE_DIR grpc/grpc.h)
|
find_path(GRPC_INCLUDE_DIR grpc/grpc.h)
|
||||||
mark_as_advanced(GRPC_INCLUDE_DIR)
|
mark_as_advanced(GRPC_INCLUDE_DIR)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
# This file is taken from
|
||||||
|
#
|
||||||
|
# https://github.com/IvanSafonov/grpc-cmake-example
|
||||||
|
#
|
||||||
|
# The original repository is open-sourced with the MIT license.
|
||||||
|
#
|
||||||
|
# Generates C++ sources from the .proto files
|
||||||
|
#
|
||||||
|
# grpc_generate_cpp (<SRCS> <HDRS> <DEST> [<ARGN>...])
|
||||||
|
#
|
||||||
|
# SRCS - variable to define with autogenerated source files
|
||||||
|
# HDRS - variable to define with autogenerated header files
|
||||||
|
# DEST - directory where the source files will be created
|
||||||
|
# ARGN - .proto files
|
||||||
|
#
|
||||||
|
function(GRPC_GENERATE_CPP SRCS HDRS DEST)
|
||||||
|
if(NOT ARGN)
|
||||||
|
message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(GRPC_GENERATE_CPP_APPEND_PATH)
|
||||||
|
# Create an include path for each file specified
|
||||||
|
foreach(FIL ${ARGN})
|
||||||
|
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||||
|
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
||||||
|
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||||
|
if(${_contains_already} EQUAL -1)
|
||||||
|
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED PROTOBUF_IMPORT_DIRS)
|
||||||
|
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
|
||||||
|
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||||
|
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||||
|
if(${_contains_already} EQUAL -1)
|
||||||
|
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${SRCS})
|
||||||
|
set(${HDRS})
|
||||||
|
foreach(FIL ${ARGN})
|
||||||
|
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||||
|
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||||
|
|
||||||
|
list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc")
|
||||||
|
list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc"
|
||||||
|
"${DEST}/${FIL_WE}.grpc.pb.h"
|
||||||
|
COMMAND protobuf::protoc
|
||||||
|
ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL}
|
||||||
|
DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin
|
||||||
|
COMMENT "Running C++ gRPC compiler on ${FIL}"
|
||||||
|
VERBATIM )
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
|
||||||
|
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||||
|
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# By default have GRPC_GENERATE_CPP macro pass -I to protoc
|
||||||
|
# for each directory where a proto file is referenced.
|
||||||
|
if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH)
|
||||||
|
set(GRPC_GENERATE_CPP_APPEND_PATH TRUE)
|
||||||
|
endif()
|
||||||
|
|
@ -31,7 +31,7 @@ message KeyValue {
|
||||||
message Event {
|
message Event {
|
||||||
enum EventType {
|
enum EventType {
|
||||||
PUT = 0;
|
PUT = 0;
|
||||||
DELETE = 1;
|
DELETE_ = 1;
|
||||||
}
|
}
|
||||||
// type is the kind of event. If type is a PUT, it indicates
|
// type is the kind of event. If type is a PUT, it indicates
|
||||||
// new data has been stored to the key. If type is a DELETE,
|
// new data has been stored to the key. If type is a DELETE,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ add_dependencies(etcd-cpp-api protobuf_generates)
|
||||||
set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11)
|
set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11)
|
||||||
|
|
||||||
target_link_libraries(etcd-cpp-api PUBLIC
|
target_link_libraries(etcd-cpp-api PUBLIC
|
||||||
${CPPREST_LIB}
|
cpprestsdk::cpprest
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${PROTOBUF_LIBRARIES}
|
${PROTOBUF_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#else
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -47,8 +53,26 @@ static bool dns_resolve(std::string const &target, std::vector<std::string> &end
|
||||||
std::cerr << "warn: invalid URL: " << target << std::endl;
|
std::cerr << "warn: invalid URL: " << target << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs) != 0) {
|
|
||||||
std::cerr << "warn: getaddrinfo() failed for endpoint " << target << std::endl;
|
#if defined(_WIN32)
|
||||||
|
{
|
||||||
|
// Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h.
|
||||||
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
int err = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
if (err != 0) {
|
||||||
|
// Tell the user that we could not find a usable Winsock DLL. */
|
||||||
|
std::cerr << "WSAStartup failed with error: %d" << err << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int r = getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs);
|
||||||
|
if (r != 0) {
|
||||||
|
std::cerr << "warn: getaddrinfo() failed for endpoint " << target
|
||||||
|
<< " with error: " << r << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply)
|
||||||
value.kvs = event.kv();
|
value.kvs = event.kv();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(mvccpb::Event::EventType::Event_EventType_DELETE == event.type())
|
else if(mvccpb::Event::EventType::Event_EventType_DELETE_ == event.type())
|
||||||
{
|
{
|
||||||
action = etcdv3::DELETE_ACTION;
|
action = etcdv3::DELETE_ACTION;
|
||||||
value.kvs = event.kv();
|
value.kvs = event.kv();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "etcd/SyncClient.hpp"
|
#include "etcd/SyncClient.hpp"
|
||||||
|
|
@ -11,6 +12,7 @@ TEST_CASE("sync operations")
|
||||||
etcd::SyncClient etcd(etcd_uri);
|
etcd::SyncClient etcd(etcd_uri);
|
||||||
etcd.rmdir("/test", true);
|
etcd.rmdir("/test", true);
|
||||||
|
|
||||||
|
|
||||||
// add
|
// add
|
||||||
CHECK(0 == etcd.add("/test/key1", "42").error_code());
|
CHECK(0 == etcd.add("/test/key1", "42").error_code());
|
||||||
CHECK(105 == etcd.add("/test/key1", "42").error_code()); // Key already exists
|
CHECK(105 == etcd.add("/test/key1", "42").error_code()); // Key already exists
|
||||||
|
|
@ -119,7 +121,7 @@ TEST_CASE("wait for a value change")
|
||||||
CHECK("43" == res.value().as_string());
|
CHECK("43" == res.value().as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
etcd.set("/test/key1", "43");
|
etcd.set("/test/key1", "43");
|
||||||
watch_thrd.join();
|
watch_thrd.join();
|
||||||
|
|
||||||
|
|
@ -136,7 +138,7 @@ TEST_CASE("wait for a directory change")
|
||||||
CHECK("44" == res.value().as_string());
|
CHECK("44" == res.value().as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
etcd.add("/test/key4", "44");
|
etcd.add("/test/key4", "44");
|
||||||
watch_thrd1.join();
|
watch_thrd1.join();
|
||||||
|
|
||||||
|
|
@ -146,7 +148,7 @@ TEST_CASE("wait for a directory change")
|
||||||
CHECK("45" == res2.value().as_string());
|
CHECK("45" == res2.value().as_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
etcd.set("/test/key4", "45");
|
etcd.set("/test/key4", "45");
|
||||||
watch_thrd2.join();
|
watch_thrd2.join();
|
||||||
|
|
||||||
|
|
@ -188,7 +190,7 @@ TEST_CASE("watch changes in the past")
|
||||||
|
|
||||||
// etcd.cancel_operations();
|
// etcd.cancel_operations();
|
||||||
|
|
||||||
// sleep(1);
|
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
// REQUIRE(res.is_done());
|
// REQUIRE(res.is_done());
|
||||||
// try {
|
// try {
|
||||||
// res.wait();
|
// res.wait();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "etcd/Client.hpp"
|
#include "etcd/Client.hpp"
|
||||||
|
|
||||||
|
|
@ -258,11 +260,11 @@ TEST_CASE("wait for a value change")
|
||||||
|
|
||||||
pplx::task<etcd::Response> res = etcd.watch("/test/key1");
|
pplx::task<etcd::Response> res = etcd.watch("/test/key1");
|
||||||
CHECK(!res.is_done());
|
CHECK(!res.is_done());
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
CHECK(!res.is_done());
|
CHECK(!res.is_done());
|
||||||
|
|
||||||
etcd.set("/test/key1", "43").get();
|
etcd.set("/test/key1", "43").get();
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
REQUIRE(res.is_done());
|
REQUIRE(res.is_done());
|
||||||
REQUIRE("set" == res.get().action());
|
REQUIRE("set" == res.get().action());
|
||||||
CHECK("43" == res.get().value().as_string());
|
CHECK("43" == res.get().value().as_string());
|
||||||
|
|
@ -275,22 +277,22 @@ TEST_CASE("wait for a directory change")
|
||||||
|
|
||||||
pplx::task<etcd::Response> res = etcd.watch("/test", true);
|
pplx::task<etcd::Response> res = etcd.watch("/test", true);
|
||||||
CHECK(!res.is_done());
|
CHECK(!res.is_done());
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
CHECK(!res.is_done());
|
CHECK(!res.is_done());
|
||||||
|
|
||||||
etcd.add("/test/key4", "44").wait();
|
etcd.add("/test/key4", "44").wait();
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
REQUIRE(res.is_done());
|
REQUIRE(res.is_done());
|
||||||
CHECK("create" == res.get().action());
|
CHECK("create" == res.get().action());
|
||||||
CHECK("44" == res.get().value().as_string());
|
CHECK("44" == res.get().value().as_string());
|
||||||
|
|
||||||
pplx::task<etcd::Response> res2 = etcd.watch("/test", true);
|
pplx::task<etcd::Response> res2 = etcd.watch("/test", true);
|
||||||
CHECK(!res2.is_done());
|
CHECK(!res2.is_done());
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
CHECK(!res2.is_done());
|
CHECK(!res2.is_done());
|
||||||
|
|
||||||
etcd.set("/test/key4", "45").wait();
|
etcd.set("/test/key4", "45").wait();
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
REQUIRE(res2.is_done());
|
REQUIRE(res2.is_done());
|
||||||
CHECK("set" == res2.get().action());
|
CHECK("set" == res2.get().action());
|
||||||
CHECK("45" == res2.get().value().as_string());
|
CHECK("45" == res2.get().value().as_string());
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "etcd/Watcher.hpp"
|
#include "etcd/Watcher.hpp"
|
||||||
|
|
@ -31,17 +32,17 @@ TEST_CASE("create watcher with cancel")
|
||||||
|
|
||||||
watcher_called = 0;
|
watcher_called = 0;
|
||||||
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
etcd.set("/test/key", "42");
|
etcd.set("/test/key", "42");
|
||||||
etcd.set("/test/key", "43");
|
etcd.set("/test/key", "43");
|
||||||
etcd.rm("/test/key");
|
etcd.rm("/test/key");
|
||||||
etcd.set("/test/key", "44");
|
etcd.set("/test/key", "44");
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
CHECK(4 == watcher_called);
|
CHECK(4 == watcher_called);
|
||||||
watcher.Cancel();
|
watcher.Cancel();
|
||||||
etcd.set("/test/key", "50");
|
etcd.set("/test/key", "50");
|
||||||
etcd.set("/test/key", "51");
|
etcd.set("/test/key", "51");
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
CHECK(4 == watcher_called);
|
CHECK(4 == watcher_called);
|
||||||
|
|
||||||
etcd.rmdir("/test", true);
|
etcd.rmdir("/test", true);
|
||||||
|
|
@ -56,7 +57,7 @@ TEST_CASE("create watcher")
|
||||||
watcher_called = 0;
|
watcher_called = 0;
|
||||||
{
|
{
|
||||||
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
||||||
sleep(1);
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
etcd.set("/test/key", "42");
|
etcd.set("/test/key", "42");
|
||||||
etcd.set("/test/key", "43");
|
etcd.set("/test/key", "43");
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +98,7 @@ TEST_CASE("watch should can be cancelled repeatedly")
|
||||||
|
|
||||||
// etcd.cancel_operations();
|
// etcd.cancel_operations();
|
||||||
|
|
||||||
// sleep(1);
|
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
// REQUIRE(res.is_done());
|
// REQUIRE(res.is_done());
|
||||||
// try {
|
// try {
|
||||||
// res.wait();
|
// res.wait();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue