blob: 557a1de1c1ae73c313dbb1c1ef7b4768f0844c1c [file] [log] [blame]
// Copyright (c) 2017 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 QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_
#define QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_
#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
#include "net/third_party/quiche/src/quic/core/quic_alarm.h"
#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h"
#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
namespace quic {
namespace test {
// Frames sent by a QuartcDataSource have a 20-byte header (4 bytes for the
// source id, 8 bytes for the sequence number, 8 bytes for the timestamp).
constexpr QuicByteCount kDataFrameHeaderSize = 20;
// Struct representing one frame of data sent by a QuartcDataSource.
struct ParsedQuartcDataFrame {
// Parses the given data as a frame generated by QuartcDataSource. Returns
// true if parsing succeeds or false if parsing fails.
static bool Parse(QuicStringPiece data, ParsedQuartcDataFrame* out);
// Note that a properly formatted, parseable frame always contains these three
// header fields.
int32_t source_id = -1;
int64_t sequence_number = -1;
QuicTime send_time = QuicTime::Zero();
// Total size, including header and payload.
QuicByteCount size = 0;
std::string payload;
};
// Alarm-based source of random data to send. QuartcDataSource is configured to
// generate new data at fixed intervals.
class QuartcDataSource {
public:
struct Config {
// 32-bit ID for this data source.
int32_t id = 0;
// Minimum bandwidth allocated to this data source.
QuicBandwidth min_bandwidth = QuicBandwidth::Zero();
// Maximum bandwidth allocated to this data source.
QuicBandwidth max_bandwidth = QuicBandwidth::Infinite();
// Interval between frames for this data source.
QuicTime::Delta frame_interval = QuicTime::Delta::FromMilliseconds(10);
// Maximum size of frames produced by this source. If this value is greater
// than 0, the source may produce multiple frames with the same timestamp
// rather than a single frame that is larger than this size.
// If less than kDataFrameHeaderSize, the source produces frames of
// kDataFrameHeaderSize.
QuicByteCount max_frame_size = 0;
};
class Delegate {
public:
virtual ~Delegate() = default;
virtual void OnDataProduced(const char* data, size_t length) = 0;
};
QuartcDataSource(const QuicClock* clock,
QuicAlarmFactory* alarm_factory,
QuicRandom* random,
const Config& config,
Delegate* delegate);
void OnSendAlarm();
// Allocates bandwidth to this source. The source clamps the given value
// between its configured min and max bandwidth, and returns any amount in
// excess of its maximum allocation.
QuicBandwidth AllocateBandwidth(QuicBandwidth bandwidth);
// Whether the data source is enabled. The data source only produces data
// when enabled. When first enabled, the data source starts sending
// immediately. When disabled, the data source stops sending immediately.
bool Enabled() const;
void SetEnabled(bool value);
// Returns the sequence number of the last frame generated (or -1 if no frames
// have been generated).
int64_t sequence_number() const { return sequence_number_ - 1; }
private:
void GenerateFrame(QuicByteCount frame_size, QuicTime now);
const QuicClock* clock_;
QuicAlarmFactory* alarm_factory_;
QuicRandom* random_;
const Config config_;
Delegate* delegate_;
std::unique_ptr<QuicAlarm> send_alarm_;
int64_t sequence_number_;
QuicBandwidth allocated_bandwidth_;
QuicTime last_send_time_;
// Buffer for frames of data generated by the source. The source writes each
// frame into this buffer, then hands the delegate a pointer to it. It's a
// std::vector simply to make it quick and easy to resize if necessary (eg. if
// |allocated_bandwidth_| increases and the frame size goes up. Otherwise, it
// would be a char[].
std::vector<char> buffer_;
};
} // namespace test
} // namespace quic
#endif // QUICHE_QUIC_QUARTC_TEST_QUARTC_DATA_SOURCE_H_