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

Unified Diff: content/browser/renderer_host/websocket_blob_sender_unittest.cc

Issue 2119973002: Port WebSockets to Mojo IPC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compile error Created 4 years, 4 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: content/browser/renderer_host/websocket_blob_sender_unittest.cc
diff --git a/content/browser/renderer_host/websocket_blob_sender_unittest.cc b/content/browser/renderer_host/websocket_blob_sender_unittest.cc
deleted file mode 100644
index 590c914bdc032033ffc40354ad012af60282fe70..0000000000000000000000000000000000000000
--- a/content/browser/renderer_host/websocket_blob_sender_unittest.cc
+++ /dev/null
@@ -1,450 +0,0 @@
-// 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 "content/browser/renderer_host/websocket_blob_sender.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/location.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "content/browser/blob_storage/chrome_blob_storage_context.h"
-#include "content/public/browser/blob_handle.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/test/test_browser_context.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/completion_callback.h"
-#include "net/base/net_errors.h"
-#include "net/base/test_completion_callback.h"
-#include "storage/common/fileapi/file_system_types.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-const char kDummyUrl[] = "http://www.example.com/";
-const char kBanana[] = "banana";
-
-// This is small so that the tests do not waste too much time just copying bytes
-// around. But it has to be larger than kMinimumNonFinalFrameSize defined in
-// websocket_blob_sender.cc.
-const size_t kInitialQuota = 16 * 1024;
-
-using net::TestCompletionCallback;
-
-// A fake channel for testing. Records the contents of the message that was sent
-// through it. Quota is restricted, and is refreshed asynchronously in response
-// to calls to SendFrame().
-class FakeChannel : public WebSocketBlobSender::Channel {
- public:
- // |notify_new_quota| will be run asynchronously on the current MessageLoop
- // every time GetSendQuota() increases.
- FakeChannel() : weak_factory_(this) {}
-
- // This method must be called before SendFrame() is.
- void set_notify_new_quota(const base::Closure& notify_new_quota) {
- notify_new_quota_ = notify_new_quota;
- }
-
- size_t GetSendQuota() const override { return current_send_quota_; }
-
- ChannelState SendFrame(bool fin, const std::vector<char>& data) override {
- ++frames_sent_;
- EXPECT_FALSE(got_fin_);
- if (fin)
- got_fin_ = true;
- EXPECT_LE(data.size(), current_send_quota_);
- message_.insert(message_.end(), data.begin(), data.end());
- current_send_quota_ -= data.size();
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&FakeChannel::RefreshQuota, weak_factory_.GetWeakPtr()));
- return net::WebSocketEventInterface::CHANNEL_ALIVE;
- }
-
- bool got_fin() const { return got_fin_; }
-
- int frames_sent() const { return frames_sent_; }
-
- const std::vector<char>& message() const { return message_; }
-
- private:
- void RefreshQuota() {
- if (current_send_quota_ == kInitialQuota)
- return;
- current_send_quota_ = kInitialQuota;
- DCHECK(!notify_new_quota_.is_null());
- notify_new_quota_.Run();
- }
-
- base::Closure notify_new_quota_;
- size_t current_send_quota_ = kInitialQuota;
- int frames_sent_ = 0;
- bool got_fin_ = false;
- std::vector<char> message_;
- base::WeakPtrFactory<FakeChannel> weak_factory_;
-};
-
-class WebSocketBlobSenderTest : public ::testing::Test {
- protected:
- // The Windows implementation of net::FileStream::Context requires a real IO
- // MessageLoop.
- WebSocketBlobSenderTest()
- : threads_(TestBrowserThreadBundle::IO_MAINLOOP),
- chrome_blob_storage_context_(
- ChromeBlobStorageContext::GetFor(&browser_context_)),
- fake_channel_(nullptr),
- sender_() {}
- ~WebSocketBlobSenderTest() override {}
-
- void SetUp() override {
- // ChromeBlobStorageContext::GetFor() does some work asynchronously.
- base::RunLoop().RunUntilIdle();
- SetUpSender();
- }
-
- // This method can be overriden to use a different channel implementation.
- virtual void SetUpSender() {
- fake_channel_ = new FakeChannel;
- sender_.reset(new WebSocketBlobSender(base::WrapUnique(fake_channel_)));
- fake_channel_->set_notify_new_quota(base::Bind(
- &WebSocketBlobSender::OnNewSendQuota, base::Unretained(sender_.get())));
- }
-
- storage::BlobStorageContext* context() {
- return chrome_blob_storage_context_->context();
- }
-
- storage::FileSystemContext* GetFileSystemContext() {
- StoragePartition* partition = BrowserContext::GetStoragePartitionForSite(
- &browser_context_, GURL(kDummyUrl));
- return partition->GetFileSystemContext();
- }
-
- // |string| is copied.
- std::unique_ptr<BlobHandle> CreateMemoryBackedBlob(const char* string) {
- std::unique_ptr<BlobHandle> handle =
- chrome_blob_storage_context_->CreateMemoryBackedBlob(string,
- strlen(string));
- EXPECT_TRUE(handle);
- return handle;
- }
-
- // Call sender_.Start() with the other parameters filled in appropriately for
- // this test fixture.
- int Start(const std::string& uuid,
- uint64_t expected_size,
- const net::CompletionCallback& callback) {
- net::WebSocketEventInterface::ChannelState channel_state =
- net::WebSocketEventInterface::CHANNEL_ALIVE;
- return sender_->Start(
- uuid, expected_size, context(), GetFileSystemContext(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get(),
- &channel_state, callback);
- }
-
- void NotCalledCallbackImpl(int rv) {
- ADD_FAILURE()
- << "Callback that should not be called was called with argument " << rv;
- }
-
- net::CompletionCallback NotCalled() {
- return base::Bind(&WebSocketBlobSenderTest::NotCalledCallbackImpl,
- base::Unretained(this));
- }
-
- void ExpectOkAndQuit(base::RunLoop* run_loop, int result) {
- EXPECT_EQ(net::OK, result);
- run_loop->Quit();
- }
-
- net::CompletionCallback ExpectOkAndQuitCallback(base::RunLoop* run_loop) {
- return base::Bind(&WebSocketBlobSenderTest::ExpectOkAndQuit,
- base::Unretained(this), run_loop);
- }
-
- TestBrowserThreadBundle threads_;
- TestBrowserContext browser_context_;
- scoped_refptr<ChromeBlobStorageContext> chrome_blob_storage_context_;
- // |fake_channel_| is owned by |sender_|.
- FakeChannel* fake_channel_;
- std::unique_ptr<WebSocketBlobSender> sender_;
-};
-
-TEST_F(WebSocketBlobSenderTest, Construction) {}
-
-TEST_F(WebSocketBlobSenderTest, EmptyBlob) {
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob("");
-
- // The APIs allow for this to be asynchronous but that is unlikely in
- // practice.
- int result = Start(handle->GetUUID(), UINT64_C(0), NotCalled());
- // If this fails with result == -1, someone has changed the code to be
- // asynchronous and this test should be adapted to match.
- EXPECT_EQ(net::OK, result);
- EXPECT_TRUE(fake_channel_->got_fin());
- EXPECT_EQ(0U, fake_channel_->message().size());
-}
-
-TEST_F(WebSocketBlobSenderTest, SmallBlob) {
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana);
-
- EXPECT_EQ(net::OK, Start(handle->GetUUID(), UINT64_C(6), NotCalled()));
- EXPECT_TRUE(fake_channel_->got_fin());
- EXPECT_EQ(1, fake_channel_->frames_sent());
- EXPECT_EQ(std::vector<char>(kBanana, kBanana + 6), fake_channel_->message());
-}
-
-TEST_F(WebSocketBlobSenderTest, SizeMismatch) {
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana);
-
- EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED,
- Start(handle->GetUUID(), UINT64_C(5), NotCalled()));
- EXPECT_EQ(0, fake_channel_->frames_sent());
-}
-
-TEST_F(WebSocketBlobSenderTest, InvalidUUID) {
- EXPECT_EQ(net::ERR_INVALID_HANDLE,
- Start("sandwich", UINT64_C(0), NotCalled()));
-}
-
-TEST_F(WebSocketBlobSenderTest, LargeMessage) {
- std::string message(kInitialQuota + 10, 'a');
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str());
-
- base::RunLoop run_loop;
- int rv = Start(handle->GetUUID(), message.size(),
- ExpectOkAndQuitCallback(&run_loop));
- EXPECT_EQ(net::ERR_IO_PENDING, rv);
- EXPECT_EQ(1, fake_channel_->frames_sent());
- run_loop.Run();
- EXPECT_EQ(2, fake_channel_->frames_sent());
- EXPECT_TRUE(fake_channel_->got_fin());
- std::vector<char> expected_message(message.begin(), message.end());
- EXPECT_EQ(expected_message, fake_channel_->message());
-}
-
-// A message exactly equal to the available quota should be sent in one frame.
-TEST_F(WebSocketBlobSenderTest, ExactSizeMessage) {
- std::string message(kInitialQuota, 'a');
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str());
-
- EXPECT_EQ(net::OK, Start(handle->GetUUID(), message.size(), NotCalled()));
- EXPECT_EQ(1, fake_channel_->frames_sent());
- EXPECT_TRUE(fake_channel_->got_fin());
- std::vector<char> expected_message(message.begin(), message.end());
- EXPECT_EQ(expected_message, fake_channel_->message());
-}
-
-// If the connection is closed while sending a message, the WebSocketBlobSender
-// object will be destroyed. It needs to handle this case without error.
-TEST_F(WebSocketBlobSenderTest, AbortedSend) {
- std::string message(kInitialQuota + 10, 'a');
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str());
-
- int rv = Start(handle->GetUUID(), message.size(), NotCalled());
- EXPECT_EQ(net::ERR_IO_PENDING, rv);
- sender_.reset();
-}
-
-// Invalid file-backed blob.
-TEST_F(WebSocketBlobSenderTest, InvalidFileBackedBlob) {
- base::FilePath path(FILE_PATH_LITERAL(
- "WebSocketBlobSentTest.InvalidFileBackedBlob.NonExistentFile"));
- std::unique_ptr<BlobHandle> handle =
- chrome_blob_storage_context_->CreateFileBackedBlob(path, 0u, 32u,
- base::Time::Now());
- EXPECT_TRUE(handle);
-
- TestCompletionCallback callback;
- int rv =
- callback.GetResult(Start(handle->GetUUID(), 5u, callback.callback()));
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, rv);
-}
-
-// A test fixture that does the additional work necessary to create working
-// file-backed blobs.
-class WebSocketFileBackedBlobSenderTest : public WebSocketBlobSenderTest {
- protected:
- void SetUp() override {
- WebSocketBlobSenderTest::SetUp();
- // temp_dir_ is recursively deleted on destruction.
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- }
-
- void CreateFile(const std::string& contents,
- const base::FilePath& path,
- base::File::Info* info) {
- ASSERT_EQ(contents.size(), static_cast<size_t>(base::WriteFile(
- path, contents.data(), contents.size())));
- ASSERT_TRUE(base::GetFileInfo(path, info));
- }
-
- std::unique_ptr<BlobHandle> CreateFileBackedBlob(
- const std::string& contents) {
- base::FilePath path = temp_dir_.path().AppendASCII("blob.dat");
- base::File::Info info;
- CreateFile(contents, path, &info);
- if (HasFatalFailure())
- return nullptr;
- return chrome_blob_storage_context_->CreateFileBackedBlob(
- path, 0u, contents.size(), info.last_modified);
- }
-
- base::ScopedTempDir temp_dir_;
-};
-
-TEST_F(WebSocketFileBackedBlobSenderTest, EmptyBlob) {
- std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob("");
- ASSERT_TRUE(handle);
-
- TestCompletionCallback callback;
- int result = callback.GetResult(
- Start(handle->GetUUID(), UINT64_C(0), callback.callback()));
- EXPECT_EQ(net::OK, result);
- EXPECT_TRUE(fake_channel_->got_fin());
- EXPECT_EQ(0U, fake_channel_->message().size());
-}
-
-TEST_F(WebSocketFileBackedBlobSenderTest, SizeMismatch) {
- std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(kBanana);
- ASSERT_TRUE(handle);
-
- TestCompletionCallback callback;
- int result = Start(handle->GetUUID(), UINT64_C(8), callback.callback());
- // This test explicitly aims to test the asynchronous code path, otherwise it
- // would be identical to the other SizeMismatch test above.
- EXPECT_EQ(net::ERR_IO_PENDING, result);
- EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, callback.WaitForResult());
- EXPECT_EQ(0, fake_channel_->frames_sent());
-}
-
-TEST_F(WebSocketFileBackedBlobSenderTest, LargeMessage) {
- std::string message = "the green potato had lunch with the angry cat. ";
- while (message.size() <= kInitialQuota) {
- message = message + message;
- }
- std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(message);
- ASSERT_TRUE(handle);
-
- TestCompletionCallback callback;
- int result = Start(handle->GetUUID(), message.size(), callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(result));
- std::vector<char> expected_message(message.begin(), message.end());
- EXPECT_EQ(expected_message, fake_channel_->message());
-}
-
-// The WebSocketBlobSender needs to handle a connection close while doing file
-// IO cleanly.
-TEST_F(WebSocketFileBackedBlobSenderTest, Aborted) {
- std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(kBanana);
-
- int rv = Start(handle->GetUUID(), UINT64_C(6), NotCalled());
- EXPECT_EQ(net::ERR_IO_PENDING, rv);
- sender_.reset();
-}
-
-class DeletingFakeChannel : public WebSocketBlobSender::Channel {
- public:
- explicit DeletingFakeChannel(
- std::unique_ptr<WebSocketBlobSender>* sender_to_delete)
- : sender_(sender_to_delete) {}
-
- size_t GetSendQuota() const override { return kInitialQuota; }
-
- ChannelState SendFrame(bool fin, const std::vector<char>& data) override {
- sender_->reset();
- // |this| is deleted here.
- return net::WebSocketEventInterface::CHANNEL_DELETED;
- }
-
- private:
- std::unique_ptr<WebSocketBlobSender>* sender_;
-};
-
-class WebSocketBlobSenderDeletingTest : public WebSocketBlobSenderTest {
- protected:
- void SetUpSender() override {
- sender_.reset(new WebSocketBlobSender(
- base::WrapUnique(new DeletingFakeChannel(&sender_))));
- }
-};
-
-// This test only does something useful when run under AddressSanitizer or a
-// similar tool that can detect use-after-free bugs.
-TEST_F(WebSocketBlobSenderDeletingTest, SenderDeleted) {
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana);
-
- EXPECT_EQ(net::ERR_CONNECTION_RESET,
- Start(handle->GetUUID(), UINT64_C(6), NotCalled()));
- EXPECT_FALSE(sender_);
-}
-
-// SendFrame() calls OnSendNewQuota() synchronously while filling the operating
-// system's socket write buffer. The purpose of this Channel implementation is
-// to verify that the synchronous case works correctly.
-class SynchronousFakeChannel : public WebSocketBlobSender::Channel {
- public:
- // This method must be called before SendFrame() is.
- void set_notify_new_quota(const base::Closure& notify_new_quota) {
- notify_new_quota_ = notify_new_quota;
- }
-
- size_t GetSendQuota() const override { return kInitialQuota; }
-
- ChannelState SendFrame(bool fin, const std::vector<char>& data) override {
- message_.insert(message_.end(), data.begin(), data.end());
- notify_new_quota_.Run();
- return net::WebSocketEventInterface::CHANNEL_ALIVE;
- }
-
- const std::vector<char>& message() const { return message_; }
-
- private:
- base::Closure notify_new_quota_;
- std::vector<char> message_;
-};
-
-class WebSocketBlobSenderSynchronousTest : public WebSocketBlobSenderTest {
- protected:
- void SetUpSender() override {
- synchronous_fake_channel_ = new SynchronousFakeChannel;
- sender_.reset(
- new WebSocketBlobSender(base::WrapUnique(synchronous_fake_channel_)));
- synchronous_fake_channel_->set_notify_new_quota(base::Bind(
- &WebSocketBlobSender::OnNewSendQuota, base::Unretained(sender_.get())));
- }
-
- SynchronousFakeChannel* synchronous_fake_channel_ = nullptr;
-};
-
-TEST_F(WebSocketBlobSenderSynchronousTest, LargeMessage) {
- std::string message(kInitialQuota + 10, 'a');
- std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str());
-
- int rv = Start(handle->GetUUID(), message.size(), NotCalled());
- EXPECT_EQ(net::OK, rv);
- std::vector<char> expected_message(message.begin(), message.end());
- EXPECT_EQ(expected_message, synchronous_fake_channel_->message());
-}
-
-} // namespace
-
-} // namespace content

Powered by Google App Engine
This is Rietveld 408576698