Commit f913656f authored by Austin Sullivan's avatar Austin Sullivan Committed by Commit Bot

Implement Cancel() for MemoryFileStreamWriter

In preparation of shared unit tests between the various FileStreamWriter
implementations.

Merge this before https://crrev.com/c/2422682

Change-Id: I56e4a3f5973a13a2bb39108114be5462296ff8e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425429Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Austin Sullivan <asully@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810731}
parent 80cd20f2
......@@ -24,6 +24,12 @@
namespace storage {
namespace {
void NeverCalled(int unused) {
ADD_FAILURE();
}
} // namespace
class LocalFileStreamWriterTest : public testing::Test {
public:
LocalFileStreamWriterTest() : file_thread_("TestFileThread") {}
......@@ -75,10 +81,6 @@ class LocalFileStreamWriterTest : public testing::Test {
base::ScopedTempDir temp_dir_;
};
void NeverCalled(int unused) {
ADD_FAILURE();
}
TEST_F(LocalFileStreamWriterTest, Write) {
base::FilePath path = CreateFileWithContent("file_a", std::string());
std::unique_ptr<LocalFileStreamWriter> writer(CreateWriter(path, 0));
......
......@@ -34,6 +34,7 @@ MemoryFileStreamWriter::MemoryFileStreamWriter(
file_path_(file_path),
offset_(initial_offset) {
DCHECK(memory_file_util_.MaybeValid());
has_pending_operation_ = false;
}
MemoryFileStreamWriter::~MemoryFileStreamWriter() = default;
......@@ -41,6 +42,11 @@ MemoryFileStreamWriter::~MemoryFileStreamWriter() = default;
int MemoryFileStreamWriter::Write(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) {
DCHECK(!has_pending_operation_);
DCHECK(cancel_callback_.is_null());
has_pending_operation_ = true;
task_runner_->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(
......@@ -66,17 +72,43 @@ int MemoryFileStreamWriter::Write(net::IOBuffer* buf,
void MemoryFileStreamWriter::OnWriteCompleted(
net::CompletionOnceCallback callback,
int result) {
DCHECK(has_pending_operation_);
if (CancelIfRequested())
return;
has_pending_operation_ = false;
if (result > 0)
offset_ += result;
std::move(callback).Run(result);
}
int MemoryFileStreamWriter::Cancel(net::CompletionOnceCallback /*callback*/) {
int MemoryFileStreamWriter::Cancel(net::CompletionOnceCallback callback) {
if (!has_pending_operation_)
return net::ERR_UNEXPECTED;
DCHECK(!callback.is_null());
cancel_callback_ = std::move(callback);
return net::ERR_IO_PENDING;
}
int MemoryFileStreamWriter::Flush(net::CompletionOnceCallback /*callback*/) {
DCHECK(!has_pending_operation_);
DCHECK(cancel_callback_.is_null());
return net::OK;
}
bool MemoryFileStreamWriter::CancelIfRequested() {
DCHECK(has_pending_operation_);
if (cancel_callback_.is_null())
return false;
has_pending_operation_ = false;
std::move(cancel_callback_).Run(net::OK);
return true;
}
} // namespace storage
......@@ -37,14 +37,20 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter
void OnWriteCompleted(net::CompletionOnceCallback callback, int result);
// Stops the in-flight operation and calls |cancel_callback_| if it has been
// set by Cancel() for the current operation.
bool CancelIfRequested();
base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_;
const scoped_refptr<base::TaskRunner> task_runner_;
const base::FilePath file_path_;
int64_t offset_;
base::WeakPtrFactory<MemoryFileStreamWriter> weak_factory_{this};
bool has_pending_operation_;
net::CompletionOnceCallback cancel_callback_;
base::WeakPtrFactory<MemoryFileStreamWriter> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(MemoryFileStreamWriter);
};
......
......@@ -16,6 +16,7 @@
#include "base/test/task_environment.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "storage/browser/file_system/file_stream_test_utils.h"
#include "storage/browser/file_system/file_stream_writer.h"
#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
......@@ -23,6 +24,12 @@
namespace storage {
namespace {
void NeverCalled(int unused) {
ADD_FAILURE();
}
} // namespace
class MemoryFileStreamWriterTest : public testing::Test {
public:
MemoryFileStreamWriterTest() {}
......@@ -159,6 +166,25 @@ TEST_F(MemoryFileStreamWriterTest, CancelAfterFinishedOperation) {
EXPECT_EQ("foo", GetFileContent(path));
}
TEST_F(MemoryFileStreamWriterTest, CancelWrite) {
base::FilePath path = Path("file_a");
bool created;
EXPECT_EQ(base::File::FILE_OK, file_util()->EnsureFileExists(path, &created));
std::unique_ptr<FileStreamWriter> writer(CreateWriter(path, 0));
scoped_refptr<net::StringIOBuffer> buffer(
base::MakeRefCounted<net::StringIOBuffer>("xxx"));
int result =
writer->Write(buffer.get(), buffer->size(), base::BindOnce(&NeverCalled));
ASSERT_EQ(net::ERR_IO_PENDING, result);
net::TestCompletionCallback callback;
writer->Cancel(callback.callback());
int cancel_result = callback.WaitForResult();
EXPECT_EQ(net::OK, cancel_result);
}
TEST_F(MemoryFileStreamWriterTest, FlushBeforeWriting) {
base::FilePath path = Path("file_a");
bool created;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment