| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include "paimon/fs/local/local_file.h" | |
| #include <cstring> | |
| #include <string> | |
| #include <utility> | |
| #include "gtest/gtest.h" | |
| #include "paimon/testing/utils/testharness.h" | |
| namespace paimon::test { | |
| TEST(LocalFileTest, TestSchemeCaseInsensitive) { | |
| ASSERT_OK(LocalFile::Create("FILE:/tmp")); | |
| ASSERT_NOK(LocalFile::Create("s3:/tmp")); | |
| } | |
| TEST(LocalFileTest, TestGetParentFileWithoutSlash) { | |
| for (const char* path : {"file", ""}) { | |
| SCOPED_TRACE(path); | |
| LocalFile file(path); | |
| std::unique_ptr<LocalFile> parent = file.GetParentFile(); | |
| ASSERT_TRUE(parent); | |
| ASSERT_TRUE(parent->IsEmpty()); | |
| ASSERT_TRUE(parent->GetPath().empty()); | |
| } | |
| } | |
| TEST(LocalFileTest, TestGetFileStatusForMissingFile) { | |
| auto test_root_dir = UniqueTestDirectory::Create(); | |
| ASSERT_TRUE(test_root_dir); | |
| ASSERT_OK_AND_ASSIGN(std::unique_ptr<LocalFile> file, | |
| LocalFile::Create(test_root_dir->Str() + "/missing-file")); | |
| Result<FileStatus> status = file->GetFileStatus(); | |
| ASSERT_TRUE(status.status().IsNotExist()) << status.status().ToString(); | |
| } | |
| TEST(LocalFileTest, TestReadWriteEmptyContent) { | |
| auto test_root_dir = UniqueTestDirectory::Create(); | |
| ASSERT_TRUE(test_root_dir); | |
| std::string test_root = test_root_dir->Str(); | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root)); | |
| if (dir->Exists().ok()) { | |
| ASSERT_TRUE(dir->Delete().ok()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| std::string path = test_root + "/test.txt"; | |
| ASSERT_OK_AND_ASSIGN(auto file, LocalFile::Create(path)); | |
| if (file->Exists().ok()) { | |
| ASSERT_TRUE(file->Delete().ok()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool is_exist, file->Exists()); | |
| ASSERT_FALSE(is_exist); | |
| ASSERT_OK(file->OpenFile(/*is_read_file=*/false)); | |
| const char* str = ""; | |
| constexpr int64_t str_size = 0; | |
| ASSERT_OK_AND_ASSIGN(int64_t write_size, file->Write(str, str_size)); | |
| ASSERT_EQ(write_size, str_size); | |
| ASSERT_OK(file->Flush()); | |
| ASSERT_TRUE(file->Exists().value()); | |
| ASSERT_OK(file->Close()); | |
| ASSERT_OK_AND_ASSIGN(auto file2, LocalFile::Create(path)); | |
| ASSERT_OK(file2->OpenFile(/*is_read_file=*/true)); | |
| char buffer[10]; | |
| ASSERT_OK_AND_ASSIGN(int64_t read_len, file2->Read(buffer, 10)); | |
| ASSERT_EQ(0, read_len); | |
| } | |
| TEST(LocalFileTest, TestSimple) { | |
| auto test_root_dir = UniqueTestDirectory::Create(); | |
| ASSERT_TRUE(test_root_dir); | |
| std::string test_root = test_root_dir->Str(); | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root)); | |
| if (dir->Exists().ok()) { | |
| ASSERT_OK(dir->Delete()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| std::string path = test_root + "/test.txt"; | |
| ASSERT_OK_AND_ASSIGN(auto file, LocalFile::Create(path)); | |
| if (file->Exists().ok()) { | |
| ASSERT_OK(file->Delete()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool is_exist, file->Exists()); | |
| ASSERT_FALSE(is_exist); | |
| ASSERT_OK(file->OpenFile(/*is_read_file=*/false)); | |
| const char* str = "test_data"; | |
| constexpr int64_t str_size = 9; | |
| ASSERT_OK_AND_ASSIGN(int64_t write_size, file->Write(str, str_size)); | |
| ASSERT_EQ(write_size, str_size); | |
| ASSERT_OK(file->Flush()); | |
| ASSERT_OK(file->Close()); | |
| ASSERT_OK_AND_ASSIGN(bool is_file, file->IsFile()); | |
| ASSERT_TRUE(is_file); | |
| ASSERT_OK_AND_ASSIGN(bool is_dir, file->IsDir()); | |
| ASSERT_FALSE(is_dir); | |
| std::vector<std::string> file_list; | |
| ASSERT_NOK(file->List(&file_list)); | |
| ASSERT_OK_AND_ASSIGN(int64_t len, file->Length()); | |
| ASSERT_EQ(len, str_size); | |
| ASSERT_OK_AND_ASSIGN(auto file2, LocalFile::Create(path)); | |
| ASSERT_OK(file2->Exists()); | |
| ASSERT_OK(file2->OpenFile(true)); | |
| char str_read[str_size + 1]; | |
| { | |
| ASSERT_OK_AND_ASSIGN(int64_t read_size, file2->Read(str_read, 4)); | |
| ASSERT_EQ(read_size, 4); | |
| str_read[read_size] = '\0'; | |
| ASSERT_EQ(strcmp(str_read, "test"), 0); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(int64_t pos, file2->Tell()); | |
| ASSERT_EQ(pos, 4); | |
| ASSERT_OK(file2->Seek(5, SEEK_SET)); | |
| ASSERT_OK_AND_ASSIGN(int64_t read_size, file2->Read(str_read, 4)); | |
| ASSERT_EQ(read_size, 4); | |
| str_read[read_size] = '\0'; | |
| ASSERT_EQ(strcmp(str_read, "data"), 0); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(int64_t read_size, file2->Read(str_read, str_size, 0)); | |
| ASSERT_EQ(read_size, str_size); | |
| str_read[read_size] = '\0'; | |
| ASSERT_EQ(strcmp(str_read, "test_data"), 0); | |
| } | |
| // dir already exists | |
| ASSERT_OK_AND_ASSIGN(success, dir->Mkdir()); | |
| ASSERT_FALSE(success); | |
| ASSERT_OK(file2->Delete()); | |
| ASSERT_FALSE(file2->Exists().value()); | |
| } | |
| TEST(LocalFileTest, TestUsage) { | |
| std::string test_root = "local_file_test_usage"; | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root)); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| std::vector<std::string> file_list; | |
| ASSERT_OK(dir->List(&file_list)); | |
| std::string path_deep_dir = test_root + "/tmp2"; | |
| ASSERT_OK_AND_ASSIGN(auto deep_dir, LocalFile::Create(path_deep_dir)); | |
| ASSERT_OK_AND_ASSIGN(success, deep_dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| std::unique_ptr<LocalFile> parent_deep_dir = deep_dir->GetParentFile(); | |
| ASSERT_EQ(parent_deep_dir->GetPath(), dir->GetPath()); | |
| ASSERT_OK(deep_dir->Delete()); | |
| ASSERT_OK(parent_deep_dir->Delete()); | |
| ASSERT_OK(dir->Delete()); | |
| } | |
| TEST(LocalFileTest, TestOpenFile) { | |
| auto test_root_dir = UniqueTestDirectory::Create(); | |
| ASSERT_TRUE(test_root_dir); | |
| std::string test_root = test_root_dir->Str(); | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root)); | |
| if (dir->Exists().ok()) { | |
| ASSERT_OK(dir->Delete()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| std::string path = test_root + "/test.txt"; | |
| ASSERT_OK_AND_ASSIGN(auto file, LocalFile::Create(path)); | |
| if (file->Exists().ok()) { | |
| ASSERT_OK(file->Delete()); | |
| } | |
| ASSERT_OK_AND_ASSIGN(bool is_exist, file->Exists()); | |
| ASSERT_FALSE(is_exist); | |
| ASSERT_NOK_WITH_MSG(file->OpenFile(/*is_read_file=*/true), "file not exist"); | |
| ASSERT_NOK_WITH_MSG(dir->OpenFile(/*is_read_file=*/true), "cannot open a directory"); | |
| std::string path3 = "test.txt"; | |
| ASSERT_OK_AND_ASSIGN(auto file3, LocalFile::Create(path3)); | |
| ASSERT_OK(file3->OpenFile(/*is_read_file=*/false)); | |
| ASSERT_OK_AND_ASSIGN(int64_t modify_time, file3->LastModifiedTimeMs()); | |
| ASSERT_GE(modify_time, -1); | |
| ASSERT_OK_AND_ASSIGN(auto dir2, LocalFile::Create("/")); | |
| ASSERT_OK_AND_ASSIGN(success, dir2->Mkdir()); | |
| ASSERT_FALSE(success); | |
| ASSERT_OK_AND_ASSIGN(auto dir3, LocalFile::Create(test_root + "/")); | |
| ASSERT_OK_AND_ASSIGN(success, dir3->Mkdir()); | |
| ASSERT_FALSE(success); | |
| } | |
| TEST(LocalFileTest, TestMkdir) { | |
| auto test_root_dir = UniqueTestDirectory::Create(); | |
| ASSERT_TRUE(test_root_dir); | |
| std::string test_root = test_root_dir->Str(); | |
| { | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root + "tmp/local/f/1")); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_FALSE(success); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root + "tmp1")); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create(test_root + "tmp1/f2/")); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_TRUE(success); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create("/")); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_FALSE(success); | |
| } | |
| { | |
| ASSERT_OK_AND_ASSIGN(auto dir, LocalFile::Create("")); | |
| ASSERT_OK_AND_ASSIGN(bool success, dir->Mkdir()); | |
| ASSERT_FALSE(success); | |
| } | |
| } | |
| } // namespace paimon::test |