mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 14:20:45 +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 += [
|
||||
":event_log_visualizer",
|
||||
":rtp_analyzer",
|
||||
"network_tester",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +312,10 @@ if (rtc_include_tests) {
|
|||
"//testing/gtest",
|
||||
]
|
||||
|
||||
if (rtc_enable_protobuf) {
|
||||
deps += [ "network_tester:network_tester_unittests" ]
|
||||
}
|
||||
|
||||
data = tools_unittests_resources
|
||||
if (is_android) {
|
||||
deps += [ "//testing/android/native_test:native_test_support" ]
|
||||
|
|
|
@ -10,5 +10,6 @@ include_rules = [
|
|||
"+webrtc/modules/congestion_controller",
|
||||
"+webrtc/modules/rtp_rtcp",
|
||||
"+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