https://github.com/akarazhev/crypto-scout-test
Test support library for crypto-scout: mock data fixtures + Podman Compose-managed TimescaleDB and RabbitMQ (Streams + AMQP) for integration tests. This project was authored with AI-driven tools.
https://github.com/akarazhev/crypto-scout-test
bybit cryprocurrency java junit podman podman-compose timescaledb
Last synced: about 1 month ago
JSON representation
Test support library for crypto-scout: mock data fixtures + Podman Compose-managed TimescaleDB and RabbitMQ (Streams + AMQP) for integration tests. This project was authored with AI-driven tools.
- Host: GitHub
- URL: https://github.com/akarazhev/crypto-scout-test
- Owner: akarazhev
- License: mit
- Created: 2025-11-05T11:58:32.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2026-02-01T18:16:40.000Z (6 months ago)
- Last Synced: 2026-02-02T02:01:31.775Z (6 months ago)
- Topics: bybit, cryprocurrency, java, junit, podman, podman-compose, timescaledb
- Language: Java
- Homepage:
- Size: 300 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# crypto-scout-test
Test support library for the crypto-scout ecosystem. Provides mock data fixtures and containerized test infrastructure (TimescaleDB + RabbitMQ).
## Features
- **MockData** - Typed access to JSON fixtures (Bybit Spot/Linear, CMC, internal)
- **PodmanCompose** - Lifecycle management for TimescaleDB and RabbitMQ containers
- **StreamTestPublisher/Consumer** - RabbitMQ Streams test utilities (thread-safe)
- **AmqpTestPublisher/Consumer** - AMQP test utilities with confirmation timeouts
- **DBUtils** - Database cleanup and connection helpers
- **Assertions** - Database state verification (table counts, etc.)
## Quick Start
### Build
```bash
mvn -q -DskipTests install
```
### Add Dependency
```xml
com.github.akarazhev.cryptoscout
crypto-scout-test
0.0.1
test
```
### Usage
**Mock Data:**
```java
var spotKlines = MockData.get(Source.BYBIT_SPOT, Type.KLINE_1);
var fgi = MockData.get(Source.CRYPTO_SCOUT, Type.FGI);
```
**Container Lifecycle:**
```java
@BeforeAll static void setUp() { PodmanCompose.up(); }
@AfterAll static void tearDown() { PodmanCompose.down(); }
```
**RabbitMQ Streams:**
```java
var publisher = StreamTestPublisher.create(reactor, executor, env, "stream");
publisher.start().await();
publisher.publish(payload).await();
var consumer = StreamTestConsumer.create(reactor, executor, env, "stream");
consumer.start().await();
var result = consumer.getResult().await();
```
**RabbitMQ AMQP:**
```java
var publisher = AmqpTestPublisher.create(reactor, executor, factory, "queue");
publisher.publish("exchange", "key", message).await();
var consumer = AmqpTestConsumer.create(reactor, executor, factory, "queue");
var received = consumer.getMessage().await();
```
**Database Operations:**
```java
DBUtils.deleteFromTables(dataSource, "table1", "table2");
Assertions.assertTableCount("table1", 5);
```
## Configuration
| Property | Default | Description |
|----------|---------|-------------|
| `podman.compose.cmd` | `podman-compose` | Podman Compose executable |
| `test.db.jdbc.url` | `jdbc:postgresql://localhost:5432/crypto_scout` | Database URL |
| `test.db.user` | `crypto_scout_db` | Database username |
| `test.db.password` | `crypto_scout_db` | Database password |
| `test.mq.host` | `localhost` | RabbitMQ host |
| `test.mq.port` | `5552` | RabbitMQ Streams port |
| `test.mq.user` | `crypto_scout_mq` | RabbitMQ username |
| `test.mq.password` | `crypto_scout_mq` | RabbitMQ password |
| `podman.compose.up.timeout.min` | `3` | Startup timeout (minutes) |
### Example
```bash
mvn -q -Dpodman.compose.up.timeout.min=5 test
```
## Requirements
- Java 25
- Maven 3.9+
- Podman + podman-compose
## Services
**TimescaleDB** (PostgreSQL 17)
- Port: 5432
- Default DB: `crypto_scout`
- Credentials: `crypto_scout_db` / `crypto_scout_db`
**RabbitMQ** 4.1.4
- AMQP: 5672
- Streams: 5552
- Credentials: `crypto_scout_mq` / `crypto_scout_mq`
## Thread Safety
All publishers and consumers are thread-safe using `AtomicReference`:
- `StreamTestPublisher` - Atomic producer state management
- `StreamTestConsumer` - Atomic result capture (first message only)
- `AmqpTestPublisher` - Atomic connection/channel state, 5s confirmation timeout
- `AmqpTestConsumer` - Thread-safe message handling
## Error Handling
All operations throw `IllegalStateException` on failure:
- `MockData.get()` - Resource not found
- `PodmanCompose.up()/down()` - Command failure or timeout
- `*Publisher.publish()` - Not started, connection closed, or timeout
- `*Consumer.getResult()/getMessage()` - Not started
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Command not found | Set `-Dpodman.compose.cmd=/path/to/podman-compose` |
| Streams unreachable | Check port 5552 is free |
| DB unreachable | Verify JDBC URL and credentials |
| Cleanup failures | Check `DBUtils.deleteFromTables()` return value |
| Temp directories | Auto-cleaned via shutdown hooks; manual cleanup if JVM killed with -9 |
## License
MIT License. See `LICENSE`.