proxygen
DownstreamTransactionTest.cpp File Reference

Go to the source code of this file.

Classes

class  DownstreamTransactionTest
 

Functions

 TEST_F (DownstreamTransactionTest, SimpleCallbackForwarding)
 
 TEST_F (DownstreamTransactionTest, RegularWindowUpdate)
 
 TEST_F (DownstreamTransactionTest, NoWindowUpdate)
 
 TEST_F (DownstreamTransactionTest, WindowIncrease)
 
 TEST_F (DownstreamTransactionTest, WindowDecrease)
 
 TEST_F (DownstreamTransactionTest, ParseErrorCbs)
 
 TEST_F (DownstreamTransactionTest, DetachFromNotify)
 
 TEST_F (DownstreamTransactionTest, DeferredEgress)
 
 TEST_F (DownstreamTransactionTest, InternalError)
 
 TEST_F (DownstreamTransactionTest, UnpausedFlowControlViolation)
 

Function Documentation

TEST_F ( DownstreamTransactionTest  ,
SimpleCallbackForwarding   
)

Test that the the transaction properly forwards callbacks to the handler and that it interacts with its transport as expected.

Definition at line 113 of file DownstreamTransactionTest.cpp.

References proxygen::DOWNSTREAM, proxygen::makeGetRequest(), and transport_.

113  {
114  // flow control is disabled
115  HTTPTransaction txn(
116  TransportDirection::DOWNSTREAM,
118  txnEgressQueue_, transactionTimeouts_.get(),
119  std::chrono::milliseconds(500));
120  setupRequestResponseFlow(&txn, 100);
121 
122  txn.onIngressHeadersComplete(makeGetRequest());
123  eventBase_.loop();
124 }
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
uint64_t StreamID
Definition: HTTPCodec.h:49
TEST_F ( DownstreamTransactionTest  ,
RegularWindowUpdate   
)

Testing that we're sending a window update for simple requests

Definition at line 129 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, EXPECT_CALL, proxygen::spdy::kInitialWindow, proxygen::makeGetRequest(), transport_, and uint32_t.

129  {
130  HTTPTransaction txn(
131  TransportDirection::DOWNSTREAM,
133  txnEgressQueue_, transactionTimeouts_.get(),
134  std::chrono::milliseconds(500),
135  nullptr,
136  true, // flow control enabled
137  400,
139  uint32_t reqBodySize = 220;
140  setupRequestResponseFlow(&txn, reqBodySize);
141 
142  // test that the window update is generated
143  EXPECT_CALL(transport_, sendWindowUpdate(_, reqBodySize));
144 
145  // run the test
146  txn.onIngressHeadersComplete(makeGetRequest());
147  eventBase_.loop();
148 }
const uint32_t kInitialWindow
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
NoWindowUpdate   
)

Definition at line 150 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, EXPECT_CALL, proxygen::spdy::kInitialWindow, proxygen::makeBuf(), proxygen::makeGetRequest(), proxygen::makeResponse(), transport_, and uint32_t.

150  {
151  HTTPTransaction txn(
152  TransportDirection::DOWNSTREAM,
154  txnEgressQueue_, transactionTimeouts_.get(),
155  std::chrono::milliseconds(500),
156  nullptr,
157  true, // flow control enabled
158  450, // more than 2x req size
160  uint32_t reqBodySize = 220;
161  setupRequestResponseFlow(&txn, reqBodySize, true);
162 
163  EXPECT_CALL(transport_, sendWindowUpdate(_, reqBodySize))
164  .Times(0);
165 
166  // run the test
167  txn.onIngressHeadersComplete(makeGetRequest());
168  txn.onIngressBody(makeBuf(reqBodySize), 0);
169  txn.onIngressEOM();
170  auto response = makeResponse(200);
171  txn.sendHeaders(*response.get());
172  txn.sendBody(makeBuf(reqBodySize));
173  txn.sendEOM();
174  eventBase_.loop();
175 }
const uint32_t kInitialWindow
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
std::unique_ptr< HTTPMessage > makeResponse(uint16_t statusCode)
Definition: TestUtils.cpp:147
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
WindowIncrease   
)

Testing window increase using window update; we're actually using this in production to avoid bumping the window using the SETTINGS frame

Definition at line 181 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, EXPECT_CALL, proxygen::spdy::kInitialWindow, proxygen::makeGetRequest(), transport_, and uint32_t.

