Skip to content

Commit

Permalink
support to change rtt dynamically in gym (#12)
Browse files Browse the repository at this point in the history
* support change rtt dynamically in gym and make a test script

* bugfix : error when handling trace with no rtt and update test script

* remove hardcode in test script about rtt
  • Loading branch information
Azson authored Apr 9, 2021
1 parent f157df9 commit cc842e7
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 0 deletions.
16 changes: 16 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 1000,
"capacity": 1000,
"rtt": 200,
"loss": 0,
"jitter": 0,
"time": 0.0
}
]
}
}
16 changes: 16 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_400.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 1000,
"capacity": 1000,
"rtt": 400,
"loss": 0,
"jitter": 0,
"time": 0.0
}
]
}
}
16 changes: 16 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_600.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 1000,
"capacity": 1000,
"rtt": 600,
"loss": 0,
"jitter": 0,
"time": 0.0
}
]
}
}
24 changes: 24 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_pattern_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 200,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 400,
"jitter": 0,
"time": 0.0
}
]
}
}
32 changes: 32 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_pattern_3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 200,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 200,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 200,
"jitter": 0,
"time": 0.0
}
]
}
}
40 changes: 40 additions & 0 deletions alphartc_gym/tests/data/rtt/trace_rtt_pattern_4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"type": "video",
"downlink": {},
"uplink": {
"trace_pattern": [
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 200,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 400,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 300,
"jitter": 0,
"time": 0.0
},
{
"duration": 2000,
"capacity": 1000,
"loss": 0,
"rtt": 500,
"jitter": 0,
"time": 0.0
}
]
}
}
114 changes: 114 additions & 0 deletions alphartc_gym/tests/test_gym_rtt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from alphartc_gym import gym
import os, json


ERROR = 0.05


def get_gym_stats(trace_path, duration_time_ms=3000, bandwidth_bps=1000):
total_stats = []
g = gym.Gym()
g.reset(trace_path=trace_path, duration_time_ms=duration_time_ms)

while True:
stats, done = g.step(bandwidth_bps)
if not done:
total_stats += stats
else:
return total_stats


def cal_pkt_transmit_time_ms(header_bytes, payload_bytes, bw_kps):
return (header_bytes + payload_bytes) * 8 / bw_kps


def get_info_from_trace(trace_file):
with open(trace_file, 'r') as f:
return json.loads(f.read())


def get_abs_path_by_name(trace_name):
trace_path = os.path.join(
os.path.dirname(__file__),
"data/rtt",
trace_name)
return trace_path


def single_rtt_available(trace_path):
total_stats = get_gym_stats(trace_path)
assert (total_stats)

for stats in total_stats:
assert (isinstance(stats, dict))


def single_rtt_persistence(trace_path):
# get information from trace
trace_data = get_info_from_trace(trace_path)
trace_pattern = trace_data["uplink"]["trace_pattern"]
one_way_delay = trace_pattern[0]["rtt"] / 2
bandwidth_kbps = trace_pattern[0]["capacity"]

total_stats = get_gym_stats(trace_path)
assert (total_stats)

for status in total_stats:
transmission_delay = cal_pkt_transmit_time_ms(status["header_length"],
status["payload_size"], bw_kps=bandwidth_kbps)
predict_arrival_time_ms = status["send_time_ms"] + one_way_delay + transmission_delay
assert abs(status["arrival_time_ms"] - predict_arrival_time_ms) <= ERROR * status["arrival_time_ms"]


def single_rtt_dynamically(trace_path, run_times=1):
# get information from trace
trace_data = get_info_from_trace(trace_path)
trace_pattern = trace_data["uplink"]["trace_pattern"]
one_way_delay_list = sorted([item["rtt"] / 2 for item in trace_pattern])
rtt_sample_cnt = [0] * len(one_way_delay_list)
bandwidth_kbps = trace_pattern[0]["capacity"]
duration_time_ms = sum([item["duration"] for item in trace_pattern]) * run_times

total_stats = get_gym_stats(trace_path, duration_time_ms=duration_time_ms)
assert (total_stats)

for status in total_stats:
transmission_delay = cal_pkt_transmit_time_ms(status["header_length"],
status["payload_size"], bw_kps=bandwidth_kbps)
actual_delay = status["arrival_time_ms"] - status["send_time_ms"] - transmission_delay
rtt_in_trace = False
for i in range(len(one_way_delay_list)):
if abs(actual_delay - one_way_delay_list[i]) <= ERROR * one_way_delay_list[i]:
rtt_sample_cnt[i] += 1
rtt_in_trace = True

assert rtt_in_trace == True, "actual rtt not exist in trace"

for i in range(len(rtt_sample_cnt)):
assert rtt_sample_cnt[i] > 0
if i:
assert abs(rtt_sample_cnt[i-1] - rtt_sample_cnt[i]) <= ERROR * rtt_sample_cnt[i]


def test_rtt_available():
traces_name = ["trace_rtt_200.json", "trace_rtt_400.json", "trace_rtt_600.json"]
for trace in traces_name:
trace_path = get_abs_path_by_name(trace)
single_rtt_available(trace_path)


def test_rtt_persistence():
traces_name = ["trace_rtt_200.json", "trace_rtt_400.json", "trace_rtt_600.json"]
for trace in traces_name:
trace_path = get_abs_path_by_name(trace)
single_rtt_persistence(trace_path)


def test_rtt_dynamically():
traces_name = ["trace_rtt_pattern_2.json", "trace_rtt_pattern_3.json", "trace_rtt_pattern_4.json"]
for trace in traces_name:
trace_path = get_abs_path_by_name(trace)
single_rtt_dynamically(trace_path, run_times=20)
9 changes: 9 additions & 0 deletions ns-app/scratch/webrtc_test/trace_player.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "ns3/point-to-point-net-device.h"
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/channel.h"

#include <nlohmann/json.hpp>
#include <boost/lexical_cast.hpp>
Expand Down Expand Up @@ -40,6 +42,9 @@ void TracePlayer::LoadTrace() {
TraceItem ti;
ti.capacity_ = lexical_cast<decltype(ti.capacity_)>(trace["capacity"]);
ti.duration_ms_ = lexical_cast<decltype(ti.duration_ms_)>(trace["duration"]);
if (trace.find("rtt") != trace.end()) {
ti.rtt_ms_ = lexical_cast<std::uint64_t>(trace["rtt"]);
}
traces.push_back(std::move(ti));
}
traces_.swap(traces);
Expand All @@ -55,6 +60,10 @@ void TracePlayer::PlayTrace(size_t trace_index) {
const auto &trace = traces_[trace_index];
for (size_t i = 0; i < nodes_.GetN(); i++) {
auto node = nodes_.Get(i);
// set delay in channel
if (trace.rtt_ms_) {
node->GetDevice(0)->GetChannel()->SetAttribute("Delay", StringValue(std::to_string(trace.rtt_ms_.value()/2.0) + "ms"));
}
for (size_t j = 0; j < node->GetNDevices(); j++) {
auto device =
dynamic_cast<PointToPointNetDevice *>(PeekPointer(node->GetDevice(j)));
Expand Down
2 changes: 2 additions & 0 deletions ns-app/scratch/webrtc_test/trace_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#include <string>
#include <cinttypes>
#include <vector>
#include <boost/optional.hpp>

struct TraceItem {
std::uint64_t capacity_;
std::uint64_t duration_ms_;
boost::optional<std::uint64_t> rtt_ms_;
};

class TracePlayer {
Expand Down

0 comments on commit cc842e7

Please sign in to comment.