aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/test
diff options
context:
space:
mode:
authorMauro <you@example.com>2021-06-30 07:57:22 +0000
committerMauro Sardara <msardara@cisco.com>2021-07-06 16:16:04 +0000
commit08233d44a6cfde878d7e10bca38ae935ed1c8fd5 (patch)
tree7ecc534d55bdc7e8dd15ecab084720910bcdf4d9 /libtransport/src/test
parent147ba39bed26887f5eba84757e2463ab8e370a9a (diff)
[HICN-713] Transport Library Major Refactoring 2
Co-authored-by: Luca Muscariello <muscariello@ieee.org> Co-authored-by: Michele Papalini <micpapal@cisco.com> Co-authored-by: Olivier Roques <oroques+fdio@cisco.com> Co-authored-by: Giulio Grassi <gigrassi@cisco.com> Signed-off-by: Mauro Sardara <msardara@cisco.com> Change-Id: I5b2c667bad66feb45abdb5effe22ed0f6c85d1c2
Diffstat (limited to 'libtransport/src/test')
-rw-r--r--libtransport/src/test/CMakeLists.txt55
-rw-r--r--libtransport/src/test/fec_reed_solomon.cc154
-rw-r--r--libtransport/src/test/fec_rely.cc156
-rw-r--r--libtransport/src/test/main.cc22
-rw-r--r--libtransport/src/test/test_auth.cc162
-rw-r--r--libtransport/src/test/test_consumer_producer_rtc.cc15
-rw-r--r--libtransport/src/test/test_core_manifest.cc19
-rw-r--r--libtransport/src/test/test_event_thread.cc11
-rw-r--r--libtransport/src/test/test_fec_reedsolomon.cc184
-rw-r--r--libtransport/src/test/test_fec_rely_wrapper.cc232
-rw-r--r--libtransport/src/test/test_indexer.cc322
-rw-r--r--libtransport/src/test/test_interest.cc5
-rw-r--r--libtransport/src/test/test_packet.cc9
-rw-r--r--libtransport/src/test/test_transport_producer.cc66
14 files changed, 834 insertions, 578 deletions
diff --git a/libtransport/src/test/CMakeLists.txt b/libtransport/src/test/CMakeLists.txt
index dd3d1d923..26fe7aee1 100644
--- a/libtransport/src/test/CMakeLists.txt
+++ b/libtransport/src/test/CMakeLists.txt
@@ -13,27 +13,40 @@
include(BuildMacros)
-list(APPEND TESTS
- test_auth
- test_consumer_producer_rtc
- test_core_manifest
- test_event_thread
- test_fec_reedsolomon
- test_interest
- test_packet
+list(APPEND TESTS_SRC
+ main.cc
+ test_auth.cc
+ test_consumer_producer_rtc.cc
+ test_core_manifest.cc
+ test_event_thread.cc
+ test_fec_reedsolomon.cc
+ test_indexer.cc
+ test_interest.cc
+ test_packet.cc
)
-foreach(test ${TESTS})
- build_executable(${test}
- NO_INSTALL
- SOURCES ${test}.cc
- LINK_LIBRARIES ${LIBTRANSPORT_SHARED} ${GTEST_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}
- INCLUDE_DIRS ${LIBTRANSPORT_INCLUDE_DIRS} ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
- DEPENDS gtest ${LIBTRANSPORT_SHARED}
- COMPONENT lib${LIBTRANSPORT}
- DEFINITIONS "${COMPILER_DEFINITIONS}"
- LINK_FLAGS ${LINK_FLAGS}
- )
+if (ENABLE_RELY)
+ list(APPEND TESTS_SRC
+ test_fec_rely_wrapper.cc
+ )
+endif()
- add_test_internal(${test})
-endforeach()
+build_executable(unit_tests
+ NO_INSTALL
+ SOURCES ${TESTS_SRC}
+ LINK_LIBRARIES
+ ${LIBRARIES}
+ ${LIBTRANSPORT_STATIC}
+ ${GTEST_LIBRARIES}
+ INCLUDE_DIRS
+ ${LIBTRANSPORT_INCLUDE_DIRS}
+ ${LIBHICN_INCLUDE_DIRS}
+ ${LIBTRANSPORT_INTERNAL_INCLUDE_DIRS}
+ ${GTEST_INCLUDE_DIRS}
+ DEPENDS gtest ${LIBTRANSPORT_SHARED}
+ COMPONENT ${LIBTRANSPORT_COMPONENT}
+ DEFINITIONS "${COMPILER_DEFINITIONS}"
+ LINK_FLAGS ${LINK_FLAGS}
+)
+
+add_test_internal(unit_tests)
diff --git a/libtransport/src/test/fec_reed_solomon.cc b/libtransport/src/test/fec_reed_solomon.cc
deleted file mode 100644
index 36543c531..000000000
--- a/libtransport/src/test/fec_reed_solomon.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-#include <hicn/transport/interfaces/socket_consumer.h>
-#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/interfaces/socket_producer.h>
-#include <hicn/transport/interfaces/global_conf_interface.h>
-
-#include <asio/io_service.hpp>
-#include <asio/steady_timer.hpp>
-#include <fec/rs.h>
-
-namespace transport {
-namespace interface {
-
-namespace {
-
-class ConsumerProducerTest : public ::testing::Test,
- public ConsumerSocket::ReadCallback {
- static const constexpr char prefix[] = "b001::1/128";
- static const constexpr char name[] = "b001::1";
- static const constexpr double prod_rate = 1.0e6;
- static const constexpr size_t payload_size = 1200;
- static constexpr std::size_t receive_buffer_size = 1500;
- static const constexpr double prod_interval_microseconds =
- double(payload_size) * 8 * 1e6 / prod_rate;
-
- public:
- ConsumerProducerTest()
- : io_service_(),
- rtc_timer_(io_service_),
- consumer_(TransportProtocolAlgorithms::RTC, io_service_),
- producer_(ProductionProtocolAlgorithms::RTC_PROD, io_service_),
- producer_prefix_(prefix),
- consumer_name_(name),
- packets_sent_(0),
- packets_received_(0) {
- global_config::IoModuleConfiguration config;
- config.name = "loopback_module";
- config.set();
- }
-
- virtual ~ConsumerProducerTest() {
- // You can do clean-up work that doesn't throw exceptions here.
- }
-
- // If the constructor and destructor are not enough for setting up
- // and cleaning up each test, you can define the following methods:
-
- virtual void SetUp() override {
- // Code here will be called immediately after the constructor (right
- // before each test).
-
- auto ret = consumer_.setSocketOption(
- ConsumerCallbacksOptions::READ_CALLBACK, this);
- ASSERT_EQ(ret, SOCKET_OPTION_SET);
-
- consumer_.connect();
- producer_.registerPrefix(producer_prefix_);
- producer_.connect();
- }
-
- virtual void TearDown() override {
- // Code here will be called immediately after each test (right
- // before the destructor).
- }
-
- void setTimer() {
- using namespace std::chrono;
- rtc_timer_.expires_from_now(
- microseconds(unsigned(prod_interval_microseconds)));
- rtc_timer_.async_wait(std::bind(&ConsumerProducerTest::produceRTCPacket,
- this, std::placeholders::_1));
- }
-
- void produceRTCPacket(const std::error_code &ec) {
- if (ec) {
- FAIL() << "Failed to schedule packet production";
- io_service_.stop();
- }
-
- producer_.produceDatagram(consumer_name_, payload_, payload_size);
- packets_sent_++;
- setTimer();
- }
-
- // Consumer callback
- bool isBufferMovable() noexcept override { return false; }
-
- void getReadBuffer(uint8_t **application_buffer,
- size_t *max_length) override {
- *application_buffer = receive_buffer_;
- *max_length = receive_buffer_size;
- }
-
- void readDataAvailable(std::size_t length) noexcept override {}
-
- size_t maxBufferSize() const override { return receive_buffer_size; }
-
- void readError(const std::error_code ec) noexcept override {
- FAIL() << "Error while reading from RTC socket";
- io_service_.stop();
- }
-
- void readSuccess(std::size_t total_size) noexcept override {
- packets_received_++;
- }
-
- asio::io_service io_service_;
- asio::steady_timer rtc_timer_;
- ConsumerSocket consumer_;
- ProducerSocket producer_;
- core::Prefix producer_prefix_;
- core::Name consumer_name_;
- uint8_t payload_[payload_size];
- uint8_t receive_buffer_[payload_size];
-
- uint64_t packets_sent_;
- uint64_t packets_received_;
-};
-
-const char ConsumerProducerTest::prefix[];
-const char ConsumerProducerTest::name[];
-
-} // namespace
-
-TEST_F(ConsumerProducerTest, EndToEnd) {
- produceRTCPacket(std::error_code());
- consumer_.consume(consumer_name_);
-
- io_service_.run();
-}
-
-} // namespace interface
-
-} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-} \ No newline at end of file
diff --git a/libtransport/src/test/fec_rely.cc b/libtransport/src/test/fec_rely.cc
deleted file mode 100644
index e7745bae5..000000000
--- a/libtransport/src/test/fec_rely.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2021 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-#include <hicn/transport/interfaces/socket_consumer.h>
-#include <hicn/transport/interfaces/socket_options_keys.h>
-#include <hicn/transport/interfaces/socket_producer.h>
-#include <hicn/transport/interfaces/global_conf_interface.h>
-
-#include <asio/io_service.hpp>
-#include <asio/steady_timer.hpp>
-
-#include <rely/encoder.hpp>
-#include <rely/decoder.hpp>
-
-namespace transport {
-namespace interface {
-
-namespace {
-
-class ConsumerProducerTest : public ::testing::Test,
- public ConsumerSocket::ReadCallback {
- static const constexpr char prefix[] = "b001::1/128";
- static const constexpr char name[] = "b001::1";
- static const constexpr double prod_rate = 1.0e6;
- static const constexpr size_t payload_size = 1200;
- static constexpr std::size_t receive_buffer_size = 1500;
- static const constexpr double prod_interval_microseconds =
- double(payload_size) * 8 * 1e6 / prod_rate;
-
- public:
- ConsumerProducerTest()
- : io_service_(),
- rtc_timer_(io_service_),
- consumer_(TransportProtocolAlgorithms::RTC, io_service_),
- producer_(ProductionProtocolAlgorithms::RTC_PROD, io_service_),
- producer_prefix_(prefix),
- consumer_name_(name),
- packets_sent_(0),
- packets_received_(0) {
- global_config::IoModuleConfiguration config;
- config.name = "loopback_module";
- config.set();
- }
-
- virtual ~ConsumerProducerTest() {
- // You can do clean-up work that doesn't throw exceptions here.
- }
-
- // If the constructor and destructor are not enough for setting up
- // and cleaning up each test, you can define the following methods:
-
- virtual void SetUp() override {
- // Code here will be called immediately after the constructor (right
- // before each test).
-
- auto ret = consumer_.setSocketOption(
- ConsumerCallbacksOptions::READ_CALLBACK, this);
- ASSERT_EQ(ret, SOCKET_OPTION_SET);
-
- consumer_.connect();
- producer_.registerPrefix(producer_prefix_);
- producer_.connect();
- }
-
- virtual void TearDown() override {
- // Code here will be called immediately after each test (right
- // before the destructor).
- }
-
- void setTimer() {
- using namespace std::chrono;
- rtc_timer_.expires_from_now(
- microseconds(unsigned(prod_interval_microseconds)));
- rtc_timer_.async_wait(std::bind(&ConsumerProducerTest::produceRTCPacket,
- this, std::placeholders::_1));
- }
-
- void produceRTCPacket(const std::error_code &ec) {
- if (ec) {
- FAIL() << "Failed to schedule packet production";
- io_service_.stop();
- }
-
- producer_.produceDatagram(consumer_name_, payload_, payload_size);
- packets_sent_++;
- setTimer();
- }
-
- // Consumer callback
- bool isBufferMovable() noexcept override { return false; }
-
- void getReadBuffer(uint8_t **application_buffer,
- size_t *max_length) override {
- *application_buffer = receive_buffer_;
- *max_length = receive_buffer_size;
- }
-
- void readDataAvailable(std::size_t length) noexcept override {}
-
- size_t maxBufferSize() const override { return receive_buffer_size; }
-
- void readError(const std::error_code ec) noexcept override {
- FAIL() << "Error while reading from RTC socket";
- io_service_.stop();
- }
-
- void readSuccess(std::size_t total_size) noexcept override {
- packets_received_++;
- }
-
- asio::io_service io_service_;
- asio::steady_timer rtc_timer_;
- ConsumerSocket consumer_;
- ProducerSocket producer_;
- core::Prefix producer_prefix_;
- core::Name consumer_name_;
- uint8_t payload_[payload_size];
- uint8_t receive_buffer_[payload_size];
-
- uint64_t packets_sent_;
- uint64_t packets_received_;
-};
-
-const char ConsumerProducerTest::prefix[];
-const char ConsumerProducerTest::name[];
-
-} // namespace
-
-TEST_F(ConsumerProducerTest, EndToEnd) {
- produceRTCPacket(std::error_code());
- consumer_.consume(consumer_name_);
-
- io_service_.run();
-}
-
-} // namespace interface
-
-} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-} \ No newline at end of file
diff --git a/libtransport/src/test/main.cc b/libtransport/src/test/main.cc
new file mode 100644
index 000000000..a4d7ce1b3
--- /dev/null
+++ b/libtransport/src/test/main.cc
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+ srand(time(0));
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+} \ No newline at end of file
diff --git a/libtransport/src/test/test_auth.cc b/libtransport/src/test/test_auth.cc
index 976981cce..db1c3b52f 100644
--- a/libtransport/src/test/test_auth.cc
+++ b/libtransport/src/test/test_auth.cc
@@ -14,7 +14,7 @@
*/
#include <gtest/gtest.h>
-#include <hicn/transport/auth/crypto_hash_type.h>
+#include <hicn/transport/auth/crypto_hash.h>
#include <hicn/transport/auth/identity.h>
#include <hicn/transport/auth/signer.h>
#include <hicn/transport/auth/verifier.h>
@@ -45,14 +45,15 @@ TEST_F(AuthTest, VoidVerifier) {
// Verify that VoidVerifier validates the packet
std::shared_ptr<Verifier> verifier = std::make_shared<VoidVerifier>();
- ASSERT_EQ(verifier->verifyPacket(&packet), true);
- ASSERT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+ EXPECT_EQ(verifier->verifyPacket(&packet), true);
+ EXPECT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
}
-TEST_F(AuthTest, RSAVerifier) {
+TEST_F(AuthTest, AsymmetricRSA) {
// Create the RSA signer from an Identity object
Identity identity("test_rsa.p12", PASSPHRASE, CryptoSuite::RSA_SHA256, 1024u,
30, "RSAVerifier");
+
std::shared_ptr<Signer> signer = identity.getSigner();
// Create a content object
@@ -66,21 +67,125 @@ TEST_F(AuthTest, RSAVerifier) {
signer->signPacket(&packet);
// Create the RSA verifier
- PARCKey *key = parcSigner_CreatePublicKey(signer->getParcSigner());
std::shared_ptr<Verifier> verifier =
- std::make_shared<AsymmetricVerifier>(key);
+ std::make_shared<AsymmetricVerifier>(identity.getCertificate());
+
+ EXPECT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
+ EXPECT_EQ(signer->getHashType(), CryptoHashType::SHA256);
+ EXPECT_EQ(signer->getSuite(), CryptoSuite::RSA_SHA256);
+ EXPECT_EQ(signer->getSignatureSize(), 128u);
+ EXPECT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+}
+
+TEST_F(AuthTest, AsymmetricBufferRSA) {
+ // Create the RSA signer from an Identity object
+ Identity identity("test_rsa.p12", PASSPHRASE, CryptoSuite::RSA_SHA256, 1024u,
+ 30, "RSAVerifier");
+
+ std::shared_ptr<AsymmetricSigner> signer = identity.getSigner();
+ std::string payload = "bonjour";
- ASSERT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
- ASSERT_EQ(signer->getCryptoHashType(), CryptoHashType::SHA_256);
- ASSERT_EQ(signer->getCryptoSuite(), CryptoSuite::RSA_SHA256);
- ASSERT_EQ(signer->getSignatureSize(), 128u);
- ASSERT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+ std::vector<uint8_t> buffer(payload.begin(), payload.end());
+ signer->signBuffer(buffer);
+ std::vector<uint8_t> sig = signer->getSignature();
- // Release PARC objects
- parcKey_Release(&key);
+ std::shared_ptr<X509> cert = identity.getCertificate();
+ AsymmetricVerifier verif(cert);
+ bool res = verif.verifyBuffer(
+ buffer, std::vector<uint8_t>(sig.data(), sig.data() + sig.size()),
+ CryptoHashType::SHA256);
+ EXPECT_EQ(res, true);
}
-TEST_F(AuthTest, HMACVerifier) {
+TEST_F(AuthTest, AsymmetricBufferDSA) {
+ // Create the DSA signer from an Identity object
+ Identity identity("test_dsa.p12", PASSPHRASE, CryptoSuite::DSA_SHA256, 1024u,
+ 30, "DSAVerifier");
+
+ std::shared_ptr<AsymmetricSigner> signer = identity.getSigner();
+ std::string payload = "bonjour";
+
+ std::vector<uint8_t> buffer(payload.begin(), payload.end());
+ signer->signBuffer(buffer);
+ std::vector<uint8_t> sig = signer->getSignature();
+
+ std::shared_ptr<X509> cert = identity.getCertificate();
+ AsymmetricVerifier verif(cert);
+ bool res = verif.verifyBuffer(
+ buffer, std::vector<uint8_t>(sig.data(), sig.data() + sig.size()),
+ CryptoHashType::SHA256);
+ EXPECT_EQ(res, true);
+}
+
+TEST_F(AuthTest, AsymmetricVerifierDSA) {
+ // Create the DSA signer from an Identity object
+ Identity identity("test_dsa.p12", PASSPHRASE, CryptoSuite::DSA_SHA256, 1024u,
+ 30, "DSAVerifier");
+
+ std::shared_ptr<Signer> signer = identity.getSigner();
+
+ // Create a content object
+ core::ContentObject packet(HF_INET6_TCP_AH, signer->getSignatureSize());
+
+ // Fill it with bogus data
+ uint8_t buffer[256] = {0};
+ packet.appendPayload(buffer, 256);
+ // this test has to be done before the signature is compute
+ // EXPECT_EQ(signer->getSignatureSize(), 256u);
+ signer->signPacket(&packet);
+ std::shared_ptr<Verifier> verifier =
+ std::make_shared<AsymmetricVerifier>(identity.getCertificate());
+
+ EXPECT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
+ EXPECT_EQ(signer->getHashType(), CryptoHashType::SHA256);
+ EXPECT_EQ(signer->getSuite(), CryptoSuite::DSA_SHA256);
+ EXPECT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+}
+
+TEST_F(AuthTest, AsymmetricBufferECDSA) {
+ // Create the ECDSA signer from an Identity object
+ Identity identity("test_ecdsa.p12", PASSPHRASE, CryptoSuite::ECDSA_SHA256,
+ 256u, 30, "ECDSAVerifier");
+
+ std::shared_ptr<AsymmetricSigner> signer = identity.getSigner();
+ std::string payload = "bonjour";
+
+ std::vector<uint8_t> buffer(payload.begin(), payload.end());
+ signer->signBuffer(buffer);
+ std::vector<uint8_t> sig = signer->getSignature();
+
+ std::shared_ptr<X509> cert = identity.getCertificate();
+ AsymmetricVerifier verif(cert);
+ bool res = verif.verifyBuffer(
+ buffer, std::vector<uint8_t>(sig.data(), sig.data() + sig.size()),
+ CryptoHashType::SHA256);
+ EXPECT_EQ(res, true);
+}
+
+TEST_F(AuthTest, AsymmetricVerifierECDSA) {
+ Identity identity("test_ecdsa.p12", PASSPHRASE, CryptoSuite::ECDSA_SHA256,
+ 256u, 30, "ECDSAVerifier");
+
+ std::shared_ptr<Signer> signer = identity.getSigner();
+ std::shared_ptr<Verifier> verifier =
+ std::make_shared<AsymmetricVerifier>(identity.getCertificate());
+ // Create a content object
+ for (int i = 0; i < 100; i++) {
+ core::ContentObject packet(HF_INET6_TCP_AH, signer->getSignatureSize());
+
+ // Fill it with bogus data
+ uint8_t buffer[256] = {0};
+ packet.appendPayload(buffer, 256);
+ signer->signPacket(&packet);
+
+ EXPECT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
+ EXPECT_EQ(signer->getHashType(), CryptoHashType::SHA256);
+ EXPECT_EQ(signer->getSuite(), CryptoSuite::ECDSA_SHA256);
+ EXPECT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+ }
+}
+
+TEST_F(AuthTest, HMACbuffer) {
// Create the HMAC signer from a passphrase
std::shared_ptr<Signer> signer =
std::make_shared<SymmetricSigner>(CryptoSuite::HMAC_SHA256, PASSPHRASE);
@@ -88,6 +193,25 @@ TEST_F(AuthTest, HMACVerifier) {
// Create a content object
core::ContentObject packet(HF_INET6_TCP_AH, signer->getSignatureSize());
+ std::string payload = "bonjour";
+ std::vector<uint8_t> buffer(payload.begin(), payload.end());
+ signer->signBuffer(buffer);
+ std::vector<uint8_t> sig = signer->getSignature();
+ SymmetricVerifier hmac(PASSPHRASE);
+ bool res = hmac.verifyBuffer(
+ buffer, std::vector<uint8_t>(sig.data(), sig.data() + sig.size()),
+ CryptoHashType::SHA256);
+ EXPECT_EQ(res, true);
+}
+
+TEST_F(AuthTest, HMACVerifier) {
+ // Create the HMAC signer from a passphrase
+ std::shared_ptr<SymmetricSigner> signer =
+ std::make_shared<SymmetricSigner>(CryptoSuite::HMAC_SHA256, PASSPHRASE);
+
+ // Create a content object
+ core::ContentObject packet(HF_INET6_TCP_AH, signer->getSignatureSize());
+
// Fill it with bogus data
uint8_t buffer[256] = {0};
packet.appendPayload(buffer, 256);
@@ -99,11 +223,11 @@ TEST_F(AuthTest, HMACVerifier) {
std::shared_ptr<Verifier> verifier =
std::make_shared<SymmetricVerifier>(PASSPHRASE);
- ASSERT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
- ASSERT_EQ(signer->getCryptoHashType(), CryptoHashType::SHA_256);
- ASSERT_EQ(signer->getCryptoSuite(), CryptoSuite::HMAC_SHA256);
- ASSERT_EQ(signer->getSignatureSize(), 32u);
- ASSERT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
+ EXPECT_EQ(packet.getFormat(), HF_INET6_TCP_AH);
+ EXPECT_EQ(signer->getHashType(), CryptoHashType::SHA256);
+ EXPECT_EQ(signer->getSuite(), CryptoSuite::HMAC_SHA256);
+ EXPECT_EQ(signer->getSignatureSize(), 32u);
+ EXPECT_EQ(verifier->verifyPackets(&packet), VerificationPolicy::ACCEPT);
}
} // namespace auth
diff --git a/libtransport/src/test/test_consumer_producer_rtc.cc b/libtransport/src/test/test_consumer_producer_rtc.cc
index 87385971a..8541a9e1a 100644
--- a/libtransport/src/test/test_consumer_producer_rtc.cc
+++ b/libtransport/src/test/test_consumer_producer_rtc.cc
@@ -14,14 +14,12 @@
*/
#include <gtest/gtest.h>
+#include <hicn/transport/core/asio_wrapper.h>
#include <hicn/transport/interfaces/global_conf_interface.h>
#include <hicn/transport/interfaces/socket_consumer.h>
#include <hicn/transport/interfaces/socket_options_keys.h>
#include <hicn/transport/interfaces/socket_producer.h>
-#include <asio/io_service.hpp>
-#include <asio/steady_timer.hpp>
-
namespace transport {
namespace interface {
@@ -151,7 +149,7 @@ const char ConsumerProducerTest::name[];
} // namespace
-TEST_F(ConsumerProducerTest, EndToEnd) {
+TEST_F(ConsumerProducerTest, DISABLED_EndToEnd) {
produceRTCPacket(std::error_code());
consumer_.consume(consumer_name_);
setStopTimer();
@@ -165,12 +163,3 @@ TEST_F(ConsumerProducerTest, EndToEnd) {
} // namespace interface
} // namespace transport
-
-int main(int argc, char **argv) {
-#if 0
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-#else
- return 0;
-#endif
-} \ No newline at end of file
diff --git a/libtransport/src/test/test_core_manifest.cc b/libtransport/src/test/test_core_manifest.cc
index f98147d43..93f4e87cb 100644
--- a/libtransport/src/test/test_core_manifest.cc
+++ b/libtransport/src/test/test_core_manifest.cc
@@ -16,7 +16,7 @@
#include <core/manifest_format_fixed.h>
#include <core/manifest_inline.h>
#include <gtest/gtest.h>
-#include <hicn/transport/auth/crypto_hash_type.h>
+#include <hicn/transport/auth/crypto_hash.h>
#include <test/packet_samples.h>
#include <climits>
@@ -124,9 +124,9 @@ TEST_F(ManifestTest, SetManifestType) {
TEST_F(ManifestTest, SetHashAlgorithm) {
manifest1_.clear();
- auth::CryptoHashType hash1 = auth::CryptoHashType::SHA_512;
- auth::CryptoHashType hash2 = auth::CryptoHashType::CRC32C;
- auth::CryptoHashType hash3 = auth::CryptoHashType::SHA_256;
+ auth::CryptoHashType hash1 = auth::CryptoHashType::SHA512;
+ auth::CryptoHashType hash2 = auth::CryptoHashType::BLAKE2B512;
+ auth::CryptoHashType hash3 = auth::CryptoHashType::SHA256;
manifest1_.setHashAlgorithm(hash1);
auto type_returned1 = manifest1_.getHashAlgorithm();
@@ -191,9 +191,9 @@ TEST_F(ManifestTest, SetSuffixList) {
data[i].resize(32);
std::generate(std::begin(data[i]), std::end(data[i]), std::ref(rbe));
suffixes[i] = idis(eng);
- entries[i] = std::make_pair(
- suffixes[i], auth::CryptoHash(data[i].data(), data[i].size(),
- auth::CryptoHashType::SHA_256));
+ entries[i] = std::make_pair(suffixes[i],
+ auth::CryptoHash(data[i].data(), data[i].size(),
+ auth::CryptoHashType::SHA256));
manifest1_.addSuffixHash(entries[i].first, entries[i].second);
}
@@ -223,8 +223,3 @@ TEST_F(ManifestTest, SetSuffixList) {
} // namespace core
} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/libtransport/src/test/test_event_thread.cc b/libtransport/src/test/test_event_thread.cc
index e66b49f10..549ff9c1a 100644
--- a/libtransport/src/test/test_event_thread.cc
+++ b/libtransport/src/test/test_event_thread.cc
@@ -71,7 +71,7 @@ double stdDeviation(const unsigned long samples[], int size) {
} // namespace
-TEST_F(EventThreadTest, SchedulingDelay) {
+TEST_F(EventThreadTest, DISABLED_SchedulingDelay) {
using namespace std::chrono;
const size_t size = 1000000;
std::vector<unsigned long> samples(size);
@@ -95,12 +95,3 @@ TEST_F(EventThreadTest, SchedulingDelay) {
}
} // namespace utils
-
-int main(int argc, char **argv) {
-#if 0
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-#else
- return 0;
-#endif
-} \ No newline at end of file
diff --git a/libtransport/src/test/test_fec_reedsolomon.cc b/libtransport/src/test/test_fec_reedsolomon.cc
index 3b10b7307..c7e10d111 100644
--- a/libtransport/src/test/test_fec_reedsolomon.cc
+++ b/libtransport/src/test/test_fec_reedsolomon.cc
@@ -14,21 +14,21 @@
* limitations under the License.
*/
-#include <core/rs.h>
#include <gtest/gtest.h>
#include <hicn/transport/core/content_object.h>
#include <hicn/transport/core/global_object_pool.h>
+#include <protocols/fec/rs.h>
#include <algorithm>
#include <iostream>
#include <random>
namespace transport {
-namespace core {
+namespace protocol {
-double ReedSolomonTest(int k, int n, int size) {
- fec::encoder encoder(k, n);
- fec::decoder decoder(k, n);
+double ReedSolomonTest(int k, int n, int seq_offset, int size) {
+ fec::RSEncoder encoder(k, n, seq_offset);
+ fec::RSDecoder decoder(k, n, seq_offset);
std::vector<fec::buffer> tx_block(k);
std::vector<fec::buffer> rx_block(k);
@@ -36,27 +36,31 @@ double ReedSolomonTest(int k, int n, int size) {
int run = 0;
int iterations = 100;
- auto &packet_manager = PacketManager<>::getInstance();
-
- encoder.setFECCallback([&tx_block](std::vector<fec::buffer> &repair_packets) {
- for (auto &p : repair_packets) {
- // Append repair symbols to tx_block
- tx_block.emplace_back(std::move(p));
- }
- });
+ auto &packet_manager = core::PacketManager<>::getInstance();
+
+ encoder.setFECCallback(
+ [&tx_block](
+ std::vector<std::pair<uint32_t, fec::buffer>> &repair_packets) {
+ for (auto &p : repair_packets) {
+ // Append repair symbols to tx_block
+ tx_block.emplace_back(std::move(p).second);
+ }
+ });
- decoder.setFECCallback([&](std::vector<fec::buffer> &source_packets) {
- for (int i = 0; i < k; i++) {
- // Compare decoded source packets with original transmitted packets.
- if (*tx_block[i] != *source_packets[i]) {
- count++;
- }
- }
- });
+ decoder.setFECCallback(
+ [&](std::vector<std::pair<uint32_t, fec::buffer>> &source_packets) {
+ for (int i = 0; i < k; i++) {
+ // Compare decoded source packets with original transmitted packets.
+ if (*tx_block[i] != *source_packets[i].second) {
+ count++;
+ }
+ }
+ });
do {
// Discard eventual packet appended in previous callback call
tx_block.erase(tx_block.begin() + k, tx_block.end());
+ auto _seq_offet = seq_offset;
// Initialization. Feed encoder with first k source packets
for (int i = 0; i < k; i++) {
@@ -74,8 +78,8 @@ double ReedSolomonTest(int k, int n, int size) {
std::generate(packet->writableData(), packet->writableTail(), rand);
std::fill(packet->writableData(), packet->writableTail(), i + 1);
- // Set first byte of payload to i, to reorder at receiver side
- packet->writableData()[0] = uint8_t(i);
+ // Set first byte of payload to seq_offset, to reorder at receiver side
+ packet->writableData()[0] = uint8_t(_seq_offet++);
// Store packet in tx buffer and clear rx buffer
tx_block[i] = std::move(packet);
@@ -99,10 +103,11 @@ double ReedSolomonTest(int k, int n, int size) {
rx_block[rxi++] = tx_block[i];
if (i < k) {
// Source packet
- decoder.consume(rx_block[rxi - 1], rx_block[rxi - 1]->data()[0]);
+ decoder.consumeSource(rx_block[rxi - 1],
+ rx_block[rxi - 1]->data()[0]);
} else {
// Repair packet
- decoder.consume(rx_block[rxi - 1]);
+ decoder.consumeRepair(rx_block[rxi - 1]);
}
}
@@ -118,10 +123,10 @@ void ReedSolomonMultiBlockTest(int n_sourceblocks) {
int n = 24;
int size = 1000;
- fec::encoder encoder(k, n);
- fec::decoder decoder(k, n);
+ fec::RSEncoder encoder(k, n);
+ fec::RSDecoder decoder(k, n);
- auto &packet_manager = PacketManager<>::getInstance();
+ auto &packet_manager = core::PacketManager<>::getInstance();
std::vector<std::pair<fec::buffer, uint32_t>> tx_block;
std::vector<std::pair<fec::buffer, uint32_t>> rx_block;
@@ -133,28 +138,31 @@ void ReedSolomonMultiBlockTest(int n_sourceblocks) {
int tx_packets = k * n_sourceblocks;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
- encoder.setFECCallback([&](std::vector<fec::buffer> &repair_packets) {
- for (auto &p : repair_packets) {
- // Append repair symbols to tx_block
- tx_block.emplace_back(std::move(p), ++i);
- }
+ encoder.setFECCallback(
+ [&](std::vector<std::pair<uint32_t, fec::buffer>> &repair_packets) {
+ for (auto &p : repair_packets) {
+ // Append repair symbols to tx_block
+ tx_block.emplace_back(std::move(p.second), ++i);
+ }
- EXPECT_EQ(tx_block.size(), size_t(n));
+ EXPECT_EQ(tx_block.size(), size_t(n));
- // Select k packets to send, including at least one symbol. We start from
- // the end for this reason.
- for (int j = n - 1; j > n - k - 1; j--) {
- rx_block.emplace_back(std::move(tx_block[j]));
- }
+ // Select k packets to send, including at least one symbol. We start
+ // from the end for this reason.
+ for (int j = n - 1; j > n - k - 1; j--) {
+ rx_block.emplace_back(std::move(tx_block[j]));
+ }
- // Clear tx block for next source block
- tx_block.clear();
- encoder.clear();
- });
+ // Clear tx block for next source block
+ tx_block.clear();
+ encoder.clear();
+ });
// The decode callback must be called exactly n_sourceblocks times
decoder.setFECCallback(
- [&](std::vector<fec::buffer> &source_packets) { count++; });
+ [&](std::vector<std::pair<uint32_t, fec::buffer>> &source_packets) {
+ count++;
+ });
// Produce n * n_sourceblocks
// - ( k ) * n_sourceblocks source packets
@@ -194,10 +202,10 @@ void ReedSolomonMultiBlockTest(int n_sourceblocks) {
int index = p.second % n;
if (index < k) {
// Source packet
- decoder.consume(p.first, p.second);
+ decoder.consumeSource(p.first, p.second);
} else {
// Repair packet
- decoder.consume(p.first);
+ decoder.consumeRepair(p.first);
}
}
@@ -205,66 +213,22 @@ void ReedSolomonMultiBlockTest(int n_sourceblocks) {
EXPECT_EQ(count, n_sourceblocks);
}
-TEST(ReedSolomonTest, RSk1n3) {
- int k = 1;
- int n = 3;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk6n10) {
- int k = 6;
- int n = 10;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk8n32) {
- int k = 8;
- int n = 32;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk16n24) {
- int k = 16;
- int n = 24;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk10n30) {
- int k = 10;
- int n = 30;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk10n40) {
- int k = 10;
- int n = 40;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk10n60) {
- int k = 10;
- int n = 60;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonTest, RSk10n90) {
- int k = 10;
- int n = 90;
- int size = 1000;
- EXPECT_LE(ReedSolomonTest(k, n, size), 0);
-}
-
-TEST(ReedSolomonMultiBlockTest, RSMB1) {
- int blocks = 1;
- ReedSolomonMultiBlockTest(blocks);
-}
+/**
+ * @brief Use foreach_rs_fec_type to automatically generate the code of the
+ * tests and avoid copy/paste the same function.
+ */
+#define _(name, k, n) \
+ TEST(ReedSolomonTest, RSK##k##N##n) { \
+ int K = k; \
+ int N = n; \
+ int seq_offset = 0; \
+ int size = 1000; \
+ EXPECT_LE(ReedSolomonTest(K, N, seq_offset, size), 0); \
+ seq_offset = 12345; \
+ EXPECT_LE(ReedSolomonTest(K, N, seq_offset, size), 0); \
+ }
+foreach_rs_fec_type
+#undef _
TEST(ReedSolomonMultiBlockTest, RSMB10) {
int blocks = 10;
@@ -281,11 +245,5 @@ TEST(ReedSolomonMultiBlockTest, RSMB1000) {
ReedSolomonMultiBlockTest(blocks);
}
-int main(int argc, char **argv) {
- srand(time(0));
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
-
-} // namespace core
+} // namespace protocol
} // namespace transport
diff --git a/libtransport/src/test/test_fec_rely_wrapper.cc b/libtransport/src/test/test_fec_rely_wrapper.cc
new file mode 100644
index 000000000..c5b73f8d2
--- /dev/null
+++ b/libtransport/src/test/test_fec_rely_wrapper.cc
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <hicn/transport/core/global_object_pool.h>
+#include <hicn/transport/utils/log.h>
+#include <protocols/fec/rely.h>
+
+#include <queue>
+
+namespace transport {
+namespace protocol {
+
+std::string printMissing(
+ const std::map<uint32_t, core::ContentObject::Ptr> &missing) {
+ std::stringstream stream;
+
+ for (auto &[seq, packet] : missing) {
+ stream << " " << seq;
+ }
+
+ stream << "\n";
+
+ return stream.str();
+}
+
+/**
+ * @brief Test encode-decode operations performed using the wrapper for rely
+ *
+ * @param k Number of source symbols
+ * @param n Sum of source symbols and repair symbols
+ * @param max_packet_size The max packet size the decoder will expect.
+ * @param timeout The timeout used by rely
+ * https://rely.steinwurf.com/docs/6.1.0/design/timeout_configuration.html
+ * @param max_iterations The number of packets to send
+ * @param loss_rate The loss rate
+ */
+void testRelyEncoderDecoder(uint32_t k, uint32_t n, size_t max_packet_size,
+ int64_t timeout, uint32_t max_iterations,
+ int loss_rate) {
+ // Create 1 encoder and 1 decoder
+ fec::RelyEncoder _encoder(k, n);
+ fec::RelyDecoder _decoder(k, n);
+
+ // Seed the pseudo-random with known value to always get same loss pattern
+ srand(k * n);
+
+ // We will interact with rely encoder/decoder using the interface
+ fec::ProducerFEC &encoder = _encoder;
+ fec::ConsumerFEC &decoder = _decoder;
+
+ // Initialize current iteration
+ uint32_t iterations = 0;
+
+ // Packet allocator
+ auto &packet_manager = core::PacketManager<>::getInstance();
+
+ // Store packets to verify them in the decoder callback
+ std::map<uint32_t, core::ContentObject::Ptr> saved_packets;
+
+ // Save repair packets here in encoder callback
+ std::queue<fec::buffer> pending_repair_packets;
+
+ // Set callback called by encoder when a buffer is required.
+ encoder.setBufferCallback([](std::size_t size) -> fec::buffer {
+ auto ret =
+ core::PacketManager<>::getInstance().getPacket<core::ContentObject>();
+ ret->updateLength(size);
+ ret->append(size);
+ ret->trimStart(ret->headerSize());
+ assert(ret->length() >= size);
+
+ return ret;
+ });
+
+ // Set callback to be called by encoder when repair packets are ready
+ encoder.setFECCallback(
+ [&](std::vector<std::pair<uint32_t, fec::buffer>> &packets) {
+ // We must get n - k symbols
+ EXPECT_EQ(packets.size(), n - k);
+ // TRANSPORT_LOGD("Got %zu symbols", packets.size());
+
+ // Save symbols in pending_repair_packets queue and increment iterations
+ for (auto &packet : packets) {
+ ++iterations;
+ pending_repair_packets.push(packet.second);
+ }
+ });
+
+ // Set callback to be called when decoder recover a packet
+ decoder.setFECCallback(
+ [&](std::vector<std::pair<uint32_t, fec::buffer>> &packets) {
+ for (auto &packet : packets) {
+ // TRANSPORT_LOGD("Recovering packet %u", packet.first);
+
+ // Ensure recovered packet is in packets actually produced by encoder
+ auto original = saved_packets.find(packet.first);
+ ASSERT_TRUE(original != saved_packets.end());
+ auto &original_packet = *original->second;
+
+ // Remove additional headers at the beginning of the packet. This may
+ // change in the future.
+ original_packet.trimStart(60 /* Ip + TCP */ + 28 /* Rely header */ +
+ 4 /* Packet size */);
+
+ // Recovered packet should be equal to the original one
+ EXPECT_TRUE(original_packet == *packet.second);
+
+ // Restore removed headers
+ original_packet.prepend(60 + 28 + 4);
+
+ // Erase packet from saved packet list
+ saved_packets.erase(original);
+ }
+ });
+
+ // Send max_iterations packets from encoder to decoder
+ while (iterations < max_iterations) {
+ // Create a payload, the size is between 50 and 1350 bytes.
+ auto payload_size = 50 + (rand() % 1300);
+ uint8_t payload[max_packet_size];
+ std::generate(payload, payload + payload_size, rand);
+
+ // Get a packet from global pool and set name
+ auto buffer = packet_manager.getPacket<core::ContentObject>();
+ buffer->setName(core::Name("b001::abcd", iterations));
+
+ // Get offset
+ auto offset = buffer->headerSize();
+
+ // Copy payload into packet. We keep the payload to compare returned packet
+ // with original one (since rely encoder does modify the packet by adding
+ // its own header).
+ buffer->appendPayload(payload, payload_size);
+
+ // Save packet in the saving_packets list
+ // TRANSPORT_LOGD("Saving packet with index %lu", iterations);
+ saved_packets.emplace(iterations, buffer);
+
+ // Feed buffer into the encoder. This will eventually trigger a call to the
+ // FEC callback as soon as k packets are fed into the endocer.
+ encoder.onPacketProduced(*buffer, offset);
+
+ // Check returned packet. We calculate the difference in size and we compare
+ // only the part of the returned packet corresponding to the original
+ // payload. Rely should only add a header and should not modify the actual
+ // payload content. If it does it, this check will fail.
+ auto diff = buffer->length() - payload_size - offset;
+ // TRANSPORT_LOGD("Difference is %zu", diff);
+ auto cmp =
+ std::memcmp(buffer->data() + offset + diff, payload, payload_size);
+ EXPECT_FALSE(cmp);
+
+ // Drop condition. Id addition to the loss rate, we ensure that no drops are
+ // perfomed in the last 10% of the total iterations. This is done because
+ // rely uses a sliding-window mechanism to recover, and if we suddenly stop
+ // we may not be able to recover missing packets that would be recovered
+ // using future packets that are not created in the test. For this reason,
+ // we ensure the test ends without losses.
+#define DROP_CONDITION(loss_rate, max_iterations) \
+ (rand() % 100) >= loss_rate || iterations >= max_iterations * 0.9
+
+ // Handle the source packet to the decoder, id drop condition returns true
+ if (DROP_CONDITION(loss_rate, max_iterations)) {
+ // Pass packet to decoder
+ // TRANSPORT_LOGD("Passing packet %u to decoder",
+ // buffer->getName().getSuffix());
+ decoder.onDataPacket(*buffer, offset);
+ } else {
+ // TRANSPORT_LOGD("Packet %u, dropped", buffer->getName().getSuffix());
+ }
+
+ // Check if previous call to encoder.consumer() generated repair packets,
+ // and if yes, feed them to the decoder.
+ while (pending_repair_packets.size()) {
+ // Also repair packets can be lost
+ if (DROP_CONDITION(loss_rate, max_iterations)) {
+ auto &packet = pending_repair_packets.front();
+ // TRANSPORT_LOGD("Passing packet %u to decoder", iterations);
+ core::ContentObject &co = (core::ContentObject &)(*packet);
+ decoder.onDataPacket(co, 0);
+ } else {
+ // TRANSPORT_LOGD("Packet (repair) %u dropped", iterations);
+ }
+
+ // Remove packet from the queue
+ pending_repair_packets.pop();
+ }
+
+ ++iterations;
+ }
+
+ // We expect this test to terminate with a full recover of all the packets and
+ // 0.001 residual losses
+ EXPECT_LE(saved_packets.size(), iterations * 0.001)
+ << printMissing(saved_packets);
+
+ // Reset seed
+ srand(time(0));
+}
+
+/**
+ * @brief Use foreach_rely_fec_type to automatically generate the code of the
+ * tests and avoid copy/paste the same function.
+ */
+#define _(name, k, n) \
+ TEST(RelyTest, RelyK##k##N##n) { \
+ int K = k; \
+ int N = n; \
+ uint32_t max_iterations = 1000; \
+ int size = 1400; \
+ int64_t timeout = 120; \
+ int loss_rate = 10; \
+ testRelyEncoderDecoder(K, N, size, timeout, max_iterations, loss_rate); \
+ }
+foreach_rely_fec_type
+#undef _
+
+} // namespace protocol
+} // namespace transport
diff --git a/libtransport/src/test/test_indexer.cc b/libtransport/src/test/test_indexer.cc
new file mode 100644
index 000000000..9c12e2037
--- /dev/null
+++ b/libtransport/src/test/test_indexer.cc
@@ -0,0 +1,322 @@
+
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <protocols/incremental_indexer_bytestream.h>
+#include <protocols/indexer.h>
+#include <protocols/rtc/rtc_indexer.h>
+
+#include <algorithm>
+#include <iostream>
+#include <random>
+
+namespace transport {
+namespace protocol {
+
+class IncrementalIndexerTest : public ::testing::Test {
+ protected:
+ IncrementalIndexerTest() : indexer_(nullptr, nullptr) {
+ // You can do set-up work for each test here.
+ }
+
+ virtual ~IncrementalIndexerTest() {
+ // You can do clean-up work that doesn't throw exceptions here.
+ }
+
+ // If the constructor and destructor are not enough for setting up
+ // and cleaning up each test, you can define the following methods:
+
+ virtual void SetUp() {
+ // Code here will be called immediately after the constructor (right
+ // before each test).
+ }
+
+ virtual void TearDown() {
+ // Code here will be called immediately after each test (right
+ // before the destructor).
+ }
+
+ IncrementalIndexer indexer_;
+};
+
+class RtcIndexerTest : public ::testing::Test {
+ protected:
+ RtcIndexerTest() : indexer_(nullptr, nullptr) {
+ // You can do set-up work for each test here.
+ }
+
+ virtual ~RtcIndexerTest() {
+ // You can do clean-up work that doesn't throw exceptions here.
+ }
+
+ // If the constructor and destructor are not enough for setting up
+ // and cleaning up each test, you can define the following methods:
+
+ virtual void SetUp() {
+ // Code here will be called immediately after the constructor (right
+ // before each test).
+ indexer_.setFirstSuffix(0);
+ indexer_.reset();
+ }
+
+ virtual void TearDown() {
+ // Code here will be called immediately after each test (right
+ // before the destructor).
+ }
+
+ static const constexpr uint32_t LIMIT = (1 << 31);
+ rtc::RtcIndexer<LIMIT> indexer_;
+};
+
+void testIncrement(Indexer &indexer) {
+ // As a first index we should get zero
+ auto index = indexer.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(0));
+
+ // Check if the sequence works for consecutive incremental numbers
+ for (uint32_t i = 1; i < 4096; i++) {
+ index = indexer.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+
+ index = indexer.getNextSuffix();
+ EXPECT_NE(index, uint32_t(0));
+}
+
+void testJump(Indexer &indexer) {
+ // Fist suffix is 0
+ auto index = indexer.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(0));
+
+ // Next suffix should be 1, but we jump to 12345
+ uint32_t jump = 12345;
+ indexer.jumpToIndex(jump);
+
+ // This takes place immediately
+ index = indexer.getNextSuffix();
+ EXPECT_EQ(index, jump);
+}
+
+TEST_F(IncrementalIndexerTest, TestReset) {
+ testIncrement(indexer_);
+
+ // Reset the indexer
+ indexer_.reset();
+
+ // Now it should startfrom zero again
+ for (uint32_t i = 0; i < 4096; i++) {
+ auto index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+}
+
+TEST_F(IncrementalIndexerTest, TestGetSuffix) { testIncrement(indexer_); }
+
+TEST_F(IncrementalIndexerTest, TestGetNextReassemblySegment) {
+ // Test suffixes for reassembly are not influenced by download suffixed
+ // increment
+ for (uint32_t i = 0; i < 4096; i++) {
+ auto index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+
+ for (uint32_t i = 0; i < 4096; i++) {
+ auto index = indexer_.getNextReassemblySegment();
+ EXPECT_EQ(index, i);
+ }
+}
+
+TEST_F(IncrementalIndexerTest, TestJumpToIndex) { testJump(indexer_); }
+
+TEST_F(IncrementalIndexerTest, TestGetFinalSuffix) {
+ // Since final suffix hasn't been discovered, it should be invalid_index
+ auto final_suffix = indexer_.getFinalSuffix();
+ ASSERT_EQ(final_suffix, Indexer::invalid_index);
+}
+
+TEST_F(IncrementalIndexerTest, TestMaxLimit) {
+ // Jump to max value for uint32_t
+ indexer_.jumpToIndex(std::numeric_limits<uint32_t>::max());
+ auto ret = indexer_.getNextSuffix();
+ ASSERT_EQ(ret, Indexer::invalid_index);
+
+ // Now the indexer should always return invalid_index
+ for (uint32_t i = 0; i < 4096; i++) {
+ ret = indexer_.getNextSuffix();
+ EXPECT_EQ(ret, Indexer::invalid_index);
+ }
+}
+
+TEST_F(IncrementalIndexerTest, TestSetFirstSuffix) {
+ // Set first suffix before starting
+ uint32_t start = 1234567890;
+ indexer_.setFirstSuffix(1234567890);
+
+ // The first suffix set should take place only after a reset
+ auto index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(0));
+
+ indexer_.reset();
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, start);
+}
+
+TEST_F(IncrementalIndexerTest, TestIsFinalSuffixDiscovered) {
+ // Final suffix should not be discovererd
+ auto ret = indexer_.isFinalSuffixDiscovered();
+ EXPECT_FALSE(ret);
+}
+
+TEST_F(RtcIndexerTest, TestReset) {
+ // Without setting anything this indexer should behave exactly as the
+ // incremental indexer for the getNextSuffix()
+ testIncrement(indexer_);
+
+ // Reset the indexer
+ indexer_.reset();
+
+ // Now it should startfrom zero again
+ for (uint32_t i = 0; i < 4096; i++) {
+ auto index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+}
+
+TEST_F(RtcIndexerTest, TestGetNextSuffix) {
+ // Without setting anything this indexer should behave exactly as the
+ // incremental indexer for the getNextSuffix()
+ testIncrement(indexer_);
+}
+
+TEST_F(RtcIndexerTest, TestGetNextReassemblySegment) {
+ // This indexer should not provide reassembly segments since they are not
+ // required for rtc
+ try {
+ indexer_.getNextReassemblySegment();
+ // We should not reach this point
+ FAIL() << "Exception expected here";
+ } catch (const errors::RuntimeException &exc) {
+ // OK correct exception
+ } catch (...) {
+ FAIL() << "Wrong exception thrown";
+ }
+}
+
+TEST_F(RtcIndexerTest, TestGetFinalSuffix) {
+ // Final suffix should be eqaul to LIMIT
+ ASSERT_EQ(indexer_.getFinalSuffix(), uint32_t(LIMIT));
+}
+
+TEST_F(RtcIndexerTest, TestJumpToIndex) { testJump(indexer_); }
+
+TEST_F(RtcIndexerTest, TestIsFinalSuffixDiscovered) {
+ // This method should always return true
+ EXPECT_TRUE(indexer_.isFinalSuffixDiscovered());
+}
+
+TEST_F(RtcIndexerTest, TestMaxLimit) {
+ // Once reached the LIMIT, this indexer should restart from 0
+
+ // Jump to max value for uint32_t
+ indexer_.jumpToIndex(LIMIT);
+ testIncrement(indexer_);
+}
+
+TEST_F(RtcIndexerTest, TestEnableFec) {
+ // Here we enable the FEC and we check we receive indexes for souece packets
+ // only
+ indexer_.enableFec(fec::FECType::RS_K1_N3);
+
+ // We did not set NFec, which should be zero. So we get only indexes for
+ // Source packets.
+
+ // With this FEC type we should get one source packet every 3 (0 . . 3 . . 6)
+ auto index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(0));
+
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(3));
+
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(6));
+
+ // Change FEC Type
+ indexer_.enableFec(fec::FECType::RS_K10_N30);
+
+ // With this FEC type we should get source packets from 7 to 9
+ for (uint32_t i = 7; i < 10; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+
+ // And then jump to 30
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, uint32_t(30));
+
+ // Let's now jump to a high value
+ indexer_.jumpToIndex(12365);
+ for (uint32_t i = 12365; i < 12369; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(index, i);
+ }
+}
+
+TEST_F(RtcIndexerTest, TestSetNFec) {
+ // Here we enable the FEC and we set a max of 20 fec packets
+ indexer_.enableFec(fec::FECType::RS_K10_N90);
+ indexer_.setNFec(20);
+
+ // We should get indexes up to 29
+ uint32_t index;
+ for (uint32_t i = 0; i < 30; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(i, index);
+ }
+
+ // Then it should jump to 90
+ for (uint32_t i = 90; i < 99; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_EQ(i, index);
+ }
+
+ // Let's set NFEC > 80
+ indexer_.setNFec(150);
+}
+
+TEST_F(RtcIndexerTest, TestSetNFecWithOffset) {
+ // Here we enable the FEC and we set a max of 20 fec packets
+ const constexpr uint32_t first_suffix = 7;
+ indexer_.setFirstSuffix(first_suffix);
+ indexer_.reset();
+ indexer_.enableFec(fec::FECType::RS_K16_N24);
+ indexer_.setNFec(8);
+
+ uint32_t index;
+ for (uint32_t i = first_suffix; i < 16 + first_suffix; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_FALSE(indexer_.isFec(index));
+ EXPECT_EQ(i, index);
+ }
+
+ for (uint32_t i = first_suffix + 16; i < 16 + 8 + first_suffix; i++) {
+ index = indexer_.getNextSuffix();
+ EXPECT_TRUE(indexer_.isFec(index));
+ EXPECT_EQ(i, index);
+ }
+}
+
+} // namespace protocol
+} // namespace transport
diff --git a/libtransport/src/test/test_interest.cc b/libtransport/src/test/test_interest.cc
index 0a835db24..8853563b0 100644
--- a/libtransport/src/test/test_interest.cc
+++ b/libtransport/src/test/test_interest.cc
@@ -260,8 +260,3 @@ TEST_F(InterestTest, AppendSuffixesEncodeAndIterate) {
} // namespace core
} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-} \ No newline at end of file
diff --git a/libtransport/src/test/test_packet.cc b/libtransport/src/test/test_packet.cc
index 0ee140e2c..76ad352d6 100644
--- a/libtransport/src/test/test_packet.cc
+++ b/libtransport/src/test/test_packet.cc
@@ -47,10 +47,6 @@ class PacketForTest : public Packet {
throw errors::NotImplementedException();
}
- void setName(Name &&name) override {
- throw errors::NotImplementedException();
- }
-
void setLifetime(uint32_t lifetime) override {
throw errors::NotImplementedException();
}
@@ -1040,8 +1036,3 @@ TEST_F(PacketTest, TestSetGetTTL) {
} // namespace core
} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/libtransport/src/test/test_transport_producer.cc b/libtransport/src/test/test_transport_producer.cc
deleted file mode 100644
index f711fb4bb..000000000
--- a/libtransport/src/test/test_transport_producer.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <random>
-
-#include "hicn/transport/interfaces/socket_producer.h"
-
-namespace transport {
-
-namespace interface {
-
-namespace {
-// The fixture for testing class Foo.
-class ProducerTest : public ::testing::Test {
- protected:
- ProducerTest() : name_("b001::123|321"), producer_() {
- // You can do set-up work for each test here.
- }
-
- virtual ~ProducerTest() {
- // You can do clean-up work that doesn't throw exceptions here.
- }
-
- // If the constructor and destructor are not enough for setting up
- // and cleaning up each test, you can define the following methods:
-
- virtual void SetUp() {
- // Code here will be called immediately after the constructor (right
- // before each test).
- }
-
- virtual void TearDown() {
- // Code here will be called immediately after each test (right
- // before the destructor).
- }
-
- Name name_;
- ProducerSocket producer_;
-};
-
-} // namespace
-
-TEST_F(ProducerTest, ProduceContent) { ASSERT_TRUE(true); }
-
-} // namespace interface
-
-} // namespace transport
-
-int main(int argc, char **argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-} \ No newline at end of file