Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/src/unit-capi-sparse_array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7162,6 +7162,6 @@ TEST_CASE_METHOD(
deserialized_array_dir->timestamp_start() == array_dir.timestamp_start());
REQUIRE(deserialized_array_dir->timestamp_end() == array_dir.timestamp_end());

REQUIRE_NOTHROW(resources.vfs().remove_dir(tiledb::sm::URI(array_name)));
REQUIRE_NOTHROW(resources.vfs()->remove_dir(tiledb::sm::URI(array_name)));
#endif
}
4 changes: 2 additions & 2 deletions test/src/unit-enumerations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3108,8 +3108,8 @@ bool EnumerationFx::vec_cmp(std::vector<T> v1, std::vector<T> v2) {
}

void EnumerationFx::rm_array() {
if (ctx_.resources().vfs().is_dir(uri_)) {
ctx_.resources().vfs().remove_dir(uri_);
if (ctx_.resources().vfs()->is_dir(uri_)) {
ctx_.resources().vfs()->remove_dir(uri_);
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/src/unit-request-handlers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ void RequestHandlerFx::create_array() {
}

void RequestHandlerFx::delete_array() {
if (ctx_.resources().vfs().is_dir(uri_)) {
ctx_.resources().vfs().remove_dir(uri_);
if (ctx_.resources().vfs()->is_dir(uri_)) {
ctx_.resources().vfs()->remove_dir(uri_);
}
}

Expand Down
16 changes: 9 additions & 7 deletions test/src/unit-s3.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ TEST_CASE(
return !result_filter(a.first, a.second);
});

auto scan = s3_test.get_s3().scanner(
s3_test.temp_dir_, result_filter, recursive, max_keys);
auto scan =
s3_test.get_fs(s3_test.temp_dir_)
.scanner(s3_test.temp_dir_, result_filter, recursive, max_keys);
std::vector results_vector(scan.begin(), scan.end());

CHECK(results_vector.size() == expected.size());
Expand All @@ -388,11 +389,12 @@ TEST_CASE("S3: S3Scanner iterator", "[s3][ls-scan-iterator]") {

std::vector<Aws::S3::Model::Object> results_vector;
DYNAMIC_SECTION("Testing with " << max_keys << " max keys from S3") {
auto scan = s3_test.get_s3().scanner(
s3_test.temp_dir_,
tiledb::sm::LsScanner::accept_all,
recursive,
max_keys);
auto scan = s3_test.get_fs(s3_test.temp_dir_)
.scanner(
s3_test.temp_dir_,
tiledb::sm::LsScanner::accept_all,
recursive,
max_keys);

SECTION("for loop") {
SECTION("range based for") {
Expand Down
18 changes: 9 additions & 9 deletions test/src/unit-ssl-config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ std::string get_test_ca_file() {

void check_failure(Filesystem fs, Config& cfg) {
Context ctx(cfg);
auto& vfs = ctx.resources().vfs();
auto vfs = ctx.resources().vfs();

if (!vfs.supports_fs(fs)) {
if (!vfs->supports_fs(fs)) {
return;
}

Expand All @@ -266,7 +266,7 @@ void check_failure(Filesystem fs, Config& cfg) {
std::vector<URI> uris;

try {
st = vfs.ls(bucket_uri, &uris);
st = vfs->ls(bucket_uri, &uris);
} catch (...) {
// Some backends throw exceptions to signal SSL error conditions
// so we pass the test by returning early here.
Expand All @@ -279,9 +279,9 @@ void check_failure(Filesystem fs, Config& cfg) {

void check_success(Filesystem fs, Config& cfg) {
Context ctx(cfg);
auto& vfs = ctx.resources().vfs();
auto vfs = ctx.resources().vfs();

if (!vfs.supports_fs(fs)) {
if (!vfs->supports_fs(fs)) {
return;
}

Expand All @@ -298,9 +298,9 @@ void check_success(Filesystem fs, Config& cfg) {
}

URI bucket_uri = URI(scheme + "://" + bucket_name);
if (vfs.is_bucket(bucket_uri)) {
vfs.remove_bucket(bucket_uri);
if (vfs->is_bucket(bucket_uri)) {
vfs->remove_bucket(bucket_uri);
}
vfs.create_bucket(bucket_uri);
REQUIRE(vfs.is_bucket(bucket_uri));
vfs->create_bucket(bucket_uri);
REQUIRE(vfs->is_bucket(bucket_uri));
}
69 changes: 60 additions & 9 deletions test/src/unit-vfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,15 @@ std::string local_path() {
TEST_CASE("VFS: Test long local paths", "[vfs][long-paths]") {
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config;
Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, Config{}};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

SECTION("- Deep hierarchy") {
// Create a nested path with a long total length
Expand Down Expand Up @@ -210,8 +217,14 @@ TEST_CASE("VFS: copy_file", "[vfs][copy_file]") {
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config = set_config_params();
Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, config};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

size_t test_str_size = 0;
SECTION("Filesize = 0 MB") {
Expand Down Expand Up @@ -292,8 +305,14 @@ TEST_CASE("VFS: copy_dir", "[vfs][copy_dir]") {
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config = set_config_params();
Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, config};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

/* Create the following file hierarchy:
*
Expand Down Expand Up @@ -400,8 +419,14 @@ TEMPLATE_LIST_TEST_CASE(
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config = set_config_params();
Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, config};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

URI path = fs.temp_dir_.add_trailing_slash();

Expand Down Expand Up @@ -643,8 +668,14 @@ TEMPLATE_LIST_TEST_CASE("VFS: File I/O", "[vfs][uri][file_io]", AllBackends) {
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config = set_config_params(disable_multipart, max_parallel_ops);
Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, config};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

// Getting file_size on a nonexistent blob shouldn't crash on Azure
URI non_existent = URI(path.to_string() + "non_existent");
Expand Down Expand Up @@ -731,18 +762,30 @@ TEST_CASE("VFS: Test end-to-end", "[.vfs-e2e]") {
ThreadPool io_tp(1);
// Will be configured from environment variables.
Config config;

Context ctx(config);
VFS vfs{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, config};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};
REQUIRE(vfs.supports_uri_scheme(test_file));
CHECK(vfs.file_size(test_file) > 0);
}

TEST_CASE("VFS: test ls_with_sizes", "[vfs][ls-with-sizes]") {
ThreadPool compute_tp(4);
ThreadPool io_tp(4);
Config config;
Context ctx(config);
VFS vfs_ls{
&g_helper_stats, g_helper_logger().get(), &compute_tp, &io_tp, Config{}};
&g_helper_stats,
g_helper_logger().get(),
&compute_tp,
&io_tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &io_tp, config)};

std::string path = local_path();
std::string dir = path + "ls_dir";
Expand Down Expand Up @@ -898,7 +941,15 @@ TEST_CASE("VFS: Throwing filters for ls_recursive", "[vfs][ls_recursive]") {

TEST_CASE("VFS: Test remove_dir_if_empty", "[vfs][remove-dir-if-empty]") {
ThreadPool tp(1);
VFS vfs{&g_helper_stats, g_helper_logger().get(), &tp, &tp, Config{}};
Config config;
Context ctx(config);
VFS vfs{
&g_helper_stats,
g_helper_logger().get(),
&tp,
&tp,
config,
ctx.resources().make_filesystems(&g_helper_stats, &tp, config)};

std::string path = local_path();
std::string dir = path + "remove_dir_if_empty/";
Expand Down
41 changes: 7 additions & 34 deletions test/support/src/vfs_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@
#include "test/support/src/helpers.h"
#include "test/support/src/vfs_helpers.h"

#if HAVE_S3
#include "tiledb/sm/filesystem/s3.h"
#endif

#include "tiledb/sm/rest/rest_client.h"

namespace tiledb::test {
Expand Down Expand Up @@ -118,7 +114,7 @@ Status vfs_test_init(
}

for (auto& supported_fs : fs_vec) {
REQUIRE(supported_fs->init(*ctx, *vfs).ok());
(void)supported_fs->init(*ctx, *vfs);
}

return Status::Ok();
Expand Down Expand Up @@ -432,11 +428,15 @@ VFSTestBase::VFSTestBase(
tiledb::test::g_helper_logger().get(),
&io_,
&compute_,
create_test_config())
create_test_config(),
tiledb::sm::ContextResources::make_filesystems(
&tiledb::test::g_helper_stats, &io_, create_test_config()))
, prefix_(prefix)
, temp_dir_(tiledb::test::test_dir(prefix_))
, is_supported_(vfs_.supports_uri_scheme(temp_dir_)) {
// TODO: Throw when we can provide a list of supported filesystems to Catch2.
if (!is_supported_) {
throw tiledb::sm::filesystem::BuiltWithout(prefix_);
}
}

VFSTestBase::~VFSTestBase() {
Expand Down Expand Up @@ -500,33 +500,6 @@ VFSTest::VFSTest(
std::sort(expected_results_.begin(), expected_results_.end());
}

S3Test::S3Test(const std::vector<size_t>& test_tree)
: VFSTestBase(test_tree, "s3://")
, S3_within_VFS(&tiledb::test::g_helper_stats, &io_, vfs_.config()) {
#ifdef HAVE_S3
s3().create_bucket(temp_dir_);
for (size_t i = 1; i <= test_tree_.size(); i++) {
sm::URI path = temp_dir_.join_path("subdir_" + std::to_string(i));
// VFS::create_dir is a no-op for S3; Just create objects.
if (test_tree_[i - 1] > 0) {
// Do not include an empty prefix in expected results.
// The only way to retrieve an empty prefix in ls_recursive results is to
// explicitly create an empty prefix object through AWS console or SDK.
expected_results_.emplace_back(path.to_string(), 0);
}
for (size_t j = 1; j <= test_tree_[i - 1]; j++) {
auto object_uri = path.join_path("test_file_" + std::to_string(j));
s3().touch(object_uri);
std::string data(j * 10, 'a');
s3().write(object_uri, data.data(), data.size());
s3().flush(object_uri);
expected_results_.emplace_back(object_uri.to_string(), data.size());
}
}
std::sort(expected_results_.begin(), expected_results_.end());
#endif
}

LocalFsTest::LocalFsTest(const std::vector<size_t>& test_tree)
: VFSTestBase(test_tree, "file://") {
#ifdef _WIN32
Expand Down
41 changes: 31 additions & 10 deletions test/support/src/vfs_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* The MIT License
*
* @copyright Copyright (c) 2020-2023 TileDB, Inc.
* @copyright Copyright (c) 2020-2025 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -39,6 +39,10 @@
#include "tiledb/sm/enums/vfs_mode.h"
#include "tiledb/sm/filesystem/vfs.h"

#if HAVE_S3
#include "tiledb/sm/filesystem/s3.h"
#endif

namespace tiledb::test {

// Forward declaration
Expand Down Expand Up @@ -1042,19 +1046,36 @@ class VFSTest : public VFSTestBase {
};

/** Test object for tiledb::sm::S3 functionality. */
class S3Test : public VFSTestBase, protected tiledb::sm::S3_within_VFS {
class S3Test : public VFSTestBase {
public:
explicit S3Test(const std::vector<size_t>& test_tree);

explicit S3Test(const std::vector<size_t>& test_tree)
: VFSTestBase(test_tree, "s3://") {
#ifdef HAVE_S3
/** Expose protected accessor from S3_within_VFS. */
tiledb::sm::S3& get_s3() {
return s3();
vfs_.create_bucket(temp_dir_);
for (size_t i = 1; i <= test_tree_.size(); i++) {
sm::URI path = temp_dir_.join_path("subdir_" + std::to_string(i));
// VFS::create_dir is a no-op for S3; Just create objects.
if (test_tree_[i - 1] > 0) {
// Do not include an empty prefix in expected results.
expected_results_.emplace_back(path.to_string(), 0);
}
for (size_t j = 1; j <= test_tree_[i - 1]; j++) {
auto object_uri = path.join_path("test_file_" + std::to_string(j));
vfs_.touch(object_uri);
std::string data(j * 10, 'a');
vfs_.write(object_uri, data.data(), data.size());
vfs_.close_file(object_uri).ok();
expected_results_.emplace_back(object_uri.to_string(), data.size());
}
}
std::sort(expected_results_.begin(), expected_results_.end());
#endif
}

/** Expose protected const accessor from S3_within_VFS. */
const tiledb::sm::S3& get_s3() const {
return s3();
#ifdef HAVE_S3
/** Expose protected accessor from S3 within VFS. */
tiledb::sm::S3& get_fs(const tiledb::sm::URI& uri) {
return dynamic_cast<tiledb::sm::S3&>(vfs_.get_fs(uri));
}
#endif
};
Expand Down
Loading