Implement QuicTransportStream, a stream that can be only accessed after client indication is received.

gfe-relnote: n/a (not used in production)
PiperOrigin-RevId: 275553939
Change-Id: I19a2bf2f8335e6408204c7b5eac6dcfe2dc0a210
diff --git a/quic/quic_transport/quic_transport_stream_test.cc b/quic/quic_transport/quic_transport_stream_test.cc
new file mode 100644
index 0000000..8c5ca5b
--- /dev/null
+++ b/quic/quic_transport/quic_transport_stream_test.cc
@@ -0,0 +1,104 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h"
+#include <memory>
+
+#include "net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_session_interface.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using testing::Return;
+
+ParsedQuicVersionVector GetVersions() {
+  return {ParsedQuicVersion{PROTOCOL_TLS1_3, QUIC_VERSION_99}};
+}
+
+class MockQuicTransportSessionInterface : public QuicTransportSessionInterface {
+ public:
+  MOCK_CONST_METHOD0(IsSessionReady, bool());
+};
+
+class MockVisitor : public QuicTransportStream::Visitor {
+ public:
+  MOCK_METHOD0(OnCanRead, void());
+  MOCK_METHOD0(OnCanWrite, void());
+};
+
+class QuicTransportStreamTest : public QuicTest {
+ public:
+  QuicTransportStreamTest()
+      : connection_(new MockQuicConnection(&helper_,
+                                           &alarm_factory_,
+                                           Perspective::IS_CLIENT,
+                                           GetVersions())),
+        session_(connection_) {
+    session_.Initialize();
+
+    stream_ = new QuicTransportStream(0, &session_, &interface_);
+    session_.ActivateStream(QuicWrapUnique(stream_));
+    stream_->set_visitor(&visitor_);
+  }
+
+  void ReceiveStreamData(QuicStringPiece data, QuicStreamOffset offset) {
+    QuicStreamFrame frame(0, false, offset, data);
+    stream_->OnStreamFrame(frame);
+  }
+
+ protected:
+  MockAlarmFactory alarm_factory_;
+  MockQuicConnectionHelper helper_;
+
+  MockQuicConnection* connection_;  // Owned by |session_|.
+  MockQuicSession session_;
+  MockQuicTransportSessionInterface interface_;
+  MockVisitor visitor_;
+  QuicTransportStream* stream_;  // Owned by |session_|.
+};
+
+TEST_F(QuicTransportStreamTest, NotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  ReceiveStreamData("test", 0);
+  EXPECT_EQ(stream_->ReadableBytes(), 0u);
+  EXPECT_FALSE(stream_->CanWrite());
+}
+
+TEST_F(QuicTransportStreamTest, ReadWhenNotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  ReceiveStreamData("test", 0);
+  char buffer[4];
+  QuicByteCount bytes_read = stream_->Read(buffer, sizeof(buffer));
+  EXPECT_EQ(bytes_read, 0u);
+}
+
+TEST_F(QuicTransportStreamTest, WriteWhenNotReady) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(false));
+  EXPECT_FALSE(stream_->Write("test"));
+}
+
+TEST_F(QuicTransportStreamTest, Ready) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  ReceiveStreamData("test", 0);
+  EXPECT_EQ(stream_->ReadableBytes(), 4u);
+  EXPECT_TRUE(stream_->CanWrite());
+  EXPECT_TRUE(stream_->Write("test"));
+}
+
+TEST_F(QuicTransportStreamTest, ReceiveData) {
+  EXPECT_CALL(interface_, IsSessionReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, OnCanRead());
+  ReceiveStreamData("test", 0);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic