Add QUIC_BUG_IF to QuicUtils::GetCryptoStreamId

In QUIC versions that use CRYPTO frames (instead of stream 1 frames) for
the crypto handshake, the concept of a "crypto stream ID" makes no
sense, so QuicUtils::GetCryptoStreamId should hit a QUIC_BUG_IF to
prevent its misuse.

gfe-relnote: Add QUIC_BUG_IF protected behind QuicVersionUsesCryptoFrames
PiperOrigin-RevId: 248463613
Change-Id: If6768658e9ffc058778b53a91f95839826602fbf
diff --git a/quic/test_tools/simple_session_notifier_test.cc b/quic/test_tools/simple_session_notifier_test.cc
index 53712fd..e5298eb 100644
--- a/quic/test_tools/simple_session_notifier_test.cc
+++ b/quic/test_tools/simple_session_notifier_test.cc
@@ -4,10 +4,12 @@
 
 #include "net/third_party/quiche/src/quic/test_tools/simple_session_notifier.h"
 
+#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
 
 using testing::_;
 using testing::InSequence;
@@ -126,6 +128,9 @@
 }
 
 TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    return;
+  }
   InSequence s;
   // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
@@ -159,6 +164,9 @@
 }
 
 TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    return;
+  }
   InSequence s;
   // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
@@ -221,6 +229,71 @@
   EXPECT_FALSE(notifier_.WillingToWrite());
 }
 
+TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
+  if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    return;
+  }
+  SimpleDataProducer producer;
+  connection_.SetDataProducer(&producer);
+  InSequence s;
+  // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, std::string(1024, 'a'));
+  producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, std::string(524, 'a'));
+  notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
+  // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+  connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<NullEncrypter>(
+                                                    Perspective::IS_CLIENT));
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, std::string(1024, 'a'));
+  notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
+  // Send stream 3 [0, 1024) and connection is blocked.
+  EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  notifier_.WriteOrBufferData(3, 1024, FIN);
+  // Send stream 5 [0, 1024).
+  EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
+  notifier_.WriteOrBufferData(5, 1024, NO_FIN);
+  // Reset stream 5 with error.
+  EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
+  notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
+
+  // Lost crypto data [500, 1500) and stream 3 [0, 512).
+  QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
+  QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
+  QuicStreamFrame stream3_frame(3, false, 0, 512);
+  notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
+  notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
+  notifier_.OnFrameLost(QuicFrame(stream3_frame));
+
+  // Connection becomes writable.
+  // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
+  // they are in different encryption levels.
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
+      .WillOnce(Invoke(&connection_,
+                       &MockQuicConnection::QuicConnection_SendCryptoData));
+  // Lost stream 3 data gets retransmitted.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
+      .WillOnce(Return(QuicConsumedData(512, false)));
+  // Buffered control frames get sent.
+  EXPECT_CALL(connection_, SendControlFrame(_))
+      .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
+  // Buffered stream 3 data [512, 1024) gets sent.
+  EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
+      .WillOnce(Return(QuicConsumedData(512, true)));
+  notifier_.OnCanWrite();
+  EXPECT_FALSE(notifier_.WillingToWrite());
+}
+
 TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
   InSequence s;
   // Send stream 3 data [0, 10) and fin.