use amqprs::{
callbacks::{ChannelCallback, DefaultChannelCallback, DefaultConnectionCallback},
channel::{
BasicConsumeArguments, Channel, ExchangeDeclareArguments, ExchangeType,
QueueDeclareArguments, QueueDeleteArguments,
},
connection::Connection,
consumer::DefaultConsumer,
error::Error,
Ack, BasicProperties, Cancel, CloseChannel, Nack, Return,
};
use async_trait::async_trait;
use std::{sync::Arc, time::Duration};
use tokio::sync::Notify;
mod common;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[should_panic = "InternalChannelError(\"channel closed\")"]
async fn test_connection_callback() {
common::setup_logging();
let args = common::build_conn_args();
let connection = Connection::open(&args).await.unwrap();
connection
.register_callback(DefaultConnectionCallback)
.await
.unwrap();
let channel = connection.open_channel(None).await.unwrap();
channel
.exchange_declare(ExchangeDeclareArguments::new("amq.direct", "invalid_type"))
.await
.unwrap();
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[should_panic = "InternalChannelError(\"channel closed\")"]
async fn test_channel_callback() {
common::setup_logging();
let args = common::build_conn_args();
let connection = Connection::open(&args).await.unwrap();
let channel = connection.open_channel(None).await.unwrap();
channel
.register_callback(DefaultChannelCallback)
.await
.unwrap();
let args = ExchangeDeclareArguments::of_type("amq.topic", ExchangeType::Topic);
channel.exchange_declare(args).await.unwrap();
}
#[tokio::test]
async fn test_channel_callback_close() {
common::setup_logging();
let args = common::build_conn_args();
let connection = Connection::open(&args).await.unwrap();
let channel = connection.open_channel(None).await.unwrap();
let cancel_notify = Arc::new(Notify::new());
channel
.register_callback(ChannelCancelCallback {
cancel_notify: Arc::clone(&cancel_notify),
})
.await
.unwrap();
const QUEUE_NAME: &str = "test-channel-callback-close";
let args = QueueDeclareArguments::default()
.queue(QUEUE_NAME.to_string())
.finish();
channel.queue_declare(args).await.unwrap();
let args = BasicConsumeArguments::default()
.queue(QUEUE_NAME.to_string())
.finish();
channel
.basic_consume(DefaultConsumer::new(true), args)
.await
.unwrap();
let args = QueueDeleteArguments::default()
.queue(QUEUE_NAME.to_string())
.finish();
channel.queue_delete(args).await.unwrap();
tokio::time::timeout(Duration::from_secs(5), cancel_notify.notified())
.await
.expect("ChannelCallback::cancel() should be called when queue was deleted");
}
struct ChannelCancelCallback {
cancel_notify: Arc<Notify>,
}
#[async_trait]
impl ChannelCallback for ChannelCancelCallback {
async fn close(&mut self, _channel: &Channel, _close: CloseChannel) -> Result<(), Error> {
Ok(())
}
async fn cancel(&mut self, _channel: &Channel, _cancel: Cancel) -> Result<(), Error> {
self.cancel_notify.notify_one();
Ok(())
}
async fn flow(&mut self, _channel: &Channel, active: bool) -> Result<bool, Error> {
Ok(active)
}
async fn publish_ack(&mut self, _channel: &Channel, _ack: Ack) {}
async fn publish_nack(&mut self, _channel: &Channel, _nack: Nack) {}
async fn publish_return(
&mut self,
_channel: &Channel,
_ret: Return,
_basic_properties: BasicProperties,
_content: Vec<u8>,
) {
}
}