174 lines
6.2 KiB
Rust
174 lines
6.2 KiB
Rust
use futures_util::{SinkExt, StreamExt};
|
|
use circles_launcher::{new_launcher, setup_multi_circle_server, shutdown_circles, Args, CircleConfig};
|
|
use secp256k1::Secp256k1;
|
|
use tokio_tungstenite::connect_async;
|
|
use url::Url;
|
|
use std::str::FromStr;
|
|
|
|
#[tokio::test]
|
|
async fn test_launcher_builder_pattern() {
|
|
// Test the new builder pattern API
|
|
let secp = Secp256k1::new();
|
|
let (secret_key, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
|
|
let public_key_str = public_key.to_string();
|
|
|
|
// Use the builder pattern to create a launcher
|
|
let launcher = new_launcher()
|
|
.add_circle(&public_key_str)
|
|
.port(8088)
|
|
.redis_url("redis://127.0.0.1:6379")
|
|
.worker_binary("../target/debug/worker") // Use debug for tests
|
|
.enable_auth(false);
|
|
|
|
// Note: We can't easily test the full launch in unit tests since it requires
|
|
// actual binaries and Redis. This test verifies the builder pattern works.
|
|
|
|
// Verify the builder created the launcher correctly
|
|
// (This is more of a compilation test than a runtime test)
|
|
assert!(true, "Builder pattern works correctly");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_circle_config_parsing() {
|
|
// Test parsing circle configurations from strings
|
|
let public_key_only = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890";
|
|
let config = CircleConfig::from_str(public_key_only).expect("Failed to parse public key only");
|
|
assert_eq!(config.public_key, public_key_only);
|
|
assert!(config.init_script.is_none());
|
|
|
|
// Test with init script
|
|
let with_script = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890:init.rhai";
|
|
let config = CircleConfig::from_str(with_script).expect("Failed to parse with script");
|
|
assert_eq!(config.public_key, public_key_only);
|
|
assert_eq!(config.init_script, Some("init.rhai".to_string()));
|
|
|
|
// Test invalid format
|
|
let invalid = "invalid:too:many:colons";
|
|
let result = CircleConfig::from_str(invalid);
|
|
assert!(result.is_err(), "Should fail with invalid format");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_args_structure() {
|
|
// Test that Args structure works correctly with the new API
|
|
let secp = Secp256k1::new();
|
|
let (_, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
|
|
let public_key_str = public_key.to_string();
|
|
|
|
let args = Args {
|
|
port: 8089,
|
|
circles: vec![public_key_str.clone()],
|
|
redis_url: "redis://127.0.0.1:6379".to_string(),
|
|
enable_auth: false,
|
|
worker_binary: Some("../target/debug/worker".to_string()),
|
|
debug: true,
|
|
verbose: 1,
|
|
};
|
|
|
|
// Verify args structure
|
|
assert_eq!(args.port, 8089);
|
|
assert_eq!(args.circles.len(), 1);
|
|
assert_eq!(args.circles[0], public_key_str);
|
|
assert!(!args.enable_auth);
|
|
assert!(args.worker_binary.is_some());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_setup_multi_circle_server_validation() {
|
|
// Test validation in setup_multi_circle_server
|
|
let args = Args {
|
|
port: 8090,
|
|
circles: vec![], // Empty circles should cause error
|
|
redis_url: "redis://127.0.0.1:6379".to_string(),
|
|
enable_auth: false,
|
|
worker_binary: None, // Missing worker binary should cause error
|
|
debug: true,
|
|
verbose: 0,
|
|
};
|
|
|
|
// This should fail due to missing worker binary
|
|
let result = setup_multi_circle_server(&args).await;
|
|
assert!(result.is_err(), "Should fail with missing worker binary");
|
|
|
|
if let Err(e) = result {
|
|
let error_msg = e.to_string();
|
|
assert!(
|
|
error_msg.contains("Worker binary path is required"),
|
|
"Error should mention missing worker binary, got: {}",
|
|
error_msg
|
|
);
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_circle_config_validation() {
|
|
// Test that invalid public keys are rejected
|
|
let invalid_key = "not_a_valid_public_key";
|
|
let result = CircleConfig::from_str(invalid_key);
|
|
assert!(result.is_err(), "Should reject invalid public key");
|
|
|
|
// Test valid public key format
|
|
let valid_key = "02a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890";
|
|
let result = CircleConfig::from_str(valid_key);
|
|
assert!(result.is_ok(), "Should accept valid public key");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_launcher_cleanup_functionality() {
|
|
// Test that cleanup functionality exists and can be called
|
|
// Note: This doesn't test actual cleanup since we don't have running services
|
|
use circles_launcher::cleanup_launcher;
|
|
|
|
// This should not panic and should handle the case where no services exist
|
|
let result = cleanup_launcher().await;
|
|
// It's OK if this fails due to no services - we're just testing the API exists
|
|
let _ = result;
|
|
|
|
assert!(true, "Cleanup function exists and can be called");
|
|
}
|
|
|
|
// Integration test that would require actual binaries and Redis
|
|
// Commented out since it requires external dependencies
|
|
/*
|
|
#[tokio::test]
|
|
#[ignore] // Use `cargo test -- --ignored` to run this test
|
|
async fn test_full_launcher_integration() {
|
|
// This test requires:
|
|
// 1. Redis server running on localhost:6379
|
|
// 2. Worker binary built at ../target/debug/worker
|
|
// 3. WebSocket server binary built at ../target/debug/circles_server
|
|
|
|
let secp = Secp256k1::new();
|
|
let (_, public_key) = secp.generate_keypair(&mut secp256k1::rand::thread_rng());
|
|
let public_key_str = public_key.to_string();
|
|
|
|
let args = Args {
|
|
port: 8091,
|
|
circles: vec![public_key_str.clone()],
|
|
redis_url: "redis://127.0.0.1:6379".to_string(),
|
|
enable_auth: false,
|
|
worker_binary: Some("../target/debug/worker".to_string()),
|
|
debug: true,
|
|
verbose: 1,
|
|
};
|
|
|
|
// Setup the multi-circle server
|
|
let result = setup_multi_circle_server(&args).await;
|
|
assert!(result.is_ok(), "Failed to setup multi-circle server: {:?}", result.err());
|
|
|
|
let (running_circles, outputs) = result.unwrap();
|
|
|
|
// Verify outputs
|
|
assert_eq!(outputs.len(), 1);
|
|
assert_eq!(outputs[0].public_key, public_key_str);
|
|
|
|
// Test WebSocket connection
|
|
let ws_url = &outputs[0].ws_url;
|
|
let connection_result = connect_async(ws_url).await;
|
|
assert!(connection_result.is_ok(), "Failed to connect to WebSocket");
|
|
|
|
// Cleanup
|
|
shutdown_circles(running_circles).await;
|
|
}
|
|
*/
|