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

Unified Diff: net/filter/sdch_stream_unittest.cc

Issue 1662763002: [ON HOLD] Implement pull-based design for content decoding (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
Index: net/filter/sdch_stream_unittest.cc
diff --git a/net/filter/sdch_stream_unittest.cc b/net/filter/sdch_stream_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fe1a194c485ffcab2d8026d985b504d199dcfe40
--- /dev/null
+++ b/net/filter/sdch_stream_unittest.cc
@@ -0,0 +1,240 @@
+// Copyright 2015 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 <string>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "net/base/io_buffer.h"
+#include "net/filter/mock_stream_source.h"
+#include "net/filter/sdch_stream_delegate.h"
+#include "net/filter/sdch_stream_source.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+using net::Error;
+using net::MockStreamSource;
+using net::SdchStreamSource;
+
+const size_t kBufferSize = 4096;
+const char* kDictionaryError = "dictionary error";
+const char* kDecodingError = "decoding error";
+
+static const char kTestVcdiffDictionary[] =
+ "DictionaryFor"
+ "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";
+static const char kTestData[] =
+ "0000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000TestData "
+ "SdchCompression1SdchCompression2SdchCompression3SdchCompression"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000\n";
+static const char kSdchCompressedTestData[] =
+ "\326\303\304\0\0\001M\0\201S\202\004\0\201E\006\001"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "TestData 00000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000\n\001S\023\077\001r\r";
+
+class SdchStreamTest : public ::testing::Test,
+ public net::SdchStreamSourceDelegate {
+ public:
+ SdchStreamTest()
+ : dictionary_error_handled_(false), decoding_error_handled_(false) {}
+
+ void SetUp() override {
+ ::testing::Test::SetUp();
+
+ out_buffer_ = new net::IOBuffer(kBufferSize);
+
+ scoped_ptr<MockStreamSource> source(new MockStreamSource);
+ source_ = source.get();
+ sdch_stream_.reset(new SdchStreamSource(std::move(source), this));
+ }
+
+ net::IOBuffer* out_buffer() { return out_buffer_.get(); }
+ char* out_data() { return out_buffer_->data(); }
+ size_t out_buffer_size() { return kBufferSize; }
+
+ Error last_error() { return last_error_; }
+ size_t last_bytes_read() { return last_bytes_read_; }
+
+ MockStreamSource* source() { return source_; }
+ SdchStreamSource* sdch_stream() { return sdch_stream_.get(); }
+
+ bool dictionary_error_handled() { return dictionary_error_handled_; }
+ bool decoding_error_handled() { return decoding_error_handled_; }
+ std::string last_get_dictionary_id() { return last_get_dictionary_id_; }
+
+ net::StreamSource::OnReadCompleteCallback callback() {
+ return base::Bind(&SdchStreamTest::OnReadComplete, base::Unretained(this));
+ }
+
+ void OnReadComplete(Error error, size_t bytes_read) {
+ last_error_ = error;
+ last_bytes_read_ = bytes_read;
+ }
+
+ void ReadStream() {
+ last_error_ = sdch_stream()->Read(out_buffer(), out_buffer_size(),
+ &last_bytes_read_, callback());
+ }
+
+ void SetTestDictionary(const std::string& dictionary_id,
+ const std::string& dictionary_text) {
+ test_dictionary_id_ = dictionary_id;
+ test_dictionary_text_ = dictionary_text;
+ }
+
+ void AppendDictionaryIdTo(std::string* resp, std::string* server_id) {
+ std::string client_id;
+ net::SdchManager::GenerateHash(kTestVcdiffDictionary, &client_id,
+ server_id);
+ SetTestDictionary(*server_id, kTestVcdiffDictionary);
+ char response[server_id->size() + 1];
+ memcpy(response, server_id->data(), server_id->size());
+ response[server_id->size()] = '\0';
+ resp->append(response, server_id->size() + 1);
+ }
+
+ // SdchStreamSourceDelegate implementation.
+ bool HandleDictionaryError(SdchStreamSource* source) override {
+ dictionary_error_handled_ = true;
+ sdch_stream()->ReplaceOutput(kDictionaryError, strlen(kDictionaryError));
+ return true;
+ }
+
+ bool HandleDecodingError(SdchStreamSource* source) override {
+ decoding_error_handled_ = true;
+ sdch_stream()->ReplaceOutput(kDecodingError, strlen(kDictionaryError));
+ return true;
+ }
+
+ bool GetDictionary(const std::string& server_id,
+ const std::string** text) override {
+ last_get_dictionary_id_ = server_id;
+ if (server_id == test_dictionary_id_) {
+ *text = &test_dictionary_text_;
+ return true;
+ }
+ return false;
+ }
+
+ void NotifyStreamDone() override {}
+
+ private:
+ // Owned by sdch_stream_.
+ MockStreamSource* source_;
+ scoped_ptr<SdchStreamSource> sdch_stream_;
+
+ scoped_refptr<net::IOBuffer> out_buffer_;
+
+ std::string test_dictionary_id_;
+ std::string test_dictionary_text_;
+
+ size_t last_bytes_read_;
+ Error last_error_;
+ std::string last_get_dictionary_id_;
+ bool dictionary_error_handled_;
+ bool decoding_error_handled_;
+};
+
+TEST_F(SdchStreamTest, EmptyStream) {
+ source()->AddReadResult("", 0, net::OK, true);
+ ReadStream();
+ EXPECT_EQ(net::OK, last_error());
+ EXPECT_EQ(0U, last_bytes_read());
+}
+
+// Ensure that GetDictionary() is not called at all if the SDCH dictionary ID is
+// malformed.
+TEST_F(SdchStreamTest, BogusDictionaryId) {
+ char id[] = {0x1f, '0', '0', '0', '0', '0', '0', '0', 0x0};
+ source()->AddReadResult(id, sizeof(id), net::OK, true);
+ SetTestDictionary(id, "...");
+ ReadStream();
+ EXPECT_TRUE(dictionary_error_handled());
+ EXPECT_EQ("", last_get_dictionary_id());
+ EXPECT_EQ(net::OK, last_error());
+ EXPECT_EQ(strlen(kDictionaryError), last_bytes_read());
+ EXPECT_EQ(0, memcmp(kDictionaryError, out_data(), last_bytes_read()));
+}
+
+// Ensure that the stream's dictionary error handler is called if GetDictionary
+// returns no dictionary.
+TEST_F(SdchStreamTest, NoDictionaryError) {
+ char id[] = "00000000";
+ source()->AddReadResult(id, sizeof(id), net::OK, true);
+ ReadStream();
+ EXPECT_TRUE(dictionary_error_handled());
+ EXPECT_EQ(id, last_get_dictionary_id());
+}
+
+TEST_F(SdchStreamTest, DictionaryLoaded) {
+ std::string response;
+ std::string server_id;
+ AppendDictionaryIdTo(&response, &server_id);
+ source()->AddReadResult(response.data(), response.size(), net::OK, true);
+ ReadStream();
+ EXPECT_FALSE(dictionary_error_handled());
+ EXPECT_EQ(server_id, last_get_dictionary_id());
+}
+
+TEST_F(SdchStreamTest, DecompressOneBlockSync) {
+ std::string response;
+ std::string server_id;
+ AppendDictionaryIdTo(&response, &server_id);
+ source()->AddReadResult(response.data(), response.size(), net::OK, true);
+ source()->AddReadResult(kSdchCompressedTestData,
+ sizeof(kSdchCompressedTestData) - 1, net::OK, true);
+ ReadStream();
+ EXPECT_FALSE(dictionary_error_handled());
+ EXPECT_FALSE(decoding_error_handled());
+ EXPECT_EQ(server_id, last_get_dictionary_id());
+ EXPECT_EQ(net::OK, last_error());
+ EXPECT_EQ(sizeof(kTestData) - 1, last_bytes_read());
+ EXPECT_EQ(0, memcmp(kTestData, out_data(), last_bytes_read()));
+}
+
+TEST_F(SdchStreamTest, DecompressTwoBlocksSync) {
+ std::string response;
+ std::string server_id;
+ AppendDictionaryIdTo(&response, &server_id);
+ source()->AddReadResult(response.data(), response.size(), net::OK, true);
+ source()->AddReadResult(kSdchCompressedTestData, 32, net::OK, true);
+ source()->AddReadResult(kSdchCompressedTestData + 32,
+ sizeof(kSdchCompressedTestData) - 1 - 32, net::OK,
+ true);
+ ReadStream();
+ EXPECT_FALSE(dictionary_error_handled());
+ EXPECT_FALSE(decoding_error_handled());
+ EXPECT_EQ(server_id, last_get_dictionary_id());
+ EXPECT_EQ(net::OK, last_error());
+ EXPECT_EQ(sizeof(kTestData) - 1, last_bytes_read());
+ EXPECT_EQ(0, memcmp(kTestData, out_data(), last_bytes_read()));
+}
+
+TEST_F(SdchStreamTest, DecompressOneBlockAsync) {
+ std::string response;
+ std::string server_id;
+ AppendDictionaryIdTo(&response, &server_id);
+ source()->AddReadResult(response.data(), response.size(), net::OK, false);
+ source()->AddReadResult(kSdchCompressedTestData,
+ sizeof(kSdchCompressedTestData) - 1, net::OK, false);
+ ReadStream();
+ EXPECT_EQ(net::ERR_IO_PENDING, last_error());
+ source()->CompleteNextRead();
+ // The callback hasn't been called yet, because the first read didn't return
+ // any bytes that could be decoded to produce output.
+ EXPECT_EQ(net::ERR_IO_PENDING, last_error());
+ source()->CompleteNextRead();
+ EXPECT_FALSE(dictionary_error_handled());
+ EXPECT_FALSE(decoding_error_handled());
+ EXPECT_EQ(server_id, last_get_dictionary_id());
+ EXPECT_EQ(net::OK, last_error());
+ EXPECT_EQ(sizeof(kTestData) - 1, last_bytes_read());
+ EXPECT_EQ(0, memcmp(kTestData, out_data(), last_bytes_read()));
+}
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698