mirror of https://github.com/libp2p/cpp-libp2p.git
masterjedy
5 years ago
14 changed files with 562 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
## |
|||
# Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
# SPDX-License-Identifier: Apache-2.0 |
|||
## |
|||
|
|||
addtest(hexutil_test |
|||
hexutil_test.cpp |
|||
) |
|||
target_link_libraries(hexutil_test |
|||
hexutil |
|||
) |
@ -0,0 +1,63 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#include "common/hexutil.hpp" |
|||
|
|||
#include <gtest/gtest.h> |
|||
#include "testutil/literals.hpp" |
|||
|
|||
using namespace libp2p::common; |
|||
using namespace std::string_literals; |
|||
|
|||
/**
|
|||
* @given Array of bytes |
|||
* @when hex it |
|||
* @then hex matches expected encoding |
|||
*/ |
|||
TEST(Common, Hexutil_Hex) { |
|||
auto bin = "00010204081020FF"_unhex; |
|||
auto hexed = hex_upper(bin); |
|||
ASSERT_EQ(hexed, "00010204081020FF"s); |
|||
} |
|||
|
|||
/**
|
|||
* @given Hexencoded string of even length |
|||
* @when unhex |
|||
* @then no exception, result matches expected value |
|||
*/ |
|||
TEST(Common, Hexutil_UnhexEven) { |
|||
auto s = "00010204081020ff"s; |
|||
|
|||
std::vector<uint8_t> actual; |
|||
ASSERT_NO_THROW( |
|||
actual = unhex(s).value()) |
|||
<< "unhex result does not contain expected std::vector<uint8_t>"; |
|||
|
|||
auto expected = "00010204081020ff"_unhex; |
|||
|
|||
ASSERT_EQ(actual, expected); |
|||
} |
|||
|
|||
/**
|
|||
* @given Hexencoded string of odd length |
|||
* @when unhex |
|||
* @then unhex result contains error |
|||
*/ |
|||
TEST(Common, Hexutil_UnhexOdd) { |
|||
ASSERT_NO_THROW({ |
|||
unhex("0").error(); |
|||
}) << "unhex did not return an error as expected"; |
|||
} |
|||
|
|||
/**
|
|||
* @given Hexencoded string with non-hex letter |
|||
* @when unhex |
|||
* @then unhex result contains error |
|||
*/ |
|||
TEST(Common, Hexutil_UnhexInvalid) { |
|||
ASSERT_NO_THROW({ |
|||
unhex("keks").error(); |
|||
}) << "unhex did not return an error as expected"; |
|||
} |
@ -0,0 +1,9 @@ |
|||
# Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
# SPDX-License-Identifier: Apache-2.0 |
|||
|
|||
add_subdirectory(libp2p) |
|||
|
|||
add_library(testutil INTERFACE) |
|||
target_link_libraries(testutil INTERFACE |
|||
testutil_peer |
|||
) |
@ -0,0 +1,77 @@ |
|||
|
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_GMOCK_ACTIONS_HPP |
|||
#define LIBP2P_GMOCK_ACTIONS_HPP |
|||
|
|||
#include <gmock/gmock.h> |
|||
#include <boost/system/error_code.hpp> |
|||
|
|||
/**
|
|||
* @code |
|||
* const int size = 1; |
|||
* EXPECT_CALL(*connection_, read(_, _, _)).WillOnce(AsioSuccess(size)); |
|||
* auto buf = std::make_shared<std::vector<uint8_t>>(size, 0); |
|||
* secure_connection_->read(*buf, size, [&size, buf](auto &&res) mutable { |
|||
* ASSERT_TRUE(res) << res.error().message(); |
|||
* ASSERT_EQ(read, size); |
|||
* }); |
|||
* @endcode |
|||
*/ |
|||
ACTION_P(AsioSuccess, size) { |
|||
// arg0 - buffer
|
|||
// arg1 - bytes
|
|||
// arg2 - callback
|
|||
arg2(size); |
|||
} |
|||
|
|||
/**
|
|||
* @code |
|||
* const int size = 1; |
|||
* boost::system::error_code ec = ...; |
|||
* EXPECT_CALL(*connection_, read(_, _, _)).WillOnce(AsioCallback(ec, size)); |
|||
* auto buf = std::make_shared<std::vector<uint8_t>>(size, 0); |
|||
* secure_connection_->read(*buf, size, [&size, buf, e=ec](auto &&ec, size_t |
|||
* read) mutable { ASSERT_EQ(ec.value(), e.value()); ASSERT_EQ(read, size); |
|||
* }); |
|||
* @endcode |
|||
*/ |
|||
ACTION_P2(AsioCallback, ec, size) { |
|||
// arg0 - buffer
|
|||
// arg1 - bytes
|
|||
// arg2 - callback
|
|||
arg2(ec, size); |
|||
} |
|||
|
|||
ACTION_P(Arg0CallbackWithArg, in) { |
|||
arg0(in); |
|||
} |
|||
|
|||
ACTION_P(Arg1CallbackWithArg, in) { |
|||
arg1(in); |
|||
} |
|||
|
|||
ACTION_P(Arg2CallbackWithArg, in) { |
|||
arg2(in); |
|||
} |
|||
|
|||
ACTION_P(Arg3CallbackWithArg, in) { |
|||
arg3(in); |
|||
} |
|||
|
|||
ACTION_P(UpgradeToSecureInbound, do_upgrade) { |
|||
arg1(do_upgrade(arg0)); |
|||
} |
|||
|
|||
ACTION_P(UpgradeToSecureOutbound, do_upgrade) { |
|||
arg2(do_upgrade(arg0)); |
|||
} |
|||
|
|||
ACTION_P(UpgradeToMuxed, do_upgrade) { |
|||
arg1(do_upgrade(arg0)); |
|||
} |
|||
|
|||
#endif // LIBP2P_GMOCK_ACTIONS_HPP
|
@ -0,0 +1,17 @@ |
|||
# Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
# SPDX-License-Identifier: Apache-2.0 |
|||
|
|||
add_library(testutil_peer |
|||
peer.cpp |
|||
) |
|||
target_link_libraries(testutil_peer |
|||
libp2p_peer_id |
|||
) |
|||
|
|||
add_library(testutil_read_writer_helper |
|||
message_read_writer_helper.cpp |
|||
message_read_writer_helper.hpp |
|||
) |
|||
target_link_libraries(testutil_read_writer_helper |
|||
uvarint |
|||
) |
@ -0,0 +1,77 @@ |
|||
|
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#include "testutil/libp2p/message_read_writer_helper.hpp" |
|||
|
|||
#include "p2p/multi/uvarint.hpp" |
|||
|
|||
ACTION_P(PutBytes, bytes) { // NOLINT
|
|||
std::copy(bytes.begin(), bytes.end(), arg0.begin()); |
|||
arg2(bytes.size()); |
|||
} |
|||
|
|||
ACTION_P(CheckBytes, bytes) { // NOLINT
|
|||
ASSERT_EQ((std::vector<uint8_t>{arg0.begin(), arg0.end()}), bytes); // NOLINT
|
|||
arg2(bytes.size()); |
|||
} |
|||
|
|||
namespace libp2p::basic { |
|||
using multi::UVarint; |
|||
using testing::_; |
|||
|
|||
void setReadExpectations( |
|||
const std::shared_ptr<ReadWriterMock> &read_writer_mock, |
|||
const std::vector<uint8_t> &msg) { |
|||
// read varint
|
|||
UVarint varint_to_read{msg.size()}; |
|||
for (size_t i = 0; i < varint_to_read.size(); ++i) { |
|||
EXPECT_CALL(*read_writer_mock, read(_, 1, _)) |
|||
.WillOnce( |
|||
PutBytes(std::vector<uint8_t>{varint_to_read.toVector()[i]})); |
|||
} |
|||
|
|||
// read message
|
|||
EXPECT_CALL(*read_writer_mock, read(_, msg.size(), _)) |
|||
.WillOnce(PutBytes(msg)); |
|||
} |
|||
|
|||
void setReadExpectations( |
|||
const std::shared_ptr<connection::StreamMock> &stream_mock, |
|||
const std::vector<uint8_t> &msg) { |
|||
// read varint
|
|||
UVarint varint_to_read{msg.size()}; |
|||
for (size_t i = 0; i < varint_to_read.size(); ++i) { |
|||
EXPECT_CALL(*stream_mock, read(_, 1, _)) |
|||
.WillOnce( |
|||
PutBytes(std::vector<uint8_t>{varint_to_read.toVector()[i]})); |
|||
} |
|||
|
|||
// read message
|
|||
EXPECT_CALL(*stream_mock, read(_, msg.size(), _)).WillOnce(PutBytes(msg)); |
|||
} |
|||
|
|||
void setWriteExpectations( |
|||
const std::shared_ptr<ReadWriterMock> &read_writer_mock, |
|||
std::vector<uint8_t> msg) { |
|||
UVarint varint_to_write{msg.size()}; |
|||
msg.insert(msg.begin(), |
|||
varint_to_write.toVector().begin(), |
|||
varint_to_write.toVector().end()); |
|||
EXPECT_CALL(*read_writer_mock, write(_, msg.size(), _)) |
|||
.WillOnce(CheckBytes(msg)); |
|||
} |
|||
|
|||
void setWriteExpectations( |
|||
const std::shared_ptr<connection::StreamMock> &stream_mock, |
|||
std::vector<uint8_t> msg) { |
|||
UVarint varint_to_write{msg.size()}; |
|||
msg.insert(msg.begin(), |
|||
varint_to_write.toVector().begin(), |
|||
varint_to_write.toVector().end()); |
|||
EXPECT_CALL(*stream_mock, write(_, msg.size(), _)) |
|||
.WillOnce(CheckBytes(msg)); |
|||
} |
|||
} // namespace libp2p::basic
|
@ -0,0 +1,44 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_MESSAGE_READ_WRITER_HELPER_HPP |
|||
#define LIBP2P_MESSAGE_READ_WRITER_HELPER_HPP |
|||
|
|||
#include <memory> |
|||
#include <vector> |
|||
|
|||
#include "mock/p2p/basic/read_writer_mock.hpp" |
|||
#include "mock/p2p/connection/stream_mock.hpp" |
|||
|
|||
/**
|
|||
* Basically, methods in this file do the same thing as |
|||
* libp2p::basic::MessageReadWriter, but with a mock |
|||
*/ |
|||
|
|||
namespace libp2p::basic { |
|||
/**
|
|||
* Set read expectations for the provided (\param read_writer_mock) to read |
|||
* (\param msg) with a prepended varint |
|||
*/ |
|||
void setReadExpectations( |
|||
const std::shared_ptr<ReadWriterMock> &read_writer_mock, |
|||
const std::vector<uint8_t> &msg); |
|||
void setReadExpectations( |
|||
const std::shared_ptr<connection::StreamMock> &stream_mock, |
|||
const std::vector<uint8_t> &msg); |
|||
|
|||
/**
|
|||
* Set write expectations for the provided (\param read_writer_mock) to write |
|||
* (\param msg) with a prepended varint |
|||
*/ |
|||
void setWriteExpectations( |
|||
const std::shared_ptr<ReadWriterMock> &read_writer_mock, |
|||
std::vector<uint8_t> msg); |
|||
void setWriteExpectations( |
|||
const std::shared_ptr<connection::StreamMock> &stream_mock, |
|||
std::vector<uint8_t> msg); |
|||
} // namespace libp2p::basic
|
|||
|
|||
#endif // LIBP2P_MESSAGE_READ_WRITER_HELPER_HPP
|
@ -0,0 +1,22 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#include "testutil/libp2p/peer.hpp" |
|||
|
|||
namespace testutil { |
|||
|
|||
PeerId randomPeerId() { |
|||
PublicKey k; |
|||
|
|||
k.type = T::ED25519; |
|||
k.data.resize(32u); |
|||
for (auto i = 0u; i < 32u; i++) { |
|||
k.data[i] = (rand() & 0xff); |
|||
} |
|||
|
|||
return PeerId::fromPublicKey(k); |
|||
} |
|||
|
|||
} // namespace testutil
|
@ -0,0 +1,24 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_TESTUTIL_PEER_HPP |
|||
#define LIBP2P_TESTUTIL_PEER_HPP |
|||
|
|||
#include "p2p/crypto/key.hpp" |
|||
#include "p2p/multi/multihash.hpp" |
|||
#include "p2p/peer/peer_id.hpp" |
|||
|
|||
namespace testutil { |
|||
|
|||
using libp2p::crypto::PublicKey; |
|||
using libp2p::multi::Multihash; |
|||
using libp2p::peer::PeerId; |
|||
using T = libp2p::crypto::PublicKey::Type; |
|||
|
|||
PeerId randomPeerId(); |
|||
|
|||
} // namespace testutil
|
|||
|
|||
#endif // LIBP2P_TESTUTIL_PEER_HPP
|
@ -0,0 +1,58 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_TEST_TESTUTIL_LITERALS_HPP_ |
|||
#define LIBP2P_TEST_TESTUTIL_LITERALS_HPP_ |
|||
|
|||
#include "p2p/common/types.hpp" |
|||
#include "p2p/common/hexutil.hpp" |
|||
#include "p2p/multi/multiaddress.hpp" |
|||
#include "p2p/multi/multihash.hpp" |
|||
#include "p2p/peer/peer_id.hpp" |
|||
|
|||
/// creates a buffer filled with characters from the original string
|
|||
/// mind that it does not perform unhexing, there is ""_unhex for it
|
|||
//inline kagome::common::Buffer operator"" _buf(const char *c, size_t s) {
|
|||
// std::vector<uint8_t> chars(c, c + s);
|
|||
// return kagome::common::Buffer(std::move(chars));
|
|||
//}
|
|||
|
|||
inline libp2p::common::Hash256 operator"" _hash256(const char *c, size_t s) { |
|||
libp2p::common::Hash256 hash{}; |
|||
std::copy_n(c, std::min(s, 32ul), hash.rbegin()); |
|||
return hash; |
|||
} |
|||
|
|||
inline std::vector<uint8_t> operator"" _v(const char *c, size_t s) { |
|||
std::vector<uint8_t> chars(c, c + s); |
|||
return chars; |
|||
} |
|||
|
|||
//inline kagome::common::Buffer operator"" _hex2buf(const char *c, size_t s) {
|
|||
// return kagome::common::Buffer::fromHex(std::string_view(c, s)).value();
|
|||
//}
|
|||
|
|||
inline std::vector<uint8_t> operator""_unhex(const char *c, size_t s) { |
|||
return libp2p::common::unhex(std::string_view(c, s)).value(); |
|||
} |
|||
|
|||
inline libp2p::multi::Multiaddress operator""_multiaddr(const char *c, |
|||
size_t s) { |
|||
return libp2p::multi::Multiaddress::create(std::string_view(c, s)).value(); |
|||
} |
|||
|
|||
/// creates a multihash instance from a hex string
|
|||
inline libp2p::multi::Multihash operator""_multihash(const char *c, size_t s) { |
|||
return libp2p::multi::Multihash::createFromHex(std::string_view(c, s)) |
|||
.value(); |
|||
} |
|||
|
|||
inline libp2p::peer::PeerId operator""_peerid(const char *c, size_t s) { |
|||
libp2p::crypto::PublicKey p; |
|||
p.data = std::vector<uint8_t>(c, c + s); |
|||
return libp2p::peer::PeerId::fromPublicKey(p); |
|||
} |
|||
|
|||
#endif // LIBP2P_TEST_TESTUTIL_LITERALS_HPP_
|
@ -0,0 +1,34 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_TEST_TESTUTIL_LIBP2P_MA_GENERATOR_HPP |
|||
#define LIBP2P_TEST_TESTUTIL_LIBP2P_MA_GENERATOR_HPP |
|||
|
|||
#include <iostream> |
|||
|
|||
#include "libp2p/multi/multiaddress.hpp" |
|||
#include "testutil/outcome.hpp" |
|||
|
|||
namespace testutil { |
|||
class MultiaddressGenerator { |
|||
using Multiaddress = libp2p::multi::Multiaddress; |
|||
|
|||
public: |
|||
inline MultiaddressGenerator(std::string prefix, uint16_t start_port) |
|||
: prefix_{std::move(prefix)}, current_port_{start_port} {} |
|||
|
|||
inline Multiaddress nextMultiaddress() { |
|||
std::string ma = prefix_ + std::to_string(current_port_++); |
|||
EXPECT_OUTCOME_TRUE(res, Multiaddress::create(ma)); |
|||
return res; |
|||
} |
|||
|
|||
private: |
|||
std::string prefix_; |
|||
uint16_t current_port_; |
|||
}; |
|||
} // namespace testutil
|
|||
|
|||
#endif // LIBP2P_TEST_TESTUTIL_LIBP2P_MA_GENERATOR_HPP
|
@ -0,0 +1,97 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_GTEST_OUTCOME_UTIL_HPP |
|||
#define LIBP2P_GTEST_OUTCOME_UTIL_HPP |
|||
|
|||
#include <gtest/gtest.h> |
|||
#include <outcome/outcome.hpp> |
|||
#include "common/visitor.hpp" |
|||
|
|||
#define PP_CAT(a, b) PP_CAT_I(a, b) |
|||
#define PP_CAT_I(a, b) PP_CAT_II(~, a##b) |
|||
#define PP_CAT_II(p, res) res |
|||
|
|||
#define UNIQUE_NAME(base) PP_CAT(base, __LINE__) |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_void(var, expr) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_TRUE(var) << "Line " << __LINE__ << ": " << var.error().message(); |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_name(var, val, expr) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_TRUE(var) << "Line " << __LINE__ << ": " << var.error().message(); \ |
|||
auto &&val = var.value(); |
|||
|
|||
#define EXPECT_OUTCOME_FALSE_void(var, expr) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_FALSE(var) << "Line " << __LINE__ << ": " << var.error().message(); |
|||
|
|||
#define EXPECT_OUTCOME_FALSE_name(var, val, expr) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_FALSE(var) << "Line " << __LINE__ << ": " << var.error().message(); \ |
|||
auto &&val = var.error(); |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_3(var, val, expr) \ |
|||
EXPECT_OUTCOME_TRUE_name(var, val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_2(val, expr) \ |
|||
EXPECT_OUTCOME_TRUE_3(UNIQUE_NAME(_r), val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_1(expr) \ |
|||
EXPECT_OUTCOME_TRUE_void(UNIQUE_NAME(_v), expr) |
|||
|
|||
#define EXPECT_OUTCOME_FALSE_3(var, val, expr) \ |
|||
EXPECT_OUTCOME_FALSE_name(var, val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_FALSE_2(val, expr) \ |
|||
EXPECT_OUTCOME_FALSE_3(UNIQUE_NAME(_r), val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_FALSE_1(expr) \ |
|||
EXPECT_OUTCOME_FALSE_void(UNIQUE_NAME(_v), expr) |
|||
|
|||
/**
|
|||
* Use this macro in GTEST with 2 arguments to assert that getResult() |
|||
* returned VALUE and immediately get this value. |
|||
* EXPECT_OUTCOME_TRUE(val, getResult()); |
|||
*/ |
|||
#define EXPECT_OUTCOME_TRUE(val, expr) \ |
|||
EXPECT_OUTCOME_TRUE_name(UNIQUE_NAME(_r), val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_FALSE(val, expr) \ |
|||
EXPECT_OUTCOME_FALSE_name(UNIQUE_NAME(_f), val, expr) |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_MSG_void(var, expr, msg) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_TRUE(var) << "Line " << __LINE__ << ": " << var.error().message() \ |
|||
<< "\t" << (msg); |
|||
|
|||
#define EXPECT_OUTCOME_TRUE_MSG_name(var, val, expr, msg) \ |
|||
auto &&var = expr; \ |
|||
EXPECT_TRUE(var) << "Line " << __LINE__ << ": " << var.error().message() \ |
|||
<< "\t" << (msg); \ |
|||
auto &&val = var.value(); |
|||
|
|||
/**
|
|||
* Use this macro in GTEST with 2 arguments to assert that |
|||
* result of expression as outcome::result<T> is value and, |
|||
* but the value itself is not necessary. |
|||
* If result is error, macro prints corresponding error message |
|||
* and appends custom error message specified in msg. |
|||
*/ |
|||
#define EXPECT_OUTCOME_TRUE_MSG_1(expr, msg) \ |
|||
EXPECT_OUTCOME_TRUE_MSG_void(UNIQUE_NAME(_v), expr, msg) |
|||
|
|||
/**
|
|||
* Use this macro in GTEST with 3 arguments to assert that |
|||
* result of expression as outcome::result<T> is value and |
|||
* immediately get access to this value. |
|||
* If result is error, macro prints corresponding error message |
|||
* and appends custom error message specified in msg. |
|||
*/ |
|||
#define EXPECT_OUTCOME_TRUE_MSG(val, expr, msg) \ |
|||
EXPECT_OUTCOME_TRUE_MSG_name(UNIQUE_NAME(_r), val, expr, msg) |
|||
|
|||
#endif // LIBP2P_GTEST_OUTCOME_UTIL_HPP
|
@ -0,0 +1,28 @@ |
|||
/**
|
|||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. |
|||
* SPDX-License-Identifier: Apache-2.0 |
|||
*/ |
|||
|
|||
#ifndef LIBP2P_TEST_TESTUTIL_TESTPARAM_HPP |
|||
#define LIBP2P_TEST_TESTUTIL_TESTPARAM_HPP |
|||
|
|||
#include <cstdint> |
|||
#include <vector> |
|||
|
|||
namespace testutil { |
|||
template <typename T> |
|||
struct TestParam { |
|||
std::vector<uint8_t> encoded_value{}; |
|||
bool should_fail{false}; |
|||
T value{}; |
|||
}; |
|||
|
|||
template <typename T> |
|||
TestParam<T> make_param(std::vector<uint8_t> &&buffer, |
|||
bool should_fail, |
|||
T &&value) { |
|||
return {buffer, should_fail, std::forward<T>(value)}; |
|||
}; |
|||
} // namespace testutil
|
|||
|
|||
#endif // LIBP2P_TEST_TESTUTIL_TESTPARAM_HPP
|
Loading…
Reference in new issue