mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-08-05 04:01:12 +03:00
Cleaning wsrep-API dependencies from library code
Replace all wsrep_api.h dependencies with similar code in library implementation. Also add gcc/g++ 4.4 to travis automation to get better compiler coverage.
This commit is contained in:
@@ -307,6 +307,10 @@ namespace wsrep
|
||||
|
||||
/**
|
||||
* Append a key into transaction write set.
|
||||
*
|
||||
* @param key Key to be appended
|
||||
*
|
||||
* @return Zero on success, non-zero on failure.
|
||||
*/
|
||||
int append_key(const wsrep::key& key)
|
||||
{
|
||||
@@ -315,6 +319,27 @@ namespace wsrep
|
||||
return transaction_.append_key(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append keys in key_array into transaction write set.
|
||||
*
|
||||
* @param keys Array of keys to be appended
|
||||
*
|
||||
* @return Zero in case of success, non-zero on failure.
|
||||
*/
|
||||
int append_keys(const wsrep::key_array& keys)
|
||||
{
|
||||
assert(mode_ == m_local || mode_ == m_toi);
|
||||
assert(state_ == s_exec);
|
||||
for (auto i(keys.begin()); i != keys.end(); ++i)
|
||||
{
|
||||
if (transaction_.append_key(*i))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data into transaction write set.
|
||||
*/
|
||||
|
@@ -20,12 +20,19 @@
|
||||
|
||||
/** @file compiler.hpp
|
||||
*
|
||||
* Compiler specific options.
|
||||
* Compiler specific macro definitions.
|
||||
*
|
||||
* WSREP_OVERRIDE - Set to "override" if the compiler supports it, otherwise
|
||||
* left empty.
|
||||
* WSREP_CONSTEXPR_OR_INLINE - Set to "constexpr" if the compiler supports it,
|
||||
* otherwise "inline".
|
||||
*/
|
||||
|
||||
#define WSREP_UNUSED __attribute__((unused))
|
||||
#if __cplusplus >= 201103L
|
||||
#define WSREP_OVERRIDE override
|
||||
#define WSREP_CONSTEXPR_OR_INLINE constexpr
|
||||
#else
|
||||
#define WSREP_OVERRIDE
|
||||
#define WSREP_CONSTEXPR_OR_INLINE inline
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
@@ -22,9 +22,16 @@
|
||||
|
||||
#include "id.hpp"
|
||||
#include "seqno.hpp"
|
||||
#include "compiler.hpp"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
/**
|
||||
* Minimum number of bytes guaratneed to store GTID string representation,
|
||||
* terminating '\0' not included (36 + 1 + 20).
|
||||
*/
|
||||
#define WSREP_LIB_GTID_C_STR_LEN 57
|
||||
|
||||
namespace wsrep
|
||||
{
|
||||
class gtid
|
||||
@@ -61,6 +68,18 @@ namespace wsrep
|
||||
wsrep::seqno seqno_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scan a GTID from C string.
|
||||
*
|
||||
* @param buf Buffer containing the string
|
||||
* @param len Length of buffer
|
||||
* @param[out] gtid Gtid to be printed to
|
||||
*
|
||||
* @return Number of bytes scanned, negative value on error.
|
||||
*/
|
||||
ssize_t scan_from_c_str(const char* buf, size_t buf_len,
|
||||
wsrep::gtid& gtid);
|
||||
|
||||
/**
|
||||
* Print a GTID into character buffer.
|
||||
* @param buf Pointer to the beginning of the buffer
|
||||
@@ -68,16 +87,16 @@ namespace wsrep
|
||||
*
|
||||
* @return Number of characters printed or negative value for error
|
||||
*/
|
||||
ssize_t gtid_print_to_c_str(const wsrep::gtid&, char* buf, size_t buf_len);
|
||||
ssize_t print_to_c_str(const wsrep::gtid&, char* buf, size_t buf_len);
|
||||
|
||||
/**
|
||||
* Return minimum number of bytes guaranteed to store GTID string
|
||||
* representation, terminating '\0' not included (36 + 1 + 20)
|
||||
* Overload for ostream operator<<.
|
||||
*/
|
||||
static inline size_t gtid_c_str_len()
|
||||
{
|
||||
return 57;
|
||||
}
|
||||
std::ostream& operator<<(std::ostream&, const wsrep::gtid&);
|
||||
|
||||
/**
|
||||
* Overload for istream operator>>.
|
||||
*/
|
||||
std::istream& operator>>(std::istream&, wsrep::gtid&);
|
||||
}
|
||||
|
||||
|
@@ -42,10 +42,11 @@ namespace wsrep
|
||||
class id
|
||||
{
|
||||
public:
|
||||
typedef struct native_type { unsigned char buf[16]; } native_type;
|
||||
/**
|
||||
* Default constructor. Constructs an empty identifier.
|
||||
*/
|
||||
id() : data_() { std::memset(data_, 0, sizeof(data_)); }
|
||||
id() : data_() { std::memset(data_.buf, 0, sizeof(data_.buf)); }
|
||||
|
||||
/**
|
||||
* Construct from string. The input string may contain either
|
||||
@@ -62,24 +63,24 @@ namespace wsrep
|
||||
{
|
||||
throw wsrep::runtime_error("Too long identifier");
|
||||
}
|
||||
std::memset(data_, 0, sizeof(data_));
|
||||
std::memcpy(data_, data, size);
|
||||
std::memset(data_.buf, 0, sizeof(data_.buf));
|
||||
std::memcpy(data_.buf, data, size);
|
||||
}
|
||||
|
||||
bool operator<(const id& other) const
|
||||
{
|
||||
return (std::memcmp(data_, other.data_, sizeof(data_)) < 0);
|
||||
return (std::memcmp(data_.buf, other.data_.buf, sizeof(data_.buf)) < 0);
|
||||
}
|
||||
|
||||
bool operator==(const id& other) const
|
||||
{
|
||||
return (std::memcmp(data_, other.data_, sizeof(data_)) == 0);
|
||||
return (std::memcmp(data_.buf, other.data_.buf, sizeof(data_.buf)) == 0);
|
||||
}
|
||||
bool operator!=(const id& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
const void* data() const { return data_; }
|
||||
const void* data() const { return data_.buf; }
|
||||
|
||||
size_t size() const { return sizeof(data_); }
|
||||
|
||||
@@ -94,7 +95,7 @@ namespace wsrep
|
||||
}
|
||||
private:
|
||||
static const wsrep::id undefined_;
|
||||
unsigned char data_[16];
|
||||
native_type data_;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream&, const wsrep::id& id);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "buffer.hpp"
|
||||
#include "client_id.hpp"
|
||||
#include "transaction_id.hpp"
|
||||
#include "compiler.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
@@ -404,6 +405,14 @@ namespace wsrep
|
||||
*/
|
||||
virtual void* native() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Empty provider magic. If none provider is passed to make_provider(),
|
||||
* a dummy provider is loaded.
|
||||
*/
|
||||
static WSREP_CONSTEXPR_OR_INLINE
|
||||
const char* none() { return "none"; }
|
||||
|
||||
/**
|
||||
* Create a new provider.
|
||||
*
|
||||
|
@@ -20,8 +20,6 @@
|
||||
#ifndef WSREP_SEQNO_HPP
|
||||
#define WSREP_SEQNO_HPP
|
||||
|
||||
#include "exception.hpp"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace wsrep
|
||||
@@ -33,6 +31,8 @@ namespace wsrep
|
||||
class seqno
|
||||
{
|
||||
public:
|
||||
typedef long long native_type;
|
||||
|
||||
seqno()
|
||||
: seqno_(-1)
|
||||
{ }
|
||||
@@ -77,8 +77,9 @@ namespace wsrep
|
||||
return (*this + seqno(other));
|
||||
}
|
||||
static seqno undefined() { return seqno(-1); }
|
||||
|
||||
private:
|
||||
long long seqno_;
|
||||
native_type seqno_;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, wsrep::seqno seqno);
|
||||
|
@@ -179,6 +179,13 @@ namespace wsrep
|
||||
rm_sync
|
||||
};
|
||||
|
||||
/**
|
||||
* Magic string to tell provider to engage into trivial (empty)
|
||||
* state transfer. No data will be passed, but the node shall be
|
||||
* considered joined.
|
||||
*/
|
||||
static WSREP_CONSTEXPR_OR_INLINE
|
||||
const char* sst_trivial() { return "trivial"; };
|
||||
|
||||
virtual ~server_state();
|
||||
|
||||
|
@@ -15,5 +15,6 @@ add_library(wsrep-lib
|
||||
server_state.cpp
|
||||
thread.cpp
|
||||
transaction.cpp
|
||||
uuid.cpp
|
||||
wsrep_provider_v26.cpp)
|
||||
target_link_libraries(wsrep-lib wsrep_api_v26 pthread dl)
|
||||
|
38
src/gtid.cpp
38
src/gtid.cpp
@@ -36,11 +36,47 @@ std::istream& wsrep::operator>>(std::istream& is, wsrep::gtid& gtid)
|
||||
std::getline(is, id_str, ':');
|
||||
long long seq;
|
||||
is >> seq;
|
||||
if (!is)
|
||||
{
|
||||
is.clear(std::ios_base::failbit);
|
||||
return is;
|
||||
}
|
||||
try
|
||||
{
|
||||
// wsrep::id constructor will throw if it cannot parse the
|
||||
// id_str.
|
||||
gtid = wsrep::gtid(wsrep::id(id_str), wsrep::seqno(seq));
|
||||
}
|
||||
catch (const wsrep::runtime_error& e)
|
||||
{
|
||||
// Formatting or extraction error. Clear the istream state and
|
||||
// set failibit.
|
||||
is.clear(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
ssize_t wsrep::gtid_print_to_c_str(
|
||||
ssize_t wsrep::scan_from_c_str(
|
||||
const char* buf, size_t buf_len, wsrep::gtid& gtid)
|
||||
{
|
||||
std::istringstream is(std::string(buf, buf_len));
|
||||
is >> gtid;
|
||||
// Whole string was consumed without failures
|
||||
if (is && is.eof())
|
||||
{
|
||||
return buf_len;
|
||||
}
|
||||
// Some failure occurred
|
||||
if (!is)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
// The string was not consumed completely, return current position
|
||||
// of the istream.
|
||||
return is.tellg();
|
||||
}
|
||||
|
||||
ssize_t wsrep::print_to_c_str(
|
||||
const wsrep::gtid& gtid, char* buf, size_t buf_len)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
22
src/id.cpp
22
src/id.cpp
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "wsrep/id.hpp"
|
||||
#include <wsrep_api.h>
|
||||
#include "uuid.hpp"
|
||||
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
@@ -29,15 +29,17 @@ const wsrep::id wsrep::id::undefined_ = wsrep::id();
|
||||
wsrep::id::id(const std::string& str)
|
||||
: data_()
|
||||
{
|
||||
wsrep_uuid_t wsrep_uuid;
|
||||
if (wsrep_uuid_scan(str.c_str(), str.size(), &wsrep_uuid) ==
|
||||
WSREP_UUID_STR_LEN)
|
||||
wsrep::uuid_t wsrep_uuid;
|
||||
|
||||
if (str.size() == WSREP_LIB_UUID_STR_LEN &&
|
||||
wsrep::uuid_scan(str.c_str(), str.size(), &wsrep_uuid) ==
|
||||
WSREP_LIB_UUID_STR_LEN)
|
||||
{
|
||||
std::memcpy(data_, wsrep_uuid.data, sizeof(data_));
|
||||
std::memcpy(data_.buf, wsrep_uuid.data, sizeof(data_.buf));
|
||||
}
|
||||
else if (str.size() <= 16)
|
||||
{
|
||||
std::memcpy(data_, str.c_str(), str.size());
|
||||
std::memcpy(data_.buf, str.c_str(), str.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -58,14 +60,14 @@ std::ostream& wsrep::operator<<(std::ostream& os, const wsrep::id& id)
|
||||
}
|
||||
else
|
||||
{
|
||||
char uuid_str[WSREP_UUID_STR_LEN + 1];
|
||||
wsrep_uuid_t uuid;
|
||||
char uuid_str[WSREP_LIB_UUID_STR_LEN + 1];
|
||||
wsrep::uuid_t uuid;
|
||||
std::memcpy(uuid.data, ptr, sizeof(uuid.data));
|
||||
if (wsrep_uuid_print(&uuid, uuid_str, sizeof(uuid_str)) < 0)
|
||||
if (wsrep::uuid_print(&uuid, uuid_str, sizeof(uuid_str)) < 0)
|
||||
{
|
||||
throw wsrep::runtime_error("Could not print uuid");
|
||||
}
|
||||
uuid_str[WSREP_UUID_STR_LEN] = '\0';
|
||||
uuid_str[WSREP_LIB_UUID_STR_LEN] = '\0';
|
||||
return (os << uuid_str);
|
||||
}
|
||||
}
|
||||
|
74
src/uuid.cpp
Normal file
74
src/uuid.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Codership Oy <info@codership.com>
|
||||
*
|
||||
* This file is part of wsrep-lib.
|
||||
*
|
||||
* Wsrep-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Wsrep-lib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "uuid.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
|
||||
int wsrep::uuid_scan (const char* str, size_t str_len, wsrep::uuid_t* uuid)
|
||||
{
|
||||
unsigned int uuid_len = 0;
|
||||
unsigned int uuid_offt = 0;
|
||||
|
||||
while (uuid_len + 1 < str_len) {
|
||||
/* We are skipping potential '-' after uuid_offt == 4, 6, 8, 10
|
||||
* which means
|
||||
* (uuid_offt >> 1) == 2, 3, 4, 5,
|
||||
* which in turn means
|
||||
* (uuid_offt >> 1) - 2 <= 3
|
||||
* since it is always >= 0, because uuid_offt is unsigned */
|
||||
if (((uuid_offt >> 1) - 2) <= 3 && str[uuid_len] == '-') {
|
||||
// skip dashes after 4th, 6th, 8th and 10th positions
|
||||
uuid_len += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isxdigit(str[uuid_len]) && isxdigit(str[uuid_len + 1])) {
|
||||
// got hex digit, scan another byte to uuid, increment uuid_offt
|
||||
sscanf (str + uuid_len, "%2hhx", uuid->data + uuid_offt);
|
||||
uuid_len += 2;
|
||||
uuid_offt += 1;
|
||||
if (sizeof (uuid->data) == uuid_offt)
|
||||
return uuid_len;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*uuid = wsrep::uuid_initializer;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int wsrep::uuid_print (const wsrep::uuid_t* uuid, char* str, size_t str_len)
|
||||
{
|
||||
if (str_len > WSREP_LIB_UUID_STR_LEN) {
|
||||
const unsigned char* u = uuid->data;
|
||||
return snprintf(str, str_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
|
||||
u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15]);
|
||||
}
|
||||
else {
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
}
|
79
src/uuid.hpp
Normal file
79
src/uuid.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Codership Oy <info@codership.com>
|
||||
*
|
||||
* This file is part of wsrep-lib.
|
||||
*
|
||||
* Wsrep-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Wsrep-lib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file uuid.hpp
|
||||
*
|
||||
* Helper methods to parse and print UUIDs, intended to use
|
||||
* internally in wsrep-lib.
|
||||
*
|
||||
* The implementation is copied from wsrep-API v26.
|
||||
*/
|
||||
|
||||
#ifndef WSREP_UUID_HPP
|
||||
#define WSREP_UUID_HPP
|
||||
|
||||
#include "wsrep/compiler.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* Length of UUID string representation, not including terminating '\0'.
|
||||
*/
|
||||
#define WSREP_LIB_UUID_STR_LEN 36
|
||||
|
||||
namespace wsrep
|
||||
{
|
||||
/**
|
||||
* UUID type.
|
||||
*/
|
||||
typedef union uuid_
|
||||
{
|
||||
unsigned char data[16];
|
||||
size_t alignment;
|
||||
} uuid_t;
|
||||
|
||||
static const wsrep::uuid_t uuid_initializer = {{0, }};
|
||||
|
||||
/**
|
||||
* Read UUID from string.
|
||||
*
|
||||
* @param str String to read from
|
||||
* @param str_len Length of string
|
||||
* @param[out] UUID to read to
|
||||
*
|
||||
* @return Number of bytes read or negative error code in case
|
||||
* of error.
|
||||
*/
|
||||
int uuid_scan(const char* str, size_t str_len, wsrep::uuid_t* uuid);
|
||||
|
||||
/**
|
||||
* Write UUID to string. The caller must allocate at least
|
||||
* WSREP_LIB_UUID_STR_LEN + 1 space for the output str parameter.
|
||||
*
|
||||
* @param uuid UUID to print
|
||||
* @param str[out] Output buffer
|
||||
* @param str_len Size of output buffer
|
||||
*
|
||||
* @return Number of chars printerd, negative error code in case of
|
||||
* error.
|
||||
*/
|
||||
int uuid_print(const wsrep::uuid_t* uuid, char* str, size_t str_len);
|
||||
}
|
||||
|
||||
#endif // WSREP_UUID_HPP
|
@@ -7,6 +7,7 @@ add_executable(wsrep-lib_test
|
||||
mock_high_priority_service.cpp
|
||||
mock_storage_service.cpp
|
||||
test_utils.cpp
|
||||
gtid_test.cpp
|
||||
id_test.cpp
|
||||
server_context_test.cpp
|
||||
transaction_test.cpp
|
||||
|
62
test/gtid_test.cpp
Normal file
62
test/gtid_test.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Codership Oy <info@codership.com>
|
||||
*
|
||||
* This file is part of wsrep-lib.
|
||||
*
|
||||
* Wsrep-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Wsrep-lib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "wsrep/gtid.hpp"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gtid_test_scan_from_string_uuid)
|
||||
{
|
||||
std::string gtid_str("6a20d44a-6e17-11e8-b1e2-9061aec0cdad:123456");
|
||||
wsrep::gtid gtid;
|
||||
ssize_t ret(wsrep::scan_from_c_str(
|
||||
gtid_str.c_str(),
|
||||
gtid_str.size(), gtid));
|
||||
BOOST_REQUIRE_MESSAGE(ret == ssize_t(gtid_str.size()),
|
||||
"Expected " << gtid_str.size() << " got " << ret);
|
||||
BOOST_REQUIRE(gtid.seqno().get() == 123456);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gtid_test_scan_from_string_uuid_too_long)
|
||||
{
|
||||
std::string gtid_str("6a20d44a-6e17-11e8-b1e2-9061aec0cdadx:123456");
|
||||
wsrep::gtid gtid;
|
||||
ssize_t ret(wsrep::scan_from_c_str(
|
||||
gtid_str.c_str(),
|
||||
gtid_str.size(), gtid));
|
||||
BOOST_REQUIRE_MESSAGE(ret == -EINVAL,
|
||||
"Expected " << -EINVAL << " got " << ret);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gtid_test_scan_from_string_seqno_out_of_range)
|
||||
{
|
||||
std::string gtid_str("6a20d44a-6e17-11e8-b1e2-9061aec0cdad:9223372036854775808");
|
||||
wsrep::gtid gtid;
|
||||
ssize_t ret(wsrep::scan_from_c_str(
|
||||
gtid_str.c_str(),
|
||||
gtid_str.size(), gtid));
|
||||
BOOST_REQUIRE_MESSAGE(ret == -EINVAL,
|
||||
"Expected " << -EINVAL << " got " << ret);
|
||||
|
||||
gtid_str = "6a20d44a-6e17-11e8-b1e2-9061aec0cdad:-9223372036854775809";
|
||||
ret = wsrep::scan_from_c_str(
|
||||
gtid_str.c_str(),
|
||||
gtid_str.size(), gtid);
|
||||
BOOST_REQUIRE_MESSAGE(ret == -EINVAL,
|
||||
"Expected " << -EINVAL << " got " << ret);
|
||||
}
|
Reference in New Issue
Block a user