123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- // Copyright 2020 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.
- #ifndef STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_WRITER_TEST_H_
- #define STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_WRITER_TEST_H_
- #include <cstdio>
- #include "base/callback_helpers.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread.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 "testing/gtest/include/gtest/gtest.h"
- namespace storage {
- // An interface for derived FileStreamWriter to implement. This allows multiple
- // FileStreamWriter implementations can share the same test framework. Tests
- // should implement CreateFileWithContent, CreateWriter, FilePathExists, and
- // GetFileContent to manipulate files for their particular implementation.
- class FileStreamWriterTest : public testing::Test {
- public:
- static constexpr base::StringPiece kTestFileName = "file_a";
- virtual bool CreateFileWithContent(const std::string& name,
- const std::string& data) = 0;
- virtual std::unique_ptr<FileStreamWriter> CreateWriter(
- const std::string& name,
- int64_t offset) = 0;
- virtual bool FilePathExists(const std::string& name) = 0;
- virtual std::string GetFileContent(const std::string& name) = 0;
- static void NeverCalled(int unused) { ADD_FAILURE(); }
- protected:
- // Must be listed before base::test::TaskEnvironment.
- base::ScopedTempDir dir_;
- base::test::TaskEnvironment task_environment_{
- base::test::TaskEnvironment::MainThreadType::IO};
- };
- template <class SubClass>
- class FileStreamWriterTypedTest : public SubClass {
- public:
- void SetUp() override { SubClass::SetUp(); }
- };
- TYPED_TEST_SUITE_P(FileStreamWriterTypedTest);
- TYPED_TEST_P(FileStreamWriterTypedTest, Write) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "foo"));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "bar"));
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ("foobar", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, WriteMiddle) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 2));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "xxx"));
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ("foxxxr", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, WriteNearEnd) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 5));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "xxx"));
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ("foobaxxx", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, WriteEnd) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 6));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "xxx"));
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ("foobarxxx",
- this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, WriteAfterEnd) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 7));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "xxx"));
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ(std::string("foobar\0xxx", 10),
- this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, WriteFailForNonexistingFile) {
- ASSERT_FALSE(this->FilePathExists(std::string(this->kTestFileName)));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, WriteStringToWriter(writer.get(), "foo"));
- EXPECT_FALSE(this->FilePathExists(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, CancelBeforeOperation) {
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- // Cancel immediately fails when there's no in-flight operation.
- EXPECT_EQ(net::ERR_UNEXPECTED, writer->Cancel(base::DoNothing()));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, CancelAfterFinishedOperation) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "foo"));
- // Cancel immediately fails when there's no in-flight operation.
- EXPECT_EQ(net::ERR_UNEXPECTED, writer->Cancel(base::DoNothing()));
- // Write operation is already completed.
- EXPECT_TRUE(this->FilePathExists(std::string(this->kTestFileName)));
- EXPECT_EQ("foobar", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, CancelWrite) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), "foobar"));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- scoped_refptr<net::StringIOBuffer> buffer(
- base::MakeRefCounted<net::StringIOBuffer>("xxx"));
- int result =
- writer->Write(buffer.get(), buffer->size(),
- base::BindOnce(&FileStreamWriterTest::NeverCalled));
- ASSERT_EQ(net::ERR_IO_PENDING, result);
- net::TestCompletionCallback callback;
- writer->Cancel(callback.callback());
- int cancel_result = writer->Cancel(callback.callback());
- EXPECT_EQ(net::OK, callback.GetResult(cancel_result));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, CancelFlush) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), ""));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "foo"));
- int cancel_expectation = net::OK;
- int result = writer->Flush(base::DoNothing());
- // Flush can run synchronously or asynchronously.
- if (result == net::OK) {
- // Cancel() should error if called when there is no in-flight operation.
- cancel_expectation = net::ERR_UNEXPECTED;
- } else {
- EXPECT_EQ(net::ERR_IO_PENDING, result);
- }
- net::TestCompletionCallback callback;
- int cancel_result = writer->Cancel(callback.callback());
- EXPECT_EQ(cancel_expectation, callback.GetResult(cancel_result));
- EXPECT_EQ("foo", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, FlushBeforeWriting) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), ""));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::OK, writer->Flush(base::DoNothing()));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "foo"));
- EXPECT_EQ("foo", this->GetFileContent(std::string(this->kTestFileName)));
- }
- TYPED_TEST_P(FileStreamWriterTypedTest, FlushAfterWriting) {
- EXPECT_TRUE(
- this->CreateFileWithContent(std::string(this->kTestFileName), ""));
- std::unique_ptr<FileStreamWriter> writer(
- this->CreateWriter(std::string(this->kTestFileName), 0));
- EXPECT_EQ(net::OK, WriteStringToWriter(writer.get(), "foo"));
- net::TestCompletionCallback callback;
- int result =
- writer->Flush(base::OnceCallback<void(int)>(callback.callback()));
- ASSERT_EQ(net::OK, callback.GetResult(result));
- EXPECT_EQ("foo", this->GetFileContent(std::string(this->kTestFileName)));
- }
- REGISTER_TYPED_TEST_SUITE_P(FileStreamWriterTypedTest,
- Write,
- WriteMiddle,
- WriteNearEnd,
- WriteEnd,
- WriteAfterEnd,
- WriteFailForNonexistingFile,
- CancelBeforeOperation,
- CancelAfterFinishedOperation,
- CancelWrite,
- CancelFlush,
- FlushBeforeWriting,
- FlushAfterWriting);
- } // namespace storage
- #endif // STORAGE_BROWSER_FILE_SYSTEM_FILE_STREAM_WRITER_TEST_H_
|