blob: e445d9011fa5576b5297a36fe2244192472d9208 [file] [log] [blame]
/*
* 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 "iceberg/table.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "iceberg/schema.h"
#include "iceberg/schema_field.h"
#include "iceberg/table_metadata.h"
#include "iceberg/test/matchers.h"
#include "iceberg/test/mock_catalog.h"
#include "iceberg/test/mock_io.h"
namespace iceberg {
template <typename T>
struct TableTraits;
template <>
struct TableTraits<Table> {
static constexpr bool kRefreshSupported = true;
static constexpr bool kTransactionSupported = true;
static Result<std::shared_ptr<Table>> Make(const TableIdentifier& ident,
std::shared_ptr<TableMetadata> metadata,
const std::string& location,
std::shared_ptr<FileIO> io,
std::shared_ptr<Catalog> catalog) {
return Table::Make(ident, std::move(metadata), location, std::move(io),
std::move(catalog));
}
};
template <>
struct TableTraits<StaticTable> {
static constexpr bool kRefreshSupported = false;
static constexpr bool kTransactionSupported = false;
static Result<std::shared_ptr<StaticTable>> Make(
const TableIdentifier& ident, std::shared_ptr<TableMetadata> metadata,
const std::string& location, std::shared_ptr<FileIO> io, std::shared_ptr<Catalog>) {
return StaticTable::Make(ident, std::move(metadata), location, std::move(io));
}
};
template <>
struct TableTraits<StagedTable> {
static constexpr bool kRefreshSupported = true;
static constexpr bool kTransactionSupported = true;
static Result<std::shared_ptr<StagedTable>> Make(
const TableIdentifier& ident, std::shared_ptr<TableMetadata> metadata,
const std::string& location, std::shared_ptr<FileIO> io,
std::shared_ptr<Catalog> catalog) {
return StagedTable::Make(ident, std::move(metadata), location, std::move(io),
std::move(catalog));
}
};
template <typename T>
class TypedTableTest : public ::testing::Test {
protected:
using Traits = TableTraits<T>;
void SetUp() override {
io_ = std::make_shared<MockFileIO>();
catalog_ = std::make_shared<MockCatalog>();
auto schema = std::make_shared<Schema>(
std::vector<SchemaField>{SchemaField::MakeRequired(1, "id", int64()),
SchemaField::MakeOptional(2, "name", string())},
1);
metadata_ = std::make_shared<TableMetadata>(
TableMetadata{.format_version = 2, .schemas = {schema}, .current_schema_id = 1});
}
Result<std::shared_ptr<T>> MakeTable(const std::string& name) {
TableIdentifier ident{.ns = Namespace{.levels = {"db"}}, .name = name};
return Traits::Make(ident, metadata_, "s3://bucket/meta.json", io_, catalog_);
}
std::shared_ptr<MockFileIO> io_;
std::shared_ptr<MockCatalog> catalog_;
std::shared_ptr<TableMetadata> metadata_;
};
using TableTypes = ::testing::Types<Table, StaticTable, StagedTable>;
TYPED_TEST_SUITE(TypedTableTest, TableTypes);
TYPED_TEST(TypedTableTest, BasicMetadata) {
ICEBERG_UNWRAP_OR_FAIL(auto table, this->MakeTable("test_table"));
EXPECT_EQ(table->name().name, "test_table");
EXPECT_EQ(table->name().ns.levels, (std::vector<std::string>{"db"}));
EXPECT_EQ(table->metadata()->format_version, 2);
EXPECT_EQ(table->metadata()->schemas.size(), 1);
}
TYPED_TEST(TypedTableTest, Refresh) {
using Traits = typename TestFixture::Traits;
ICEBERG_UNWRAP_OR_FAIL(auto table, this->MakeTable("test_table"));
if constexpr (Traits::kRefreshSupported) {
if constexpr (std::is_same_v<TypeParam, Table>) {
TableIdentifier ident{.ns = Namespace{.levels = {"db"}}, .name = "test_table"};
ICEBERG_UNWRAP_OR_FAIL(auto refreshed,
Table::Make(ident, this->metadata_, "s3://bucket/meta2.json",
this->io_, this->catalog_));
EXPECT_CALL(*this->catalog_, LoadTable(::testing::_))
.WillOnce(::testing::Return(refreshed));
}
EXPECT_THAT(table->Refresh(), IsOk());
} else {
EXPECT_THAT(table->Refresh(), IsError(ErrorKind::kNotSupported));
}
}
TYPED_TEST(TypedTableTest, NewTransaction) {
using Traits = typename TestFixture::Traits;
ICEBERG_UNWRAP_OR_FAIL(auto table, this->MakeTable("test_table"));
if constexpr (Traits::kTransactionSupported) {
EXPECT_THAT(table->NewTransaction(), IsOk());
} else {
EXPECT_THAT(table->NewTransaction(), IsError(ErrorKind::kNotSupported));
}
}
} // namespace iceberg