Skip to content

Commit cc842e7

Browse files
authored
support to change rtt dynamically in gym (#12)
* 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
1 parent f157df9 commit cc842e7

File tree

9 files changed

+269
-0
lines changed

9 files changed

+269
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 1000,
8+
"capacity": 1000,
9+
"rtt": 200,
10+
"loss": 0,
11+
"jitter": 0,
12+
"time": 0.0
13+
}
14+
]
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 1000,
8+
"capacity": 1000,
9+
"rtt": 400,
10+
"loss": 0,
11+
"jitter": 0,
12+
"time": 0.0
13+
}
14+
]
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 1000,
8+
"capacity": 1000,
9+
"rtt": 600,
10+
"loss": 0,
11+
"jitter": 0,
12+
"time": 0.0
13+
}
14+
]
15+
}
16+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 2000,
8+
"capacity": 1000,
9+
"loss": 0,
10+
"rtt": 200,
11+
"jitter": 0,
12+
"time": 0.0
13+
},
14+
{
15+
"duration": 2000,
16+
"capacity": 1000,
17+
"loss": 0,
18+
"rtt": 400,
19+
"jitter": 0,
20+
"time": 0.0
21+
}
22+
]
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 2000,
8+
"capacity": 1000,
9+
"loss": 0,
10+
"rtt": 200,
11+
"jitter": 0,
12+
"time": 0.0
13+
},
14+
{
15+
"duration": 2000,
16+
"capacity": 1000,
17+
"loss": 0,
18+
"rtt": 200,
19+
"jitter": 0,
20+
"time": 0.0
21+
},
22+
{
23+
"duration": 2000,
24+
"capacity": 1000,
25+
"loss": 0,
26+
"rtt": 200,
27+
"jitter": 0,
28+
"time": 0.0
29+
}
30+
]
31+
}
32+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"type": "video",
3+
"downlink": {},
4+
"uplink": {
5+
"trace_pattern": [
6+
{
7+
"duration": 2000,
8+
"capacity": 1000,
9+
"loss": 0,
10+
"rtt": 200,
11+
"jitter": 0,
12+
"time": 0.0
13+
},
14+
{
15+
"duration": 2000,
16+
"capacity": 1000,
17+
"loss": 0,
18+
"rtt": 400,
19+
"jitter": 0,
20+
"time": 0.0
21+
},
22+
{
23+
"duration": 2000,
24+
"capacity": 1000,
25+
"loss": 0,
26+
"rtt": 300,
27+
"jitter": 0,
28+
"time": 0.0
29+
},
30+
{
31+
"duration": 2000,
32+
"capacity": 1000,
33+
"loss": 0,
34+
"rtt": 500,
35+
"jitter": 0,
36+
"time": 0.0
37+
}
38+
]
39+
}
40+
}

