2828
2929#include " iceberg/arrow/arrow_fs_file_io_internal.h"
3030#include " iceberg/catalog/memory/in_memory_catalog.h"
31+ #include " iceberg/result.h"
32+ #include " iceberg/snapshot.h"
3133#include " iceberg/table.h"
3234#include " iceberg/table_identifier.h"
3335#include " iceberg/table_metadata.h"
3739
3840namespace iceberg {
3941
40- // Base test fixture for table update operations
42+ // / \brief Base test fixture for table update operations.
4143class UpdateTestBase : public ::testing::Test {
4244 protected:
45+ virtual std::string MetadataResource () const { return " TableMetadataV2Valid.json" ; }
46+ virtual std::string TableName () const { return " test_table" ; }
47+
4348 void SetUp () override {
49+ table_ident_ = TableIdentifier{.name = TableName ()};
50+ table_location_ = " /warehouse/" + TableName ();
51+
4452 InitializeFileIO ();
45- RegisterTableFromResource (" TableMetadataV2Valid.json " );
53+ RegisterTableFromResource (MetadataResource () );
4654 }
4755
4856 // / \brief Initialize file IO and create necessary directories.
@@ -56,82 +64,91 @@ class UpdateTestBase : public ::testing::Test {
5664 static_cast <arrow::ArrowFileSystemFileIO&>(*file_io_).fs ());
5765 ASSERT_TRUE (arrow_fs != nullptr );
5866 ASSERT_TRUE (arrow_fs->CreateDir (table_location_ + " /metadata" ).ok ());
59- ASSERT_TRUE (arrow_fs->CreateDir (table_location_ + " /metadata" ).ok ());
6067 }
6168
6269 // / \brief Register a table from a metadata resource file.
6370 // /
6471 // / \param resource_name The name of the metadata resource file
6572 void RegisterTableFromResource (const std::string& resource_name) {
66- // Drop existing table if it exists
6773 std::ignore = catalog_->DropTable (table_ident_, /* purge=*/ false );
6874
69- // Write table metadata to the table location.
7075 auto metadata_location = std::format (" {}/metadata/00001-{}.metadata.json" ,
7176 table_location_, Uuid::GenerateV7 ().ToString ());
7277 ICEBERG_UNWRAP_OR_FAIL (auto metadata, ReadTableMetadataFromResource (resource_name));
7378 metadata->location = table_location_;
7479 ASSERT_THAT (TableMetadataUtil::Write (*file_io_, metadata_location, *metadata),
7580 IsOk ());
7681
77- // Register the table in the catalog.
7882 ICEBERG_UNWRAP_OR_FAIL (table_,
7983 catalog_->RegisterTable (table_ident_, metadata_location));
8084 }
8185
82- const TableIdentifier table_ident_{. name = " test_table " };
83- const std::string table_location_{ " /warehouse/test_table " };
84- std::shared_ptr<FileIO> file_io_ ;
85- std::shared_ptr<InMemoryCatalog> catalog_ ;
86- std::shared_ptr<Table> table_ ;
87- };
86+ // / \brief Reload the table from catalog and return its metadata.
87+ std::shared_ptr<TableMetadata> ReloadMetadata () {
88+ auto result = catalog_-> LoadTable (table_ident_) ;
89+ EXPECT_TRUE (result. has_value ()) << " Failed to reload table " ;
90+ return result. value ()-> metadata () ;
91+ }
8892
89- // Base test fixture for table update operations on minimal table metadata.
90- class MinimalUpdateTestBase : public ::testing::Test {
91- protected:
92- void SetUp () override {
93- InitializeFileIO ();
94- RegisterMinimalTableFromResource (" TableMetadataV2ValidMinimal.json" );
93+ // / \brief Assert that a ref exists with the given type and snapshot id.
94+ void ExpectRef (const std::string& name, SnapshotRefType type, int64_t snapshot_id) {
95+ auto metadata = ReloadMetadata ();
96+ auto it = metadata->refs .find (name);
97+ ASSERT_NE (it, metadata->refs .end ()) << " Ref not found: " << name;
98+ EXPECT_EQ (it->second ->type (), type);
99+ EXPECT_EQ (it->second ->snapshot_id , snapshot_id);
95100 }
96101
97- // / \brief Initialize file IO and create necessary directories.
98- void InitializeFileIO () {
99- file_io_ = arrow::ArrowFileSystemFileIO::MakeMockFileIO ();
100- catalog_ =
101- InMemoryCatalog::Make (" test_catalog" , file_io_, " /warehouse/" , /* properties=*/ {});
102+ void ExpectBranch (const std::string& name, int64_t snapshot_id) {
103+ ExpectRef (name, SnapshotRefType::kBranch , snapshot_id);
104+ }
102105
103- // Arrow MockFS cannot automatically create directories.
104- auto arrow_fs = std::dynamic_pointer_cast<::arrow::fs::internal::MockFileSystem>(
105- static_cast <arrow::ArrowFileSystemFileIO&>(*file_io_).fs ());
106- ASSERT_TRUE (arrow_fs != nullptr );
107- ASSERT_TRUE (arrow_fs->CreateDir (table_location_ + " /metadata" ).ok ());
106+ void ExpectTag (const std::string& name, int64_t snapshot_id) {
107+ ExpectRef (name, SnapshotRefType::kTag , snapshot_id);
108108 }
109109
110- // / \brief Register a minimal table from a metadata resource file.
111- // /
112- // / \param resource_name The name of the metadata resource file
113- void RegisterMinimalTableFromResource (const std::string& resource_name) {
114- // Drop existing table if it exists
115- std::ignore = catalog_->DropTable (table_ident_, /* purge=*/ false );
110+ // / \brief Assert that a ref does not exist.
111+ void ExpectNoRef (const std::string& name) {
112+ auto metadata = ReloadMetadata ();
113+ EXPECT_FALSE (metadata->refs .contains (name)) << " Ref should not exist: " << name;
114+ }
116115
117- // Write table metadata to the table location.
118- auto metadata_location = std::format (" {}/metadata/00001-{}.metadata.json" ,
119- table_location_, Uuid::GenerateV7 ().ToString ());
120- ICEBERG_UNWRAP_OR_FAIL (auto metadata, ReadTableMetadataFromResource (resource_name));
121- metadata->location = table_location_;
122- ASSERT_THAT (TableMetadataUtil::Write (*file_io_, metadata_location, *metadata),
123- IsOk ());
116+ // / \brief Assert the current snapshot id after reloading.
117+ void ExpectCurrentSnapshot (int64_t snapshot_id) {
118+ auto result = catalog_->LoadTable (table_ident_);
119+ ASSERT_TRUE (result.has_value ());
120+ auto snap_result = result.value ()->current_snapshot ();
121+ ASSERT_TRUE (snap_result.has_value ());
122+ EXPECT_EQ (snap_result.value ()->snapshot_id , snapshot_id);
123+ }
124124
125- // Register the table in the catalog.
126- ICEBERG_UNWRAP_OR_FAIL (minimal_table_,
127- catalog_->RegisterTable (table_ident_, metadata_location));
125+ // / \brief Assert that a commit succeeded.
126+ template <typename T>
127+ void ExpectCommitOk (const T& result) {
128+ EXPECT_THAT (result, IsOk ());
129+ }
130+
131+ // / \brief Assert that a commit failed with the given error kind and message substring.
132+ template <typename T>
133+ void ExpectCommitError (const T& result, ErrorKind kind, const std::string& message) {
134+ EXPECT_THAT (result, IsError (kind));
135+ EXPECT_THAT (result, HasErrorMessage (message));
128136 }
129137
130- const TableIdentifier table_ident_{. name = " minimal_table " } ;
131- const std::string table_location_{ " /warehouse/minimal_table " } ;
138+ TableIdentifier table_ident_;
139+ std::string table_location_;
132140 std::shared_ptr<FileIO> file_io_;
133141 std::shared_ptr<InMemoryCatalog> catalog_;
134- std::shared_ptr<Table> minimal_table_;
142+ std::shared_ptr<Table> table_;
143+ };
144+
145+ // / \brief Test fixture for table update operations on minimal table metadata.
146+ class MinimalUpdateTestBase : public UpdateTestBase {
147+ protected:
148+ std::string MetadataResource () const override {
149+ return " TableMetadataV2ValidMinimal.json" ;
150+ }
151+ std::string TableName () const override { return " minimal_table" ; }
135152};
136153
137154} // namespace iceberg
0 commit comments