blob: 28c50d487a0557de84f46e9632a741f978c88e83 [file] [log] [blame]
// Copyright 2019 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/native_file_system/native_file_system_file_handle_impl.h"
#include <limits>
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "content/browser/native_file_system/fixed_native_file_system_permission_grant.h"
#include "content/public/test/browser_task_environment.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_stream_reader.h"
#include "storage/browser/test/async_file_test_helper.h"
#include "storage/browser/test/test_file_system_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
using storage::FileSystemURL;
namespace content {
using blink::mojom::PermissionStatus;
using storage::FileSystemURL;
class NativeFileSystemFileHandleImplTest : public testing::Test {
public:
NativeFileSystemFileHandleImplTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
scoped_feature_list_.InitAndEnableFeature(
blink::features::kNativeFileSystemAPI);
}
void SetUp() override {
ASSERT_TRUE(dir_.CreateUniqueTempDir());
file_system_context_ = CreateFileSystemContextForTesting(
/*quota_manager_proxy=*/nullptr, dir_.GetPath());
test_file_url_ = file_system_context_->CreateCrackedFileSystemURL(
test_src_origin_.GetURL(), storage::kFileSystemTypeTest,
base::FilePath::FromUTF8Unsafe("test"));
ASSERT_EQ(base::File::FILE_OK,
AsyncFileTestHelper::CreateFile(file_system_context_.get(),
test_file_url_));
chrome_blob_context_ = base::MakeRefCounted<ChromeBlobStorageContext>();
chrome_blob_context_->InitializeOnIOThread(base::FilePath(), nullptr);
manager_ = base::MakeRefCounted<NativeFileSystemManagerImpl>(
file_system_context_, chrome_blob_context_,
/*permission_context=*/nullptr,
/*off_the_record=*/false);
handle_ = std::make_unique<NativeFileSystemFileHandleImpl>(
manager_.get(),
NativeFileSystemManagerImpl::BindingContext(
test_src_origin_, test_src_url_, /*process_id=*/1,
/*frame_id=*/MSG_ROUTING_NONE),
test_file_url_,
NativeFileSystemManagerImpl::SharedHandleState(
allow_grant_, allow_grant_, /*file_system=*/{}));
}
void TearDown() override { task_environment_.RunUntilIdle(); }
std::string ReadFile(const FileSystemURL& url) {
std::unique_ptr<storage::FileStreamReader> reader =
file_system_context_->CreateFileStreamReader(
url, 0, std::numeric_limits<int64_t>::max(), base::Time());
std::string result;
while (true) {
auto buf = base::MakeRefCounted<net::IOBufferWithSize>(4096);
net::TestCompletionCallback callback;
int rv = reader->Read(buf.get(), buf->size(), callback.callback());
if (rv == net::ERR_IO_PENDING)
rv = callback.WaitForResult();
EXPECT_GE(rv, 0);
if (rv < 0)
return "(read failure)";
if (rv == 0)
return result;
result.append(buf->data(), rv);
}
}
protected:
const GURL test_src_url_ = GURL("http://example.com/foo");
const url::Origin test_src_origin_ = url::Origin::Create(test_src_url_);
base::test::ScopedFeatureList scoped_feature_list_;
BrowserTaskEnvironment task_environment_;
base::ScopedTempDir dir_;
scoped_refptr<storage::FileSystemContext> file_system_context_;
scoped_refptr<ChromeBlobStorageContext> chrome_blob_context_;
scoped_refptr<NativeFileSystemManagerImpl> manager_;
FileSystemURL test_file_url_;
scoped_refptr<FixedNativeFileSystemPermissionGrant> allow_grant_ =
base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>(
FixedNativeFileSystemPermissionGrant::PermissionStatus::GRANTED);
std::unique_ptr<NativeFileSystemFileHandleImpl> handle_;
};
TEST_F(NativeFileSystemFileHandleImplTest, CreateFileWriterOverLimitNotOK) {
int max_files = 5;
handle_->set_max_swap_files_for_testing(max_files);
const FileSystemURL base_swap_url =
file_system_context_->CreateCrackedFileSystemURL(
test_src_origin_.GetURL(), storage::kFileSystemTypeTest,
base::FilePath::FromUTF8Unsafe("test.crswap"));
std::vector<mojo::PendingRemote<blink::mojom::NativeFileSystemFileWriter>>
writers;
for (int i = 0; i < max_files; i++) {
FileSystemURL swap_url;
if (i == 0) {
swap_url = base_swap_url;
} else {
swap_url = file_system_context_->CreateCrackedFileSystemURL(
test_src_origin_.GetURL(), storage::kFileSystemTypeTest,
base::FilePath::FromUTF8Unsafe(
base::StringPrintf("test.%d.crswap", i)));
}
base::RunLoop loop;
handle_->CreateFileWriter(
/*keepExistingData=*/false,
base::BindLambdaForTesting(
[&](blink::mojom::NativeFileSystemErrorPtr result,
mojo::PendingRemote<blink::mojom::NativeFileSystemFileWriter>
writer_remote) {
EXPECT_EQ(blink::mojom::NativeFileSystemStatus::kOk,
result->status);
EXPECT_EQ("", ReadFile(swap_url));
writers.push_back(std::move(writer_remote));
loop.Quit();
}));
loop.Run();
}
base::RunLoop loop;
handle_->CreateFileWriter(
/*keepExistingData=*/false,
base::BindLambdaForTesting(
[&](blink::mojom::NativeFileSystemErrorPtr result,
mojo::PendingRemote<blink::mojom::NativeFileSystemFileWriter>
writer_remote) {
EXPECT_EQ(blink::mojom::NativeFileSystemStatus::kOperationFailed,
result->status);
loop.Quit();
}));
loop.Run();
}
} // namespace content