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

Unified Diff: net/http2/tools/random_decoder_test.cc

Issue 2293613002: Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Replace LOG(INFO) by VLOG(2) in DecodeBufferTest.SlowDecodeTestStruct so that trybots do not fail. Created 4 years 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/http2/tools/random_decoder_test.h ('k') | net/net.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http2/tools/random_decoder_test.cc
diff --git a/net/http2/tools/random_decoder_test.cc b/net/http2/tools/random_decoder_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8fd36743dff0dcdf11fe8a8161e5626c0567a39c
--- /dev/null
+++ b/net/http2/tools/random_decoder_test.cc
@@ -0,0 +1,179 @@
+// Copyright 2016 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/http2/tools/random_decoder_test.h"
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "net/http2/decoder/decode_buffer.h"
+#include "net/http2/decoder/decode_status.h"
+#include "net/http2/http2_constants.h"
+#include "net/http2/tools/failure.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// It's rather time consuming to decode large buffers one at a time,
+// especially with the log level cranked up. So, by default we don't do
+// that unless explicitly requested.
+
+using ::testing::AssertionFailure;
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using base::StringPiece;
+
+namespace net {
+namespace test {
+
+std::string HexEncode(StringPiece s) {
+ return base::HexEncode(s.data(), s.size());
+}
+
+RandomDecoderTest::RandomDecoderTest() {}
+
+bool RandomDecoderTest::StopDecodeOnDone() {
+ return stop_decode_on_done_;
+}
+
+DecodeStatus RandomDecoderTest::DecodeSegments(DecodeBuffer* original,
+ const SelectSize& select_size) {
+ DecodeStatus status = DecodeStatus::kDecodeInProgress;
+ bool first = true;
+ VLOG(2) << "DecodeSegments: input size=" << original->Remaining();
+ while (first || original->HasData()) {
+ size_t remaining = original->Remaining();
+ size_t size = std::min(
+ remaining, select_size.Run(first, original->Offset(), remaining));
+ DecodeBuffer db(original->cursor(), size);
+ VLOG(2) << "Decoding " << size << " bytes of " << remaining << " remaining";
+ if (first) {
+ first = false;
+ status = StartDecoding(&db);
+ } else {
+ status = ResumeDecoding(&db);
+ }
+ // A decoder MUST consume some input (if any is available), else we could
+ // get stuck in infinite loops.
+ if (db.Offset() == 0 && db.HasData() &&
+ status != DecodeStatus::kDecodeError) {
+ ADD_FAILURE() << "Decoder didn't make any progress; db.FullSize="
+ << db.FullSize()
+ << " original.Offset=" << original->Offset();
+ return DecodeStatus::kDecodeError;
+ }
+ original->AdvanceCursor(db.Offset());
+ switch (status) {
+ case DecodeStatus::kDecodeDone:
+ if (original->Empty() || StopDecodeOnDone()) {
+ return DecodeStatus::kDecodeDone;
+ }
+ continue;
+ case DecodeStatus::kDecodeInProgress:
+ continue;
+ case DecodeStatus::kDecodeError:
+ return DecodeStatus::kDecodeError;
+ }
+ }
+ return status;
+}
+
+// Decode |original| multiple times, with different segmentations, validating
+// after each decode, returning on the first failure.
+AssertionResult RandomDecoderTest::DecodeAndValidateSeveralWays(
+ DecodeBuffer* original,
+ bool return_non_zero_on_first,
+ const Validator& validator) {
+ const uint32_t original_remaining = original->Remaining();
+ VLOG(1) << "DecodeAndValidateSeveralWays - Start, remaining = "
+ << original_remaining;
+ uint32_t first_consumed;
+ {
+ // Fast decode (no stopping unless decoder does so).
+ DecodeBuffer input(original->cursor(), original_remaining);
+ VLOG(2) << "DecodeSegmentsAndValidate with SelectRemaining";
+ VERIFY_SUCCESS(DecodeSegmentsAndValidate(
+ &input, base::Bind(&SelectRemaining), validator))
+ << "\nFailed with SelectRemaining; input.Offset=" << input.Offset()
+ << "; input.Remaining=" << input.Remaining();
+ first_consumed = input.Offset();
+ }
+ if (original_remaining <= 30) {
+ // Decode again, one byte at a time.
+ DecodeBuffer input(original->cursor(), original_remaining);
+ VLOG(2) << "DecodeSegmentsAndValidate with SelectOne";
+ VERIFY_SUCCESS(
+ DecodeSegmentsAndValidate(&input, base::Bind(&SelectOne), validator))
+ << "\nFailed with SelectOne; input.Offset=" << input.Offset()
+ << "; input.Remaining=" << input.Remaining();
+ VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectOne";
+ }
+ if (original_remaining <= 20) {
+ // Decode again, one or zero bytes at a time.
+ DecodeBuffer input(original->cursor(), original_remaining);
+ VLOG(2) << "DecodeSegmentsAndValidate with SelectZeroAndOne";
+ bool zero_next = !return_non_zero_on_first;
+ VERIFY_SUCCESS(DecodeSegmentsAndValidate(
+ &input, base::Bind(&SelectZeroAndOne, &zero_next), validator))
+ << "\nFailed with SelectZeroAndOne";
+ VERIFY_EQ(first_consumed, input.Offset())
+ << "\nFailed with SelectZeroAndOne; input.Offset=" << input.Offset()
+ << "; input.Remaining=" << input.Remaining();
+ }
+ {
+ // Decode again, with randomly selected segment sizes.
+ DecodeBuffer input(original->cursor(), original_remaining);
+ VLOG(2) << "DecodeSegmentsAndValidate with SelectRandom";
+ VERIFY_SUCCESS(DecodeSegmentsAndValidate(
+ &input, base::Bind(&RandomDecoderTest::SelectRandom,
+ base::Unretained(this), return_non_zero_on_first),
+ validator))
+ << "\nFailed with SelectRandom; input.Offset=" << input.Offset()
+ << "; input.Remaining=" << input.Remaining();
+ VERIFY_EQ(first_consumed, input.Offset()) << "\nFailed with SelectRandom";
+ }
+ VERIFY_EQ(original_remaining, original->Remaining());
+ original->AdvanceCursor(first_consumed);
+ VLOG(1) << "DecodeAndValidateSeveralWays - SUCCESS";
+ return ::testing::AssertionSuccess();
+}
+
+// static
+size_t RandomDecoderTest::SelectZeroAndOne(bool* zero_next,
+ bool first,
+ size_t offset,
+ size_t remaining) {
+ if (*zero_next) {
+ *zero_next = false;
+ return 0;
+ } else {
+ *zero_next = true;
+ return 1;
+ }
+}
+
+size_t RandomDecoderTest::SelectRandom(bool return_non_zero_on_first,
+ bool first,
+ size_t offset,
+ size_t remaining) {
+ uint32_t r = random_.Rand32();
+ if (first && return_non_zero_on_first) {
+ CHECK_LT(0u, remaining);
+ if (remaining == 1) {
+ return 1;
+ }
+ return 1 + (r % remaining); // size in range [1, remaining).
+ }
+ return r % (remaining + 1); // size in range [0, remaining].
+}
+
+uint32_t RandomDecoderTest::RandStreamId() {
+ return random_.Rand32() & StreamIdMask();
+}
+
+} // namespace test
+} // namespace net
« no previous file with comments | « net/http2/tools/random_decoder_test.h ('k') | net/net.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698