Skip to content

Commit 8b7036b

Browse files
committed
more tests
1 parent af2a28b commit 8b7036b

File tree

3 files changed

+188
-5
lines changed

3 files changed

+188
-5
lines changed

crates/iceberg/src/catalog/mod.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,14 +963,15 @@ mod tests {
963963
use std::fs::File;
964964
use std::io::BufReader;
965965

966+
use base64::Engine as _;
966967
use serde::Serialize;
967968
use serde::de::DeserializeOwned;
968969
use uuid::uuid;
969970

970971
use super::ViewUpdate;
971972
use crate::io::FileIOBuilder;
972973
use crate::spec::{
973-
BlobMetadata, FormatVersion, MAIN_BRANCH, NestedField, NullOrder, Operation,
974+
BlobMetadata, EncryptedKey, FormatVersion, MAIN_BRANCH, NestedField, NullOrder, Operation,
974975
PartitionStatisticsFile, PrimitiveType, Schema, Snapshot, SnapshotReference,
975976
SnapshotRetention, SortDirection, SortField, SortOrder, SqlViewRepresentation,
976977
StatisticsFile, Summary, TableMetadata, TableMetadataBuilder, Transform, Type,
@@ -2194,6 +2195,49 @@ mod tests {
21942195
);
21952196
}
21962197

2198+
#[test]
2199+
fn test_add_encryption_key() {
2200+
let key_bytes = "key".as_bytes();
2201+
let encoded_key = base64::engine::general_purpose::STANDARD.encode(key_bytes);
2202+
test_serde_json(
2203+
format!(
2204+
r#"
2205+
{{
2206+
"action": "add-encryption-key",
2207+
"encryption-key": {{
2208+
"key-id": "a",
2209+
"encrypted-key-metadata": "{encoded_key}",
2210+
"encrypted-by-id": "b"
2211+
}}
2212+
}}
2213+
"#
2214+
),
2215+
TableUpdate::AddEncryptionKey {
2216+
encryption_key: EncryptedKey {
2217+
key_id: "a".to_string(),
2218+
encrypted_key_metadata: key_bytes.to_vec(),
2219+
encrypted_by_id: "b".to_string(),
2220+
properties: HashMap::new(),
2221+
},
2222+
},
2223+
);
2224+
}
2225+
2226+
#[test]
2227+
fn test_remove_encryption_key() {
2228+
test_serde_json(
2229+
r#"
2230+
{
2231+
"action": "remove-encryption-key",
2232+
"key-id": "a"
2233+
}
2234+
"#,
2235+
TableUpdate::RemoveEncryptionKey {
2236+
key_id: "a".to_string(),
2237+
},
2238+
);
2239+
}
2240+
21972241
#[test]
21982242
fn test_table_commit() {
21992243
let table = {

crates/iceberg/src/spec/encrypted_key.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@ use serde::{Deserialize, Serialize};
2626
pub struct EncryptedKey {
2727
/// Unique identifier for the key
2828
#[builder(setter(into))]
29-
key_id: String,
29+
pub(crate) key_id: String,
3030
/// Encrypted key metadata as binary data
3131
#[builder(setter(into))]
32-
encrypted_key_metadata: Vec<u8>,
32+
pub(crate) encrypted_key_metadata: Vec<u8>,
3333
/// Identifier of the entity that encrypted this key
3434
#[builder(setter(into))]
35-
encrypted_by_id: String,
35+
pub(crate) encrypted_by_id: String,
3636
/// Additional properties associated with the key
3737
#[builder(default)]
38-
properties: HashMap<String, String>,
38+
pub(crate) properties: HashMap<String, String>,
3939
}
4040

4141
impl EncryptedKey {

crates/iceberg/src/spec/table_metadata_builder.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,4 +3179,143 @@ mod tests {
31793179
)
31803180
);
31813181
}
3182+
3183+
#[test]
3184+
fn test_encryption_keys() {
3185+
let builder = builder_without_changes(FormatVersion::V2);
3186+
3187+
// Create test encryption keys
3188+
let encryption_key_1 = EncryptedKey::builder()
3189+
.key_id("key-1")
3190+
.encrypted_key_metadata(vec![1, 2, 3, 4])
3191+
.encrypted_by_id("encryption-service-1")
3192+
.properties(HashMap::from_iter(vec![(
3193+
"algorithm".to_string(),
3194+
"AES-256".to_string(),
3195+
)]))
3196+
.build();
3197+
3198+
let encryption_key_2 = EncryptedKey::builder()
3199+
.key_id("key-2")
3200+
.encrypted_key_metadata(vec![5, 6, 7, 8])
3201+
.encrypted_by_id("encryption-service-2")
3202+
.properties(HashMap::new())
3203+
.build();
3204+
3205+
// Add first encryption key
3206+
let build_result = builder
3207+
.add_encryption_key(encryption_key_1.clone())
3208+
.build()
3209+
.unwrap();
3210+
3211+
assert_eq!(build_result.changes.len(), 1);
3212+
assert_eq!(build_result.metadata.encryption_keys.len(), 1);
3213+
assert_eq!(
3214+
build_result.metadata.encryption_key("key-1"),
3215+
Some(&encryption_key_1)
3216+
);
3217+
assert_eq!(build_result.changes[0], TableUpdate::AddEncryptionKey {
3218+
encryption_key: encryption_key_1.clone()
3219+
});
3220+
3221+
// Add second encryption key
3222+
let build_result = build_result
3223+
.metadata
3224+
.into_builder(Some(
3225+
"s3://bucket/test/location/metadata/metadata1.json".to_string(),
3226+
))
3227+
.add_encryption_key(encryption_key_2.clone())
3228+
.build()
3229+
.unwrap();
3230+
3231+
assert_eq!(build_result.changes.len(), 1);
3232+
assert_eq!(build_result.metadata.encryption_keys.len(), 2);
3233+
assert_eq!(
3234+
build_result.metadata.encryption_key("key-1"),
3235+
Some(&encryption_key_1)
3236+
);
3237+
assert_eq!(
3238+
build_result.metadata.encryption_key("key-2"),
3239+
Some(&encryption_key_2)
3240+
);
3241+
assert_eq!(build_result.changes[0], TableUpdate::AddEncryptionKey {
3242+
encryption_key: encryption_key_2.clone()
3243+
});
3244+
3245+
// Try to add duplicate key - should not create a change
3246+
let build_result = build_result
3247+
.metadata
3248+
.into_builder(Some(
3249+
"s3://bucket/test/location/metadata/metadata2.json".to_string(),
3250+
))
3251+
.add_encryption_key(encryption_key_1.clone())
3252+
.build()
3253+
.unwrap();
3254+
3255+
assert_eq!(build_result.changes.len(), 0);
3256+
assert_eq!(build_result.metadata.encryption_keys.len(), 2);
3257+
3258+
// Remove first encryption key
3259+
let build_result = build_result
3260+
.metadata
3261+
.into_builder(Some(
3262+
"s3://bucket/test/location/metadata/metadata3.json".to_string(),
3263+
))
3264+
.remove_encryption_key("key-1")
3265+
.build()
3266+
.unwrap();
3267+
3268+
assert_eq!(build_result.changes.len(), 1);
3269+
assert_eq!(build_result.metadata.encryption_keys.len(), 1);
3270+
assert_eq!(build_result.metadata.encryption_key("key-1"), None);
3271+
assert_eq!(
3272+
build_result.metadata.encryption_key("key-2"),
3273+
Some(&encryption_key_2)
3274+
);
3275+
assert_eq!(build_result.changes[0], TableUpdate::RemoveEncryptionKey {
3276+
key_id: "key-1".to_string()
3277+
});
3278+
3279+
// Try to remove non-existent key - should not create a change
3280+
let build_result = build_result
3281+
.metadata
3282+
.into_builder(Some(
3283+
"s3://bucket/test/location/metadata/metadata4.json".to_string(),
3284+
))
3285+
.remove_encryption_key("non-existent-key")
3286+
.build()
3287+
.unwrap();
3288+
3289+
assert_eq!(build_result.changes.len(), 0);
3290+
assert_eq!(build_result.metadata.encryption_keys.len(), 1);
3291+
3292+
// Test encryption_keys_iter()
3293+
let keys: Vec<(&String, &EncryptedKey)> =
3294+
build_result.metadata.encryption_keys_iter().collect();
3295+
assert_eq!(keys.len(), 1);
3296+
assert_eq!(keys[0].0, "key-2");
3297+
assert_eq!(keys[0].1, &encryption_key_2);
3298+
3299+
// Remove last encryption key
3300+
let build_result = build_result
3301+
.metadata
3302+
.into_builder(Some(
3303+
"s3://bucket/test/location/metadata/metadata5.json".to_string(),
3304+
))
3305+
.remove_encryption_key("key-2")
3306+
.build()
3307+
.unwrap();
3308+
3309+
assert_eq!(build_result.changes.len(), 1);
3310+
assert_eq!(build_result.metadata.encryption_keys.len(), 0);
3311+
assert_eq!(build_result.metadata.encryption_key("key-2"), None);
3312+
assert_eq!(build_result.changes[0], TableUpdate::RemoveEncryptionKey {
3313+
key_id: "key-2".to_string()
3314+
});
3315+
3316+
// Verify empty encryption_keys_iter()
3317+
let keys: Vec<(&String, &EncryptedKey)> =
3318+
build_result.metadata.encryption_keys_iter().collect();
3319+
assert_eq!(keys.len(), 0);
3320+
}
31823321
}

0 commit comments

Comments
 (0)