Commit ddf7d8de authored by Andreas Schmidt's avatar Andreas Schmidt

Add packet loss statistics.

parent 349b320d
Pipeline #1718 failed with stages
in 1 minute and 16 seconds
......@@ -143,10 +143,10 @@ cdef extern from "proto/socket.h":
uint32_t PrrtSocket_get_rtprop(PrrtSocket *socket)
bint PrrtSocket_uses_thread_pinning(PrrtSocket *socket)
uint32_t PrrtSocket_get_rtt(PrrtSocket *socket)
float PrrtSocket_get_plr(PrrtSocket *socket)
bint PrrtSocket_enable_thread_pinning(PrrtSocket *socket)
cdef extern from "proto/stores/packetDeliveryStore.h":
ctypedef struct PrrtPacketDeliveryStore:
pass
......
......@@ -10,7 +10,7 @@ add_library(PRRT ../defines.h
applicationConstraints.c applicationConstraints.h
vdmcode/block_code.c vdmcode/block_code.h
stores/deliveredPacketTable.c stores/deliveredPacketTable.h
stores/lossGatherer.c stores/lossGatherer.h
types/lossStatistics.c types/lossStatistics.h
processes/dataReceiver.c processes/dataReceiver.h
processes/feedbackReceiver.c processes/feedbackReceiver.h
processes/dataTransmitter.c processes/dataTransmitter.h
......@@ -18,6 +18,7 @@ add_library(PRRT ../defines.h
stores/packetTimeoutTable.c stores/packetTimeoutTable.h
stores/dataPacketStore.c stores/dataPacketStore.h
types/packetTimeout.c types/packetTimeout.h
stores/packetDeliveryStore.c stores/packetDeliveryStore.h)
stores/packetDeliveryStore.c stores/packetDeliveryStore.h
stores/receptionTable.c stores/receptionTable.h)
target_link_libraries(PRRT rt)
......@@ -33,6 +33,13 @@ void PrrtChannelStateInformation_update_rtprop(PrrtChannelStateInformation *csi,
pthread_mutex_unlock(&csi->lock);
}
void PrrtChannelStateInformation_update_plr(PrrtChannelStateInformation *csi, prrtSequenceNumber_t erasures,
prrtSequenceNumber_t packets) {
pthread_mutex_lock(&csi->lock);
csi->plr = ((float) erasures) / packets;
pthread_mutex_unlock(&csi->lock);
}
prrtTimedelta_t PrrtChannelStateInformation_get_rtprop(PrrtChannelStateInformation *csi)
{
......@@ -50,3 +57,7 @@ bool PrrtChannelStateInformation_destroy(PrrtChannelStateInformation *csi)
error:
return false;
}
prrtPacketLossRate_t PrrtChannelStateInformation_get_plr(PrrtChannelStateInformation *csi) {
return csi->plr;
}
......@@ -10,11 +10,15 @@ typedef struct prrtChannelStateInformation {
prrtTimestamp_t rtprop_stamp;
prrtTimedelta_t rtprop_filter_length_us;
bool rtprop_expired;
prrtPacketLossRate_t plr;
} PrrtChannelStateInformation;
PrrtChannelStateInformation* PrrtChannelStateInformation_create(void);
void PrrtChannelStateInformation_update_rtprop(PrrtChannelStateInformation *csi, prrtTimedelta_t rtprop);
prrtTimedelta_t PrrtChannelStateInformation_get_rtprop(PrrtChannelStateInformation *csi);
prrtPacketLossRate_t PrrtChannelStateInformation_get_plr(PrrtChannelStateInformation* csi);
void PrrtChannelStateInformation_update_plr(PrrtChannelStateInformation *csi, prrtSequenceNumber_t erasures,
prrtSequenceNumber_t packets);
bool PrrtChannelStateInformation_destroy(PrrtChannelStateInformation* csi);
void PrrtChannelStateInformation_print(PrrtChannelStateInformation *csi);
......
......@@ -409,7 +409,6 @@ void *decode_data_header(void *dstBuffer, const void *srcBuffer) {
return dstBuffer;
}
int PrrtPacket_destroy(PrrtPacket *packet) {
if (packet->payload != NULL) {
free(packet->payload);
......@@ -494,7 +493,8 @@ PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, p
prrtTimedelta_t groupRTT, prrtSequenceNumber_t gapLength,
prrtSequenceNumber_t gapCount, prrtSequenceNumber_t burstLength,
prrtSequenceNumber_t burstCount, uint32_t bandwidth,
uint32_t receiverAddr, prrtTimestamp_t forwardTripTime) {
uint32_t receiverAddr, prrtTimestamp_t forwardTripTime,
prrtSequenceNumber_t erasureCount, prrtSequenceNumber_t packetCount) {
PrrtPacket *packet = create_header(priority, sequenceNumber, PRRT_PACKET_FEEDBACK_HEADER_SIZE, PACKET_TYPE_FEEDBACK,
index);
......@@ -505,8 +505,8 @@ PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, p
payload->receiverAddress = receiverAddr;
payload->groupRTT_us = groupRTT;
payload->forwardTripTimestamp_us = forwardTripTime;
payload->erasureCount = 0;
payload->packetCount = 0;
payload->erasureCount = erasureCount;
payload->packetCount = packetCount;
payload->gapLength = gapLength;
payload->gapCount = gapCount;
payload->burstLength = burstLength;
......
......@@ -22,6 +22,7 @@ typedef uint32_t prrtTimestamp_t;
typedef uint32_t prrtTimedelta_t;
typedef int32_t prrtTimeDifference_t;
typedef uint32_t prrtPacketLength_t;
typedef float prrtPacketLossRate_t;
typedef struct prrtIncompleteBlock {
prrtSequenceNumber_t sequenceNumberBase;
......@@ -29,7 +30,7 @@ typedef struct prrtIncompleteBlock {
} PrrtIncompleteBlock;
typedef struct prrtPacket {
ListNode asListNode;
ListNode asListNode;
uint8_t type_priority;
prrtIndex_t index;
prrtSequenceNumber_t sequenceNumber;
......@@ -90,12 +91,14 @@ PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, p
prrtTimedelta_t groupRTT, prrtSequenceNumber_t gapLength,
prrtSequenceNumber_t gapCount, prrtSequenceNumber_t burstLength,
prrtSequenceNumber_t burstCount, uint32_t bandwidth,
uint32_t receiverAddr, prrtTimestamp_t forwardTripTime);
uint32_t receiverAddr, prrtTimestamp_t forwardTripTime,
prrtSequenceNumber_t erasureCount, prrtSequenceNumber_t packetCount);
PrrtPacket *PrrtPacket_create_redundancy_packet(uint8_t priority, void *payloadPointer,
prrtPacketLength_t payloadLength,
prrtSequenceNumber_t sequenceNumber, uint8_t index,
prrtSequenceNumber_t baseSequenceNumber, PrrtCodingParams* codingParams);
prrtSequenceNumber_t baseSequenceNumber,
PrrtCodingParams *codingParams);
bool PrrtPacket_decode(void *srcBuffer, uint16_t srcBufferSize, PrrtPacket *targetPacket);
......
#include <netdb.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include "../../defines.h"
#include "../../util/dbg.h"
#include "../../util/common.h"
#include "../types/lossStatistics.h"
#include "../block.h"
#include "../clock.h"
#include "../socket.h"
......@@ -66,9 +66,11 @@ static bool send_feedback(const PrrtSocket *sock_ptr, struct sockaddr_in remote)
prrtTimestamp_t forwardTripTime = (uint32_t) (((int64_t) PrrtClock_get_current_time_us()) +
(sock_ptr->lastSentTimestamp - sock_ptr->lastReceivedTimestamp));
PrrtLossStatistics stats = sock_ptr->lossStatistics;
PrrtPacket *feedback_pkt_ptr = PrrtPacket_create_feedback_packet(0, 19, 4715, 0, 4, 6, 8, 9, 5,
sock_ptr->address->sin_addr.s_addr,
forwardTripTime);
forwardTripTime, stats.erasureCount, stats.packetCount);
prrtPacketLength_t length = PrrtPacket_size(feedback_pkt_ptr);
void *buf = calloc(1, length);
check_mem(buf);
......@@ -104,6 +106,7 @@ static void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct
check(PrrtPacketTimeoutTable_insert(sock_ptr->packetTimeoutTable, packetTimeout), "Could not insert data packet.");
prrtSequenceNumber_t seqno = packet->sequenceNumber;
PrrtReceptionTable_mark_received(sock_ptr->dataReceptionTable, seqno);
XlapTimeStampCycle(sock_ptr, ts_data_packet, seqno, SendFeedbackStart);
check(send_feedback(sock_ptr, remote), "Sending feedback failed.");
......@@ -153,6 +156,8 @@ static void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct
static void handle_redundancy_packet(PrrtSocket *socket, PrrtPacket *packet) {
PrrtPacketRedundancyPayload *redundancyPayload = packet->payload;
PrrtReceptionTable_mark_received(socket->redundancyReceptionTable, packet->sequenceNumber);
if (!PrrtDeliveredPacketTable_test_is_block_relevant(socket->deliveredPacketTable,
redundancyPayload->baseSequenceNumber,
redundancyPayload->n)) {
......
......@@ -37,10 +37,12 @@ static void handle_feedback(PrrtSocket *prrtSocket, const size_t length)
check_mem(prrtPacket);
PrrtPacket_decode(bufin, (uint16_t) n, prrtPacket);
prrtTimestamp_t forwardTripTimestamp = ((PrrtPacketFeedbackPayload *) prrtPacket->payload)->forwardTripTimestamp_us;
PrrtPacketFeedbackPayload *feedbackPayload = (PrrtPacketFeedbackPayload *) prrtPacket->payload;
prrtTimestamp_t forwardTripTimestamp = feedbackPayload->forwardTripTimestamp_us;
PrrtChannelStateInformation_update_rtprop(prrtSocket->receiver->csi,
(prrtTimedelta_t) (receiveTime - forwardTripTimestamp));
PrrtChannelStateInformation_update_plr(prrtSocket->receiver->csi, feedbackPayload->erasureCount, feedbackPayload->packetCount);
error:
if(prrtPacket != NULL) { PrrtPacket_destroy(prrtPacket); }
......
......@@ -104,6 +104,9 @@ PrrtSocket *PrrtSocket_create(const bool is_sender, prrtTimedelta_t target_delay
s->repairBlockStore = PrrtRepairBlockStore_create();
s->packetDeliveryStore = PrrtPacketDeliveryStore_create();
s->dataReceptionTable = PrrtReceptionTable_create();
s->redundancyReceptionTable = PrrtReceptionTable_create();
}
return s;
......@@ -423,6 +426,16 @@ int PrrtSocket_close(PrrtSocket *s) {
s->sendDataQueue = NULL;
}
if (s->dataReceptionTable != NULL) {
PrrtReceptionTable_destroy(s->dataReceptionTable);
s->dataReceptionTable = NULL;
}
if (s->redundancyReceptionTable != NULL) {
PrrtReceptionTable_destroy(s->redundancyReceptionTable);
s->redundancyReceptionTable = NULL;
}
if (s->packetDeliveryStore != NULL) {
PrrtPacketDeliveryStore_destroy(s->packetDeliveryStore);
s->packetDeliveryStore = NULL;
......@@ -549,6 +562,8 @@ bool PrrtSocket_cleanup(PrrtSocket *s) {
PrrtRepairBlockStore_expire_block_range(s->repairBlockStore, (prrtSequenceNumber_t) (current_start - SEQNO_SPACE/2),
(prrtSequenceNumber_t) (current_start - 1));
}
s->lossStatistics = PrrtLossStatistics_add(PrrtReceptionTable_calculate_statistics(s->dataReceptionTable), PrrtReceptionTable_calculate_statistics(s->redundancyReceptionTable));
}
return true;
}
......@@ -560,3 +575,7 @@ bool PrrtSocket_uses_thread_pinning(PrrtSocket *s) {
uint32_t PrrtSocket_get_rtprop(PrrtSocket *s) {
return PrrtChannelStateInformation_get_rtprop(s->receiver->csi);
}
prrtPacketLossRate_t PrrtSocket_get_plr(PrrtSocket *socket) {
return PrrtChannelStateInformation_get_plr(socket->receiver->csi);
}
......@@ -13,8 +13,10 @@
#include "stores/dataPacketStore.h"
#include "stores/deliveredPacketTable.h"
#include "stores/packetTimeoutTable.h"
#include "stores/receptionTable.h"
#include "stores/repairBlockStore.h"
#include "stores/packetDeliveryStore.h"
#include "types/lossStatistics.h"
#include "clock.h"
#include "../xlap/xlap.h"
#include "receiver.h"
......@@ -62,6 +64,11 @@ typedef struct prrtSocket {
prrtTimestamp_t lastSentTimestamp;
prrtTimestamp_t lastReceivedTimestamp;
PrrtLossStatistics lossStatistics;
PrrtReceptionTable* dataReceptionTable;
PrrtReceptionTable* redundancyReceptionTable;
PrrtApplicationConstraints *applicationConstraints;
PrrtCodingParams *codingParameters;
......@@ -122,4 +129,6 @@ bool PrrtSocket_uses_thread_pinning(PrrtSocket *s);
uint32_t PrrtSocket_get_rtprop(PrrtSocket *s);
prrtPacketLossRate_t PrrtSocket_get_plr(PrrtSocket *socket);
#endif // PRRT_SOCKET_H
......@@ -5,6 +5,7 @@
#include <stdbool.h>
#include "../packet.h"
#include "../../util/bitmap.h"
#include "../types/lossStatistics.h"
typedef struct {
prrtSequenceNumber_t start;
......@@ -22,4 +23,5 @@ bool PrrtDeliveredPacketTable_test_is_block_relevant(PrrtDeliveredPacketTable *t
void PrrtDeliveredPacketTable_forward_start(PrrtDeliveredPacketTable *fpt_ptr, prrtSequenceNumber_t new_start);
#endif //PRRT_DELIVERED_PACKET_TABLE_H
#include <stddef.h>
#include <malloc.h>
#include "../../defines.h"
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "lossGatherer.h"
LossGatherer *LossGatherer_create()
{
LossGatherer *lg = calloc(1, sizeof(LossGatherer));
check_mem(lg);
lg->bitmap = Bitmap_create(false, SEQNO_SPACE);
return lg;
error:
PERROR("Could not create loss gatherer.%s", "");
return NULL;
}
bool LossGatherer_destroy(LossGatherer *lossGatherer)
{
Bitmap_destroy(lossGatherer->bitmap);
free(lossGatherer);
return true;
}
LossStatistics LossGatherer_calculate_statistics(LossGatherer *lossGatherer, uint32_t start, uint16_t length)
{
check(length != 0, "Cannot calculate stats over empty sequence.");
bool x0 = LossGatherer_check_loss(lossGatherer, start);
LossStatistics statistics = {
.errorCount = (uint16_t) x0,
.packetCount = length,
.gapCount = (uint16_t) x0,
.burstCount = (uint16_t) (1 - ((uint16_t) x0)),
};
statistics.gapLength = statistics.gapCount;
statistics.burstLength = statistics.burstCount;
bool isInGap = x0;
uint16_t i = 0;
for(i = 1; i < length; i++) {
bool currentPosition = LossGatherer_check_loss(lossGatherer, start + i);
statistics.errorCount += currentPosition;
if(isInGap && currentPosition) {
statistics.gapLength++;
} else if(isInGap && (currentPosition == false)) {
isInGap = false;
statistics.burstCount++;
statistics.burstLength++;
} else if((isInGap == false) && currentPosition) {
isInGap = true;
statistics.gapCount++;
statistics.gapLength++;
} else {
statistics.burstLength++;
}
}
return statistics;
error:
PERROR("Stats error.%s","");
LossStatistics ls;
return ls;
}
bool LossGatherer_check_loss(LossGatherer *lossGatherer, uint32_t sequenceNumber)
{
return Bitmap_get(lossGatherer->bitmap, sequenceNumber);
}
bool LossGatherer_mark_loss(LossGatherer *lossGatherer, uint32_t sequenceNumber)
{
return Bitmap_set(lossGatherer->bitmap, sequenceNumber, true);
}
#include "../../defines.h"
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "receptionTable.h"
PrrtReceptionTable *PrrtReceptionTable_create(void) {
PrrtReceptionTable* t = calloc(1, sizeof(PrrtReceptionTable));
check_mem(t);
t->start = 0;
t->maxNumberInWindow = 0;
t->windowSize = 1000;
t->bitmap = Bitmap_create(false, SEQNO_SPACE);
pthread_mutexattr_t attr;
check(pthread_mutexattr_init(&attr) == EXIT_SUCCESS, "Mutex attr init failed.");
check(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EXIT_SUCCESS, "Setting type failed.");
check(pthread_mutex_init(&t->lock, &attr) == 0, "Mutex init failed.");
return t;
error:
PERROR("Out of memory.%s", "");
return NULL;
}
bool PrrtReceptionTable_destroy(PrrtReceptionTable *t) {
pthread_mutex_destroy(&t->lock);
Bitmap_destroy(t->bitmap);
free(t);
return true;
}
bool PrrtReceptionTable_mark_received(PrrtReceptionTable *t, prrtSequenceNumber_t markedNumber) {
check(pthread_mutex_lock(&t->lock) == EXIT_SUCCESS, "Lock failed.");
prrtSequenceNumber_t markedNumber_relative = (prrtSequenceNumber_t) (markedNumber - t->start);
prrtSequenceNumber_t maxNumberInWindow_relative = (prrtSequenceNumber_t) (t->maxNumberInWindow - t->start);
if (markedNumber_relative < t->windowSize) {
Bitmap_set_1(t->bitmap, markedNumber);
if(markedNumber_relative > maxNumberInWindow_relative) {
t->maxNumberInWindow = markedNumber;
}
}
if(markedNumber_relative > (t->windowSize/2)) {
prrtSequenceNumber_t new_start = (prrtSequenceNumber_t) (markedNumber - (t->windowSize / 2));
Bitmap_set_range_0(t->bitmap, t->start, (prrtSequenceNumber_t ) (new_start - t->start));
t->start = new_start;
}
check(pthread_mutex_unlock(&t->lock) == EXIT_SUCCESS, "Lock failed.");
return 0;
error:
PERROR("PrrtReceptionTable_mark_received failed%s.", "");
return false;
}
PrrtLossStatistics PrrtReceptionTable_calculate_statistics(PrrtReceptionTable *t) {
check(pthread_mutex_lock(&t->lock) == EXIT_SUCCESS, "Lock failed.");
prrtSequenceNumber_t length = (prrtSequenceNumber_t) ((t->maxNumberInWindow - t->start) + 1);
bool x0 = Bitmap_get(t->bitmap, t->start) == false;
PrrtLossStatistics statistics = {
.erasureCount = (uint16_t) x0,
.packetCount = length,
.gapCount = (uint16_t) x0,
.burstCount = (uint16_t) (1 - ((uint16_t) x0)),
};
statistics.gapLength = statistics.gapCount;
statistics.burstLength = statistics.burstCount;
bool isInGap = x0;
uint16_t i = 0;
for(i = 1; i < length; i++) {
bool currentPosition = Bitmap_get(t->bitmap, t->start + i) == false;
statistics.erasureCount += currentPosition;
if(isInGap && currentPosition) {
statistics.gapLength++;
} else if(isInGap && (currentPosition == false)) {
isInGap = false;
statistics.burstCount++;
statistics.burstLength++;
} else if((isInGap == false) && currentPosition) {
isInGap = true;
statistics.gapCount++;
statistics.gapLength++;
} else {
statistics.burstLength++;
}
}
check(pthread_mutex_unlock(&t->lock) == EXIT_SUCCESS, "Lock failed.");
return statistics;
error:
PERROR("PrrtReceptionTable_calculate_statistics failed%s.", "");
return statistics;
}
#ifndef PRRT_RECEPTIONTABLE_H
#define PRRT_RECEPTIONTABLE_H
#include <stdint.h>
#include <stdbool.h>
#include "../packet.h"
#include "../../util/bitmap.h"
#include "../types/lossStatistics.h"
typedef struct {
prrtSequenceNumber_t start;
Bitmap* bitmap;
prrtSequenceNumber_t maxNumberInWindow;
prrtSequenceNumber_t windowSize;
pthread_mutex_t lock;
} PrrtReceptionTable;
PrrtReceptionTable * PrrtReceptionTable_create(void);
bool PrrtReceptionTable_mark_received(PrrtReceptionTable* t, prrtSequenceNumber_t markedNumber);
PrrtLossStatistics PrrtReceptionTable_calculate_statistics(PrrtReceptionTable *lossGatherer);
bool PrrtReceptionTable_destroy(PrrtReceptionTable * t);
#endif //PRRT_RECEPTIONTABLE_H
#include "lossStatistics.h"
PrrtLossStatistics PrrtLossStatistics_add(PrrtLossStatistics a, PrrtLossStatistics b) {
PrrtLossStatistics result;
result.packetCount = a.packetCount + b.packetCount;
result.erasureCount = a.erasureCount + b.erasureCount;
result.burstCount = a.burstCount + b.burstCount;
result.burstLength = a.burstLength + b.burstLength;
result.gapCount = a.gapCount + b.gapCount;
result.gapLength = a.gapLength + b.gapLength;
return result;
}
#ifndef PRRT_LOSSGATHERER_H
#define PRRT_LOSSGATHERER_H
#ifndef PRRT_LOSS_STATISTICS_H
#define PRRT_LOSS_STATISTICS_H
#include "../../util/bitmap.h"
typedef struct lossGatherer {
Bitmap* bitmap;
uint16_t start;
} LossGatherer;
#include <stdint.h>
typedef struct lossStatistics {
uint16_t packetCount;
uint16_t errorCount;
uint16_t erasureCount;
uint16_t gapLength;
uint16_t gapCount;
uint16_t burstLength;
uint16_t burstCount;
} LossStatistics;
} PrrtLossStatistics;
LossGatherer* LossGatherer_create(void);
LossStatistics LossGatherer_calculate_statistics(LossGatherer *lossGatherer, uint32_t start, uint16_t length);
bool LossGatherer_mark_loss(LossGatherer* lossGatherer, uint32_t sequenceNumber);
bool LossGatherer_check_loss(LossGatherer *lossGatherer, uint32_t sequenceNumber);
bool LossGatherer_destroy(LossGatherer* lossGatherer);
PrrtLossStatistics PrrtLossStatistics_add(PrrtLossStatistics a, PrrtLossStatistics b);
#define LossStatistics_get_packet_loss_rate(stats) (((float) stats.errorCount) / stats.packetCount)
#define LossStatistics_get_packet_loss_rate(stats) (((float) stats.erasureCount) / stats.packetCount)
#define LossStatistics_get_avg_gap_length(stats) (((float) stats.gapLength) / stats.gapCount)
#define LossStatistics_get_avg_burst_length(stats) (((float) stats.burstLength) / stats.burstCount)
#endif //PRRT_LOSSGATHERER_H
#endif //PRRT_LOSS_STATISTICS_H
\ No newline at end of file
......@@ -12,7 +12,10 @@ cdef extern from "proto/stores/dataPacketStore.c":
cdef extern from "proto/stores/deliveredPacketTable.c":
pass
cdef extern from "proto/stores/lossGatherer.c":
cdef extern from "proto/stores/receptionTable.c":
pass
cdef extern from "proto/stores/packetTimeoutTable.c":
pass
cdef extern from "proto/stores/packetTimeoutTable.c":
......@@ -27,6 +30,9 @@ cdef extern from "proto/stores/packetDeliveryStore.c":
cdef extern from "proto/types/packetTimeout.c":
pass
cdef extern from "proto/types/lossStatistics.c":
pass
cdef extern from "proto/processes/feedbackReceiver.c":
pass
......@@ -121,6 +127,13 @@ cdef class PrrtSocket:
self.isSender = isSender
property plr:
def __get__(self):
if not self.isSender:
raise Exception("Not a sender.")
return cprrt.PrrtSocket_get_plr(self._c_socket)
property thread_pinning:
def __get__(self):
......
add_subdirectory(lib/gtest-1.8.0)
include_directories(SYSTEM ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
add_executable(prrtTests bitmap_tests.cpp lossGatherer_tests.cpp delivered_packet_table_tests.cpp bptree_tests.cpp PrrtBlock_tests.cpp)
add_executable(prrtTests bitmap_tests.cpp receptionTable_tests.cpp delivered_packet_table_tests.cpp bptree_tests.cpp PrrtBlock_tests.cpp)
target_link_libraries(prrtTests LINK_PUBLIC gtest PRRT UTIL gtest_main)
\ No newline at end of file
#include <gtest/gtest.h>
extern "C" {
#include "prrt/proto/stores/lossGatherer.h"
}
class LossGathererTest : public ::testing::Test {
protected:
virtual void SetUp()
{
lg = LossGatherer_create();
}
virtual void TearDown()
{
LossGatherer_destroy(lg);
}
LossGatherer *lg;
};
TEST_F(LossGathererTest, CreateDestroy)
{
LossGatherer *lg = LossGatherer_create();
void *n = NULL;
ASSERT_NE(n, lg);
ASSERT_NE(n, lg->bitmap);
LossGatherer_destroy(lg);
}
TEST_F(LossGathererTest, CheckLoss)
{
ASSERT_FALSE(LossGatherer_check_loss(lg, 0));
ASSERT_FALSE(LossGatherer_check_loss(lg, 1));
ASSERT_FALSE(LossGatherer_check_loss(lg, 2));
ASSERT_FALSE(LossGatherer_check_loss(lg, 3));
ASSERT_FALSE(LossGatherer_check_loss(lg, 4));
LossGatherer_mark_loss(lg, 2);
LossGatherer_mark_loss(lg, 3);
ASSERT_FALSE(LossGatherer_check_loss(lg, 0));
ASSERT_FALSE(LossGatherer_check_loss(lg, 1));
ASSERT_TRUE(LossGatherer_check_loss(lg, 2));
ASSERT_TRUE(LossGatherer_check_loss(lg, 3));
ASSERT_FALSE(LossGatherer_check_loss(lg, 4));
}
TEST_F(LossGathererTest, CalculateStatistics)
{
LossGatherer_mark_loss(lg, 8);
LossGatherer_mark_loss(lg, 9);
LossStatistics stats = LossGatherer_calculate_statistics(lg, 0, 10);
printf("PC: %d, EC: %d, GC: %d, GL: %d, BC: %d, BL: %d\n", stats.packetCount, stats.errorCount, stats.gapCount,
stats.gapLength, stats.burstCount, stats.burstLength);
ASSERT_EQ(10, stats.packetCount);
ASSERT_EQ(2, stats.errorCount);
ASSERT_EQ(1, stats.gapCount);
ASSERT_EQ(2, stats.gapLength);
ASSERT_EQ(8, stats.burstLength);
ASSERT_EQ(1, stats.burstCount);
LossGatherer_mark_loss(lg, 0);
LossGatherer_mark_loss(lg, 1);
ASSERT_TRUE(LossGatherer_check_loss(lg, 0));
ASSERT_TRUE(LossGatherer_check_loss(lg, 1));
ASSERT_FALSE(LossGatherer_check_loss(lg, 2));
ASSERT_FALSE(LossGatherer_check_loss(lg, 3));
ASSERT_FALSE(LossGatherer_check_loss(lg, 7));
ASSERT_TRUE(LossGatherer_check_loss(lg, 8));
ASSERT_TRUE(LossGatherer_check_loss(lg, 9));
ASSERT_FALSE(LossGatherer_check_loss(lg, 10));
printf("PLR: %f, ABL: %f, AGL: %f\n", LossStatistics_get_packet_loss_rate(stats),
LossStatistics_get_avg_burst_length(stats), LossStatistics_get_avg_gap_length(stats));
stats = LossGatherer_calculate_statistics(lg, 0, 20);
printf("PC: %d, EC: %d, GC: %d, GL: %d, BC: %d, BL: %d\n", stats.packetCount, stats.errorCount, stats.gapCount,
stats.gapLength, stats.burstCount, stats.burstLength);
ASSERT_EQ(20, stats.packetCount);
ASSERT_EQ(4, stats.errorCount);
ASSERT_EQ(2, stats.gapCount);
ASSERT_EQ(4, stats.gapLength);
ASSERT_EQ(16, stats.burstLength);
ASSERT_EQ(2, stats.burstCount);
printf("PLR: %f, ABL: %f, AGL: %f\n", LossStatistics_get_packet_loss_rate(stats),
LossStatistics_get_avg_burst_length(stats), LossStatistics_get_avg_gap_length(stats));
LossGatherer_mark_loss(lg, 2);
LossGatherer_mark_loss(lg, 3);
stats = LossGatherer_calculate_statistics(lg, 0, 20);
printf("PC: %d, EC: %d, GC: %d, GL: %d, BC: %d, BL: %d\n", stats.packetCount, stats.errorCount, stats.gapCount,
stats.gapLength, stats.burstCount, stats.burstLength);
ASSERT_EQ(20, stats.packetCount);
ASSERT_EQ(6, stats.errorCount);
ASSERT_EQ(2, stats.gapCount);
ASSERT_EQ(6, stats.gapLength);
ASSERT_EQ(14, stats.burstLength);
ASSERT_EQ(2, stats.burstCount);
printf("PLR: %f, ABL: %f, AGL: %f\n", LossStatistics_get_packet_loss_rate(stats),
LossStatistics_get_avg_burst_length(stats), LossStatistics_get_avg_gap_length(stats));
}
#include <gtest/gtest.h>
extern "C" {
#include "prrt/proto/stores/receptionTable.h"
}
class ReceptionTableTest : public ::testing::Test {
protected:
virtual void SetUp()
{
lg = PrrtReceptionTable_create();
}
virtual void TearDown()
{
PrrtReceptionTable_destroy(lg);
}
PrrtReceptionTable *lg;
};
TEST_F(ReceptionTableTest, CreateDestroy)
{
PrrtReceptionTable *lg = PrrtReceptionTable_create();
void *n = NULL;
ASSERT_NE(n, lg);
ASSERT_NE(n, lg->bitmap);
PrrtReceptionTable_destroy(lg);
}
TEST_F(ReceptionTableTest, CalculateStatistics)
{
PrrtReceptionTable_mark_received(lg, 0);
PrrtReceptionTable_mark_received(lg, 1);
PrrtReceptionTable_mark_received(lg, 2);
PrrtReceptionTable_mark_received(lg, 3);
PrrtReceptionTable_mark_received(lg, 4);
PrrtReceptionTable_mark_received(lg, 5);
PrrtReceptionTable_mark_received(lg, 6);
PrrtReceptionTable_mark_received(lg, 9);