blob: a90402468231acc84d3f60c54e85da64e9c3ddf4 [file] [log] [blame]
/*
* Copyright 2024-present Alibaba Inc.
*
* Licensed 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.
*/
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
// Assert utilities is adapted from RocksDB
// https://github.com/facebook/rocksdb/blob/main/test_util/testharness.cc
// Copyright 2024 Google LLC.
//
// Licensed 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.
// UniqueTestDirectory utility is adapted from LiteRT
// https://github.com/google-ai-edge/LiteRT/blob/main/litert/test/common.cc
#include "paimon/testing/utils/testharness.h"
#include <unistd.h>
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>
#include "paimon/common/utils/string_utils.h"
#include "paimon/common/utils/uuid.h"
#include "paimon/fs/file_system.h"
#include "paimon/fs/file_system_factory.h"
#include "paimon/status.h"
namespace paimon::test {
std::string GetDataDir() {
const auto result = std::getenv("PAIMON_TEST_DATA");
if (!result || !result[0]) {
return "test/test_data/";
}
return std::string(result);
}
std::map<std::string, std::string> GetJindoTestOptions() {
const char* home = std::getenv("HOME");
std::string home_str = "";
if (home) {
home_str = std::string(home);
}
std::string config_file_path = home_str + "/.osscredentials";
std::ifstream config_file(config_file_path);
std::string access_key_id = "";
std::string access_key_secret = "";
if (config_file.is_open()) {
std::string line;
while (std::getline(config_file, line)) {
std::vector<std::string> key_value = StringUtils::Split(line, "=");
if (key_value.size() != 2) {
continue;
}
if (key_value[0].find("accessid") != std::string::npos) {
StringUtils::Trim(&key_value[1]);
access_key_id = key_value[1];
}
if (key_value[0].find("accesskey") != std::string::npos) {
StringUtils::Trim(&key_value[1]);
access_key_secret = key_value[1];
}
}
config_file.close();
}
std::map<std::string, std::string> options = {
{"fs.oss.bucket.paimon-unittest.endpoint", "oss-cn-hangzhou-zmf.aliyuncs.com"},
{"fs.oss.bucket.paimon-unittest.accessKeyId", access_key_id},
{"fs.oss.bucket.paimon-unittest.accessKeySecret", access_key_secret},
{"fs.oss.user", "paimon"},
};
return options;
}
std::string GetJindoTestDir() {
static const std::string dir = "oss://paimon-unittest/temp/";
return dir;
}
int64_t RandomNumber(int64_t min, int64_t max) {
static thread_local std::mt19937 generator(
std::random_device{}()); // NOLINT(whitespace/braces)
std::uniform_int_distribution<int64_t> distribution(min, max);
return distribution(generator);
}
std::string GetPidStr() {
return std::to_string(getpid());
}
::testing::AssertionResult AssertStatus(const char* s_expr, const Status& s) {
if (s.ok()) {
return ::testing::AssertionSuccess();
} else {
return ::testing::AssertionFailure() << s_expr << std::endl << s.ToString();
}
}
std::unique_ptr<UniqueTestDirectory> UniqueTestDirectory::Create(const std::string& fs_identifier) {
static const size_t kMaxTries = 1000;
std::string tmp_dir = fs_identifier == "jindo"
? GetJindoTestDir()
: std::filesystem::temp_directory_path().string() + "/";
std::map<std::string, std::string> fs_options =
fs_identifier == "jindo" ? GetJindoTestOptions() : std::map<std::string, std::string>();
auto fs = FileSystemFactory::Get(fs_identifier, tmp_dir, fs_options);
if (!fs.ok()) {
return nullptr;
}
for (size_t i = 0; i < kMaxTries; ++i) {
std::string uuid;
if (!UUID::Generate(&uuid)) {
continue;
}
std::string test_dir = tmp_dir + "paimon_test_" + uuid;
auto is_exist = fs.value()->Exists(test_dir);
if (!is_exist.ok() || is_exist.value()) {
continue;
}
auto status = fs.value()->Mkdirs(test_dir);
if (status.ok()) {
return std::unique_ptr<UniqueTestDirectory>(
new UniqueTestDirectory(test_dir, std::move(fs).value()));
}
}
return nullptr;
}
UniqueTestDirectory::~UniqueTestDirectory() {
auto is_exist = fs_->Exists(tmpdir_);
assert(is_exist.ok());
if (is_exist.value()) {
[[maybe_unused]] auto status = fs_->Delete(tmpdir_, /*recursive=*/true);
assert(status.ok());
}
fs_.reset();
}
bool TestUtil::CopyDirectory(const std::filesystem::path& source,
const std::filesystem::path& destination) {
namespace fs = std::filesystem;
try {
if (!fs::exists(destination)) {
fs::create_directories(destination);
}
for (const auto& entry : fs::directory_iterator(source)) {
const auto& source_path = entry.path();
auto destination_path = destination / source_path.filename();
if (fs::is_directory(source_path)) {
CopyDirectory(source_path, destination_path);
} else if (fs::is_regular_file(source_path)) {
fs::copy(source_path, destination_path, fs::copy_options::overwrite_existing);
}
}
} catch (const std::exception& e) {
std::cerr << "Error while copying directory: " << e.what() << std::endl;
return false;
}
return true;
}
} // namespace paimon::test