aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/test/test_fec_reedsolomon.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/test/test_fec_reedsolomon.cc')
-rw-r--r--libtransport/src/test/test_fec_reedsolomon.cc184
1 files changed, 71 insertions, 113 deletions
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