Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Unified Diff: net/quic/reliable_quic_stream_test.cc

Issue 14651009: Land Recent QUIC changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix integer constant is too large for 'unsigned long' type Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/reliable_quic_stream.cc ('k') | net/quic/spdy_utils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/reliable_quic_stream_test.cc
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index 0c2079c9159e5c446b7ac788322e86442bb289e0..d86a0b6c77bedfc8e4ddb120adb48106905c1b4d 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -5,15 +5,21 @@
#include "net/quic/reliable_quic_stream.h"
#include "net/quic/quic_connection.h"
+#include "net/quic/quic_spdy_compressor.h"
+#include "net/quic/quic_spdy_decompressor.h"
#include "net/quic/quic_utils.h"
+#include "net/quic/spdy_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
using base::StringPiece;
+using std::min;
using testing::_;
using testing::InSequence;
using testing::Return;
+using testing::SaveArg;
using testing::StrEq;
+using testing::StrictMock;
namespace net {
namespace test {
@@ -22,81 +28,284 @@ namespace {
const char kData1[] = "FooAndBar";
const char kData2[] = "EepAndBaz";
const size_t kDataLen = 9;
+const QuicGuid kGuid = 42;
+const QuicGuid kStreamId = 3;
+const bool kIsServer = true;
+const bool kShouldProcessData = true;
-class QuicReliableTestStream : public ReliableQuicStream {
+class TestStream : public ReliableQuicStream {
public:
- QuicReliableTestStream(QuicStreamId id, QuicSession* session)
- : ReliableQuicStream(id, session) {
+ TestStream(QuicStreamId id,
+ QuicSession* session,
+ bool should_process_data)
+ : ReliableQuicStream(id, session),
+ should_process_data_(should_process_data) {
}
+
virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
- return 0;
+ LOG(INFO) << "data_len: " << data_len;
+ data_ += string(data, data_len);
+ return should_process_data_ ? data_len : 0;
}
+
using ReliableQuicStream::WriteData;
using ReliableQuicStream::CloseReadSide;
using ReliableQuicStream::CloseWriteSide;
+
+ const string& data() const { return data_; }
+
+ private:
+ bool should_process_data_;
+ string data_;
};
class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
public:
- ReliableQuicStreamTest()
- : connection_(new MockConnection(1, IPEndPoint(), false)),
- session_(connection_, true),
- stream_(1, &session_) {
+ ReliableQuicStreamTest() {
+ headers_[":host"] = "www.google.com";
+ headers_[":path"] = "/index.hml";
+ headers_[":scheme"] = "https";
}
+ void Initialize(bool stream_should_process_data) {
+ connection_ = new MockConnection(kGuid, IPEndPoint(), kIsServer);
+ session_.reset(new MockSession(connection_, kIsServer));
+ stream_.reset(new TestStream(kStreamId, session_.get(),
+ stream_should_process_data));
+ stream2_.reset(new TestStream(kStreamId + 2, session_.get(),
+ stream_should_process_data));
+ compressor_.reset(new QuicSpdyCompressor());
+ decompressor_.reset(new QuicSpdyDecompressor);
+ }
+
+ protected:
MockConnection* connection_;
- MockSession session_;
- QuicReliableTestStream stream_;
+ scoped_ptr<MockSession> session_;
+ scoped_ptr<TestStream> stream_;
+ scoped_ptr<TestStream> stream2_;
+ scoped_ptr<QuicSpdyCompressor> compressor_;
+ scoped_ptr<QuicSpdyDecompressor> decompressor_;
+ SpdyHeaderBlock headers_;
};
TEST_F(ReliableQuicStreamTest, WriteAllData) {
+ Initialize(kShouldProcessData);
+
connection_->options()->max_packet_length =
1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion);
// TODO(rch): figure out how to get StrEq working here.
- //EXPECT_CALL(session_, WriteData(_, StrEq(kData1), _, _)).WillOnce(
- EXPECT_CALL(session_, WriteData(1, _, _, _)).WillOnce(
+ //EXPECT_CALL(*session_, WriteData(kStreamId, StrEq(kData1), _, _)).WillOnce(
+ EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
Return(QuicConsumedData(kDataLen, true)));
- EXPECT_EQ(kDataLen, stream_.WriteData(kData1, false).bytes_consumed);
+ EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
}
TEST_F(ReliableQuicStreamTest, WriteData) {
+ Initialize(kShouldProcessData);
+
connection_->options()->max_packet_length =
1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion);
// TODO(rch): figure out how to get StrEq working here.
- //EXPECT_CALL(session_, WriteData(_, StrEq(kData1), _, _)).WillOnce(
- EXPECT_CALL(session_, WriteData(_, _, _, _)).WillOnce(
+ //EXPECT_CALL(*session_, WriteData(_, StrEq(kData1), _, _)).WillOnce(
+ EXPECT_CALL(*session_, WriteData(_, _, _, _)).WillOnce(
Return(QuicConsumedData(kDataLen - 1, false)));
// The return will be kDataLen, because the last byte gets buffered.
- EXPECT_EQ(kDataLen, stream_.WriteData(kData1, false).bytes_consumed);
+ EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
// Queue a bytes_consumed write.
- EXPECT_EQ(kDataLen, stream_.WriteData(kData2, false).bytes_consumed);
+ EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed);
// Make sure we get the tail of the first write followed by the bytes_consumed
InSequence s;
- //EXPECT_CALL(session_, WriteData(_, StrEq(&kData2[kDataLen - 1]), _, _)).
- EXPECT_CALL(session_, WriteData(_, _, _, _)).
+ //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData1[kDataLen - 1]), _, _)).
+ EXPECT_CALL(*session_, WriteData(_, _, _, _)).
WillOnce(Return(QuicConsumedData(1, false)));
- //EXPECT_CALL(session_, WriteData(_, StrEq(kData2), _, _)).
- EXPECT_CALL(session_, WriteData(_, _, _, _)).
+ //EXPECT_CALL(*session_, WriteData(_, StrEq(kData2), _, _)).
+ EXPECT_CALL(*session_, WriteData(_, _, _, _)).
WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
- stream_.OnCanWrite();
+ stream_->OnCanWrite();
// And finally the end of the bytes_consumed
- //EXPECT_CALL(session_, WriteData(_, StrEq(&kData2[kDataLen - 2]), _, _)).
- EXPECT_CALL(session_, WriteData(_, _, _, _)).
+ //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData2[kDataLen - 2]), _, _)).
+ EXPECT_CALL(*session_, WriteData(_, _, _, _)).
WillOnce(Return(QuicConsumedData(2, true)));
- stream_.OnCanWrite();
+ stream_->OnCanWrite();
}
TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
- stream_.CloseReadSide();
- stream_.CloseWriteSide();
- EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_.stream_error());
- EXPECT_EQ(QUIC_NO_ERROR, stream_.connection_error());
- stream_.ConnectionClose(QUIC_INTERNAL_ERROR, false);
- EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_.stream_error());
- EXPECT_EQ(QUIC_NO_ERROR, stream_.connection_error());
+ Initialize(kShouldProcessData);
+
+ stream_->CloseReadSide();
+ stream_->CloseWriteSide();
+ EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+ EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
+ stream_->ConnectionClose(QUIC_INTERNAL_ERROR, false);
+ EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
+ EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeaders) {
+ Initialize(kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ QuicStreamFrame frame(kStreamId, false, 0, compressed_headers);
+
+ stream_->OnStreamFrame(frame);
+ EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_), stream_->data());
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersWithInvalidHeaderId) {
+ Initialize(kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ compressed_headers.replace(0, 1, 1, '\xFF'); // Illegal header id.
+ QuicStreamFrame frame(kStreamId, false, 0, compressed_headers);
+
+ EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID));
+ stream_->OnStreamFrame(frame);
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBody) {
+ Initialize(kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ string body = "this is the body";
+ string data = compressed_headers + body;
+ QuicStreamFrame frame(kStreamId, false, 0, data);
+
+ stream_->OnStreamFrame(frame);
+ EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
+ stream_->data());
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyFragments) {
+ Initialize(kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ string body = "this is the body";
+ string data = compressed_headers + body;
+
+ for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
+ Initialize(kShouldProcessData);
+ for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
+ size_t remaining_data = data.length() - offset;
+ StringPiece fragment(data.data() + offset,
+ min(fragment_size, remaining_data));
+ QuicStreamFrame frame(kStreamId, false, offset, fragment);
+
+ stream_->OnStreamFrame(frame);
+ }
+ ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
+ stream_->data()) << "fragment_size: " << fragment_size;
+ }
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) {
+ Initialize(!kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ string body = "this is the body";
+ string data = compressed_headers + body;
+ QuicStreamFrame frame(kStreamId, false, 0, data);
+ string uncompressed_headers =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+ string uncompressed_data = uncompressed_headers + body;
+
+ stream_->OnStreamFrame(frame);
+ EXPECT_EQ(uncompressed_data, stream_->data());
+
+ char buffer[1024];
+ ASSERT_LT(data.length(), arraysize(buffer));
+ struct iovec vec;
+ vec.iov_base = buffer;
+ vec.iov_len = arraysize(buffer);
+
+ size_t bytes_read = stream_->Readv(&vec, 1);
+ EXPECT_EQ(uncompressed_headers.length(), bytes_read);
+ EXPECT_EQ(uncompressed_headers, string(buffer, bytes_read));
+
+ bytes_read = stream_->Readv(&vec, 1);
+ EXPECT_EQ(body.length(), bytes_read);
+ EXPECT_EQ(body, string(buffer, bytes_read));
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
+ Initialize(!kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ string body = "this is the body";
+ string data = compressed_headers + body;
+ QuicStreamFrame frame(kStreamId, false, 0, data);
+ string uncompressed_headers =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+ string uncompressed_data = uncompressed_headers + body;
+
+ stream_->OnStreamFrame(frame);
+ EXPECT_EQ(uncompressed_data, stream_->data());
+
+ char buffer[1];
+ struct iovec vec;
+ vec.iov_base = buffer;
+ vec.iov_len = arraysize(buffer);
+ for (size_t i = 0; i < uncompressed_data.length(); ++i) {
+ size_t bytes_read = stream_->Readv(&vec, 1);
+ ASSERT_EQ(1u, bytes_read);
+ EXPECT_EQ(uncompressed_data.data()[i], buffer[0]);
+ }
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
+ Initialize(!kShouldProcessData);
+
+ string compressed_headers = compressor_->CompressHeaders(headers_);
+ string body = "this is the body";
+ string data = compressed_headers + body;
+ QuicStreamFrame frame(kStreamId, false, 0, data);
+ string uncompressed_headers =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+ string uncompressed_data = uncompressed_headers + body;
+
+ stream_->OnStreamFrame(frame);
+ EXPECT_EQ(uncompressed_data, stream_->data());
+
+ char buffer1[1];
+ char buffer2[1];
+ struct iovec vec[2];
+ vec[0].iov_base = buffer1;
+ vec[0].iov_len = arraysize(buffer1);
+ vec[1].iov_base = buffer2;
+ vec[1].iov_len = arraysize(buffer2);
+ for (size_t i = 0; i < uncompressed_data.length(); i += 2) {
+ size_t bytes_read = stream_->Readv(vec, 2);
+ ASSERT_EQ(2u, bytes_read) << i;
+ ASSERT_EQ(uncompressed_data.data()[i], buffer1[0]) << i;
+ ASSERT_EQ(uncompressed_data.data()[i + 1], buffer2[0]) << i;
+ }
+}
+
+TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) {
+ Initialize(kShouldProcessData);
+
+ string compressed_headers1 = compressor_->CompressHeaders(headers_);
+ QuicStreamFrame frame1(stream_->id(), false, 0, compressed_headers1);
+ string decompressed_headers1 =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+
+ headers_["content-type"] = "text/plain";
+ string compressed_headers2 = compressor_->CompressHeaders(headers_);
+ QuicStreamFrame frame2(stream2_->id(), false, 0, compressed_headers2);
+ string decompressed_headers2 =
+ SpdyUtils::SerializeUncompressedHeaders(headers_);
+
+ stream2_->OnStreamFrame(frame2);
+ EXPECT_EQ("", stream_->data());
+
+ stream_->OnStreamFrame(frame1);
+ EXPECT_EQ(decompressed_headers1, stream_->data());
+
+ EXPECT_EQ(2u, session_->decompressor()->current_header_id());
+ stream2_->OnDecompressorAvailable();
+ EXPECT_EQ(decompressed_headers2, stream2_->data());
}
} // namespace
« no previous file with comments | « net/quic/reliable_quic_stream.cc ('k') | net/quic/spdy_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698