blob: c509be08b0f19b1f8441fb6dd21862aaebf1b2dc [file] [log] [blame]
// Copyright 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_subscribe_windows.h"
#include <optional>
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/web_transport/web_transport.h"
namespace moqt {
namespace test {
class QUICHE_EXPORT SubscribeWindowTest : public quic::test::QuicTest {
public:
SubscribeWindowTest() {}
const uint64_t subscribe_id_ = 2;
const uint64_t start_group_ = 4;
const uint64_t start_object_ = 0;
const uint64_t end_group_ = 5;
const uint64_t end_object_ = 5;
};
TEST_F(SubscribeWindowTest, Queries) {
SubscribeWindow window(subscribe_id_, MoqtForwardingPreference::kObject,
start_group_, start_object_, end_group_, end_object_);
EXPECT_EQ(window.subscribe_id(), 2);
EXPECT_TRUE(window.InWindow(FullSequence(4, 0)));
EXPECT_TRUE(window.InWindow(FullSequence(5, 5)));
EXPECT_FALSE(window.InWindow(FullSequence(5, 6)));
EXPECT_FALSE(window.InWindow(FullSequence(6, 0)));
EXPECT_FALSE(window.InWindow(FullSequence(3, 12)));
}
TEST_F(SubscribeWindowTest, AddQueryRemoveStreamIdTrack) {
SubscribeWindow window(subscribe_id_, MoqtForwardingPreference::kTrack,
start_group_, start_object_, end_group_, end_object_);
window.AddStream(4, 0, 2);
EXPECT_QUIC_BUG(window.AddStream(5, 2, 6), "Stream already added");
EXPECT_EQ(*window.GetStreamForSequence(FullSequence(5, 2)), 2);
window.RemoveStream(7, 2);
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(4, 0)).has_value());
}
TEST_F(SubscribeWindowTest, AddQueryRemoveStreamIdGroup) {
SubscribeWindow window(subscribe_id_, MoqtForwardingPreference::kGroup,
start_group_, start_object_, end_group_, end_object_);
window.AddStream(4, 0, 2);
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(5, 0)).has_value());
window.AddStream(5, 2, 6);
EXPECT_QUIC_BUG(window.AddStream(5, 3, 6), "Stream already added");
EXPECT_EQ(*window.GetStreamForSequence(FullSequence(4, 1)), 2);
EXPECT_EQ(*window.GetStreamForSequence(FullSequence(5, 0)), 6);
window.RemoveStream(5, 1);
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(5, 2)).has_value());
}
TEST_F(SubscribeWindowTest, AddQueryRemoveStreamIdObject) {
SubscribeWindow window(subscribe_id_, MoqtForwardingPreference::kObject,
start_group_, start_object_, end_group_, end_object_);
window.AddStream(4, 0, 2);
window.AddStream(4, 1, 6);
window.AddStream(4, 2, 10);
EXPECT_QUIC_BUG(window.AddStream(4, 2, 14), "Stream already added");
EXPECT_EQ(*window.GetStreamForSequence(FullSequence(4, 0)), 2);
EXPECT_EQ(*window.GetStreamForSequence(FullSequence(4, 2)), 10);
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(4, 4)).has_value());
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(5, 0)).has_value());
window.RemoveStream(4, 2);
EXPECT_FALSE(window.GetStreamForSequence(FullSequence(4, 2)).has_value());
}
TEST_F(SubscribeWindowTest, AddQueryRemoveStreamIdDatagram) {
SubscribeWindow window(subscribe_id_, MoqtForwardingPreference::kDatagram,
start_group_, start_object_, end_group_, end_object_);
EXPECT_QUIC_BUG(window.AddStream(4, 0, 2), "Adding a stream for datagram");
}
class QUICHE_EXPORT MoqtSubscribeWindowsTest : public quic::test::QuicTest {
public:
MoqtSubscribeWindowsTest() : windows_(MoqtForwardingPreference::kObject) {}
MoqtSubscribeWindows windows_;
};
TEST_F(MoqtSubscribeWindowsTest, IsEmpty) {
EXPECT_TRUE(windows_.IsEmpty());
windows_.AddWindow(0, 1, 3);
EXPECT_FALSE(windows_.IsEmpty());
}
TEST_F(MoqtSubscribeWindowsTest, IsSubscribed) {
EXPECT_TRUE(windows_.IsEmpty());
// The first two windows overlap; the third is open-ended.
windows_.AddWindow(0, 1, 0, 3, 9);
windows_.AddWindow(1, 2, 4, 4, 3);
windows_.AddWindow(2, 10, 0);
EXPECT_FALSE(windows_.IsEmpty());
EXPECT_TRUE(windows_.SequenceIsSubscribed(FullSequence(0, 8)).empty());
auto hits = windows_.SequenceIsSubscribed(FullSequence(1, 0));
EXPECT_EQ(hits.size(), 1);
EXPECT_EQ(hits[0]->subscribe_id(), 0);
EXPECT_TRUE(windows_.SequenceIsSubscribed(FullSequence(4, 4)).empty());
EXPECT_TRUE(windows_.SequenceIsSubscribed(FullSequence(8, 3)).empty());
hits = windows_.SequenceIsSubscribed(FullSequence(100, 7));
EXPECT_EQ(hits.size(), 1);
EXPECT_EQ(hits[0]->subscribe_id(), 2);
hits = windows_.SequenceIsSubscribed(FullSequence(3, 0));
EXPECT_EQ(hits.size(), 2);
EXPECT_EQ(hits[0]->subscribe_id() + hits[1]->subscribe_id(), 1);
}
TEST_F(MoqtSubscribeWindowsTest, AddGetRemoveWindow) {
windows_.AddWindow(0, 1, 0, 3, 9);
SubscribeWindow* window = windows_.GetWindow(0);
EXPECT_EQ(window->subscribe_id(), 0);
EXPECT_EQ(windows_.GetWindow(1), nullptr);
windows_.RemoveWindow(0);
EXPECT_EQ(windows_.GetWindow(0), nullptr);
}
} // namespace test
} // namespace moqt