forked from sanyaade-mobiledev/chromium.src
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement network performance simulation for remoting perf tests.
The new FakePacketSocketFactory allows to simulate fake network with given latency/bandwidth parameters. BUG=394067 Review URL: https://codereview.chromium.org/427613005 Cr-Commit-Position: refs/heads/master@{#290128} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290128 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
sergeyu@chromium.org
committed
Aug 16, 2014
1 parent
c4f1833
commit c44593f
Showing
12 changed files
with
1,064 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "remoting/test/fake_network_dispatcher.h" | ||
|
||
#include "base/bind.h" | ||
#include "base/location.h" | ||
#include "base/single_thread_task_runner.h" | ||
#include "net/base/io_buffer.h" | ||
|
||
namespace remoting { | ||
|
||
FakeNetworkDispatcher::FakeNetworkDispatcher() | ||
: allocated_address_(0) { | ||
} | ||
|
||
FakeNetworkDispatcher::~FakeNetworkDispatcher() { | ||
CHECK(nodes_.empty()); | ||
} | ||
|
||
rtc::IPAddress FakeNetworkDispatcher::AllocateAddress() { | ||
in6_addr addr; | ||
memset(&addr, 0, sizeof(addr)); | ||
|
||
// fc00::/7 is reserved for unique local addresses. | ||
addr.s6_addr[0] = 0xfc; | ||
|
||
// Copy |allocated_address_| to the end of |addr|. | ||
++allocated_address_; | ||
for (size_t i = 0; i < sizeof(allocated_address_); ++i) { | ||
addr.s6_addr[15 - i] = (allocated_address_ >> (8 * i)) & 0xff; | ||
} | ||
|
||
return rtc::IPAddress(addr); | ||
} | ||
|
||
void FakeNetworkDispatcher::AddNode(Node* node) { | ||
DCHECK(node->GetThread()->BelongsToCurrentThread()); | ||
|
||
base::AutoLock auto_lock(nodes_lock_); | ||
DCHECK(nodes_.find(node->GetAddress()) == nodes_.end()); | ||
nodes_[node->GetAddress()] = node; | ||
} | ||
|
||
void FakeNetworkDispatcher::RemoveNode(Node* node) { | ||
DCHECK(node->GetThread()->BelongsToCurrentThread()); | ||
|
||
base::AutoLock auto_lock(nodes_lock_); | ||
DCHECK(nodes_[node->GetAddress()] == node); | ||
nodes_.erase(node->GetAddress()); | ||
} | ||
|
||
void FakeNetworkDispatcher::DeliverPacket( | ||
const rtc::SocketAddress& from, | ||
const rtc::SocketAddress& to, | ||
const scoped_refptr<net::IOBuffer>& data, | ||
int data_size) { | ||
Node* node; | ||
{ | ||
base::AutoLock auto_lock(nodes_lock_); | ||
|
||
NodesMap::iterator node_it = nodes_.find(to.ipaddr()); | ||
if (node_it == nodes_.end()) { | ||
LOG(ERROR) << "Tried to deliver packet to unknown target: " | ||
<< to.ToString(); | ||
return; | ||
} | ||
|
||
node = node_it->second; | ||
|
||
// Check if |node| belongs to a different thread and post a task in that | ||
// case. | ||
scoped_refptr<base::SingleThreadTaskRunner> task_runner = node->GetThread(); | ||
if (!task_runner->BelongsToCurrentThread()) { | ||
task_runner->PostTask(FROM_HERE, | ||
base::Bind(&FakeNetworkDispatcher::DeliverPacket, | ||
this, from, to, data, data_size)); | ||
return; | ||
} | ||
} | ||
|
||
// Call ReceivePacket() without lock held. It's safe because at this point we | ||
// know that |node| belongs to the current thread. | ||
node->ReceivePacket(from, to, data, data_size); | ||
} | ||
|
||
} // namespace remoting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef REMOTING_TEST_FAKE_NETWORK_DISPATCHER_H_ | ||
#define REMOTING_TEST_FAKE_NETWORK_DISPATCHER_H_ | ||
|
||
#include <map> | ||
|
||
#include "base/compiler_specific.h" | ||
#include "base/memory/ref_counted.h" | ||
#include "base/synchronization/lock.h" | ||
#include "third_party/libjingle/source/talk/p2p/base/packetsocketfactory.h" | ||
|
||
namespace base { | ||
class SingleThreadTaskRunner; | ||
} // namespace base | ||
|
||
namespace net { | ||
class IOBuffer; | ||
} // namespace net | ||
|
||
namespace remoting { | ||
|
||
class FakeNetworkDispatcher | ||
: public base::RefCountedThreadSafe<FakeNetworkDispatcher> { | ||
public: | ||
class Node { | ||
public: | ||
virtual ~Node() {}; | ||
|
||
// Return thread on which ReceivePacket() should be called. | ||
virtual const scoped_refptr<base::SingleThreadTaskRunner>& GetThread() | ||
const = 0; | ||
virtual const rtc::IPAddress& GetAddress() const = 0; | ||
|
||
// Deliver a packet sent by a different node. | ||
virtual void ReceivePacket(const rtc::SocketAddress& from, | ||
const rtc::SocketAddress& to, | ||
const scoped_refptr<net::IOBuffer>& data, | ||
int data_size) = 0; | ||
}; | ||
|
||
FakeNetworkDispatcher(); | ||
|
||
rtc::IPAddress AllocateAddress(); | ||
|
||
// Must be called on the thread that the |node| works on. | ||
void AddNode(Node* node); | ||
void RemoveNode(Node* node); | ||
|
||
void DeliverPacket(const rtc::SocketAddress& from, | ||
const rtc::SocketAddress& to, | ||
const scoped_refptr<net::IOBuffer>& data, | ||
int data_size); | ||
|
||
private: | ||
typedef std::map<rtc::IPAddress, Node*> NodesMap; | ||
|
||
friend class base::RefCountedThreadSafe<FakeNetworkDispatcher>; | ||
virtual ~FakeNetworkDispatcher(); | ||
|
||
NodesMap nodes_; | ||
base::Lock nodes_lock_; | ||
|
||
// A counter used to allocate unique addresses in AllocateAddress(). | ||
int allocated_address_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(FakeNetworkDispatcher); | ||
}; | ||
|
||
} // namespace remoting | ||
|
||
#endif // REMOTING_TEST_FAKE_NETWORK_DISPATCHER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "remoting/test/fake_network_manager.h" | ||
|
||
#include "base/bind.h" | ||
#include "base/logging.h" | ||
#include "base/message_loop/message_loop.h" | ||
#include "jingle/glue/utils.h" | ||
#include "third_party/webrtc/base/socketaddress.h" | ||
|
||
namespace remoting { | ||
|
||
FakeNetworkManager::FakeNetworkManager(const rtc::IPAddress& address) | ||
: started_(false), | ||
weak_factory_(this) { | ||
network_.reset(new rtc::Network("fake", "Fake Network", address, 32)); | ||
network_->AddIP(address); | ||
} | ||
|
||
FakeNetworkManager::~FakeNetworkManager() { | ||
} | ||
|
||
void FakeNetworkManager::StartUpdating() { | ||
started_ = true; | ||
base::MessageLoop::current()->PostTask( | ||
FROM_HERE, | ||
base::Bind(&FakeNetworkManager::SendNetworksChangedSignal, | ||
weak_factory_.GetWeakPtr())); | ||
} | ||
|
||
void FakeNetworkManager::StopUpdating() { | ||
started_ = false; | ||
} | ||
|
||
void FakeNetworkManager::GetNetworks(NetworkList* networks) const { | ||
networks->clear(); | ||
networks->push_back(network_.get()); | ||
} | ||
|
||
void FakeNetworkManager::SendNetworksChangedSignal() { | ||
SignalNetworksChanged(); | ||
} | ||
|
||
} // namespace remoting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef REMOTING_TEST_FAKE_NETWORK_MANAGER_H_ | ||
#define REMOTING_TEST_FAKE_NETWORK_MANAGER_H_ | ||
|
||
#include "base/memory/scoped_ptr.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "third_party/webrtc/base/network.h" | ||
|
||
namespace remoting { | ||
|
||
// FakeNetworkManager always returns one interface with the IP address | ||
// specified in the constructor. | ||
class FakeNetworkManager : public rtc::NetworkManager { | ||
public: | ||
FakeNetworkManager(const rtc::IPAddress& address); | ||
virtual ~FakeNetworkManager(); | ||
|
||
// rtc::NetworkManager interface. | ||
virtual void StartUpdating() OVERRIDE; | ||
virtual void StopUpdating() OVERRIDE; | ||
virtual void GetNetworks(NetworkList* networks) const OVERRIDE; | ||
|
||
protected: | ||
void SendNetworksChangedSignal(); | ||
|
||
bool started_; | ||
scoped_ptr<rtc::Network> network_; | ||
|
||
base::WeakPtrFactory<FakeNetworkManager> weak_factory_; | ||
}; | ||
|
||
} // namespace remoting | ||
|
||
#endif // REMOTING_TEST_FAKE_NETWORK_MANAGER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "remoting/test/fake_port_allocator.h" | ||
|
||
#include "remoting/test/fake_network_dispatcher.h" | ||
#include "remoting/test/fake_network_manager.h" | ||
#include "remoting/test/fake_socket_factory.h" | ||
|
||
namespace remoting { | ||
|
||
namespace { | ||
|
||
class FakePortAllocatorSession | ||
: public cricket::HttpPortAllocatorSessionBase { | ||
public: | ||
FakePortAllocatorSession( | ||
cricket::HttpPortAllocatorBase* allocator, | ||
const std::string& content_name, | ||
int component, | ||
const std::string& ice_username_fragment, | ||
const std::string& ice_password, | ||
const std::vector<rtc::SocketAddress>& stun_hosts, | ||
const std::vector<std::string>& relay_hosts, | ||
const std::string& relay); | ||
virtual ~FakePortAllocatorSession(); | ||
|
||
// cricket::HttpPortAllocatorBase overrides. | ||
virtual void ConfigReady(cricket::PortConfiguration* config) OVERRIDE; | ||
virtual void SendSessionRequest(const std::string& host, int port) OVERRIDE; | ||
|
||
private: | ||
DISALLOW_COPY_AND_ASSIGN(FakePortAllocatorSession); | ||
}; | ||
|
||
FakePortAllocatorSession::FakePortAllocatorSession( | ||
cricket::HttpPortAllocatorBase* allocator, | ||
const std::string& content_name, | ||
int component, | ||
const std::string& ice_username_fragment, | ||
const std::string& ice_password, | ||
const std::vector<rtc::SocketAddress>& stun_hosts, | ||
const std::vector<std::string>& relay_hosts, | ||
const std::string& relay) | ||
: HttpPortAllocatorSessionBase(allocator, | ||
content_name, | ||
component, | ||
ice_username_fragment, | ||
ice_password, | ||
stun_hosts, | ||
relay_hosts, | ||
relay, | ||
std::string()) { | ||
set_flags(cricket::PORTALLOCATOR_DISABLE_TCP | | ||
cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG | | ||
cricket::PORTALLOCATOR_ENABLE_IPV6 | | ||
cricket::PORTALLOCATOR_DISABLE_STUN | | ||
cricket::PORTALLOCATOR_DISABLE_RELAY); | ||
} | ||
|
||
FakePortAllocatorSession::~FakePortAllocatorSession() { | ||
} | ||
|
||
void FakePortAllocatorSession::ConfigReady( | ||
cricket::PortConfiguration* config) { | ||
// Filter out non-UDP relay ports, so that we don't try using TCP. | ||
for (cricket::PortConfiguration::RelayList::iterator relay = | ||
config->relays.begin(); relay != config->relays.end(); ++relay) { | ||
cricket::PortList filtered_ports; | ||
for (cricket::PortList::iterator port = | ||
relay->ports.begin(); port != relay->ports.end(); ++port) { | ||
if (port->proto == cricket::PROTO_UDP) { | ||
filtered_ports.push_back(*port); | ||
} | ||
} | ||
relay->ports = filtered_ports; | ||
} | ||
cricket::BasicPortAllocatorSession::ConfigReady(config); | ||
} | ||
|
||
void FakePortAllocatorSession::SendSessionRequest( | ||
const std::string& host, | ||
int port) { | ||
ReceiveSessionResponse(std::string()); | ||
} | ||
|
||
} // namespace | ||
|
||
// static | ||
scoped_ptr<FakePortAllocator> FakePortAllocator::Create( | ||
scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher) { | ||
scoped_ptr<FakePacketSocketFactory> socket_factory( | ||
new FakePacketSocketFactory(fake_network_dispatcher)); | ||
scoped_ptr<rtc::NetworkManager> network_manager( | ||
new FakeNetworkManager(socket_factory->GetAddress())); | ||
|
||
return scoped_ptr<FakePortAllocator>( | ||
new FakePortAllocator(network_manager.Pass(), socket_factory.Pass())); | ||
} | ||
|
||
FakePortAllocator::FakePortAllocator( | ||
scoped_ptr<rtc::NetworkManager> network_manager, | ||
scoped_ptr<FakePacketSocketFactory> socket_factory) | ||
: HttpPortAllocatorBase(network_manager.get(), | ||
socket_factory.get(), | ||
std::string()), | ||
network_manager_(network_manager.Pass()), | ||
socket_factory_(socket_factory.Pass()) {} | ||
|
||
FakePortAllocator::~FakePortAllocator() { | ||
} | ||
|
||
cricket::PortAllocatorSession* FakePortAllocator::CreateSessionInternal( | ||
const std::string& content_name, | ||
int component, | ||
const std::string& ice_username_fragment, | ||
const std::string& ice_password) { | ||
return new FakePortAllocatorSession( | ||
this, content_name, component, ice_username_fragment, ice_password, | ||
stun_hosts(), relay_hosts(), relay_token()); | ||
} | ||
|
||
} // namespace remoting |
Oops, something went wrong.