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

Unified Diff: net/quic/quic_headers_stream_test.cc

Issue 1408803002: relnote: Measure HOL blocking in QUIC headers stream. Flag protected by quic_measure_headers_hol_bl… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@uma_for_hol_merge
Patch Set: get rid of git certs leakage Created 5 years, 2 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/quic_headers_stream.cc ('k') | net/quic/quic_stream_sequencer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_headers_stream_test.cc
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index fd566bfbace8a9a4a11b27067e864601fa91c98c..661a0e88c089f9e6501ae9dc2bc5029e3c8f716f 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -4,6 +4,7 @@
#include "net/quic/quic_headers_stream.h"
+#include "base/test/histogram_tester.h"
#include "net/quic/quic_utils.h"
#include "net/quic/spdy_utils.h"
#include "net/quic/test_tools/quic_connection_peer.h"
@@ -14,10 +15,14 @@
#include "net/spdy/spdy_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+using base::Bucket;
+using base::HistogramTester;
using base::StringPiece;
using std::ostream;
using std::string;
using std::vector;
+using testing::ElementsAre;
+using testing::InSequence;
using testing::Invoke;
using testing::StrictMock;
using testing::WithArgs;
@@ -27,6 +32,9 @@ namespace net {
namespace test {
namespace {
+// TODO(ckrasic): this workaround is due to absence of std::initializer_list
+const bool kFins[] = {false, true};
+
class MockVisitor : public SpdyFramerVisitorInterface {
public:
MOCK_METHOD1(OnError, void(SpdyFramer* framer));
@@ -124,6 +132,7 @@ class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
EXPECT_EQ(version(), session_.connection()->version());
EXPECT_TRUE(headers_stream_ != nullptr);
VLOG(1) << GetParam();
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
}
QuicConsumedData SaveIov(const QuicIOVector& data) {
@@ -246,8 +255,7 @@ TEST_P(QuicHeadersStreamTest, EffectivePriority) {
TEST_P(QuicHeadersStreamTest, WriteHeaders) {
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
+ for (bool fin : kFins) {
if (perspective() == Perspective::IS_SERVER) {
WriteHeadersAndExpectSynReply(stream_id, fin);
} else {
@@ -263,8 +271,7 @@ TEST_P(QuicHeadersStreamTest, WriteHeaders) {
TEST_P(QuicHeadersStreamTest, ProcessRawData) {
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
+ for (bool fin : kFins) {
for (QuicPriority priority = 0; priority < 7; ++priority) {
// Replace with "WriteHeadersAndSaveData"
scoped_ptr<SpdySerializedFrame> frame;
@@ -296,6 +303,121 @@ TEST_P(QuicHeadersStreamTest, ProcessRawData) {
}
}
+TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) {
+// In the absence of surfacing HOL measurements externally, via UMA
+// or tcp connection stats, log messages are the only indication.
+// This test verifies that false positives are not generated when
+// headers arrive in order.
+#if 0
+ ScopedMockLog log(kDoNotCaptureLogsYet);
+ EXPECT_CALL(log, Log(_, _, _)).Times(0);
+ log.StartCapturingLogs();
+#endif
+ InSequence seq;
+ HistogramTester histogram_tester;
+ bool fin = true;
+ for (int stream_num = 0; stream_num < 10; stream_num++) {
+ QuicStreamId stream_id = QuicClientDataStreamId(stream_num);
+ // Replace with "WriteHeadersAndSaveData"
+ scoped_ptr<SpdySerializedFrame> frame;
+ if (perspective() == Perspective::IS_SERVER) {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ headers_frame.set_has_priority(true);
+ frame.reset(framer_.SerializeFrame(headers_frame));
+ EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
+ } else {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ frame.reset(framer_.SerializeFrame(headers_frame));
+ }
+ EXPECT_CALL(session_, OnStreamHeaders(stream_id, _));
+ EXPECT_CALL(session_,
+ OnStreamHeadersComplete(stream_id, fin, frame->size()));
+ stream_frame_.data = StringPiece(frame->data(), frame->size());
+ headers_stream_->OnStreamFrame(stream_frame_);
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+ stream_frame_.offset += frame->size();
+ }
+ histogram_tester.ExpectTotalCount("Net.QuicSession.HeadersHOLBlockedTime", 0);
+}
+
+TEST_P(QuicHeadersStreamTest, NonEmptyHeaderHOLBlockedTime) {
+// In the absence of surfacing HOL measurements externally, via UMA
+// or tcp connection stats, log messages are the only indication.
+// This test verifies that HOL blocking log messages are correct
+// when there are out of order arrivals.
+#if 0
+ ScopedMockLog log(kDoNotCaptureLogsYet);
+#endif
+ HistogramTester histogram_tester;
+ QuicStreamId stream_id;
+ bool fin = true;
+ QuicStreamFrame stream_frames[10];
+ scoped_ptr<SpdySerializedFrame> frames[10];
+ // First create all the frames in order
+ {
+ InSequence seq;
+ for (int stream_num = 0; stream_num < 10; ++stream_num) {
+ stream_id = QuicClientDataStreamId(stream_num);
+ if (perspective() == Perspective::IS_SERVER) {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ headers_frame.set_has_priority(true);
+ frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)).Times(1);
+ } else {
+ SpdyHeadersIR headers_frame(stream_id);
+ headers_frame.set_header_block(headers_);
+ headers_frame.set_fin(fin);
+ frames[stream_num].reset(framer_.SerializeFrame(headers_frame));
+ }
+ stream_frames[stream_num] = stream_frame_;
+ stream_frames[stream_num].data =
+ StringPiece(frames[stream_num]->data(), frames[stream_num]->size());
+ DVLOG(1) << "make frame for stream " << stream_num << " offset "
+ << stream_frames[stream_num].offset;
+ stream_frame_.offset += frames[stream_num]->size();
+ EXPECT_CALL(session_, OnStreamHeaders(stream_id, _)).Times(1);
+ EXPECT_CALL(session_, OnStreamHeadersComplete(stream_id, fin, _))
+ .Times(1);
+ }
+ }
+#if 0
+ // Actually writing the frames in reverse order will trigger log messages.
+ {
+ InSequence seq;
+ for (int stream_num = 0; stream_num < 10; ++stream_num) {
+ stream_id = QuicClientDataStreamId(stream_num);
+ if (stream_num > 0) {
+ string expected_msg = StringPrintf(
+ "stream %d: Net.QuicSession.HeadersHOLBlockedTime %d",
+ stream_id, stream_num);
+#ifndef NDEBUG
+ EXPECT_CALL(log, Log(INFO, _, expected_msg));
+#endif
+ }
+ }
+ }
+ log.StartCapturingLogs();
+#endif
+ for (int stream_num = 9; stream_num >= 0; --stream_num) {
+ DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset "
+ << stream_frames[stream_num].offset;
+ headers_stream_->OnStreamFrame(stream_frames[stream_num]);
+ connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
+ }
+ // We expect 1 sample each for delays from 1 to 9 ms (8 and 9 go
+ // into the same bucket).
+ EXPECT_THAT(
+ histogram_tester.GetAllSamples("Net.QuicSession.HeadersHOLBlockedTime"),
+ ElementsAre(Bucket(1, 1), Bucket(2, 1), Bucket(3, 1), Bucket(4, 1),
+ Bucket(5, 1), Bucket(6, 1), Bucket(7, 1), Bucket(8, 2)));
+}
+
TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
// We want to create a frame that is more than the SPDY Framer's max control
// frame size, which is 16K, but less than the HPACK decoders max decode
@@ -305,8 +427,7 @@ TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
headers_["key2"] = string(1 << 13, '.');
for (QuicStreamId stream_id = kClientDataStreamId1;
stream_id < kClientDataStreamId3; stream_id += 2) {
- for (int count = 0; count < 2; ++count) {
- bool fin = (count == 0);
+ for (bool fin : kFins) {
for (QuicPriority priority = 0; priority < 7; ++priority) {
// Replace with "WriteHeadersAndSaveData"
scoped_ptr<SpdySerializedFrame> frame;
« no previous file with comments | « net/quic/quic_headers_stream.cc ('k') | net/quic/quic_stream_sequencer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698