Skip to content
Closed
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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ rand = "0.8.5"
regex = "1.11.3"
reqwest = { version = "0.12.12", default-features = false, features = ["json"] }
roaring = { version = "0.11" }
rstest = "0.26"
fastnum = { version = "0.7", default-features = false, features = ["std", "serde"] }
serde = { version = "1.0.219", features = ["rc"] }
serde_bytes = "0.11.17"
Expand Down
352 changes: 1 addition & 351 deletions crates/catalog/glue/tests/glue_catalog_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ use std::collections::HashMap;

use iceberg::io::{S3_ACCESS_KEY_ID, S3_ENDPOINT, S3_REGION, S3_SECRET_ACCESS_KEY};
use iceberg::spec::{NestedField, PrimitiveType, Schema, Type};
use iceberg::transaction::{ApplyTransactionAction, Transaction};
use iceberg::{
Catalog, CatalogBuilder, Namespace, NamespaceIdent, Result, TableCreation, TableIdent,
};
use iceberg::{Catalog, CatalogBuilder, NamespaceIdent, Result, TableCreation, TableIdent};
use iceberg_catalog_glue::{
AWS_ACCESS_KEY_ID, AWS_REGION_NAME, AWS_SECRET_ACCESS_KEY, GLUE_CATALOG_PROP_URI,
GLUE_CATALOG_PROP_WAREHOUSE, GlueCatalog, GlueCatalogBuilder,
Expand Down Expand Up @@ -116,353 +113,6 @@ fn set_table_creation(location: Option<String>, name: impl ToString) -> Result<T
Ok(builder.build())
}

#[tokio::test]
async fn test_rename_table() -> Result<()> {
let catalog = get_catalog().await;
let creation = set_table_creation(None, "my_table")?;
// Use unique namespace to avoid conflicts
let namespace = Namespace::new(NamespaceIdent::new(normalize_test_name_with_parts!(
"test_rename_table"
)));
cleanup_namespace(&catalog, namespace.name()).await;

catalog
.create_namespace(namespace.name(), HashMap::new())
.await?;

let table = catalog.create_table(namespace.name(), creation).await?;

let dest = TableIdent::new(namespace.name().clone(), "my_table_rename".to_string());

catalog.rename_table(table.identifier(), &dest).await?;

let table = catalog.load_table(&dest).await?;
assert_eq!(table.identifier(), &dest);

let src = TableIdent::new(namespace.name().clone(), "my_table".to_string());

let src_table_exists = catalog.table_exists(&src).await?;
assert!(!src_table_exists);

Ok(())
}

#[tokio::test]
async fn test_table_exists() -> Result<()> {
let catalog = get_catalog().await;
let creation = set_table_creation(None, "my_table")?;
// Use unique namespace to avoid conflicts
let namespace = Namespace::new(NamespaceIdent::new(normalize_test_name_with_parts!(
"test_table_exists"
)));
cleanup_namespace(&catalog, namespace.name()).await;

catalog
.create_namespace(namespace.name(), HashMap::new())
.await?;

let ident = TableIdent::new(namespace.name().clone(), "my_table".to_string());

let exists = catalog.table_exists(&ident).await?;
assert!(!exists);

let table = catalog.create_table(namespace.name(), creation).await?;

let exists = catalog.table_exists(table.identifier()).await?;

assert!(exists);

Ok(())
}

#[tokio::test]
async fn test_drop_table() -> Result<()> {
let catalog = get_catalog().await;
let creation = set_table_creation(None, "my_table")?;
// Use unique namespace to avoid conflicts
let namespace = Namespace::new(NamespaceIdent::new(normalize_test_name_with_parts!(
"test_drop_table"
)));
cleanup_namespace(&catalog, namespace.name()).await;

catalog
.create_namespace(namespace.name(), HashMap::new())
.await?;

let table = catalog.create_table(namespace.name(), creation).await?;

catalog.drop_table(table.identifier()).await?;

let result = catalog.table_exists(table.identifier()).await?;

assert!(!result);

Ok(())
}

#[tokio::test]
async fn test_load_table() -> Result<()> {
let catalog = get_catalog().await;
let creation = set_table_creation(None, "my_table")?;
// Use unique namespace to avoid conflicts
let namespace = Namespace::new(NamespaceIdent::new(normalize_test_name_with_parts!(
"test_load_table"
)));
cleanup_namespace(&catalog, namespace.name()).await;

catalog
.create_namespace(namespace.name(), HashMap::new())
.await?;

let expected = catalog.create_table(namespace.name(), creation).await?;

let result = catalog
.load_table(&TableIdent::new(
namespace.name().clone(),
"my_table".to_string(),
))
.await?;

assert_eq!(result.identifier(), expected.identifier());
assert_eq!(result.metadata_location(), expected.metadata_location());
assert_eq!(result.metadata(), expected.metadata());

Ok(())
}

#[tokio::test]
async fn test_create_table() -> Result<()> {
let catalog = get_catalog().await;
// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_create_table"));
cleanup_namespace(&catalog, &namespace).await;
set_test_namespace(&catalog, &namespace).await?;
// inject custom location, ignore the namespace prefix
let creation = set_table_creation(Some("s3a://warehouse/hive".into()), "my_table")?;
let result = catalog.create_table(&namespace, creation).await?;

assert_eq!(result.identifier().name(), "my_table");
assert!(
result
.metadata_location()
.is_some_and(|location| location.starts_with("s3a://warehouse/hive/metadata/00000-"))
);
assert!(
catalog
.file_io()
.exists("s3a://warehouse/hive/metadata/")
.await?
);

Ok(())
}

