#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/task_environment.h"
#include "base/test/test_file_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/download/public/common/download_path_reservation_tracker.h"
#include "components/download/public/common/mock_download_item.h"
#include "net/base/filename_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/download/internal/common/android/download_collection_bridge.h"
#endif
AnyNumber;
Return;
ReturnRef;
ReturnRefOfCopy;
namespace download {
namespace {
class DownloadPathReservationTrackerTest : public testing::Test { … };
DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest() =
default;
void DownloadPathReservationTrackerTest::SetUp() { … }
void DownloadPathReservationTrackerTest::TearDown() { … }
std::unique_ptr<MockDownloadItem>
DownloadPathReservationTrackerTest::CreateDownloadItem(int32_t id) { … }
base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory(
const base::FilePath::CharType* suffix) { … }
bool DownloadPathReservationTrackerTest::IsPathInUse(
const base::FilePath& path) { … }
void DownloadPathReservationTrackerTest::RunUntilIdle() { … }
void DownloadPathReservationTrackerTest::CallGetReservedPath(
DownloadItem* download_item,
const base::FilePath& target_path,
bool create_directory,
DownloadPathReservationTracker::FilenameConflictAction conflict_action,
base::FilePath* return_path,
PathValidationResult* return_result) { … }
void DownloadPathReservationTrackerTest::TestReservedPathCallback(
base::FilePath* return_path,
PathValidationResult* return_result,
PathValidationResult result,
const base::FilePath& path) { … }
base::FilePath
DownloadPathReservationTrackerTest::GetLongNamePathInDownloadsDirectory(
size_t repeat,
const base::FilePath::CharType* suffix) { … }
void SetDownloadItemState(MockDownloadItem* download_item,
DownloadItem::DownloadState state) { … }
void DownloadPathReservationTrackerTest::CreateReservation(
MockDownloadItem* item,
const base::FilePath& path,
DownloadPathReservationTracker::FilenameConflictAction conflict_action,
PathValidationResult expected_result,
const base::FilePath& expected_reserved_path) { … }
}
TEST_F(DownloadPathReservationTrackerTest, BasicReservation) { … }
TEST_F(DownloadPathReservationTrackerTest, InterruptedDownload) { … }
TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles_Overwrite) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictWithSource) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictingReservation_Prevented) { … }
TEST_F(DownloadPathReservationTrackerTest, ConflictingCaseReservations) { … }
TEST_F(DownloadPathReservationTrackerTest, UnresolvedConflicts) { … }
#if BUILDFLAG(IS_FUCHSIA)
#define MAYBE_UnwriteableDirectory …
#else
#define MAYBE_UnwriteableDirectory …
#endif
TEST_F(DownloadPathReservationTrackerTest, MAYBE_UnwriteableDirectory) { … }
TEST_F(DownloadPathReservationTrackerTest, CreateDefaultDownloadPath) { … }
TEST_F(DownloadPathReservationTrackerTest, UpdatesToTargetPath) { … }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) {
int real_max_length =
base::GetMaximumPathComponentLength(default_download_path());
ASSERT_NE(-1, real_max_length);
#if BUILDFLAG(IS_WIN)
const size_t max_length = real_max_length - strlen(":Zone.Identifier");
#else
const size_t max_length = real_max_length - 11;
#endif
std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
base::FilePath path(GetLongNamePathInDownloadsDirectory(
max_length, FILE_PATH_LITERAL(".txt")));
ASSERT_FALSE(IsPathInUse(path));
base::FilePath reserved_path;
PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
DownloadPathReservationTracker::FilenameConflictAction conflict_action =
DownloadPathReservationTracker::OVERWRITE;
bool create_directory = false;
CallGetReservedPath(item.get(), path, create_directory, conflict_action,
&reserved_path, &result);
EXPECT_TRUE(IsPathInUse(reserved_path));
EXPECT_EQ(PathValidationResult::SUCCESS, result);
EXPECT_EQ(max_length, reserved_path.BaseName().value().size());
EXPECT_EQ(path.Extension(), reserved_path.Extension());
SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
}
TEST_F(DownloadPathReservationTrackerTest, TruncationConflict) {
int real_max_length =
base::GetMaximumPathComponentLength(default_download_path());
ASSERT_NE(-1, real_max_length);
#if BUILDFLAG(IS_WIN)
const size_t max_length = real_max_length - strlen(":Zone.Identifier");
#else
const size_t max_length = real_max_length - 11;
#endif
std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
base::FilePath path(GetLongNamePathInDownloadsDirectory(
max_length, FILE_PATH_LITERAL(".txt")));
base::FilePath path0(GetLongNamePathInDownloadsDirectory(
max_length - 4, FILE_PATH_LITERAL(".txt")));
base::FilePath path1(GetLongNamePathInDownloadsDirectory(
max_length - 8, FILE_PATH_LITERAL(" (1).txt")));
base::FilePath path2(GetLongNamePathInDownloadsDirectory(
max_length - 8, FILE_PATH_LITERAL(" (2).txt")));
ASSERT_FALSE(IsPathInUse(path));
ASSERT_TRUE(base::WriteFile(path0, ""));
ASSERT_TRUE(base::WriteFile(path1, ""));
base::FilePath reserved_path;
PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
DownloadPathReservationTracker::FilenameConflictAction conflict_action =
DownloadPathReservationTracker::UNIQUIFY;
bool create_directory = false;
CallGetReservedPath(item.get(), path, create_directory, conflict_action,
&reserved_path, &result);
EXPECT_TRUE(IsPathInUse(reserved_path));
EXPECT_EQ(PathValidationResult::SUCCESS_RESOLVED_CONFLICT, result);
EXPECT_EQ(path2, reserved_path);
SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
}
TEST_F(DownloadPathReservationTrackerTest, TruncationFail) {
int real_max_length =
base::GetMaximumPathComponentLength(default_download_path());
ASSERT_NE(-1, real_max_length);
#if BUILDFLAG(IS_WIN)
const size_t max_length = real_max_length - strlen(":Zone.Identifier");
#else
const size_t max_length = real_max_length - 11;
#endif
std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
base::FilePath path(GetPathInDownloadsDirectory(
(FILE_PATH_LITERAL("a.") + base::FilePath::StringType(max_length, 'b'))
.c_str()));
ASSERT_FALSE(IsPathInUse(path));
base::FilePath reserved_path;
PathValidationResult result = PathValidationResult::SUCCESS;
DownloadPathReservationTracker::FilenameConflictAction conflict_action =
DownloadPathReservationTracker::OVERWRITE;
bool create_directory = false;
CallGetReservedPath(item.get(), path, create_directory, conflict_action,
&reserved_path, &result);
EXPECT_EQ(PathValidationResult::NAME_TOO_LONG, result);
SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
}
#endif
}