/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2014, Telestax Inc and individual contributors
* by the @authors tag.
*
* This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
package org.restcomm.media.rtcp;
import org.junit.Assert;
import org.junit.Test;
import org.restcomm.media.rtcp.RtcpIntervalCalculator;
/**
* Tests the algorithm to calculate sending intervals for RTCP reports.
*
* @author Henrique Rosa (henrique.rosa@telestax.com)
*
*/
public class RtcpIntervalCalculatorTest {
// Default values
public static final int RTP_BW = 8000;
public static final double RTCP_BW_FRACTION = 0.05;
public static final double RTCP_BW = RTP_BW * RTCP_BW_FRACTION;
public static final double RTCP_SENDER_BW_FRACTION = 0.25;
public static final double RTCP_RECEIVER_BW_FRACTION = 1.0 - RTCP_SENDER_BW_FRACTION;
public static final double RTCP_AVG_SIZE = 200.0;
// Default messages
private static final String INTERVAL_RANGE = "The interval (%d) must be in range [%d;%d]";
@Test
public void testInitialReceiverInterval() {
// GIVEN
boolean initial = true;
// simulate two participants: remote is sender, local is receiver
boolean weSent = false;
int members = 2;
int senders = 1;
for(int i = 0; i < 1000; i++) {
// WHEN
long interval = RtcpIntervalCalculator.calculateInterval(initial,
weSent, senders, members, RTCP_AVG_SIZE, RTCP_BW,
RTCP_BW_FRACTION, RTCP_SENDER_BW_FRACTION,
RTCP_RECEIVER_BW_FRACTION);
// THEN
// senders > members * 0.25, then does not impact C nor N
double c = RTCP_AVG_SIZE / RTCP_BW;
int n = members;
// initial == true, then Tmin = 2.5 seconds
double tMin = RtcpIntervalCalculator.INITIAL_MIN_TIME;
double tD = Math.max(tMin, n * c);
// T = [Td * 0.5; Td * 1.5]
// t = T / (e - 3/2)
// Values will be converted to milliseconds (* 1000)
double compensation = Math.E - (3.0 / 2.0);
long lowT = (long) (((tD * 0.5) / compensation) * 1000);
long highT = (long) (((tD * 1.5) / compensation) * 1000);
String msg = String.format(INTERVAL_RANGE, interval, lowT, highT);
Assert.assertTrue(msg, interval >= lowT);
Assert.assertTrue(msg, interval <= highT);
}
}
@Test
public void testReceiverIntervalWithSenderMinority() {
// GIVEN
// no rtcp packet has been sent yet
boolean initial = false;
// simulate 4 participants: only one is sender (which affects variables), local is receiver
boolean weSent = false;
int members = 4;
int senders = 1;
for(int i = 0; i < 1000; i++) {
// WHEN
long interval = RtcpIntervalCalculator.calculateInterval(initial,
weSent, senders, members, RTCP_AVG_SIZE, RTCP_BW,
RTCP_BW_FRACTION, RTCP_SENDER_BW_FRACTION,
RTCP_RECEIVER_BW_FRACTION);
// THEN
// senders <= members * 0.25, then DOES impact C nor N
// we_sent == false, then C = avg_rtcp_size / (rtcp_bw * 0.75)
double c = RTCP_AVG_SIZE / (RTCP_BW * RTCP_RECEIVER_BW_FRACTION);
// we_sent == false, then n = num_receivers = members - senders
int n = members - senders;
// initial == false, then Tmin = 5 seconds
double tMin = RtcpIntervalCalculator.MIN_TIME;
double tD = Math.max(tMin, n * c);
// T = [Td * 0.5; Td * 1.5]
// t = T / (e - 3/2)
// Values will be converted to milliseconds (* 1000)
double compensation = Math.E - (3.0 / 2.0);
long lowT = (long) (((tD * 0.5) / compensation) * 1000);
long highT = (long) (((tD * 1.5) / compensation) * 1000);
String msg = String.format(INTERVAL_RANGE, interval, lowT, highT);
Assert.assertTrue(msg, interval >= lowT);
Assert.assertTrue(msg, interval <= highT);
}
}
@Test
public void testInitialSenderIntervalWithSenderMinority() {
// GIVEN
// no rtcp packet has been sent yet
boolean initial = true;
// simulate 8 participants: only three are senders (which affects variables), local is sender
boolean weSent = true;
int members = 12;
int senders = 3;
for(int i = 0; i < 1000; i++) {
// WHEN
long interval = RtcpIntervalCalculator.calculateInterval(initial,
weSent, senders, members, RTCP_AVG_SIZE, RTCP_BW,
RTCP_BW_FRACTION, RTCP_SENDER_BW_FRACTION,
RTCP_RECEIVER_BW_FRACTION);
// THEN
// senders <= members * 0.25, then DOES impact C nor N
// we_sent == false, then C = avg_rtcp_size / (rtcp_bw * 0.25)
double c = RTCP_AVG_SIZE / (RTCP_BW * RTCP_SENDER_BW_FRACTION);
// we_sent == true, then n = senders
int n = senders;
// initial == true, then Tmin = 2.5 seconds
double tMin = RtcpIntervalCalculator.INITIAL_MIN_TIME;
double tD = Math.max(tMin, n * c);
// T = [Td * 0.5; Td * 1.5]
// t = T / (e - 3/2)
// Values will be converted to milliseconds (* 1000)
double compensation = Math.E - (3.0 / 2.0);
long lowT = (long) (((tD * 0.5) / compensation) * 1000);
long highT = (long) (((tD * 1.5) / compensation) * 1000);
String msg = String.format(INTERVAL_RANGE, interval, lowT, highT);
Assert.assertTrue(msg, interval >= lowT);
Assert.assertTrue(msg, interval <= highT);
}
}
@Test
public void testSenderIntervalWithSenderMinority() {
// GIVEN
// no rtcp packet has been sent yet
boolean initial = false;
// simulate 8 participants: only three are senders (which affects variables), local is sender
boolean weSent = true;
int members = 8;
int senders = 2;
for(int i = 0; i < 1000; i++) {
// WHEN
long interval = RtcpIntervalCalculator.calculateInterval(initial,
weSent, senders, members, RTCP_AVG_SIZE, RTCP_BW,
RTCP_BW_FRACTION, RTCP_SENDER_BW_FRACTION,
RTCP_RECEIVER_BW_FRACTION);
// THEN
// senders <= members * 0.25, then DOES impact C nor N
// we_sent == false, then C = avg_rtcp_size / (rtcp_bw * 0.25)
double c = RTCP_AVG_SIZE / (RTCP_BW * RTCP_SENDER_BW_FRACTION);
// we_sent == true, then n = senders
int n = senders;
// initial == false, then Tmin = 5 seconds
double tMin = RtcpIntervalCalculator.MIN_TIME;
double tD = Math.max(tMin, n * c);
// T = [Td * 0.5; Td * 1.5]
// t = T / (e - 3/2)
// Values will be converted to milliseconds (* 1000)
double compensation = Math.E - (3.0 / 2.0);
long lowT = (long) (((tD * 0.5) / compensation) * 1000);
long highT = (long) (((tD * 1.5) / compensation) * 1000);
String msg = String.format(INTERVAL_RANGE, interval, lowT, highT);
Assert.assertTrue(msg, interval >= lowT);
Assert.assertTrue(msg, interval <= highT);
}
}
}