181  {
182  // set initial window size higher than per-stream window
183  HTTPTransaction txn(
184  TransportDirection::DOWNSTREAM,
186  txnEgressQueue_, transactionTimeouts_.get(),
187  std::chrono::milliseconds(500),
188  nullptr,
189  true, // flow control enabled
192  uint32_t reqSize = 500;
193  setupRequestResponseFlow(&txn, reqSize);
194 
195  // we expect the difference from the per stream window and the initial window,
196  // together with the bytes sent in the request
197  uint32_t perStreamWindow = spdy::kInitialWindow + 1024 * 1024;
198  uint32_t expectedWindowUpdate =
199  perStreamWindow - spdy::kInitialWindow;
200  EXPECT_CALL(transport_, sendWindowUpdate(_, expectedWindowUpdate));
201 
202  // use a higher window
203  txn.setReceiveWindow(perStreamWindow);
204 
205  txn.onIngressHeadersComplete(makeGetRequest());
206  eventBase_.loop();
207 }
const uint32_t kInitialWindow
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
WindowDecrease   
)

Testing that we're not sending window update when per-stream window size is smaller than the initial window size

Definition at line 213 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, EXPECT_CALL, proxygen::spdy::kInitialWindow, proxygen::makeGetRequest(), transport_, and uint32_t.

213  {
214  // set initial window size higher than per-stream window
215  HTTPTransaction txn(
216  TransportDirection::DOWNSTREAM,
218  txnEgressQueue_, transactionTimeouts_.get(),
219  std::chrono::milliseconds(500),
220  nullptr,
221  true, // flow control enabled
224  setupRequestResponseFlow(&txn, 500);
225 
226  // in this case, there should be no window update, as we decrease the window
227  // below the number of bytes we're sending
228  EXPECT_CALL(transport_, sendWindowUpdate(_, _)).Times(0);
229 
230  // use a smaller window
231  uint32_t perStreamWindow = spdy::kInitialWindow - 1000;
232  txn.setReceiveWindow(perStreamWindow);
233 
234  txn.onIngressHeadersComplete(makeGetRequest());
235  eventBase_.loop();
236 }
const uint32_t kInitialWindow
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
ParseErrorCbs   
)

Definition at line 238 of file DownstreamTransactionTest.cpp.

References testing::_, ASSERT_EQ, proxygen::DOWNSTREAM, dummy(), EXPECT_CALL, proxygen::HTTPException::getDirection(), proxygen::HTTPException::INGRESS, testing::Invoke(), proxygen::makeBuf(), string, transport_, and proxygen::Exception::what().

