gfe-relnote: Let GFE be able to use HTTP2(tree-style) priority write scheduler in QUIC and enable it via a connection option H2PR. Protected by gfe2_reloadable_flag_quic_use_http2_priority_write_scheduler.

PiperOrigin-RevId: 260938733
Change-Id: I6d3f6c325a07b17bdfd8c416add8327b8d54be8a
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index dce8ec6..267208f 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -917,6 +917,88 @@
   session_.OnCanWrite();
 }
 
+TEST_P(QuicSessionTestServer, Http2Priority) {
+  if (VersionHasIetfQuicFrames(GetParam().transport_version)) {
+    return;
+  }
+  SetQuicReloadableFlag(quic_use_http2_priority_write_scheduler, true);
+  QuicTagVector copt;
+  copt.push_back(kH2PR);
+  QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+  session_.OnConfigNegotiated();
+  ASSERT_TRUE(session_.use_http2_priority_write_scheduler());
+
+  session_.set_writev_consumes_all_data(true);
+  TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream4 = session_.CreateOutgoingBidirectionalStream();
+  TestStream* stream6 = session_.CreateOutgoingBidirectionalStream();
+
+  session_.set_writev_consumes_all_data(true);
+  /*
+           0
+          /|\
+         2 4 6
+  */
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  // Verify streams are scheduled round robin.
+  InSequence s;
+  EXPECT_CALL(*stream2, OnCanWrite());
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+
+  /*
+           0
+           |
+           4
+          / \
+         2   6
+  */
+  // Update stream 4's priority.
+  stream4->SetPriority(
+      spdy::SpdyStreamPrecedence(0, spdy::kHttp2DefaultStreamWeight, true));
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+    session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  }));
+  EXPECT_CALL(*stream4, OnCanWrite());
+  EXPECT_CALL(*stream2, OnCanWrite());
+  session_.OnCanWrite();
+  EXPECT_CALL(*stream6, OnCanWrite());
+  session_.OnCanWrite();
+
+  /*
+         0
+         |
+         6
+         |
+         4
+         |
+         2
+  */
+  // Update stream 6's priority.
+  stream6->SetPriority(
+      spdy::SpdyStreamPrecedence(0, spdy::kHttp2DefaultStreamWeight, true));
+  session_.MarkConnectionLevelWriteBlocked(stream2->id());
+  session_.MarkConnectionLevelWriteBlocked(stream4->id());
+  session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+  EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+    session_.MarkConnectionLevelWriteBlocked(stream6->id());
+  }));
+  EXPECT_CALL(*stream6, OnCanWrite());
+  EXPECT_CALL(*stream4, OnCanWrite());
+  session_.OnCanWrite();
+  EXPECT_CALL(*stream2, OnCanWrite());
+  session_.OnCanWrite();
+}
+
 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
   // Encryption needs to be established before data can be sent.
   CryptoHandshakeMessage msg;