webrtc_m130/test/scenario/simulated_time.h
Sebastian Jansson 800e121dca Adds support to change transport routes in Scenario tests.
This CL makes it possible to change transport routes while running
a scenario based test.

To make this possible in a consistent manner, the scenario test
framework is modified to only allow shared transport for all streams
between two CallClients. This is what typically is done in practice and
it is quite complex to even reason about the implications of using
mixed transports for a single call.

Bug: webrtc:9718
Change-Id: Ib836928feed98aa2bbbe0295e158157a6518348b
Reviewed-on: https://webrtc-review.googlesource.com/c/107200
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25287}
2018-10-22 11:14:37 +00:00

158 lines
5.2 KiB
C++

/*
* Copyright 2018 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 TEST_SCENARIO_SIMULATED_TIME_H_
#define TEST_SCENARIO_SIMULATED_TIME_H_
#include <deque>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "test/scenario/call_client.h"
#include "test/scenario/column_printer.h"
#include "test/scenario/network_node.h"
#include "test/scenario/scenario_config.h"
namespace webrtc {
namespace test {
class PacketStream {
public:
explicit PacketStream(PacketStreamConfig config);
private:
std::vector<int64_t> PullPackets(Timestamp at_time);
void OnTargetRateUpdate(DataRate target_rate);
friend class SimulatedTimeClient;
PacketStreamConfig config_;
bool next_frame_is_keyframe_ = true;
Timestamp next_frame_time_ = Timestamp::MinusInfinity();
DataRate target_rate_ = DataRate::Zero();
int64_t budget_ = 0;
};
class SimulatedFeedback : NetworkReceiverInterface {
public:
SimulatedFeedback(SimulatedTimeClientConfig config,
uint64_t return_receiver_id,
NetworkNode* return_node);
bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
uint64_t receiver,
Timestamp at_time) override;
private:
friend class SimulatedTimeClient;
const SimulatedTimeClientConfig config_;
const uint64_t return_receiver_id_;
NetworkNode* return_node_;
Timestamp last_feedback_time_ = Timestamp::MinusInfinity();
int32_t next_feedback_seq_num_ = 1;
std::map<int64_t, Timestamp> receive_times_;
};
struct SimpleFeedbackReportPacket {
struct ReceiveInfo {
int64_t sequence_number;
Timestamp receive_time;
};
std::vector<ReceiveInfo> receive_times;
};
SimpleFeedbackReportPacket FeedbackFromBuffer(
rtc::CopyOnWriteBuffer raw_buffer);
rtc::CopyOnWriteBuffer FeedbackToBuffer(
const SimpleFeedbackReportPacket packet);
class SimulatedSender {
public:
struct PacketReadyToSend {
SentPacket send_info;
rtc::CopyOnWriteBuffer data;
};
struct PendingPacket {
int64_t size;
};
SimulatedSender(NetworkNode* send_node, uint64_t send_receiver_id);
SimulatedSender(const SimulatedSender&) = delete;
~SimulatedSender();
TransportPacketsFeedback PullFeedbackReport(SimpleFeedbackReportPacket report,
Timestamp at_time);
std::vector<PacketReadyToSend> PaceAndPullSendPackets(Timestamp at_time);
void Update(NetworkControlUpdate update);
private:
friend class SimulatedTimeClient;
NetworkNode* send_node_;
uint64_t send_receiver_id_;
PacerConfig pacer_config_;
DataSize max_in_flight_ = DataSize::Infinity();
std::deque<PendingPacket> packet_queue_;
std::vector<SentPacket> sent_packets_;
Timestamp last_update_ = Timestamp::MinusInfinity();
int64_t pacing_budget_ = 0;
int64_t next_sequence_number_ = 1;
int64_t next_feedback_seq_num_ = 1;
DataSize data_in_flight_ = DataSize::Zero();
};
// SimulatedTimeClient emulates core parts of the behavior of WebRTC from the
// perspective of congestion controllers. This is intended for use in functional
// unit tests to ensure that congestion controllers behave in a reasonable way.
// It does not, however, completely simulate the actual behavior of WebRTC. For
// a more accurate simulation, use the real time only CallClient.
class SimulatedTimeClient : NetworkReceiverInterface {
public:
SimulatedTimeClient(std::string log_filename,
SimulatedTimeClientConfig config,
std::vector<PacketStreamConfig> stream_configs,
std::vector<NetworkNode*> send_link,
std::vector<NetworkNode*> return_link,
uint64_t send_receiver_id,
uint64_t return_receiver_id,
Timestamp at_time);
SimulatedTimeClient(const SimulatedTimeClient&) = delete;
~SimulatedTimeClient();
void Update(NetworkControlUpdate update);
void CongestionProcess(Timestamp at_time);
void PacerProcess(Timestamp at_time);
void ProcessFrames(Timestamp at_time);
void TriggerFakeReroute(Timestamp at_time);
TimeDelta GetNetworkControllerProcessInterval() const;
double target_rate_kbps() const;
bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
uint64_t receiver,
Timestamp at_time) override;
private:
friend class Scenario;
LoggingNetworkControllerFactory network_controller_factory_;
std::unique_ptr<NetworkControllerInterface> congestion_controller_;
std::vector<NetworkNode*> send_link_;
std::vector<NetworkNode*> return_link_;
SimulatedSender sender_;
SimulatedFeedback feedback_;
TargetRateConstraints current_contraints_;
DataRate target_rate_ = DataRate::Infinity();
FILE* packet_log_ = nullptr;
std::vector<std::unique_ptr<PacketStream>> packet_streams_;
};
} // namespace test
} // namespace webrtc
#endif // TEST_SCENARIO_SIMULATED_TIME_H_