238  {
239  // Test where the transaction gets on parse error and then a body
240  // callback. This is possible because codecs are stateless between
241  // frames.
242 
243  HTTPTransaction txn(
244  TransportDirection::DOWNSTREAM,
246  txnEgressQueue_, transactionTimeouts_.get(),
247  std::chrono::milliseconds(500));
248 
249  HTTPException err(HTTPException::Direction::INGRESS, "test");
250  err.setHttpStatusCode(400);
251 
253 
254  EXPECT_CALL(handler_, setTransaction(&txn));
255  EXPECT_CALL(handler_, onError(_))
256  .WillOnce(Invoke([] (const HTTPException& ex) {
257  ASSERT_EQ(ex.getDirection(), HTTPException::Direction::INGRESS);
258  ASSERT_EQ(std::string(ex.what()), "test");
259  }));
260  // onBody() is suppressed since ingress is complete after ingress onError()
261  // onEOM() is suppressed since ingress is complete after ingress onError()
262  EXPECT_CALL(transport_, sendAbort(_, _));
263  EXPECT_CALL(handler_, detachTransaction());
264  EXPECT_CALL(transport_, detach(&txn));
265 
266  txn.setHandler(&handler_);
267  txn.onError(err);
268  // Since the transaction is already closed for ingress, giving it
269  // ingress body causes the transaction to be aborted and closed
270  // immediately.
271  txn.onIngressBody(makeBuf(10), 0);
272 
273  eventBase_.loop();
274 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
Direction getDirection() const
Definition: HTTPException.h:67
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void dummy()
const char * string
Definition: Conv.cpp:212
AsyncFizzClient::UniquePtr transport_
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
const char * what(void) const noexceptoverride
Definition: Exception.cpp:26
TEST_F ( DownstreamTransactionTest  ,
DetachFromNotify   
)

Definition at line 276 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, dummy(), EXPECT_CALL, EXPECT_EQ, proxygen::HTTPMessage::getStatusCode(), handler(), proxygen::HTTPException::INGRESS_AND_EGRESS, testing::Invoke(), testing::InvokeWithoutArgs(), proxygen::makeBuf(), proxygen::makeGetRequest(), proxygen::makeResponse(), and transport_.

276  {
277  unique_ptr<StrictMock<MockHTTPHandler>> handler(
279 
280  HTTPTransaction txn(
281  TransportDirection::DOWNSTREAM,
283  txnEgressQueue_, transactionTimeouts_.get(),
284  std::chrono::milliseconds(500));
285 
287 
288  EXPECT_CALL(*handler, setTransaction(&txn));
289  EXPECT_CALL(*handler, onHeadersComplete(_))
290  .WillOnce(Invoke([&](std::shared_ptr<HTTPMessage> /*msg*/) {
291  auto response = makeResponse(200);
292  txn.sendHeaders(*response.get());
293  txn.sendBody(makeBuf(10));
294  }));
295  EXPECT_CALL(transport_, sendHeaders(&txn, _, _, _))
296  .WillOnce(Invoke([&](Unused, const HTTPMessage& headers, Unused, Unused) {
297  EXPECT_EQ(headers.getStatusCode(), 200);
298  }));
299  EXPECT_CALL(transport_, notifyEgressBodyBuffered(10));
300  EXPECT_CALL(transport_, notifyEgressBodyBuffered(-10))
301  .WillOnce(InvokeWithoutArgs([&] () {
302  txn.setHandler(nullptr);
303  handler.reset();
304  }));
305  EXPECT_CALL(transport_, detach(&txn));
306 
307  HTTPException err(HTTPException::Direction::INGRESS_AND_EGRESS, "test");
308 
309  txn.setHandler(handler.get());
310  txn.onIngressHeadersComplete(makeGetRequest());
311  txn.onError(err);
312 }
uint16_t getStatusCode() const
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
void handler(int, siginfo_t *, void *)
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void dummy()
std::unique_ptr< HTTPMessage > makeResponse(uint16_t statusCode)
Definition: TestUtils.cpp:147
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
DeferredEgress   
)

Definition at line 314 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, dummy(), EXPECT_CALL, EXPECT_EQ, proxygen::HTTPMessage::getStatusCode(), proxygen::HTTPException::INGRESS_AND_EGRESS, testing::Invoke(), proxygen::makeBuf(), proxygen::makeGetRequest(), proxygen::makeResponse(), testing::Return(), and transport_.

314  {
315  EXPECT_CALL(transport_, describe(_))
316  .WillRepeatedly(Return());
317  EXPECT_CALL(transport_, notifyPendingEgress())
318  .WillRepeatedly(Return());
319 
320  HTTPTransaction txn(
321  TransportDirection::DOWNSTREAM,
323  txnEgressQueue_, transactionTimeouts_.get(),
324  std::chrono::milliseconds(500),
325  nullptr, true, 10, 10);
326 
328 
329  EXPECT_CALL(handler_, setTransaction(&txn));
330  EXPECT_CALL(handler_, onHeadersComplete(_))
331  .WillOnce(Invoke([&](std::shared_ptr<HTTPMessage> /*msg*/) {
332  auto response = makeResponse(200);
333  txn.sendHeaders(*response.get());
334  txn.sendBody(makeBuf(10));
335  txn.sendBody(makeBuf(20));
336  }));
337  EXPECT_CALL(transport_, sendHeaders(&txn, _, _, _))
338  .WillOnce(Invoke([&](Unused, const HTTPMessage& headers, Unused, Unused) {
339  EXPECT_EQ(headers.getStatusCode(), 200);
340  }));
341 
342  // when enqueued
343  EXPECT_CALL(transport_, notifyEgressBodyBuffered(10));
344  EXPECT_CALL(handler_, onEgressPaused());
345  // sendBody
346  EXPECT_CALL(transport_, notifyEgressBodyBuffered(20));
347 
348  txn.setHandler(&handler_);
349  txn.onIngressHeadersComplete(makeGetRequest());
350 
351  // onWriteReady, send, then dequeue (SPDY window now full)
352  EXPECT_CALL(transport_, notifyEgressBodyBuffered(-20));
353 
354  EXPECT_EQ(txn.onWriteReady(20, 1), false);
355 
356  // enqueued after window update
357  EXPECT_CALL(transport_, notifyEgressBodyBuffered(20));
358 
359  txn.onIngressWindowUpdate(20);
360 
361  // Buffer released on error
362  EXPECT_CALL(transport_, notifyEgressBodyBuffered(-20));
363  EXPECT_CALL(handler_, onError(_));
364  EXPECT_CALL(handler_, detachTransaction());
365  EXPECT_CALL(transport_, detach(&txn));
366 
367  HTTPException err(HTTPException::Direction::INGRESS_AND_EGRESS, "test");
368  txn.onError(err);
369 }
uint16_t getStatusCode() const
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void dummy()
std::unique_ptr< HTTPMessage > makeResponse(uint16_t statusCode)
Definition: TestUtils.cpp:147
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
internal::ReturnAction< R > Return(R value)
TEST_F ( DownstreamTransactionTest  ,
InternalError   
)

Definition at line 371 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, dummy(), EXPECT_CALL, EXPECT_EQ, proxygen::HTTPMessage::getStatusCode(), handler(), proxygen::HTTPException::INGRESS_AND_EGRESS, proxygen::INTERNAL_ERROR, testing::Invoke(), proxygen::makeGetRequest(), proxygen::makeResponse(), and transport_.

371  {
372  unique_ptr<StrictMock<MockHTTPHandler>> handler(
374 
375  HTTPTransaction txn(
376  TransportDirection::DOWNSTREAM,
378  txnEgressQueue_, transactionTimeouts_.get(),
379  std::chrono::milliseconds(500));
380 
382 
383  EXPECT_CALL(*handler, setTransaction(&txn));
384  EXPECT_CALL(*handler, onHeadersComplete(_))
385  .WillOnce(Invoke([&](std::shared_ptr<HTTPMessage> /*msg*/) {
386  auto response = makeResponse(200);
387  txn.sendHeaders(*response.get());
388  }));
389  EXPECT_CALL(transport_, sendHeaders(&txn, _, _, _))
390  .WillOnce(Invoke([&](Unused, const HTTPMessage& headers, Unused, Unused) {
391  EXPECT_EQ(headers.getStatusCode(), 200);
392  }));
393  EXPECT_CALL(transport_, sendAbort(&txn, ErrorCode::INTERNAL_ERROR));
394  EXPECT_CALL(*handler, detachTransaction());
395  EXPECT_CALL(transport_, detach(&txn));
396 
397  HTTPException err(HTTPException::Direction::INGRESS_AND_EGRESS, "test");
398 
399  txn.setHandler(handler.get());
400  txn.onIngressHeadersComplete(makeGetRequest());
401  txn.sendAbort();
402 }
uint16_t getStatusCode() const
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
void handler(int, siginfo_t *, void *)
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void dummy()
std::unique_ptr< HTTPMessage > makeResponse(uint16_t statusCode)
Definition: TestUtils.cpp:147
AsyncFizzClient::UniquePtr transport_
std::unique_ptr< HTTPMessage > makeGetRequest()
Definition: TestUtils.cpp:98
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _
TEST_F ( DownstreamTransactionTest  ,
UnpausedFlowControlViolation   
)

Definition at line 404 of file DownstreamTransactionTest.cpp.

References testing::_, proxygen::DOWNSTREAM, EXPECT_CALL, proxygen::FLOW_CONTROL_ERROR, handler(), proxygen::spdy::kInitialWindow, proxygen::makeBuf(), proxygen::makePostRequest(), and transport_.

404  {
406 
407  InSequence enforceOrder;
408  HTTPTransaction txn(
409  TransportDirection::DOWNSTREAM,
411  txnEgressQueue_, transactionTimeouts_.get(),
412  std::chrono::milliseconds(500),
413  nullptr,
414  true, // flow control enabled
415  400,
417 
418  EXPECT_CALL(handler, setTransaction(&txn));
419  EXPECT_CALL(handler, onHeadersComplete(_));
420  EXPECT_CALL(transport_, sendAbort(&txn, ErrorCode::FLOW_CONTROL_ERROR));
421  EXPECT_CALL(handler, detachTransaction());
422  EXPECT_CALL(transport_, detach(&txn));
423 
424  txn.setHandler(&handler);
425  txn.onIngressHeadersComplete(makePostRequest(401));
426  txn.onIngressBody(makeBuf(401), 0);
427 }
const uint32_t kInitialWindow
std::unique_ptr< HTTPMessage > makePostRequest(uint32_t contentLength)
Definition: TestUtils.cpp:124
void handler(int, siginfo_t *, void *)
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
AsyncFizzClient::UniquePtr transport_
#define EXPECT_CALL(obj, call)
uint64_t StreamID
Definition: HTTPCodec.h:49
const internal::AnythingMatcher _