#[tokio::test]
async fn test_list_tables() -> Result<()> {
let catalog = get_catalog().await;
// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_list_tables"));
cleanup_namespace(&catalog, &namespace).await;
set_test_namespace(&catalog, &namespace).await?;

let expected = vec![];
let result = catalog.list_tables(&namespace).await?;

assert_eq!(result, expected);

Ok(())
}

#[tokio::test]
async fn test_drop_namespace() -> Result<()> {
let catalog = get_catalog().await;
// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_drop_namespace"));
cleanup_namespace(&catalog, &namespace).await;
set_test_namespace(&catalog, &namespace).await?;

let exists = catalog.namespace_exists(&namespace).await?;
assert!(exists);

catalog.drop_namespace(&namespace).await?;

let exists = catalog.namespace_exists(&namespace).await?;
assert!(!exists);

Ok(())
}

#[tokio::test]
async fn test_update_namespace() -> Result<()> {
let catalog = get_catalog().await;
// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_update_namespace"));
cleanup_namespace(&catalog, &namespace).await;
set_test_namespace(&catalog, &namespace).await?;

let before_update = catalog.get_namespace(&namespace).await?;
let before_update = before_update.properties().get("description");

assert_eq!(before_update, None);

let properties = HashMap::from([("description".to_string(), "my_update".to_string())]);

catalog.update_namespace(&namespace, properties).await?;

let after_update = catalog.get_namespace(&namespace).await?;
let after_update = after_update.properties().get("description");

assert_eq!(after_update, Some("my_update".to_string()).as_ref());

Ok(())
}

#[tokio::test]
async fn test_namespace_exists() -> Result<()> {
let catalog = get_catalog().await;

// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_namespace_exists"));
cleanup_namespace(&catalog, &namespace).await;

let exists = catalog.namespace_exists(&namespace).await?;
assert!(!exists);

set_test_namespace(&catalog, &namespace).await?;

let exists = catalog.namespace_exists(&namespace).await?;
assert!(exists);

Ok(())
}

#[tokio::test]
async fn test_get_namespace() -> Result<()> {
let catalog = get_catalog().await;

// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_get_namespace"));
cleanup_namespace(&catalog, &namespace).await;

let does_not_exist = catalog.get_namespace(&namespace).await;
assert!(does_not_exist.is_err());

set_test_namespace(&catalog, &namespace).await?;

let result = catalog.get_namespace(&namespace).await?;
let expected = Namespace::new(namespace);

assert_eq!(result, expected);

Ok(())
}

#[tokio::test]
async fn test_create_namespace() -> Result<()> {
let catalog = get_catalog().await;

let properties = HashMap::new();
// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_create_namespace"));
cleanup_namespace(&catalog, &namespace).await;

let expected = Namespace::new(namespace.clone());

let result = catalog.create_namespace(&namespace, properties).await?;

assert_eq!(result, expected);

Ok(())
}

#[tokio::test]
async fn test_list_namespace() -> Result<()> {
let catalog = get_catalog().await;

// Use unique namespace to avoid conflicts
let namespace = NamespaceIdent::new(normalize_test_name_with_parts!("test_list_namespace"));
cleanup_namespace(&catalog, &namespace).await;
set_test_namespace(&catalog, &namespace).await?;

let result = catalog.list_namespaces(None).await?;
assert!(result.contains(&namespace));

let empty_result = catalog.list_namespaces(Some(&namespace)).await?;
assert!(empty_result.is_empty());

Ok(())
}

#[tokio::test]
async fn test_update_table() -> Result<()> {
let catalog = get_catalog().await;
let creation = set_table_creation(None, "my_table")?;
// Use unique namespace to avoid conflicts
let namespace = Namespace::new(NamespaceIdent::new(normalize_test_name_with_parts!(
"test_update_table"
)));
cleanup_namespace(&catalog, namespace.name()).await;

catalog
.create_namespace(namespace.name(), HashMap::new())
.await?;

let expected = catalog.create_table(namespace.name(), creation).await?;

let table = catalog
.load_table(&TableIdent::new(
namespace.name().clone(),
"my_table".to_string(),
))
.await?;

assert_eq!(table.identifier(), expected.identifier());
assert_eq!(table.metadata_location(), expected.metadata_location());
assert_eq!(table.metadata(), expected.metadata());

// Store the original metadata location for comparison
let original_metadata_location = table.metadata_location();

// Update table properties using the transaction
let tx = Transaction::new(&table);
let tx = tx
.update_table_properties()
.set("test_property".to_string(), "test_value".to_string())
.apply(tx)?;

// Commit the transaction to the catalog
let updated_table = tx.commit(&catalog).await?;

// Verify the update was successful
assert_eq!(
updated_table.metadata().properties().get("test_property"),
Some(&"test_value".to_string())
);

// Verify the metadata location has been updated
assert_ne!(
updated_table.metadata_location(),
original_metadata_location,
"Metadata location should be updated after commit"
);

// Load the table again from the catalog to verify changes were persisted
let reloaded_table = catalog.load_table(table.identifier()).await?;

// Verify the reloaded table matches the updated table
assert_eq!(
reloaded_table.metadata().properties().get("test_property"),
Some(&"test_value".to_string())
);
assert_eq!(
reloaded_table.metadata_location(),
updated_table.metadata_location(),
"Reloaded table should have the same metadata location as the updated table"
);

Ok(())
}

#[tokio::test]
async fn test_register_table() -> Result<()> {
let catalog = get_catalog().await;
Expand Down
Loading
Loading