TEST_F(ProxygenTransportTest, push_abort) { // Push a resource Array headers; uint8_t pri = 1; headers.add(String("hello"), String("world")); // dict serializtion path auto id = pushResource(headers, pri); // Creates a new transaction and sends headers, but not body MockHTTPTransaction pushTxn(TransportDirection::DOWNSTREAM, HTTPCodec::StreamID(1), 1, m_egressQueue, WheelTimerInstance(m_timeouts.get())); HTTPPushTransactionHandler* pushHandler = nullptr; expectPushPromiseAndHeaders(pushTxn, pri, &pushHandler); m_server.deliverMessages(); HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS, "Stream aborted, streamID"); ex.setProxygenError(proxygen::kErrorStreamAbort); ex.setCodecStatusCode(proxygen::ErrorCode::CANCEL); pushTxn.onError(ex); pushHandler->detachTransaction(); m_transport->pushResourceBody(id, nullptr, 0, true); m_server.deliverMessages(); sendResponse("12345"); }
TEST_F(ProxygenTransportTest, push_abort_incomplete) { // Push a resource Array headers; uint8_t pri = 1; headers.add(String("hello"), String("world")); // dict serializtion path pushResource(headers, pri); // Creates a new transaction and sends headers, but not body MockHTTPTransaction pushTxn(TransportDirection::DOWNSTREAM, HTTPCodec::StreamID(1), 1, m_egressQueue, WheelTimerInstance(m_timeouts.get())); HTTPPushTransactionHandler* pushHandler = nullptr; expectPushPromiseAndHeaders(pushTxn, pri, &pushHandler); m_server.deliverMessages(); sendResponse("12345"); EXPECT_CALL(pushTxn, sendAbort()) .WillOnce(Invoke([pushHandler] { pushHandler->detachTransaction(); })); // Simulate termination of the VM thread while there is an incomplete push // This aborts the incomplete push TearDown(); }
TEST_F(ProxygenTransportTest, push) { // Push a resource Array headers; uint8_t pri = 1; headers.append("hello: world"); // vec serialization path auto id = pushResource(headers, pri); // And some body bytes std::string body("12345"); m_transport->pushResourceBody(id, body.data(), body.length(), false); EXPECT_EQ(m_server.m_messageQueue.size(), 3); // Creates a new transaction and sends headers/body MockHTTPTransaction pushTxn(TransportDirection::DOWNSTREAM, HTTPCodec::StreamID(1), 1, m_egressQueue, WheelTimerInstance(m_timeouts.get())); HTTPPushTransactionHandler* pushHandler = nullptr; expectPushPromiseAndHeaders(pushTxn, pri, &pushHandler); EXPECT_CALL(pushTxn, sendBody(_)); m_server.deliverMessages(); // Send Push EOM m_transport->pushResourceBody(id, nullptr, 0, true); EXPECT_EQ(m_server.m_messageQueue.size(), 1); EXPECT_CALL(pushTxn, sendEOM()); m_server.deliverMessages(); pushHandler->detachTransaction(); // Send response sendResponse("12345"); }
ProxygenTransportTest() : m_timeouts(folly::HHWheelTimer::newTimer( &m_eventBase, std::chrono::milliseconds( folly::HHWheelTimer::DEFAULT_TICK_INTERVAL), folly::AsyncTimeout::InternalEnum::NORMAL, std::chrono::milliseconds(100))), m_txn( TransportDirection::DOWNSTREAM, HTTPCodec::StreamID(1), 1, m_egressQueue, WheelTimerInstance(m_timeouts.get())) { m_transport = std::make_shared<ProxygenTransport>(&m_server); m_transport->setTransactionReference(m_transport); m_transport->setTransaction(&m_txn); }
TEST_F(ProxygenTransportTest, push_empty_body) { // Push a resource Array headers; uint8_t pri = 1; headers.add(String("hello"), String("world")); // dict serializtion path pushResource(headers, pri, true /* eom, no body */); // Creates a new transaction and sends headers and an empty body MockHTTPTransaction pushTxn(TransportDirection::DOWNSTREAM, HTTPCodec::StreamID(1), 1, m_egressQueue, WheelTimerInstance(m_timeouts.get())); HTTPPushTransactionHandler* pushHandler = nullptr; expectPushPromiseAndHeaders(pushTxn, pri, &pushHandler); EXPECT_CALL(pushTxn, sendEOM()); m_server.deliverMessages(); pushHandler->detachTransaction(); // Send response sendResponse("12345"); }
HTTPConnector::HTTPConnector(Callback* callback, folly::HHWheelTimer* timeoutSet) : HTTPConnector(callback, WheelTimerInstance(timeoutSet)) { }