blob: f261e1f78f83b3b063b6791c9a20d2b543855bc6 [file] [log] [blame]
// Copyright (c) 2023 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 "quiche/quic/moqt/moqt_framer.h"
#include <memory>
#include <string>
#include <vector>
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/test_tools/moqt_test_message.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/simple_buffer_allocator.h"
namespace moqt::test {
struct MoqtFramerTestParams {
MoqtFramerTestParams(MoqtMessageType message_type, bool uses_web_transport)
: message_type(message_type), uses_web_transport(uses_web_transport) {}
MoqtMessageType message_type;
bool uses_web_transport;
};
std::vector<MoqtFramerTestParams> GetMoqtFramerTestParams() {
std::vector<MoqtFramerTestParams> params;
std::vector<MoqtMessageType> message_types = {
MoqtMessageType::kObjectWithPayloadLength,
MoqtMessageType::kObjectWithoutPayloadLength,
MoqtMessageType::kClientSetup,
MoqtMessageType::kServerSetup,
MoqtMessageType::kSubscribeRequest,
MoqtMessageType::kSubscribeOk,
MoqtMessageType::kSubscribeError,
MoqtMessageType::kUnsubscribe,
MoqtMessageType::kSubscribeFin,
MoqtMessageType::kSubscribeRst,
MoqtMessageType::kAnnounce,
MoqtMessageType::kAnnounceOk,
MoqtMessageType::kAnnounceError,
MoqtMessageType::kUnannounce,
MoqtMessageType::kGoAway,
};
std::vector<bool> uses_web_transport_bool = {
false,
true,
};
for (const MoqtMessageType message_type : message_types) {
if (message_type == MoqtMessageType::kClientSetup) {
for (const bool uses_web_transport : uses_web_transport_bool) {
params.push_back(
MoqtFramerTestParams(message_type, uses_web_transport));
}
} else {
// All other types are processed the same for either perspective or
// transport.
params.push_back(MoqtFramerTestParams(message_type, true));
}
}
return params;
}
std::string ParamNameFormatter(
const testing::TestParamInfo<MoqtFramerTestParams>& info) {
return MoqtMessageTypeToString(info.param.message_type) + "_" +
(info.param.uses_web_transport ? "WebTransport" : "QUIC");
}
class MoqtFramerTest
: public quic::test::QuicTestWithParam<MoqtFramerTestParams> {
public:
MoqtFramerTest()
: message_type_(GetParam().message_type),
webtrans_(GetParam().uses_web_transport),
buffer_allocator_(quiche::SimpleBufferAllocator::Get()),
framer_(buffer_allocator_, GetParam().uses_web_transport) {}
std::unique_ptr<TestMessageBase> MakeMessage(MoqtMessageType message_type) {
switch (message_type) {
case MoqtMessageType::kObjectWithPayloadLength:
return std::make_unique<ObjectMessageWithLength>();
case MoqtMessageType::kObjectWithoutPayloadLength:
return std::make_unique<ObjectMessageWithoutLength>();
case MoqtMessageType::kClientSetup:
return std::make_unique<ClientSetupMessage>(webtrans_);
case MoqtMessageType::kServerSetup:
return std::make_unique<ServerSetupMessage>();
case MoqtMessageType::kSubscribeRequest:
return std::make_unique<SubscribeRequestMessage>();
case MoqtMessageType::kSubscribeOk:
return std::make_unique<SubscribeOkMessage>();
case MoqtMessageType::kSubscribeError:
return std::make_unique<SubscribeErrorMessage>();
case MoqtMessageType::kUnsubscribe:
return std::make_unique<UnsubscribeMessage>();
case MoqtMessageType::kSubscribeFin:
return std::make_unique<SubscribeFinMessage>();
case MoqtMessageType::kSubscribeRst:
return std::make_unique<SubscribeRstMessage>();
case MoqtMessageType::kAnnounce:
return std::make_unique<AnnounceMessage>();
case moqt::MoqtMessageType::kAnnounceOk:
return std::make_unique<AnnounceOkMessage>();
case moqt::MoqtMessageType::kAnnounceError:
return std::make_unique<AnnounceErrorMessage>();
case moqt::MoqtMessageType::kUnannounce:
return std::make_unique<UnannounceMessage>();
case moqt::MoqtMessageType::kGoAway:
return std::make_unique<GoAwayMessage>();
default:
return nullptr;
}
}
quiche::QuicheBuffer SerializeMessage(
TestMessageBase::MessageStructuredData& structured_data) {
switch (message_type_) {
case MoqtMessageType::kObjectWithPayloadLength:
case MoqtMessageType::kObjectWithoutPayloadLength: {
auto data = std::get<MoqtObject>(structured_data);
return framer_.SerializeObject(data, "foo");
}
case MoqtMessageType::kClientSetup: {
auto data = std::get<MoqtClientSetup>(structured_data);
return framer_.SerializeClientSetup(data);
}
case MoqtMessageType::kServerSetup: {
auto data = std::get<MoqtServerSetup>(structured_data);
return framer_.SerializeServerSetup(data);
}
case MoqtMessageType::kSubscribeRequest: {
auto data = std::get<MoqtSubscribeRequest>(structured_data);
return framer_.SerializeSubscribeRequest(data);
}
case MoqtMessageType::kSubscribeOk: {
auto data = std::get<MoqtSubscribeOk>(structured_data);
return framer_.SerializeSubscribeOk(data);
}
case MoqtMessageType::kSubscribeError: {
auto data = std::get<MoqtSubscribeError>(structured_data);
return framer_.SerializeSubscribeError(data);
}
case MoqtMessageType::kUnsubscribe: {
auto data = std::get<MoqtUnsubscribe>(structured_data);
return framer_.SerializeUnsubscribe(data);
}
case MoqtMessageType::kSubscribeFin: {
auto data = std::get<MoqtSubscribeFin>(structured_data);
return framer_.SerializeSubscribeFin(data);
}
case MoqtMessageType::kSubscribeRst: {
auto data = std::get<MoqtSubscribeRst>(structured_data);
return framer_.SerializeSubscribeRst(data);
}
case MoqtMessageType::kAnnounce: {
auto data = std::get<MoqtAnnounce>(structured_data);
return framer_.SerializeAnnounce(data);
}
case moqt::MoqtMessageType::kAnnounceOk: {
auto data = std::get<MoqtAnnounceOk>(structured_data);
return framer_.SerializeAnnounceOk(data);
}
case moqt::MoqtMessageType::kAnnounceError: {
auto data = std::get<MoqtAnnounceError>(structured_data);
return framer_.SerializeAnnounceError(data);
}
case MoqtMessageType::kUnannounce: {
auto data = std::get<MoqtUnannounce>(structured_data);
return framer_.SerializeUnannounce(data);
}
case moqt::MoqtMessageType::kGoAway: {
auto data = std::get<MoqtGoAway>(structured_data);
return framer_.SerializeGoAway(data);
}
}
}
MoqtMessageType message_type_;
bool webtrans_;
quiche::SimpleBufferAllocator* buffer_allocator_;
MoqtFramer framer_;
};
INSTANTIATE_TEST_SUITE_P(MoqtFramerTests, MoqtFramerTest,
testing::ValuesIn(GetMoqtFramerTestParams()),
ParamNameFormatter);
TEST_P(MoqtFramerTest, OneMessage) {
auto message = MakeMessage(message_type_);
auto structured_data = message->structured_data();
auto buffer = SerializeMessage(structured_data);
EXPECT_EQ(buffer.size(), message->total_message_size());
EXPECT_EQ(buffer.AsStringView(), message->PacketSample());
}
} // namespace moqt::test