Skip to content

Commit 368c398

Browse files
committed
Add Integration test for RabbitMqEventPublisher.
1 parent d499784 commit 368c398

File tree

3 files changed

+128
-3
lines changed

3 files changed

+128
-3
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: RabbitMQ Integration Tests
2+
3+
on: [push, pull_request]
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.ref }}
7+
cancel-in-progress: true
8+
9+
jobs:
10+
integration-tests:
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
rabbitmq:
15+
image: rabbitmq:3
16+
env:
17+
RABBITMQ_DEFAULT_USER: guest
18+
RABBITMQ_DEFAULT_PASS: guest
19+
ports:
20+
- 5672:5672
21+
options: >-
22+
--health-cmd "rabbitmqctl node_health_check"
23+
--health-interval 10s
24+
--health-timeout 5s
25+
--health-retries 5
26+
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v4
30+
31+
- name: Run RabbitMQ integration tests
32+
run: cargo test --features integration-tests-events-rabbitmq -- --nocapture --verbose --color=always
33+
env:
34+
RUST_BACKTRACE: 1

ldk-server/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ lapin = { version = "2.5.1", optional = true }
2525
[features]
2626
default = []
2727
events-rabbitmq = ["dep:lapin"]
28+
29+
# Feature-flags related to integration tests.
30+
integration-tests-events-rabbitmq = ["events-rabbitmq"]
31+
32+
[dev-dependencies]
33+
futures-util = "0.3.31"

ldk-server/src/io/events/rabbitmq/mod.rs

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,91 @@ impl EventPublisher for RabbitMqEventPublisher {
143143
}
144144
}
145145

146-
// Ensure the publisher is Send and Sync for use in async contexts
147-
unsafe impl Send for RabbitMqEventPublisher {}
148-
unsafe impl Sync for RabbitMqEventPublisher {}
146+
#[cfg(test)]
147+
#[cfg(feature = "integration-tests-events-rabbitmq")]
148+
mod integration_tests_events_rabbitmq {
149+
use super::*;
150+
use lapin::{
151+
options::{BasicAckOptions, BasicConsumeOptions, QueueBindOptions, QueueDeclareOptions},
152+
types::FieldTable,
153+
Channel, Connection,
154+
};
155+
use ldk_server_protos::events::event_envelope::Event;
156+
use ldk_server_protos::events::PaymentForwarded;
157+
use std::io;
158+
use std::time::Duration;
159+
use tokio;
160+
161+
use futures_util::stream::StreamExt;
162+
#[tokio::test]
163+
async fn test_publish_and_consume_event() {
164+
let config = RabbitMqConfig {
165+
connection_string: "amqp://guest:guest@localhost:5672/%2f".to_string(),
166+
exchange_name: "test_exchange".to_string(),
167+
};
168+
169+
let publisher = RabbitMqEventPublisher::new(config.clone());
170+
171+
let conn = Connection::connect(&config.connection_string, ConnectionProperties::default())
172+
.await
173+
.expect("Failed make rabbitmq connection");
174+
let channel = conn.create_channel().await.expect("Failed to create rabbitmq channel");
175+
176+
let queue_name = "test_queue";
177+
setup_queue(&queue_name, &channel, &config).await;
178+
179+
let event = EventEnvelope {
180+
event: Some(Event::PaymentForwarded(PaymentForwarded::default())),
181+
};
182+
publisher.publish(event.clone()).await.expect("Failed to publish event");
183+
184+
consume_event(&queue_name, &channel, &event).await.expect("Failed to consume event");
185+
}
186+
187+
async fn setup_queue(queue_name: &str, channel: &Channel, config: &RabbitMqConfig) {
188+
channel
189+
.queue_declare(queue_name, QueueDeclareOptions::default(), FieldTable::default())
190+
.await
191+
.unwrap();
192+
channel
193+
.exchange_declare(
194+
&config.exchange_name,
195+
ExchangeKind::Fanout,
196+
ExchangeDeclareOptions { durable: true, ..Default::default() },
197+
FieldTable::default(),
198+
)
199+
.await
200+
.unwrap();
201+
202+
channel
203+
.queue_bind(
204+
queue_name,
205+
&config.exchange_name,
206+
"",
207+
QueueBindOptions::default(),
208+
FieldTable::default(),
209+
)
210+
.await
211+
.unwrap();
212+
}
213+
214+
async fn consume_event(
215+
queue_name: &str, channel: &Channel, expected_event: &EventEnvelope,
216+
) -> io::Result<()> {
217+
let mut consumer = channel
218+
.basic_consume(
219+
queue_name,
220+
"test_consumer",
221+
BasicConsumeOptions::default(),
222+
FieldTable::default(),
223+
)
224+
.await
225+
.unwrap();
226+
let delivery =
227+
tokio::time::timeout(Duration::from_secs(10), consumer.next()).await?.unwrap().unwrap();
228+
let received_event = EventEnvelope::decode(&*delivery.data)?;
229+
assert_eq!(received_event, *expected_event, "Event mismatch");
230+
channel.basic_ack(delivery.delivery_tag, BasicAckOptions::default()).await.unwrap();
231+
Ok(())
232+
}
233+
}

0 commit comments

Comments
 (0)