mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 06:40:43 +01:00
Add first part of the network_tester functionality.
BUG=webrtc:7426 Review-Url: https://codereview.webrtc.org/2779233002 Cr-Commit-Position: refs/heads/master@{#17635}
This commit is contained in:
parent
e0ab0ad85d
commit
333d0ff631
15 changed files with 678 additions and 0 deletions
1
resources/network_tester/client_config.dat.sha1
Normal file
1
resources/network_tester/client_config.dat.sha1
Normal file
|
@ -0,0 +1 @@
|
||||||
|
8a7265ba397c621574b321a451605ac94f58b1d3
|
1
resources/network_tester/server_config.dat.sha1
Normal file
1
resources/network_tester/server_config.dat.sha1
Normal file
|
@ -0,0 +1 @@
|
||||||
|
8a7265ba397c621574b321a451605ac94f58b1d3
|
|
@ -36,6 +36,7 @@ group("tools") {
|
||||||
public_deps += [
|
public_deps += [
|
||||||
":event_log_visualizer",
|
":event_log_visualizer",
|
||||||
":rtp_analyzer",
|
":rtp_analyzer",
|
||||||
|
"network_tester",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,6 +312,10 @@ if (rtc_include_tests) {
|
||||||
"//testing/gtest",
|
"//testing/gtest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (rtc_enable_protobuf) {
|
||||||
|
deps += [ "network_tester:network_tester_unittests" ]
|
||||||
|
}
|
||||||
|
|
||||||
data = tools_unittests_resources
|
data = tools_unittests_resources
|
||||||
if (is_android) {
|
if (is_android) {
|
||||||
deps += [ "//testing/android/native_test:native_test_support" ]
|
deps += [ "//testing/android/native_test:native_test_support" ]
|
||||||
|
|
|
@ -10,5 +10,6 @@ include_rules = [
|
||||||
"+webrtc/modules/congestion_controller",
|
"+webrtc/modules/congestion_controller",
|
||||||
"+webrtc/modules/rtp_rtcp",
|
"+webrtc/modules/rtp_rtcp",
|
||||||
"+webrtc/system_wrappers",
|
"+webrtc/system_wrappers",
|
||||||
|
"+webrtc/p2p",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
93
webrtc/tools/network_tester/BUILD.gn
Normal file
93
webrtc/tools/network_tester/BUILD.gn
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a BSD-style license
|
||||||
|
# that can be found in the LICENSE file in the root of the source
|
||||||
|
# tree. An additional intellectual property rights grant can be found
|
||||||
|
# in the file PATENTS. All contributing project authors may
|
||||||
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
|
|
||||||
|
import("../../webrtc.gni")
|
||||||
|
import("//third_party/protobuf/proto_library.gni")
|
||||||
|
|
||||||
|
if (rtc_enable_protobuf) {
|
||||||
|
proto_library("network_tester_config_proto") {
|
||||||
|
sources = [
|
||||||
|
"network_tester_config.proto",
|
||||||
|
]
|
||||||
|
proto_out_dir = "webrtc/tools/network_tester"
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_library("network_tester_packet_proto") {
|
||||||
|
sources = [
|
||||||
|
"network_tester_packet.proto",
|
||||||
|
]
|
||||||
|
proto_out_dir = "webrtc/tools/network_tester"
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_static_library("network_tester") {
|
||||||
|
sources = [
|
||||||
|
"config_reader.cc",
|
||||||
|
"config_reader.h",
|
||||||
|
"packet_sender.cc",
|
||||||
|
"packet_sender.h",
|
||||||
|
"test_controller.cc",
|
||||||
|
"test_controller.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [ "WEBRTC_NETWORK_TESTER_PROTO" ]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
":network_tester_config_proto",
|
||||||
|
":network_tester_packet_proto",
|
||||||
|
"../../base:rtc_task_queue",
|
||||||
|
"../../p2p",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (!build_with_chromium && is_clang) {
|
||||||
|
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||||
|
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
network_tester_unittests_resources = [
|
||||||
|
"//resources/network_tester/client_config.dat",
|
||||||
|
"//resources/network_tester/server_config.dat",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (is_ios) {
|
||||||
|
bundle_data("network_tester_unittests_bundle_data") {
|
||||||
|
testonly = true
|
||||||
|
sources = network_tester_unittests_resources
|
||||||
|
outputs = [
|
||||||
|
"{{bundle_resources_dir}}/{{source_file_part}}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc_source_set("network_tester_unittests") {
|
||||||
|
sources = [
|
||||||
|
"network_tester_unittest.cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
testonly = true
|
||||||
|
deps = [
|
||||||
|
":network_tester",
|
||||||
|
"//testing/gtest",
|
||||||
|
"//webrtc/base:rtc_base_tests_utils",
|
||||||
|
"//webrtc/test:test_support",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (is_ios) {
|
||||||
|
deps += [ ":network_tester_unittests_bundle_data" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
defines = [ "GTEST_RELATIVE_PATH" ]
|
||||||
|
|
||||||
|
data = network_tester_unittests_resources
|
||||||
|
|
||||||
|
if (!build_with_chromium && is_clang) {
|
||||||
|
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||||
|
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
webrtc/tools/network_tester/config_reader.cc
Normal file
50
webrtc/tools/network_tester/config_reader.cc
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
#include "webrtc/tools/network_tester/config_reader.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
ConfigReader::ConfigReader(const std::string& config_file_path)
|
||||||
|
: proto_config_index_(0) {
|
||||||
|
std::ifstream config_stream(config_file_path,
|
||||||
|
std::ios_base::in | std::ios_base::binary);
|
||||||
|
RTC_DCHECK(config_stream.is_open());
|
||||||
|
RTC_DCHECK(config_stream.good());
|
||||||
|
std::string config_data((std::istreambuf_iterator<char>(config_stream)),
|
||||||
|
(std::istreambuf_iterator<char>()));
|
||||||
|
if (config_data.size() > 0) {
|
||||||
|
proto_all_configs_.ParseFromString(config_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigReader::~ConfigReader() = default;
|
||||||
|
|
||||||
|
rtc::Optional<ConfigReader::Config> ConfigReader::GetNextConfig() {
|
||||||
|
#ifdef WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
if (proto_config_index_ >= proto_all_configs_.configs_size())
|
||||||
|
return rtc::Optional<Config>();
|
||||||
|
auto proto_config = proto_all_configs_.configs(proto_config_index_++);
|
||||||
|
RTC_DCHECK(proto_config.has_packet_send_interval_ms());
|
||||||
|
RTC_DCHECK(proto_config.has_packet_size());
|
||||||
|
RTC_DCHECK(proto_config.has_execution_time_ms());
|
||||||
|
Config config;
|
||||||
|
config.packet_send_interval_ms = proto_config.packet_send_interval_ms();
|
||||||
|
config.packet_size = proto_config.packet_size();
|
||||||
|
config.execution_time_ms = proto_config.execution_time_ms();
|
||||||
|
return rtc::Optional<Config>(config);
|
||||||
|
#else
|
||||||
|
return rtc::Optional<Config>();
|
||||||
|
#endif // WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
53
webrtc/tools/network_tester/config_reader.h
Normal file
53
webrtc/tools/network_tester/config_reader.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
|
||||||
|
#define WEBRTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "webrtc/base/constructormagic.h"
|
||||||
|
#include "webrtc/base/optional.h"
|
||||||
|
|
||||||
|
#include "webrtc/base/ignore_wundef.h"
|
||||||
|
|
||||||
|
#ifdef WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
RTC_PUSH_IGNORING_WUNDEF()
|
||||||
|
#include "webrtc/tools/network_tester/network_tester_config.pb.h"
|
||||||
|
RTC_POP_IGNORING_WUNDEF()
|
||||||
|
using webrtc::network_tester::config::NetworkTesterAllConfigs;
|
||||||
|
#else
|
||||||
|
class NetworkTesterConfigs;
|
||||||
|
#endif // WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class ConfigReader {
|
||||||
|
public:
|
||||||
|
struct Config {
|
||||||
|
int packet_send_interval_ms;
|
||||||
|
int packet_size;
|
||||||
|
int execution_time_ms;
|
||||||
|
};
|
||||||
|
explicit ConfigReader(const std::string& config_file_path);
|
||||||
|
~ConfigReader();
|
||||||
|
|
||||||
|
rtc::Optional<Config> GetNextConfig();
|
||||||
|
|
||||||
|
private:
|
||||||
|
NetworkTesterAllConfigs proto_all_configs_;
|
||||||
|
int proto_config_index_;
|
||||||
|
RTC_DISALLOW_COPY_AND_ASSIGN(ConfigReader);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
|
30
webrtc/tools/network_tester/create_network_tester_config.py
Normal file
30
webrtc/tools/network_tester/create_network_tester_config.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a BSD-style license
|
||||||
|
# that can be found in the LICENSE file in the root of the source
|
||||||
|
# tree. An additional intellectual property rights grant can be found
|
||||||
|
# in the file PATENTS. All contributing project authors may
|
||||||
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
|
|
||||||
|
import network_tester_config_pb2
|
||||||
|
|
||||||
|
|
||||||
|
def AddConfig(all_configs,
|
||||||
|
packet_send_interval_ms,
|
||||||
|
packet_size,
|
||||||
|
execution_time_ms):
|
||||||
|
config = all_configs.configs.add()
|
||||||
|
config.packet_send_interval_ms = packet_send_interval_ms
|
||||||
|
config.packet_size = packet_size
|
||||||
|
config.execution_time_ms = execution_time_ms
|
||||||
|
|
||||||
|
def main():
|
||||||
|
all_configs = network_tester_config_pb2.NetworkTesterAllConfigs()
|
||||||
|
AddConfig(all_configs, 10, 50, 200)
|
||||||
|
AddConfig(all_configs, 10, 100, 200)
|
||||||
|
with open("network_tester_config.dat", 'wb') as f:
|
||||||
|
f.write(all_configs.SerializeToString())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
13
webrtc/tools/network_tester/network_tester_config.proto
Normal file
13
webrtc/tools/network_tester/network_tester_config.proto
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
package webrtc.network_tester.config;
|
||||||
|
|
||||||
|
message NetworkTesterConfig {
|
||||||
|
optional int32 packet_send_interval_ms = 1;
|
||||||
|
optional float packet_size = 2;
|
||||||
|
optional int32 execution_time_ms = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NetworkTesterAllConfigs {
|
||||||
|
repeated NetworkTesterConfig configs = 1;
|
||||||
|
}
|
18
webrtc/tools/network_tester/network_tester_packet.proto
Normal file
18
webrtc/tools/network_tester/network_tester_packet.proto
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
package webrtc.network_tester.packet;
|
||||||
|
|
||||||
|
message NetworkTesterPacket {
|
||||||
|
enum Type {
|
||||||
|
HAND_SHAKING = 0;
|
||||||
|
TEST_START = 1;
|
||||||
|
TEST_DATA = 2;
|
||||||
|
TEST_DONE = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional Type type = 1;
|
||||||
|
optional int64 send_timestamp = 2;
|
||||||
|
optional int64 arrival_timestamp = 3;
|
||||||
|
optional int64 sequence_number = 4;
|
||||||
|
optional int32 packet_size = 5;
|
||||||
|
}
|
29
webrtc/tools/network_tester/network_tester_unittest.cc
Normal file
29
webrtc/tools/network_tester/network_tester_unittest.cc
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/tools/network_tester/test_controller.h"
|
||||||
|
|
||||||
|
#include "webrtc/base/gunit.h"
|
||||||
|
#include "webrtc/test/gtest.h"
|
||||||
|
#include "webrtc/test/testsupport/fileutils.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
TEST(NetworkTesterTest, ServerClient) {
|
||||||
|
TestController client(
|
||||||
|
0, 0, webrtc::test::ResourcePath("network_tester/client_config", "dat"));
|
||||||
|
TestController server(
|
||||||
|
9090, 9090,
|
||||||
|
webrtc::test::ResourcePath("network_tester/server_config", "dat"));
|
||||||
|
client.SendConnectTo("127.0.0.1", 9090);
|
||||||
|
EXPECT_TRUE_WAIT(server.IsTestDone() && client.IsTestDone(), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
126
webrtc/tools/network_tester/packet_sender.cc
Normal file
126
webrtc/tools/network_tester/packet_sender.cc
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/tools/network_tester/packet_sender.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "webrtc/base/timeutils.h"
|
||||||
|
#include "webrtc/tools/network_tester/config_reader.h"
|
||||||
|
#include "webrtc/tools/network_tester/test_controller.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class SendPacketTask : public rtc::QueuedTask {
|
||||||
|
public:
|
||||||
|
explicit SendPacketTask(PacketSender* packet_sender)
|
||||||
|
: packet_sender_(packet_sender) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Run() override {
|
||||||
|
if (packet_sender_->IsSending()) {
|
||||||
|
packet_sender_->SendPacket();
|
||||||
|
rtc::TaskQueue::Current()->PostDelayedTask(
|
||||||
|
std::unique_ptr<QueuedTask>(this),
|
||||||
|
packet_sender_->GetSendIntervalMs());
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PacketSender* const packet_sender_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UpdateTestSettingTask : public rtc::QueuedTask {
|
||||||
|
public:
|
||||||
|
UpdateTestSettingTask(PacketSender* packet_sender,
|
||||||
|
std::unique_ptr<ConfigReader> config_reader)
|
||||||
|
: packet_sender_(packet_sender),
|
||||||
|
config_reader_(std::move(config_reader)) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Run() override {
|
||||||
|
auto config = config_reader_->GetNextConfig();
|
||||||
|
if (config) {
|
||||||
|
packet_sender_->UpdateTestSetting((*config).packet_size,
|
||||||
|
(*config).packet_send_interval_ms);
|
||||||
|
rtc::TaskQueue::Current()->PostDelayedTask(
|
||||||
|
std::unique_ptr<QueuedTask>(this), (*config).execution_time_ms);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
packet_sender_->StopSending();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PacketSender* const packet_sender_;
|
||||||
|
const std::unique_ptr<ConfigReader> config_reader_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
PacketSender::PacketSender(TestController* test_controller,
|
||||||
|
const std::string& config_file_path)
|
||||||
|
: worker_queue_("Packet Sender", rtc::TaskQueue::Priority::HIGH),
|
||||||
|
packet_size_(0),
|
||||||
|
send_interval_ms_(0),
|
||||||
|
sequence_number_(0),
|
||||||
|
sending_(false),
|
||||||
|
config_file_path_(config_file_path),
|
||||||
|
test_controller_(test_controller) {}
|
||||||
|
|
||||||
|
PacketSender::~PacketSender() = default;
|
||||||
|
|
||||||
|
void PacketSender::StartSending() {
|
||||||
|
sending_ = true;
|
||||||
|
worker_queue_checker_.Detach();
|
||||||
|
worker_queue_.PostTask(
|
||||||
|
std::unique_ptr<rtc::QueuedTask>(new UpdateTestSettingTask(
|
||||||
|
this,
|
||||||
|
std::unique_ptr<ConfigReader>(new ConfigReader(config_file_path_)))));
|
||||||
|
worker_queue_.PostTask(
|
||||||
|
std::unique_ptr<rtc::QueuedTask>(new SendPacketTask(this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketSender::StopSending() {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
|
||||||
|
sending_ = false;
|
||||||
|
test_controller_->OnTestDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PacketSender::IsSending() const {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
|
||||||
|
return sending_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketSender::SendPacket() {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
|
||||||
|
NetworkTesterPacket packet;
|
||||||
|
packet.set_type(NetworkTesterPacket::TEST_DATA);
|
||||||
|
packet.set_sequence_number(sequence_number_++);
|
||||||
|
packet.set_send_timestamp(rtc::TimeMicros());
|
||||||
|
test_controller_->SendData(packet, rtc::Optional<size_t>(packet_size_));
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t PacketSender::GetSendIntervalMs() const {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
|
||||||
|
return send_interval_ms_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PacketSender::UpdateTestSetting(size_t packet_size,
|
||||||
|
int64_t send_interval_ms) {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
|
||||||
|
send_interval_ms_ = send_interval_ms;
|
||||||
|
packet_size_ = packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
65
webrtc/tools/network_tester/packet_sender.h
Normal file
65
webrtc/tools/network_tester/packet_sender.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_
|
||||||
|
#define WEBRTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "webrtc/base/ignore_wundef.h"
|
||||||
|
#include "webrtc/base/sequenced_task_checker.h"
|
||||||
|
#include "webrtc/base/task_queue.h"
|
||||||
|
|
||||||
|
#ifdef WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
RTC_PUSH_IGNORING_WUNDEF()
|
||||||
|
#include "webrtc/tools/network_tester/network_tester_packet.pb.h"
|
||||||
|
RTC_POP_IGNORING_WUNDEF()
|
||||||
|
using webrtc::network_tester::packet::NetworkTesterPacket;
|
||||||
|
#else
|
||||||
|
class NetworkTesterPacket;
|
||||||
|
#endif // WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class TestController;
|
||||||
|
|
||||||
|
class PacketSender {
|
||||||
|
public:
|
||||||
|
PacketSender(TestController* test_controller,
|
||||||
|
const std::string& config_file_path);
|
||||||
|
~PacketSender();
|
||||||
|
|
||||||
|
void StartSending();
|
||||||
|
void StopSending();
|
||||||
|
bool IsSending() const;
|
||||||
|
|
||||||
|
void SendPacket();
|
||||||
|
|
||||||
|
int64_t GetSendIntervalMs() const;
|
||||||
|
void UpdateTestSetting(size_t packet_size, int64_t send_interval_ms);
|
||||||
|
|
||||||
|
private:
|
||||||
|
rtc::TaskQueue worker_queue_;
|
||||||
|
rtc::SequencedTaskChecker worker_queue_checker_;
|
||||||
|
|
||||||
|
size_t packet_size_;
|
||||||
|
int64_t send_interval_ms_;
|
||||||
|
int64_t sequence_number_;
|
||||||
|
bool sending_;
|
||||||
|
const std::string config_file_path_;
|
||||||
|
TestController* const test_controller_;
|
||||||
|
|
||||||
|
RTC_DISALLOW_COPY_AND_ASSIGN(PacketSender);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_
|
118
webrtc/tools/network_tester/test_controller.cc
Normal file
118
webrtc/tools/network_tester/test_controller.cc
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/tools/network_tester/test_controller.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
TestController::TestController(int min_port,
|
||||||
|
int max_port,
|
||||||
|
const std::string& config_file_path)
|
||||||
|
: config_file_path_(config_file_path),
|
||||||
|
local_test_done_(false),
|
||||||
|
remote_test_done_(false) {
|
||||||
|
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
|
||||||
|
send_data_.fill(42);
|
||||||
|
packet_sender_checker_.Detach();
|
||||||
|
auto socket =
|
||||||
|
std::unique_ptr<rtc::AsyncPacketSocket>(socket_factory_.CreateUdpSocket(
|
||||||
|
rtc::SocketAddress(rtc::GetAnyIP(AF_INET), 0), min_port, max_port));
|
||||||
|
socket->SignalReadPacket.connect(this, &TestController::OnReadPacket);
|
||||||
|
udp_transport_.reset(
|
||||||
|
new cricket::UdpTransport("network tester transport", std::move(socket)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestController::SendConnectTo(const std::string& hostname, int port) {
|
||||||
|
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
|
||||||
|
udp_transport_->SetRemoteAddress(rtc::SocketAddress(hostname, port));
|
||||||
|
NetworkTesterPacket packet;
|
||||||
|
packet.set_type(NetworkTesterPacket::HAND_SHAKING);
|
||||||
|
SendData(packet, rtc::Optional<size_t>());
|
||||||
|
rtc::CritScope scoped_lock(&local_test_done_lock_);
|
||||||
|
local_test_done_ = false;
|
||||||
|
remote_test_done_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestController::Run() {
|
||||||
|
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
|
||||||
|
rtc::Thread::Current()->ProcessMessages(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestController::SendData(const NetworkTesterPacket& packet,
|
||||||
|
rtc::Optional<size_t> data_size) {
|
||||||
|
// Can be call from packet_sender or from test_controller thread.
|
||||||
|
size_t packet_size = packet.ByteSize();
|
||||||
|
send_data_[0] = packet_size;
|
||||||
|
packet.SerializeToArray(&send_data_[1], std::numeric_limits<char>::max());
|
||||||
|
if (data_size && *data_size > packet_size)
|
||||||
|
packet_size = *data_size;
|
||||||
|
udp_transport_->SendPacket(send_data_.data(), packet_size + 1,
|
||||||
|
rtc::PacketOptions(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestController::OnTestDone() {
|
||||||
|
RTC_DCHECK_CALLED_SEQUENTIALLY(&packet_sender_checker_);
|
||||||
|
NetworkTesterPacket packet;
|
||||||
|
packet.set_type(NetworkTesterPacket::TEST_DONE);
|
||||||
|
SendData(packet, rtc::Optional<size_t>());
|
||||||
|
rtc::CritScope scoped_lock(&local_test_done_lock_);
|
||||||
|
local_test_done_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestController::IsTestDone() {
|
||||||
|
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
|
||||||
|
rtc::CritScope scoped_lock(&local_test_done_lock_);
|
||||||
|
return local_test_done_ && remote_test_done_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestController::OnReadPacket(rtc::AsyncPacketSocket* socket,
|
||||||
|
const char* data,
|
||||||
|
size_t len,
|
||||||
|
const rtc::SocketAddress& remote_addr,
|
||||||
|
const rtc::PacketTime& packet_time) {
|
||||||
|
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
|
||||||
|
size_t packet_size = data[0];
|
||||||
|
std::string receive_data(&data[1], packet_size);
|
||||||
|
NetworkTesterPacket packet;
|
||||||
|
packet.ParseFromString(receive_data);
|
||||||
|
RTC_CHECK(packet.has_type());
|
||||||
|
switch (packet.type()) {
|
||||||
|
case NetworkTesterPacket::HAND_SHAKING: {
|
||||||
|
NetworkTesterPacket packet;
|
||||||
|
packet.set_type(NetworkTesterPacket::TEST_START);
|
||||||
|
udp_transport_->SetRemoteAddress(remote_addr);
|
||||||
|
SendData(packet, rtc::Optional<size_t>());
|
||||||
|
packet_sender_.reset(new PacketSender(this, config_file_path_));
|
||||||
|
packet_sender_->StartSending();
|
||||||
|
rtc::CritScope scoped_lock(&local_test_done_lock_);
|
||||||
|
local_test_done_ = false;
|
||||||
|
remote_test_done_ = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkTesterPacket::TEST_START: {
|
||||||
|
packet_sender_.reset(new PacketSender(this, config_file_path_));
|
||||||
|
packet_sender_->StartSending();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkTesterPacket::TEST_DATA: {
|
||||||
|
packet.set_arrival_timestamp(packet_time.timestamp);
|
||||||
|
packet.set_packet_size(len);
|
||||||
|
// log packet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetworkTesterPacket::TEST_DONE: {
|
||||||
|
remote_test_done_ = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { RTC_NOTREACHED(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
75
webrtc/tools/network_tester/test_controller.h
Normal file
75
webrtc/tools/network_tester/test_controller.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
|
||||||
|
#define WEBRTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "webrtc/base/ignore_wundef.h"
|
||||||
|
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
|
||||||
|
#include "webrtc/p2p/base/udptransport.h"
|
||||||
|
#include "webrtc/tools/network_tester/packet_sender.h"
|
||||||
|
|
||||||
|
#ifdef WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
RTC_PUSH_IGNORING_WUNDEF()
|
||||||
|
#include "webrtc/tools/network_tester/network_tester_packet.pb.h"
|
||||||
|
RTC_POP_IGNORING_WUNDEF()
|
||||||
|
using webrtc::network_tester::packet::NetworkTesterPacket;
|
||||||
|
#else
|
||||||
|
class NetworkTesterPacket;
|
||||||
|
#endif // WEBRTC_NETWORK_TESTER_PROTO
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
constexpr size_t kEthernetMtu = 1500;
|
||||||
|
|
||||||
|
class TestController : public sigslot::has_slots<> {
|
||||||
|
public:
|
||||||
|
TestController(int min_port,
|
||||||
|
int max_port,
|
||||||
|
const std::string& config_file_path);
|
||||||
|
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
void SendConnectTo(const std::string& hostname, int port);
|
||||||
|
|
||||||
|
void SendData(const NetworkTesterPacket& packet,
|
||||||
|
rtc::Optional<size_t> data_size);
|
||||||
|
|
||||||
|
void OnTestDone();
|
||||||
|
|
||||||
|
bool IsTestDone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnReadPacket(rtc::AsyncPacketSocket* socket,
|
||||||
|
const char* data,
|
||||||
|
size_t len,
|
||||||
|
const rtc::SocketAddress& remote_addr,
|
||||||
|
const rtc::PacketTime& packet_time);
|
||||||
|
rtc::ThreadChecker test_controller_thread_checker_;
|
||||||
|
rtc::SequencedTaskChecker packet_sender_checker_;
|
||||||
|
rtc::BasicPacketSocketFactory socket_factory_;
|
||||||
|
const std::string config_file_path_;
|
||||||
|
rtc::CriticalSection local_test_done_lock_;
|
||||||
|
bool local_test_done_ GUARDED_BY(local_test_done_lock_);
|
||||||
|
bool remote_test_done_;
|
||||||
|
std::array<char, kEthernetMtu> send_data_;
|
||||||
|
std::unique_ptr<cricket::UdpTransport> udp_transport_;
|
||||||
|
std::unique_ptr<PacketSender> packet_sender_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
|
Loading…
Reference in a new issue