@@ -4947,3 +4947,61 @@ TEST_F(HTTP2DownstreamSessionTest, Observer_PreWrite) {
4947
4947
4948
4948
expectDetachSession ();
4949
4949
}
4950
+
4951
+ TEST_F (HTTPDownstreamSessionTest, InvariantViolation) {
4952
+ folly::DelayedDestruction::DestructorGuard g (httpSession_);
4953
+
4954
+ auto handler = addSimpleStrictHandler ();
4955
+ auto & txn = handler->txn_ ;
4956
+ // attempting to egress body first => invariantViolation
4957
+ handler->expectHeaders ([&]() { handler->sendBody (100 ); });
4958
+
4959
+ EXPECT_CALL (*handler, _onInvariantViolation (_)).WillOnce ([&]() {
4960
+ // invariantViolation callback can send headers if allowed
4961
+ CHECK (txn->canSendHeaders ());
4962
+ txn->sendHeaders (getResponse (500 , 0 ));
4963
+ });
4964
+
4965
+ sendRequest (getGetRequest (), /* eom=*/ true );
4966
+
4967
+ // this should detach transaction since invariantViolation triggers abort
4968
+ EXPECT_CALL (*handler, _detachTransaction);
4969
+ flushRequestsAndLoopN (1 );
4970
+ evbLoopNonBlockN (1 );
4971
+
4972
+ EXPECT_CALL (callbacks_, onHeadersComplete (_, _)).WillOnce ([](auto , auto msg) {
4973
+ EXPECT_EQ (msg->getStatusCode (), 500 );
4974
+ });
4975
+
4976
+ parseOutput (*clientCodec_);
4977
+ gracefulShutdown ();
4978
+ }
4979
+
4980
+ TEST_F (HTTP2DownstreamSessionTest, InvariantViolation) {
4981
+ auto handler = addSimpleStrictHandler ();
4982
+ auto & txn = handler->txn_ ;
4983
+ // attempting to egress body first => invariantViolation
4984
+ handler->expectHeaders ([&]() { handler->sendBody (100 ); });
4985
+
4986
+ EXPECT_CALL (*handler, _onInvariantViolation (_)).WillOnce ([&]() {
4987
+ // invariantViolation callback can send headers if allowed
4988
+ CHECK (txn->canSendHeaders ());
4989
+ txn->sendHeaders (getResponse (500 , 0 ));
4990
+ txn->sendEOM ();
4991
+ });
4992
+
4993
+ sendRequest (getGetRequest (), /* eom=*/ true );
4994
+
4995
+ // this should detach transaction since invariantViolation triggers abort
4996
+ EXPECT_CALL (*handler, _detachTransaction);
4997
+ flushRequestsAndLoopN (1 );
4998
+ evbLoopNonBlockN (2 );
4999
+
5000
+ EXPECT_CALL (callbacks_, onHeadersComplete (_, _)).WillOnce ([](auto , auto msg) {
5001
+ EXPECT_EQ (msg->getStatusCode (), 500 );
5002
+ });
5003
+ EXPECT_CALL (callbacks_, onAbort (_, ErrorCode::NO_ERROR));
5004
+
5005
+ parseOutput (*clientCodec_);
5006
+ gracefulShutdown ();
5007
+ }
0 commit comments