xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/nghttp2_data_provider_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/http2/adapter/nghttp2_data_provider.h"
2 
3 #include "quiche/http2/adapter/test_utils.h"
4 #include "quiche/common/platform/api/quiche_test.h"
5 
6 namespace http2 {
7 namespace adapter {
8 namespace test {
9 
10 const size_t kFrameHeaderSize = 9;
11 
12 // Verifies that a nghttp2_data_provider derived from a DataFrameSource works
13 // correctly with nghttp2-style callbacks when the amount of data read is less
14 // than what the source provides.
TEST(DataProviderTest,ReadLessThanSourceProvides)15 TEST(DataProviderTest, ReadLessThanSourceProvides) {
16   DataSavingVisitor visitor;
17   TestDataFrameSource source(visitor, true);
18   source.AppendPayload("Example payload");
19   source.EndData();
20   auto provider = MakeDataProvider(&source);
21   uint32_t data_flags = 0;
22   const int32_t kStreamId = 1;
23   const size_t kReadLength = 10;
24   // Read callback selects a payload length given an upper bound.
25   ssize_t result =
26       provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
27                               &data_flags, &provider->source, nullptr);
28   ASSERT_EQ(kReadLength, result);
29   EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY, data_flags);
30 
31   const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
32   // Sends the frame header and some payload bytes.
33   int send_result = callbacks::DataFrameSourceSendCallback(
34       nullptr, nullptr, framehd, result, &provider->source, nullptr);
35   EXPECT_EQ(0, send_result);
36   // Data accepted by the visitor includes a frame header and kReadLength bytes
37   // of payload.
38   EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kReadLength);
39 }
40 
41 // Verifies that a nghttp2_data_provider derived from a DataFrameSource works
42 // correctly with nghttp2-style callbacks when the amount of data read is more
43 // than what the source provides.
TEST(DataProviderTest,ReadMoreThanSourceProvides)44 TEST(DataProviderTest, ReadMoreThanSourceProvides) {
45   DataSavingVisitor visitor;
46   const absl::string_view kPayload = "Example payload";
47   TestDataFrameSource source(visitor, true);
48   source.AppendPayload(kPayload);
49   source.EndData();
50   auto provider = MakeDataProvider(&source);
51   uint32_t data_flags = 0;
52   const int32_t kStreamId = 1;
53   const size_t kReadLength = 30;
54   // Read callback selects a payload length given an upper bound.
55   ssize_t result =
56       provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
57                               &data_flags, &provider->source, nullptr);
58   ASSERT_EQ(kPayload.size(), result);
59   EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
60 
61   const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
62   // Sends the frame header and some payload bytes.
63   int send_result = callbacks::DataFrameSourceSendCallback(
64       nullptr, nullptr, framehd, result, &provider->source, nullptr);
65   EXPECT_EQ(0, send_result);
66   // Data accepted by the visitor includes a frame header and the entire
67   // payload.
68   EXPECT_EQ(visitor.data().size(), kFrameHeaderSize + kPayload.size());
69 }
70 
71 // Verifies that a nghttp2_data_provider derived from a DataFrameSource works
72 // correctly with nghttp2-style callbacks when the source is blocked.
TEST(DataProviderTest,ReadFromBlockedSource)73 TEST(DataProviderTest, ReadFromBlockedSource) {
74   DataSavingVisitor visitor;
75   // Source has no payload, but also no fin, so it's blocked.
76   TestDataFrameSource source(visitor, false);
77   auto provider = MakeDataProvider(&source);
78   uint32_t data_flags = 0;
79   const int32_t kStreamId = 1;
80   const size_t kReadLength = 10;
81   ssize_t result =
82       provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
83                               &data_flags, &provider->source, nullptr);
84   // Read operation is deferred, since the source is blocked.
85   EXPECT_EQ(NGHTTP2_ERR_DEFERRED, result);
86 }
87 
88 // Verifies that a nghttp2_data_provider derived from a DataFrameSource works
89 // correctly with nghttp2-style callbacks when the source provides only fin and
90 // no data.
TEST(DataProviderTest,ReadFromZeroLengthSource)91 TEST(DataProviderTest, ReadFromZeroLengthSource) {
92   DataSavingVisitor visitor;
93   // Empty payload and fin=true indicates the source is done.
94   TestDataFrameSource source(visitor, true);
95   source.EndData();
96   auto provider = MakeDataProvider(&source);
97   uint32_t data_flags = 0;
98   const int32_t kStreamId = 1;
99   const size_t kReadLength = 10;
100   ssize_t result =
101       provider->read_callback(nullptr, kStreamId, nullptr, kReadLength,
102                               &data_flags, &provider->source, nullptr);
103   ASSERT_EQ(0, result);
104   EXPECT_EQ(NGHTTP2_DATA_FLAG_NO_COPY | NGHTTP2_DATA_FLAG_EOF, data_flags);
105 
106   const uint8_t framehd[kFrameHeaderSize] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
107   int send_result = callbacks::DataFrameSourceSendCallback(
108       nullptr, nullptr, framehd, result, &provider->source, nullptr);
109   EXPECT_EQ(0, send_result);
110   // Data accepted by the visitor includes a frame header with fin and zero
111   // bytes of payload.
112   EXPECT_EQ(visitor.data().size(), kFrameHeaderSize);
113 }
114 
115 }  // namespace test
116 }  // namespace adapter
117 }  // namespace http2
118