Fixes CI failures, document how to use in CMake
Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
parent
8364dd24d0
commit
6599cf706b
30
README.md
30
README.md
|
|
@ -83,6 +83,36 @@ dependencies have been successfully installed:
|
||||||
cmake ..
|
cmake ..
|
||||||
make -j$(nproc) && make install
|
make -j$(nproc) && make install
|
||||||
|
|
||||||
|
## Using this package in your CMake project
|
||||||
|
|
||||||
|
To use this package in your CMake project, you can either
|
||||||
|
|
||||||
|
- install, then find the library using `find_package()`:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
find_package(etcd-cpp-apiv3 REQUIRED)
|
||||||
|
target_link_libraries(your_target PRIVATE etcd-cpp-api)
|
||||||
|
```
|
||||||
|
|
||||||
|
- or, add this repository as a subdirectory in your project, and link the library directly:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
add_subdirectory(thirdparty/etcd-cpp-apiv3)
|
||||||
|
target_link_libraries(your_target PRIVATE etcd-cpp-api)
|
||||||
|
```
|
||||||
|
|
||||||
|
- or, use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html):
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
etcd-cpp-apiv3
|
||||||
|
https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3.git
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(etcd-cpp-apiv3)
|
||||||
|
target_link_libraries(your_target PRIVATE etcd-cpp-api)
|
||||||
|
```
|
||||||
|
|
||||||
## Compatible etcd version
|
## Compatible etcd version
|
||||||
|
|
||||||
The _etcd-cpp-apiv3_ should work well with etcd > 3.0. Feel free to issue an issue to us on
|
The _etcd-cpp-apiv3_ should work well with etcd > 3.0. Feel free to issue an issue to us on
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,8 @@ set(ETCD_CPP_INCLUDE_DIRS "${ETCD_CPP_INCLUDE_DIR}")
|
||||||
include(FindPackageMessage)
|
include(FindPackageMessage)
|
||||||
find_package_message(etcd
|
find_package_message(etcd
|
||||||
"Found etcd: ${CMAKE_CURRENT_LIST_FILE} (found version \"@etcd-cpp-api_VERSION@\")"
|
"Found etcd: ${CMAKE_CURRENT_LIST_FILE} (found version \"@etcd-cpp-api_VERSION@\")"
|
||||||
"etcd-cpp-apiv3 version: @etcd-cpp-api_VERSION@\netcd-cpp-apiv3 libraries: ${ETCD_CPP_LIBRARIES}, \netcd-cpp-apiv3 core libraries: ${ETCD_CPP_CORE_LIBRARIES}\ninclude directories: ${ETCD_CPP_INCLUDE_DIRS}"
|
"etcd-cpp-apiv3 version: @etcd-cpp-api_VERSION@\n"
|
||||||
|
"etcd-cpp-apiv3 libraries: ${ETCD_CPP_LIBRARIES}\n"
|
||||||
|
"etcd-cpp-apiv3 core libraries: ${ETCD_CPP_CORE_LIBRARIES}\n"
|
||||||
|
"include directories: ${ETCD_CPP_INCLUDE_DIRS}"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,8 @@ class Client {
|
||||||
/**
|
/**
|
||||||
* Removes a single key. The key has to point to a plain, non directory entry.
|
* Removes a single key. The key has to point to a plain, non directory entry.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rm(std::string const& key);
|
pplx::task<Response> rm(std::string const& key);
|
||||||
|
|
||||||
|
|
@ -351,6 +353,8 @@ class Client {
|
||||||
* Removes a single key but only if it has a specific value. Fails if the key
|
* Removes a single key but only if it has a specific value. Fails if the key
|
||||||
* does not exists or the its value differs from the expected one.
|
* does not exists or the its value differs from the expected one.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rm_if(std::string const& key,
|
pplx::task<Response> rm_if(std::string const& key,
|
||||||
std::string const& old_value);
|
std::string const& old_value);
|
||||||
|
|
@ -361,6 +365,8 @@ class Client {
|
||||||
* from the expected one.
|
* from the expected one.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
* @param old_index is the expected index of the existing value
|
* @param old_index is the expected index of the existing value
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rm_if(std::string const& key, int64_t old_index);
|
pplx::task<Response> rm_if(std::string const& key, int64_t old_index);
|
||||||
|
|
||||||
|
|
@ -370,6 +376,8 @@ class Client {
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param recursive if true then delete a whole subtree, otherwise deletes
|
* @param recursive if true then delete a whole subtree, otherwise deletes
|
||||||
* only an empty directory.
|
* only an empty directory.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rmdir(std::string const& key, bool recursive = false);
|
pplx::task<Response> rmdir(std::string const& key, bool recursive = false);
|
||||||
|
|
||||||
|
|
@ -381,6 +389,8 @@ class Client {
|
||||||
*
|
*
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param range_end is the end of key range to be removed.
|
* @param range_end is the end of key range to be removed.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rmdir(std::string const& key, const char* range_end);
|
pplx::task<Response> rmdir(std::string const& key, const char* range_end);
|
||||||
|
|
||||||
|
|
@ -389,6 +399,8 @@ class Client {
|
||||||
*
|
*
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param range_end is the end of key range to be removed.
|
* @param range_end is the end of key range to be removed.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
pplx::task<Response> rmdir(std::string const& key,
|
pplx::task<Response> rmdir(std::string const& key,
|
||||||
std::string const& range_end);
|
std::string const& range_end);
|
||||||
|
|
|
||||||
|
|
@ -397,6 +397,8 @@ class SyncClient {
|
||||||
/**
|
/**
|
||||||
* Removes a single key. The key has to point to a plain, non directory entry.
|
* Removes a single key. The key has to point to a plain, non directory entry.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
Response rm(std::string const& key);
|
Response rm(std::string const& key);
|
||||||
|
|
||||||
|
|
@ -404,6 +406,8 @@ class SyncClient {
|
||||||
* Removes a single key but only if it has a specific value. Fails if the key
|
* Removes a single key but only if it has a specific value. Fails if the key
|
||||||
* does not exists or the its value differs from the expected one.
|
* does not exists or the its value differs from the expected one.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
Response rm_if(std::string const& key, std::string const& old_value);
|
Response rm_if(std::string const& key, std::string const& old_value);
|
||||||
|
|
||||||
|
|
@ -413,6 +417,8 @@ class SyncClient {
|
||||||
* from the expected one.
|
* from the expected one.
|
||||||
* @param key is the key to be deleted
|
* @param key is the key to be deleted
|
||||||
* @param old_index is the expected index of the existing value
|
* @param old_index is the expected index of the existing value
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the key does not exist.
|
||||||
*/
|
*/
|
||||||
Response rm_if(std::string const& key, int64_t old_index);
|
Response rm_if(std::string const& key, int64_t old_index);
|
||||||
|
|
||||||
|
|
@ -422,6 +428,8 @@ class SyncClient {
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param recursive if true then delete a whole subtree, otherwise deletes
|
* @param recursive if true then delete a whole subtree, otherwise deletes
|
||||||
* only an empty directory.
|
* only an empty directory.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
Response rmdir(std::string const& key, bool recursive = false);
|
Response rmdir(std::string const& key, bool recursive = false);
|
||||||
|
|
||||||
|
|
@ -433,6 +441,8 @@ class SyncClient {
|
||||||
*
|
*
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param range_end is the end of key range to be removed.
|
* @param range_end is the end of key range to be removed.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
Response rmdir(std::string const& key, const char* range_end);
|
Response rmdir(std::string const& key, const char* range_end);
|
||||||
|
|
||||||
|
|
@ -441,6 +451,8 @@ class SyncClient {
|
||||||
*
|
*
|
||||||
* @param key is the directory to be created to be listed
|
* @param key is the directory to be created to be listed
|
||||||
* @param range_end is the end of key range to be removed.
|
* @param range_end is the end of key range to be removed.
|
||||||
|
*
|
||||||
|
* @return Returns etcdv3::ERROR_KEY_NOT_FOUND if the no key been deleted.
|
||||||
*/
|
*/
|
||||||
Response rmdir(std::string const& key, std::string const& range_end);
|
Response rmdir(std::string const& key, std::string const& range_end);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class AsyncCampaignResponse : public etcdv3::V3Response {
|
||||||
class AsyncDeleteResponse : public etcdv3::V3Response {
|
class AsyncDeleteResponse : public etcdv3::V3Response {
|
||||||
public:
|
public:
|
||||||
AsyncDeleteResponse(){};
|
AsyncDeleteResponse(){};
|
||||||
void ParseResponse(bool prefix, DeleteRangeResponse& resp);
|
void ParseResponse(DeleteRangeResponse& resp);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncHeadResponse : public etcdv3::V3Response {
|
class AsyncHeadResponse : public etcdv3::V3Response {
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,7 @@ void etcdv3::AsyncCampaignResponse::ParseResponse(CampaignResponse& reply) {
|
||||||
value.kvs.set_lease(leader.lease());
|
value.kvs.set_lease(leader.lease());
|
||||||
}
|
}
|
||||||
|
|
||||||
void etcdv3::AsyncDeleteResponse::ParseResponse(bool prefix,
|
void etcdv3::AsyncDeleteResponse::ParseResponse(DeleteRangeResponse& resp) {
|
||||||
DeleteRangeResponse& resp) {
|
|
||||||
index = resp.header().revision();
|
index = resp.header().revision();
|
||||||
|
|
||||||
if (resp.prev_kvs_size() == 0) {
|
if (resp.prev_kvs_size() == 0) {
|
||||||
|
|
@ -56,13 +55,15 @@ void etcdv3::AsyncDeleteResponse::ParseResponse(bool prefix,
|
||||||
etcdv3::KeyValue kv;
|
etcdv3::KeyValue kv;
|
||||||
kv.kvs.CopyFrom(resp.prev_kvs(cnt));
|
kv.kvs.CopyFrom(resp.prev_kvs(cnt));
|
||||||
values.push_back(kv);
|
values.push_back(kv);
|
||||||
|
prev_values.push_back(kv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prefix) {
|
// flatten values/prev_values 0 to value/prev_value
|
||||||
prev_value = values[0];
|
if (!values.empty()) {
|
||||||
value = values[0];
|
value = values[0];
|
||||||
value.kvs.clear_value();
|
}
|
||||||
values.clear();
|
if (!prev_values.empty()) {
|
||||||
|
prev_value = prev_values[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +137,7 @@ void etcdv3::AsyncPutResponse::ParseResponse(PutResponse& resp) {
|
||||||
// get all previous values
|
// get all previous values
|
||||||
etcdv3::KeyValue kv;
|
etcdv3::KeyValue kv;
|
||||||
kv.kvs.CopyFrom(resp.prev_kv());
|
kv.kvs.CopyFrom(resp.prev_kv());
|
||||||
|
prev_values.push_back(kv);
|
||||||
prev_value = kv;
|
prev_value = kv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,40 +178,55 @@ void etcdv3::AsyncTxnResponse::ParseResponse(TxnResponse& reply) {
|
||||||
error_code = response.get_error_code();
|
error_code = response.get_error_code();
|
||||||
}
|
}
|
||||||
if (!response.get_error_message().empty()) {
|
if (!response.get_error_message().empty()) {
|
||||||
error_message += "\n" + response.get_error_message();
|
if (!error_message.empty()) {
|
||||||
|
error_message += "\n";
|
||||||
|
}
|
||||||
|
error_message += response.get_error_message();
|
||||||
}
|
}
|
||||||
for (auto const& value : response.get_values()) {
|
for (auto const& value : response.get_values()) {
|
||||||
values.emplace_back(value);
|
values.emplace_back(value);
|
||||||
}
|
}
|
||||||
|
for (auto const& prev_value : response.get_prev_values()) {
|
||||||
|
prev_values.emplace_back(prev_value);
|
||||||
|
}
|
||||||
} else if (ResponseOp::ResponseCase::kResponsePut == resp.response_case()) {
|
} else if (ResponseOp::ResponseCase::kResponsePut == resp.response_case()) {
|
||||||
AsyncPutResponse response;
|
AsyncPutResponse response;
|
||||||
response.ParseResponse(*(resp.mutable_response_put()));
|
response.ParseResponse(*(resp.mutable_response_put()));
|
||||||
prev_value.kvs.CopyFrom(response.get_prev_value().kvs);
|
|
||||||
|
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
error_code = response.get_error_code();
|
error_code = response.get_error_code();
|
||||||
}
|
}
|
||||||
if (!response.get_error_message().empty()) {
|
if (!response.get_error_message().empty()) {
|
||||||
error_message += "\n" + response.get_error_message();
|
if (!error_message.empty()) {
|
||||||
|
error_message += "\n";
|
||||||
|
}
|
||||||
|
error_message += response.get_error_message();
|
||||||
}
|
}
|
||||||
for (auto const& value : response.get_values()) {
|
for (auto const& value : response.get_values()) {
|
||||||
values.emplace_back(value);
|
values.emplace_back(value);
|
||||||
}
|
}
|
||||||
|
for (auto const& prev_value : response.get_prev_values()) {
|
||||||
|
prev_values.emplace_back(prev_value);
|
||||||
|
}
|
||||||
} else if (ResponseOp::ResponseCase::kResponseDeleteRange ==
|
} else if (ResponseOp::ResponseCase::kResponseDeleteRange ==
|
||||||
resp.response_case()) {
|
resp.response_case()) {
|
||||||
AsyncDeleteResponse response;
|
AsyncDeleteResponse response;
|
||||||
response.ParseResponse(true, *(resp.mutable_response_delete_range()));
|
response.ParseResponse(*(resp.mutable_response_delete_range()));
|
||||||
prev_value.kvs.CopyFrom(response.get_prev_value().kvs);
|
|
||||||
|
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
error_code = response.get_error_code();
|
error_code = response.get_error_code();
|
||||||
}
|
}
|
||||||
if (!response.get_error_message().empty()) {
|
if (!response.get_error_message().empty()) {
|
||||||
error_message += "\n" + response.get_error_message();
|
if (!error_message.empty()) {
|
||||||
|
error_message += "\n";
|
||||||
|
}
|
||||||
|
error_message += response.get_error_message();
|
||||||
}
|
}
|
||||||
for (auto const& value : response.get_values()) {
|
for (auto const& value : response.get_values()) {
|
||||||
values.emplace_back(value);
|
values.emplace_back(value);
|
||||||
}
|
}
|
||||||
|
for (auto const& prev_value : response.get_prev_values()) {
|
||||||
|
prev_values.emplace_back(prev_value);
|
||||||
|
}
|
||||||
} else if (ResponseOp::ResponseCase::kResponseTxn == resp.response_case()) {
|
} else if (ResponseOp::ResponseCase::kResponseTxn == resp.response_case()) {
|
||||||
AsyncTxnResponse response;
|
AsyncTxnResponse response;
|
||||||
response.ParseResponse(*(resp.mutable_response_txn()));
|
response.ParseResponse(*(resp.mutable_response_txn()));
|
||||||
|
|
@ -218,7 +235,10 @@ void etcdv3::AsyncTxnResponse::ParseResponse(TxnResponse& reply) {
|
||||||
error_code = response.get_error_code();
|
error_code = response.get_error_code();
|
||||||
}
|
}
|
||||||
if (!response.get_error_message().empty()) {
|
if (!response.get_error_message().empty()) {
|
||||||
error_message += "\n" + response.get_error_message();
|
if (!error_message.empty()) {
|
||||||
|
error_message += "\n";
|
||||||
|
}
|
||||||
|
error_message += response.get_error_message();
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip
|
// skip
|
||||||
|
|
@ -341,11 +361,13 @@ etcdv3::AsyncCompareAndSwapAction::AsyncCompareAndSwapAction(
|
||||||
etcdv3::Transaction txn;
|
etcdv3::Transaction txn;
|
||||||
if (type == etcdv3::AtomicityType::PREV_VALUE) {
|
if (type == etcdv3::AtomicityType::PREV_VALUE) {
|
||||||
txn.setup_compare_and_swap(parameters.key, parameters.old_value,
|
txn.setup_compare_and_swap(parameters.key, parameters.old_value,
|
||||||
parameters.value);
|
parameters.value, parameters.lease_id);
|
||||||
} else if (type == etcdv3::AtomicityType::PREV_INDEX) {
|
} else if (type == etcdv3::AtomicityType::PREV_INDEX) {
|
||||||
txn.setup_compare_and_swap(parameters.key, parameters.old_revision,
|
txn.setup_compare_and_swap(parameters.key, parameters.old_revision,
|
||||||
parameters.value);
|
parameters.value, parameters.lease_id);
|
||||||
}
|
}
|
||||||
|
// backwards compatibility
|
||||||
|
txn.add_success_range(parameters.key);
|
||||||
|
|
||||||
response_reader =
|
response_reader =
|
||||||
parameters.kv_stub->AsyncTxn(&context, *txn.txn_request, &cq_);
|
parameters.kv_stub->AsyncTxn(&context, *txn.txn_request, &cq_);
|
||||||
|
|
@ -377,7 +399,7 @@ etcdv3::AsyncDeleteAction::AsyncDeleteAction(ActionParameters&& params)
|
||||||
DeleteRangeRequest del_request;
|
DeleteRangeRequest del_request;
|
||||||
detail::make_request_with_ranges(del_request, parameters.key,
|
detail::make_request_with_ranges(del_request, parameters.key,
|
||||||
parameters.range_end, parameters.withPrefix);
|
parameters.range_end, parameters.withPrefix);
|
||||||
del_request.set_prev_kv(true);
|
del_request.set_prev_kv(true /* fetch prev values */);
|
||||||
|
|
||||||
response_reader =
|
response_reader =
|
||||||
parameters.kv_stub->AsyncDeleteRange(&context, del_request, &cq_);
|
parameters.kv_stub->AsyncDeleteRange(&context, del_request, &cq_);
|
||||||
|
|
@ -392,8 +414,7 @@ etcdv3::AsyncDeleteResponse etcdv3::AsyncDeleteAction::ParseResponse() {
|
||||||
del_resp.set_error_code(status.error_code());
|
del_resp.set_error_code(status.error_code());
|
||||||
del_resp.set_error_message(status.error_message());
|
del_resp.set_error_message(status.error_message());
|
||||||
} else {
|
} else {
|
||||||
del_resp.ParseResponse(
|
del_resp.ParseResponse(reply);
|
||||||
parameters.withPrefix || !parameters.range_end.empty(), reply);
|
|
||||||
}
|
}
|
||||||
return del_resp;
|
return del_resp;
|
||||||
}
|
}
|
||||||
|
|
@ -949,7 +970,9 @@ etcdv3::AsyncSetAction::AsyncSetAction(etcdv3::ActionParameters&& params,
|
||||||
etcdv3::Transaction txn;
|
etcdv3::Transaction txn;
|
||||||
isCreate = create;
|
isCreate = create;
|
||||||
txn.add_compare_mod(parameters.key, 0 /* not exists */);
|
txn.add_compare_mod(parameters.key, 0 /* not exists */);
|
||||||
txn.add_success_put(parameters.key, parameters.key, parameters.lease_id);
|
txn.add_success_put(parameters.key, parameters.value, parameters.lease_id);
|
||||||
|
// backwards compatibility
|
||||||
|
txn.add_success_range(parameters.key);
|
||||||
if (create) {
|
if (create) {
|
||||||
txn.add_failure_put(parameters.key, parameters.value, parameters.lease_id);
|
txn.add_failure_put(parameters.key, parameters.value, parameters.lease_id);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1035,7 +1058,10 @@ etcdv3::AsyncUpdateAction::AsyncUpdateAction(etcdv3::ActionParameters&& params)
|
||||||
: etcdv3::Action(std::move(params)) {
|
: etcdv3::Action(std::move(params)) {
|
||||||
etcdv3::Transaction txn;
|
etcdv3::Transaction txn;
|
||||||
txn.add_compare_version(parameters.key, CompareResult::GREATER, 0); // exists
|
txn.add_compare_version(parameters.key, CompareResult::GREATER, 0); // exists
|
||||||
txn.add_success_put(parameters.key, parameters.value, parameters.lease_id);
|
txn.add_success_put(parameters.key, parameters.value, parameters.lease_id,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
|
// backwards compatibility
|
||||||
|
txn.add_success_range(parameters.key);
|
||||||
txn.add_failure_range(parameters.key);
|
txn.add_failure_range(parameters.key);
|
||||||
response_reader =
|
response_reader =
|
||||||
parameters.kv_stub->AsyncTxn(&context, *txn.txn_request, &cq_);
|
parameters.kv_stub->AsyncTxn(&context, *txn.txn_request, &cq_);
|
||||||
|
|
@ -1065,8 +1091,17 @@ etcdv3::AsyncWatchAction::AsyncWatchAction(etcdv3::ActionParameters&& params)
|
||||||
isCancelled.store(false);
|
isCancelled.store(false);
|
||||||
stream = parameters.watch_stub->AsyncWatch(&context, &cq_,
|
stream = parameters.watch_stub->AsyncWatch(&context, &cq_,
|
||||||
(void*) etcdv3::WATCH_CREATE);
|
(void*) etcdv3::WATCH_CREATE);
|
||||||
this->watch_id =
|
// The unique watcher id causes the watcher cannot be cancelled as expected
|
||||||
std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
// on Ubuntu 20.04.
|
||||||
|
//
|
||||||
|
// See CI failures:
|
||||||
|
// https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/actions/runs/5561397273/jobs/10159051536
|
||||||
|
//
|
||||||
|
// Added in https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/pull/232
|
||||||
|
// Removed in https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/pull/236
|
||||||
|
//
|
||||||
|
// this->watch_id =
|
||||||
|
// std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||||||
// #ifndef NDEBUG
|
// #ifndef NDEBUG
|
||||||
// std::clog << "etcd-cpp-apiv3: watch_id: " << this->watch_id << std::endl;
|
// std::clog << "etcd-cpp-apiv3: watch_id: " << this->watch_id << std::endl;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,8 @@ void etcdv3::Transaction::setup_compare_and_delete(
|
||||||
std::string const& delete_key, std::string const& range_end,
|
std::string const& delete_key, std::string const& range_end,
|
||||||
const bool recursive) {
|
const bool recursive) {
|
||||||
this->add_compare_value(key, CompareResult::EQUAL, prev_value);
|
this->add_compare_value(key, CompareResult::EQUAL, prev_value);
|
||||||
this->add_success_delete(delete_key, range_end, recursive);
|
this->add_success_delete(delete_key, range_end, recursive,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
this->add_failure_range(key);
|
this->add_failure_range(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,7 +279,8 @@ void etcdv3::Transaction::setup_compare_or_delete(std::string const& key,
|
||||||
std::string const& range_end,
|
std::string const& range_end,
|
||||||
const bool recursive) {
|
const bool recursive) {
|
||||||
this->add_compare_value(key, CompareResult::NOT_EQUAL, prev_value);
|
this->add_compare_value(key, CompareResult::NOT_EQUAL, prev_value);
|
||||||
this->add_success_delete(delete_key, range_end, recursive);
|
this->add_success_delete(delete_key, range_end, recursive,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
this->add_failure_range(key);
|
this->add_failure_range(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,7 +326,8 @@ void etcdv3::Transaction::setup_compare_and_delete(
|
||||||
std::string const& delete_key, std::string const& range_end,
|
std::string const& delete_key, std::string const& range_end,
|
||||||
const bool recursive) {
|
const bool recursive) {
|
||||||
this->add_compare_mod(key, CompareResult::EQUAL, prev_revision);
|
this->add_compare_mod(key, CompareResult::EQUAL, prev_revision);
|
||||||
this->add_success_delete(delete_key, range_end, recursive);
|
this->add_success_delete(delete_key, range_end, recursive,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
this->add_failure_range(key);
|
this->add_failure_range(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,7 +337,8 @@ void etcdv3::Transaction::setup_compare_or_delete(std::string const& key,
|
||||||
std::string const& range_end,
|
std::string const& range_end,
|
||||||
const bool recursive) {
|
const bool recursive) {
|
||||||
this->add_compare_mod(key, CompareResult::NOT_EQUAL, prev_revision);
|
this->add_compare_mod(key, CompareResult::NOT_EQUAL, prev_revision);
|
||||||
this->add_success_delete(delete_key, range_end, recursive);
|
this->add_success_delete(delete_key, range_end, recursive,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
this->add_failure_range(key);
|
this->add_failure_range(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,11 +348,13 @@ void etcdv3::Transaction::setup_put(std::string const& key,
|
||||||
}
|
}
|
||||||
|
|
||||||
void etcdv3::Transaction::setup_delete(std::string const& key) {
|
void etcdv3::Transaction::setup_delete(std::string const& key) {
|
||||||
this->add_success_delete(key);
|
this->add_success_delete(key, "", false,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void etcdv3::Transaction::setup_delete(std::string const& key,
|
void etcdv3::Transaction::setup_delete(std::string const& key,
|
||||||
std::string const& range_end,
|
std::string const& range_end,
|
||||||
const bool recursive) {
|
const bool recursive) {
|
||||||
this->add_success_delete(key, range_end, recursive);
|
this->add_success_delete(key, range_end, recursive,
|
||||||
|
true /* for backwards compatibility */);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ char const* etcdv3::COMPARESWAP_ACTION = "compareAndSwap";
|
||||||
char const* etcdv3::UPDATE_ACTION = "update";
|
char const* etcdv3::UPDATE_ACTION = "update";
|
||||||
char const* etcdv3::SET_ACTION = "set";
|
char const* etcdv3::SET_ACTION = "set";
|
||||||
char const* etcdv3::GET_ACTION = "get";
|
char const* etcdv3::GET_ACTION = "get";
|
||||||
char const* etcdv3::PUT_ACTION = "put";
|
char const* etcdv3::PUT_ACTION = "set"; // alias
|
||||||
char const* etcdv3::DELETE_ACTION = "delete";
|
char const* etcdv3::DELETE_ACTION = "delete";
|
||||||
char const* etcdv3::COMPAREDELETE_ACTION = "compareAndDelete";
|
char const* etcdv3::COMPAREDELETE_ACTION = "compareAndDelete";
|
||||||
char const* etcdv3::LOCK_ACTION = "lock";
|
char const* etcdv3::LOCK_ACTION = "lock";
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ TEST_CASE("sync operations") {
|
||||||
etcd::SyncClient etcd(etcd_url);
|
etcd::SyncClient etcd(etcd_url);
|
||||||
etcd.rmdir("/test", true);
|
etcd.rmdir("/test", true);
|
||||||
|
|
||||||
|
etcd::Response res;
|
||||||
|
int64_t index;
|
||||||
|
|
||||||
// add
|
// add
|
||||||
CHECK(0 == etcd.add("/test/key1", "42").error_code());
|
CHECK(0 == etcd.add("/test/key1", "42").error_code());
|
||||||
CHECK(etcd::ERROR_KEY_ALREADY_EXISTS ==
|
CHECK(etcd::ERROR_KEY_ALREADY_EXISTS ==
|
||||||
|
|
@ -22,7 +25,9 @@ TEST_CASE("sync operations") {
|
||||||
CHECK(0 == etcd.modify("/test/key1", "43").error_code());
|
CHECK(0 == etcd.modify("/test/key1", "43").error_code());
|
||||||
CHECK(etcd::ERROR_KEY_NOT_FOUND ==
|
CHECK(etcd::ERROR_KEY_NOT_FOUND ==
|
||||||
etcd.modify("/test/key2", "43").error_code()); // Key not found
|
etcd.modify("/test/key2", "43").error_code()); // Key not found
|
||||||
CHECK("43" == etcd.modify("/test/key1", "42").prev_value().as_string());
|
res = etcd.modify("/test/key1", "42");
|
||||||
|
CHECK(0 == res.error_code());
|
||||||
|
CHECK("43" == res.prev_value().as_string());
|
||||||
|
|
||||||
// set
|
// set
|
||||||
CHECK(0 == etcd.set("/test/key1", "43").error_code()); // overwrite
|
CHECK(0 == etcd.set("/test/key1", "43").error_code()); // overwrite
|
||||||
|
|
@ -60,7 +65,7 @@ TEST_CASE("sync operations") {
|
||||||
|
|
||||||
// compare and swap
|
// compare and swap
|
||||||
etcd.set("/test/key1", "42");
|
etcd.set("/test/key1", "42");
|
||||||
int64_t index = etcd.modify_if("/test/key1", "43", "42").index();
|
index = etcd.modify_if("/test/key1", "43", "42").index();
|
||||||
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
||||||
etcd.modify_if("/test/key1", "44", "42").error_code());
|
etcd.modify_if("/test/key1", "44", "42").error_code());
|
||||||
REQUIRE(etcd.modify_if("/test/key1", "44", index).is_ok());
|
REQUIRE(etcd.modify_if("/test/key1", "44", index).is_ok());
|
||||||
|
|
@ -71,16 +76,20 @@ TEST_CASE("sync operations") {
|
||||||
etcd.set("/test/key1", "42");
|
etcd.set("/test/key1", "42");
|
||||||
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
||||||
etcd.rm_if("/test/key1", "43").error_code());
|
etcd.rm_if("/test/key1", "43").error_code());
|
||||||
CHECK(0 == etcd.rm_if("/test/key1", "42").error_code());
|
res = etcd.rm_if("/test/key1", "42");
|
||||||
|
CHECK(
|
||||||
|
(0 == res.error_code() || etcd::ERROR_KEY_NOT_FOUND == res.error_code()));
|
||||||
|
|
||||||
// atomic compare-and-delete based on prevIndex
|
// atomic compare-and-delete based on prevIndex
|
||||||
index = etcd.set("/test/key1", "42").index();
|
index = etcd.set("/test/key1", "42").index();
|
||||||
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
CHECK(etcd::ERROR_COMPARE_FAILED ==
|
||||||
etcd.rm_if("/test/key1", index - 1).error_code());
|
etcd.rm_if("/test/key1", index - 1).error_code());
|
||||||
CHECK(0 == etcd.rm_if("/test/key1", index).error_code());
|
res = etcd.rm_if("/test/key1", index);
|
||||||
|
CHECK(
|
||||||
|
(0 == res.error_code() || etcd::ERROR_KEY_NOT_FOUND == res.error_code()));
|
||||||
|
|
||||||
// leasegrant
|
// leasegrant
|
||||||
etcd::Response res = etcd.leasegrant(60);
|
res = etcd.leasegrant(60);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
CHECK(60 == res.value().ttl());
|
CHECK(60 == res.value().ttl());
|
||||||
CHECK(0 < res.value().lease());
|
CHECK(0 < res.value().lease());
|
||||||
|
|
@ -96,6 +105,7 @@ TEST_CASE("sync operations") {
|
||||||
res = etcd.set("/test/key1", "43", leaseid);
|
res = etcd.set("/test/key1", "43", leaseid);
|
||||||
REQUIRE(0 == res.error_code());
|
REQUIRE(0 == res.error_code());
|
||||||
CHECK("set" == res.action());
|
CHECK("set" == res.action());
|
||||||
|
res = etcd.get("/test/key1");
|
||||||
CHECK(leaseid == res.value().lease());
|
CHECK(leaseid == res.value().lease());
|
||||||
|
|
||||||
// modify with lease
|
// modify with lease
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,13 @@ TEST_CASE("set a key") {
|
||||||
CHECK(0 == etcd.set("/test", "42").get().error_code()); // Not a file
|
CHECK(0 == etcd.set("/test", "42").get().error_code()); // Not a file
|
||||||
|
|
||||||
// set with ttl
|
// set with ttl
|
||||||
resp = etcd.set("/test/key1", "50", 10).get();
|
resp = etcd.set("/test/key1", "50").get();
|
||||||
REQUIRE(0 == resp.error_code()); // overwrite
|
REQUIRE(0 == resp.error_code()); // overwrite
|
||||||
CHECK("set" == resp.action());
|
CHECK("set" == resp.action());
|
||||||
CHECK("43" == resp.prev_value().as_string());
|
CHECK("43" == resp.prev_value().as_string());
|
||||||
|
resp = etcd.get("/test/key1").get();
|
||||||
CHECK("50" == resp.value().as_string());
|
CHECK("50" == resp.value().as_string());
|
||||||
CHECK(0 < resp.value().lease());
|
CHECK(0 == resp.value().lease());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("atomic compare-and-swap") {
|
TEST_CASE("atomic compare-and-swap") {
|
||||||
|
|
@ -115,11 +116,11 @@ TEST_CASE("atomic compare-and-swap") {
|
||||||
CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
|
CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
|
||||||
CHECK("etcd-cpp-apiv3: compare failed" == res.error_message());
|
CHECK("etcd-cpp-apiv3: compare failed" == res.error_message());
|
||||||
|
|
||||||
// modify fails the second time
|
// modify fails on non-existing keys
|
||||||
res = etcd.modify_if("/test/key222", "44", "42").get();
|
res = etcd.modify_if("/test/key222", "44", "42").get();
|
||||||
CHECK(!res.is_ok());
|
CHECK(!res.is_ok());
|
||||||
CHECK(etcd::ERROR_KEY_NOT_FOUND == res.error_code());
|
CHECK(etcd::ERROR_COMPARE_FAILED == res.error_code());
|
||||||
CHECK("etcd-cpp-apiv3: key not found" == res.error_message());
|
CHECK("etcd-cpp-apiv3: compare failed" == res.error_message());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("delete a value") {
|
TEST_CASE("delete a value") {
|
||||||
|
|
@ -144,10 +145,10 @@ TEST_CASE("delete a value") {
|
||||||
CHECK(modify_index == resp.prev_value().modified_index());
|
CHECK(modify_index == resp.prev_value().modified_index());
|
||||||
CHECK(version == resp.prev_value().version());
|
CHECK(version == resp.prev_value().version());
|
||||||
CHECK("delete" == resp.action());
|
CHECK("delete" == resp.action());
|
||||||
CHECK(modify_index == resp.value().modified_index());
|
|
||||||
CHECK(create_index == resp.value().created_index());
|
CHECK(create_index == resp.value().created_index());
|
||||||
|
CHECK(modify_index == resp.value().modified_index());
|
||||||
CHECK(version == resp.value().version());
|
CHECK(version == resp.value().version());
|
||||||
CHECK("" == resp.value().as_string());
|
CHECK("43" == resp.value().as_string());
|
||||||
CHECK("/test/key1" == resp.value().key());
|
CHECK("/test/key1" == resp.value().key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,6 +559,8 @@ TEST_CASE("lease grant") {
|
||||||
res = etcd.set("/test/key1", "43", leaseid).get();
|
res = etcd.set("/test/key1", "43", leaseid).get();
|
||||||
REQUIRE(0 == res.error_code()); // overwrite
|
REQUIRE(0 == res.error_code()); // overwrite
|
||||||
CHECK("set" == res.action());
|
CHECK("set" == res.action());
|
||||||
|
res = etcd.get("/test/key1").get();
|
||||||
|
REQUIRE(0 == res.error_code()); // overwrite
|
||||||
CHECK(leaseid == res.value().lease());
|
CHECK(leaseid == res.value().lease());
|
||||||
|
|
||||||
// change with lease id
|
// change with lease id
|
||||||
|
|
@ -566,6 +569,8 @@ TEST_CASE("lease grant") {
|
||||||
res = etcd.set("/test/key1", "43", leaseid).get();
|
res = etcd.set("/test/key1", "43", leaseid).get();
|
||||||
REQUIRE(0 == res.error_code()); // overwrite
|
REQUIRE(0 == res.error_code()); // overwrite
|
||||||
CHECK("set" == res.action());
|
CHECK("set" == res.action());
|
||||||
|
res = etcd.get("/test/key1").get();
|
||||||
|
REQUIRE(0 == res.error_code()); // overwrite
|
||||||
CHECK(leaseid == res.value().lease());
|
CHECK(leaseid == res.value().lease());
|
||||||
|
|
||||||
// failure to attach lease id
|
// failure to attach lease id
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue