1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8 
9 #include <folly/portability/GTest.h>
10 #include <quic/common/test/TestUtils.h>
11 #include <quic/dsr/Types.h>
12 #include <quic/dsr/frontend/PacketBuilder.h>
13 #include <quic/dsr/test/TestCommon.h>
14 #include <quic/fizz/server/handshake/FizzServerQuicHandshakeContext.h>
15 #include <quic/handshake/test/Mocks.h>
16 #include <quic/server/state/ServerStateMachine.h>
17 
18 namespace quic {
19 namespace test {
20 
operator ==(const SendInstruction & instruction,const WriteStreamFrame & frame)21 bool operator==(
22     const SendInstruction& instruction,
23     const WriteStreamFrame& frame) {
24   return instruction.streamId == frame.streamId &&
25       instruction.offset == frame.offset && instruction.len == frame.len &&
26       instruction.fin == frame.fin;
27 }
28 
operator ==(const WriteStreamFrame & frame,const SendInstruction & instruction)29 bool operator==(
30     const WriteStreamFrame& frame,
31     const SendInstruction& instruction) {
32   return instruction == frame;
33 }
34 
35 class PacketBuilderTest : public DSRCommonTestFixture {
36  public:
PacketBuilderTest()37   PacketBuilderTest()
38       : cid(getTestConnectionId(0)),
39         header(ProtectionType::KeyPhaseZero, cid) {}
40 
41  protected:
42   ConnectionId cid;
43   ShortHeader header;
44 };
45 
TEST_F(PacketBuilderTest,SimpleBuild)46 TEST_F(PacketBuilderTest, SimpleBuild) {
47   StreamId id = 0;
48   uint64_t offset = 1;
49   uint64_t length = 1000;
50   bool fin = true;
51   uint64_t bufMetaStartingOffset = 333;
52   SendInstruction::Builder siBuilder(conn_, id);
53   siBuilder.setOffset(offset);
54   siBuilder.setLength(length);
55   siBuilder.setFin(fin);
56   siBuilder.setBufMetaStartingOffset(bufMetaStartingOffset);
57   auto sendInstruction = siBuilder.build();
58   DSRPacketBuilder packetBuilder(kDefaultUDPSendPacketLen, header, 0);
59   uint32_t streamEncodedSize = 1003;
60   SendInstruction instructionCopy(sendInstruction);
61   packetBuilder.addSendInstruction(
62       std::move(sendInstruction), streamEncodedSize);
63   auto packet = std::move(packetBuilder).buildPacket();
64   const auto& writePacket = packet.packet;
65   const auto& si = packet.sendInstructions.front();
66   EXPECT_EQ(1, writePacket.frames.size());
67   const auto& writeStreamFrame =
68       *writePacket.frames.front().asWriteStreamFrame();
69   EXPECT_TRUE(writeStreamFrame == instructionCopy);
70   EXPECT_TRUE(writeStreamFrame == si);
71   EXPECT_GT(packet.encodedSize, streamEncodedSize);
72 }
73 
TEST_F(PacketBuilderTest,SizeTooSmall)74 TEST_F(PacketBuilderTest, SizeTooSmall) {
75   DSRPacketBuilder packetBuilder(5, header, 0);
76   EXPECT_EQ(0, packetBuilder.remainingSpace());
77 }
78 
TEST_F(PacketBuilderTest,WriteTwoInstructions)79 TEST_F(PacketBuilderTest, WriteTwoInstructions) {
80   DSRPacketBuilder packetBuilder(kDefaultUDPSendPacketLen, header, 0);
81 
82   StreamId id = 0;
83   packetBuilder.addSendInstruction(
84       SendInstruction::Builder(conn_, id)
85           .setOffset(0)
86           .setLength(100)
87           .setFin(false)
88           .setBufMetaStartingOffset(333)
89           .build(),
90       110);
91   packetBuilder.addSendInstruction(
92       SendInstruction::Builder(conn_, id)
93           .setOffset(100)
94           .setLength(100)
95           .setFin(true)
96           .setBufMetaStartingOffset(333)
97           .build(),
98       110);
99   auto packet = std::move(packetBuilder).buildPacket();
100   const auto& writePacket = packet.packet;
101   EXPECT_EQ(2, packet.sendInstructions.size());
102   EXPECT_EQ(2, writePacket.frames.size());
103   WriteStreamFrame expectedFirstFrame(id, 0, 100, false, true);
104   WriteStreamFrame expectedSecondFrame(id, 100, 100, true, true);
105   EXPECT_EQ(expectedFirstFrame, *writePacket.frames[0].asWriteStreamFrame());
106   EXPECT_EQ(expectedSecondFrame, *writePacket.frames[1].asWriteStreamFrame());
107   EXPECT_TRUE(expectedFirstFrame == packet.sendInstructions[0]);
108   EXPECT_TRUE(expectedSecondFrame == packet.sendInstructions[1]);
109 }
110 
111 } // namespace test
112 } // namespace quic
113