minio-rs/tests/s3/bucket_notification.rs
Henk-Jan Lebbink c450081b2e
Refactor string parameters to typed wrapper structs (#200)
- Replaced raw string parameters with validated wrapper types (BucketName, ObjectName, Region, VersionId, etc.) following the "parse, don't validate" pattern
- Bucket and object names are now validated at construction time, ensuring compile-time correctness
- Added both relaxed (MinIO-compatible) and strict (AWS S3-compliant) validation modes for bucket names
2026-01-27 14:12:49 +01:00

146 lines
5.0 KiB
Rust

// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
// Copyright 2025 MinIO, Inc.
//
// Licensed 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.
use minio::s3::client::DEFAULT_REGION;
use minio::s3::response::{
DeleteBucketNotificationResponse, GetBucketNotificationResponse, PutBucketNotificationResponse,
};
use minio::s3::response_traits::{HasBucket, HasRegion};
use minio::s3::types::{BucketName, NotificationConfig, S3Api};
use minio_common::example::create_bucket_notification_config_example;
use minio_common::test_context::TestContext;
const SQS_ARN: &str = "arn:minio:sqs:us-east-1:miniojavatest:webhook";
/// Tests bucket notification configuration.
///
/// ## Prerequisites (MinIO Admin Configuration Required)
///
/// This test requires notification targets to be configured via MinIO admin before it can run.
/// Bucket notifications cannot be configured via the S3 API alone - the notification targets
/// (webhooks, Kafka, NATS, AMQP, etc.) must first be set up using MinIO admin commands.
///
/// ### Example: Configure a webhook notification target
///
/// ```bash
/// # Configure webhook target with ARN "miniojavatest"
/// mc admin config set myminio notify_webhook:miniojavatest \
/// endpoint="http://example.com/webhook" \
/// queue_limit="10"
///
/// # Restart MinIO to apply changes
/// mc admin service restart myminio
///
/// # Verify the ARN is available
/// mc admin info myminio --json | jq '.info.services.notifications'
/// # Should show: arn:minio:sqs:us-east-1:miniojavatest:webhook
/// ```
///
/// ### Test Behavior
///
/// - If notification targets are properly configured, the test runs normally
/// - If targets are not configured, the test gracefully skips (not a failure)
/// - This allows the test suite to pass in development environments without notification infrastructure
#[minio_macros::test(
skip_if_express,
ignore = "Requires notification target configuration; enable when madmin is ported to Rust"
)]
async fn test_bucket_notification(ctx: TestContext, bucket: BucketName) {
let config: NotificationConfig = create_bucket_notification_config_example();
let resp: PutBucketNotificationResponse = ctx
.client
.put_bucket_notification(&bucket)
.unwrap()
.notification_config(config.clone())
.build()
.send()
.await
.unwrap();
assert_eq!(resp.bucket(), Some(&bucket));
assert_eq!(resp.region(), &*DEFAULT_REGION);
//println!("response of setting notification: resp={:?}", resp);
let resp: GetBucketNotificationResponse = ctx
.client
.get_bucket_notification(&bucket)
.unwrap()
.build()
.send()
.await
.unwrap();
let config2: NotificationConfig = resp.config().unwrap();
assert_eq!(config2, config);
assert_eq!(resp.bucket(), Some(&bucket));
assert_eq!(resp.region(), &*DEFAULT_REGION);
//println!("response of getting notification: resp={:?}", resp);
assert_eq!(config2.queue_config_list.as_ref().unwrap().len(), 1);
assert!(
config2.queue_config_list.as_ref().unwrap()[0]
.events
.contains(&String::from("s3:ObjectCreated:Put"))
);
assert!(
config2.queue_config_list.as_ref().unwrap()[0]
.events
.contains(&String::from("s3:ObjectCreated:Copy"))
);
assert_eq!(
config2.queue_config_list.as_ref().unwrap()[0]
.prefix_filter_rule
.as_ref()
.unwrap()
.value,
"images"
);
assert_eq!(
config2.queue_config_list.as_ref().unwrap()[0]
.suffix_filter_rule
.as_ref()
.unwrap()
.value,
"pg"
);
assert_eq!(
config2.queue_config_list.as_ref().unwrap()[0].queue,
SQS_ARN
);
let resp: DeleteBucketNotificationResponse = ctx
.client
.delete_bucket_notification(&bucket)
.unwrap()
.build()
.send()
.await
.unwrap();
assert_eq!(resp.bucket(), Some(&bucket));
assert_eq!(resp.region(), &*DEFAULT_REGION);
//println!("response of deleting notification: resp={:?}", resp);
let resp: GetBucketNotificationResponse = ctx
.client
.get_bucket_notification(&bucket)
.unwrap()
.build()
.send()
.await
.unwrap();
assert_eq!(resp.bucket(), Some(&bucket));
assert_eq!(resp.region(), &*DEFAULT_REGION);
assert_eq!(resp.config().unwrap(), NotificationConfig::default());
}