alphartc_gym/tests/test_gym_rtt.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
from alphartc_gym import gym
5+
import os, json
6+
7+
8+
ERROR = 0.05
9+
10+
11+
def get_gym_stats(trace_path, duration_time_ms=3000, bandwidth_bps=1000):
12+
total_stats = []
13+
g = gym.Gym()
14+
g.reset(trace_path=trace_path, duration_time_ms=duration_time_ms)
15+
16+
while True:
17+
stats, done = g.step(bandwidth_bps)
18+
if not done:
19+
total_stats += stats
20+
else:
21+
return total_stats
22+
23+
24+
def cal_pkt_transmit_time_ms(header_bytes, payload_bytes, bw_kps):
25+
return (header_bytes + payload_bytes) * 8 / bw_kps
26+
27+
28+
def get_info_from_trace(trace_file):
29+
with open(trace_file, 'r') as f:
30+
return json.loads(f.read())
31+
32+
33+
def get_abs_path_by_name(trace_name):
34+
trace_path = os.path.join(
35+
os.path.dirname(__file__),
36+
"data/rtt",
37+
trace_name)
38+
return trace_path
39+
40+
41+
def single_rtt_available(trace_path):
42+
total_stats = get_gym_stats(trace_path)
43+
assert (total_stats)
44+
45+
for stats in total_stats:
46+
assert (isinstance(stats, dict))
47+
48+
49+
def single_rtt_persistence(trace_path):
50+
# get information from trace
51+
trace_data = get_info_from_trace(trace_path)
52+
trace_pattern = trace_data["uplink"]["trace_pattern"]
53+
one_way_delay = trace_pattern[0]["rtt"] / 2
54+
bandwidth_kbps = trace_pattern[0]["capacity"]
55+
56+
total_stats = get_gym_stats(trace_path)
57+
assert (total_stats)
58+
59+
for status in total_stats:
60+
transmission_delay = cal_pkt_transmit_time_ms(status["header_length"],
61+
status["payload_size"], bw_kps=bandwidth_kbps)
62+
predict_arrival_time_ms = status["send_time_ms"] + one_way_delay + transmission_delay
63+
assert abs(status["arrival_time_ms"] - predict_arrival_time_ms) <= ERROR * status["arrival_time_ms"]
64+
65+
66+
def single_rtt_dynamically(trace_path, run_times=1):
67+
# get information from trace
68+
trace_data = get_info_from_trace(trace_path)
69+
trace_pattern = trace_data["uplink"]["trace_pattern"]
70+
one_way_delay_list = sorted([item["rtt"] / 2 for item in trace_pattern])
71+
rtt_sample_cnt = [0] * len(one_way_delay_list)
72+
bandwidth_kbps = trace_pattern[0]["capacity"]
73+
duration_time_ms = sum([item["duration"] for item in trace_pattern]) * run_times
74+
75+
total_stats = get_gym_stats(trace_path, duration_time_ms=duration_time_ms)
76+
assert (total_stats)
77+
78+
for status in total_stats:
79+
transmission_delay = cal_pkt_transmit_time_ms(status["header_length"],
80+
status["payload_size"], bw_kps=bandwidth_kbps)
81+
actual_delay = status["arrival_time_ms"] - status["send_time_ms"] - transmission_delay
82+
rtt_in_trace = False
83+
for i in range(len(one_way_delay_list)):
84+
if abs(actual_delay - one_way_delay_list[i]) <= ERROR * one_way_delay_list[i]:
85+
rtt_sample_cnt[i] += 1
86+
rtt_in_trace = True
87+
88+
assert rtt_in_trace == True, "actual rtt not exist in trace"
89+
90+
for i in range(len(rtt_sample_cnt)):
91+
assert rtt_sample_cnt[i] > 0
92+
if i:
93+
assert abs(rtt_sample_cnt[i-1] - rtt_sample_cnt[i]) <= ERROR * rtt_sample_cnt[i]
94+
95+
96+
def test_rtt_available():
97+
traces_name = ["trace_rtt_200.json", "trace_rtt_400.json", "trace_rtt_600.json"]
98+
for trace in traces_name:
99+
trace_path = get_abs_path_by_name(trace)
100+
single_rtt_available(trace_path)
101+
102+
103+
def test_rtt_persistence():
104+
traces_name = ["trace_rtt_200.json", "trace_rtt_400.json", "trace_rtt_600.json"]
105+
for trace in traces_name:
106+
trace_path = get_abs_path_by_name(trace)
107+
single_rtt_persistence(trace_path)
108+
109+
110+
def test_rtt_dynamically():
111+
traces_name = ["trace_rtt_pattern_2.json", "trace_rtt_pattern_3.json", "trace_rtt_pattern_4.json"]
112+
for trace in traces_name:
113+
trace_path = get_abs_path_by_name(trace)
114+
single_rtt_dynamically(trace_path, run_times=20)

ns-app/scratch/webrtc_test/trace_player.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "ns3/point-to-point-net-device.h"
44
#include "ns3/simulator.h"
5+
#include "ns3/string.h"
6+
#include "ns3/channel.h"
57

68
#include <nlohmann/json.hpp>
79
#include <boost/lexical_cast.hpp>
@@ -40,6 +42,9 @@ void TracePlayer::LoadTrace() {
4042
TraceItem ti;
4143
ti.capacity_ = lexical_cast<decltype(ti.capacity_)>(trace["capacity"]);
4244
ti.duration_ms_ = lexical_cast<decltype(ti.duration_ms_)>(trace["duration"]);
45+
if (trace.find("rtt") != trace.end()) {
46+
ti.rtt_ms_ = lexical_cast<std::uint64_t>(trace["rtt"]);
47+
}
4348
traces.push_back(std::move(ti));
4449
}
4550
traces_.swap(traces);
@@ -55,6 +60,10 @@ void TracePlayer::PlayTrace(size_t trace_index) {
5560
const auto &trace = traces_[trace_index];
5661
for (size_t i = 0; i < nodes_.GetN(); i++) {
5762
auto node = nodes_.Get(i);
63+
// set delay in channel
64+
if (trace.rtt_ms_) {
65+
node->GetDevice(0)->GetChannel()->SetAttribute("Delay", StringValue(std::to_string(trace.rtt_ms_.value()/2.0) + "ms"));
66+
}
5867
for (size_t j = 0; j < node->GetNDevices(); j++) {
5968
auto device =
6069
dynamic_cast<PointToPointNetDevice *>(PeekPointer(node->GetDevice(j)));

ns-app/scratch/webrtc_test/trace_player.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
#include <string>
66
#include <cinttypes>
77
#include <vector>
8+
#include <boost/optional.hpp>
89

910
struct TraceItem {
1011
std::uint64_t capacity_;
1112
std::uint64_t duration_ms_;
13+
boost::optional<std::uint64_t> rtt_ms_;
1214
};
1315

1416
class TracePlayer {

0 commit comments

Comments
 (0)