// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/fileapi/copy_from_fd.h"
#include <unistd.h>
#include <memory>
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "net/base/io_buffer.h"
#include "storage/browser/file_system/file_stream_writer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash {
namespace {
class FakeFileStreamWriter : public storage::FileStreamWriter {
public:
int Write(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) override {
CHECK(::content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
data_.append(buf->data(), buf->size());
return buf->size();
}
int Cancel(net::CompletionOnceCallback callback) override {
CHECK(::content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
return net::ERR_NOT_IMPLEMENTED;
}
int Flush(storage::FlushMode flush_mode,
net::CompletionOnceCallback callback) override {
CHECK(::content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
flushed_ = true;
return net::OK;
}
std::string data_;
bool flushed_ = false;
};
} // namespace
TEST(CopyFromFileDescriptorTest, Basic) {
content::BrowserTaskEnvironment task_environment(
base::test::TaskEnvironment::MainThreadType::IO);
ASSERT_TRUE(
::content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath temp_file_path;
base::ScopedFD scoped_fd = base::CreateAndOpenFdForTemporaryFileInDir(
temp_dir.GetPath(), &temp_file_path);
ASSERT_TRUE(scoped_fd.is_valid());
ASSERT_EQ(write(scoped_fd.get(), "abcdefghij", 10), 10);
ASSERT_EQ(lseek(scoped_fd.get(), 3, SEEK_SET), 3);
auto fs_writer = std::make_unique<FakeFileStreamWriter>();
auto callback = base::BindOnce(
[](int expected_fd, FakeFileStreamWriter* expected_fs_writer,
base::RepeatingClosure quit_closure, base::ScopedFD ret_scoped_fd,
std::unique_ptr<storage::FileStreamWriter> ret_fs_writer,
net::Error ret_error) {
ASSERT_TRUE(
::content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
ASSERT_EQ(ret_scoped_fd.get(), expected_fd);
ASSERT_EQ(ret_fs_writer.get(), expected_fs_writer);
EXPECT_EQ(ret_error, net::OK);
EXPECT_EQ(expected_fs_writer->data_.size(), 10u - 3u);
EXPECT_EQ(expected_fs_writer->data_, "defghij");
EXPECT_TRUE(expected_fs_writer->flushed_);
quit_closure.Run();
},
scoped_fd.get(), fs_writer.get(), task_environment.QuitClosure());
CopyFromFileDescriptor(std::move(scoped_fd), std::move(fs_writer),
storage::FlushPolicy::FLUSH_ON_COMPLETION,
std::move(callback));
task_environment.RunUntilQuit();
}
} // namespace ash