photoncloud-monorepo/chainfire/crates/chainfire-server/tests/integration_test.rs
centra 5c6eb04a46 T036: Add VM cluster deployment configs for nixos-anywhere
- netboot-base.nix with SSH key auth
- Launch scripts for node01/02/03
- Node configuration.nix and disko.nix
- Nix modules for first-boot automation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 09:59:19 +09:00

160 lines
4.5 KiB
Rust

//! Integration tests for Chainfire
//!
//! These tests verify that the server, client, and all components work together correctly.
use chainfire_client::Client;
use chainfire_server::{
config::{ClusterConfig, NetworkConfig, NodeConfig, RaftConfig, ServerConfig, StorageConfig},
server::Server,
};
use std::time::Duration;
use tokio::time::sleep;
/// Create a test server configuration
fn test_config(port: u16) -> (ServerConfig, tempfile::TempDir) {
use std::net::SocketAddr;
let api_addr: SocketAddr = format!("127.0.0.1:{}", port).parse().unwrap();
let raft_addr: SocketAddr = format!("127.0.0.1:{}", port + 100).parse().unwrap();
let gossip_addr: SocketAddr = format!("127.0.0.1:{}", port + 200).parse().unwrap();
let temp_dir = tempfile::tempdir().unwrap();
let config = ServerConfig {
node: NodeConfig {
id: 1,
name: format!("test-node-{}", port),
role: "control_plane".to_string(),
},
cluster: ClusterConfig {
id: 1,
bootstrap: true,
initial_members: vec![],
},
network: NetworkConfig {
api_addr,
raft_addr,
gossip_addr,
tls: None,
},
storage: StorageConfig {
data_dir: temp_dir.path().to_path_buf(),
},
raft: RaftConfig::default(),
};
(config, temp_dir)
}
#[tokio::test]
async fn test_single_node_kv_operations() {
// Start server
let (config, _temp_dir) = test_config(23790);
let api_addr = config.network.api_addr;
let server = Server::new(config).await.unwrap();
// Run server in background
let server_handle = tokio::spawn(async move {
let _ = server.run().await;
});
// Wait for server to start
sleep(Duration::from_millis(500)).await;
// Connect client
let mut client = Client::connect(format!("http://{}", api_addr))
.await
.unwrap();
// Test put
let rev = client.put("test/key1", "value1").await.unwrap();
assert!(rev > 0);
// Test get
let value = client.get("test/key1").await.unwrap();
assert_eq!(value, Some(b"value1".to_vec()));
// Test put with different value
let rev2 = client.put("test/key1", "value2").await.unwrap();
assert!(rev2 > rev);
// Test get updated value
let value = client.get("test/key1").await.unwrap();
assert_eq!(value, Some(b"value2".to_vec()));
// Test get non-existent key
let value = client.get("test/nonexistent").await.unwrap();
assert!(value.is_none());
// Test delete
let deleted = client.delete("test/key1").await.unwrap();
assert!(deleted);
// Verify deletion
let value = client.get("test/key1").await.unwrap();
assert!(value.is_none());
// Test delete non-existent key
let deleted = client.delete("test/nonexistent").await.unwrap();
assert!(!deleted);
// Test prefix operations
client.put("prefix/a", "1").await.unwrap();
client.put("prefix/b", "2").await.unwrap();
client.put("prefix/c", "3").await.unwrap();
client.put("other/key", "other").await.unwrap();
let prefix_values = client.get_prefix("prefix/").await.unwrap();
assert_eq!(prefix_values.len(), 3);
// Cleanup
server_handle.abort();
}
#[tokio::test]
async fn test_cluster_status() {
let (config, _temp_dir) = test_config(23800);
let api_addr = config.network.api_addr;
let server = Server::new(config).await.unwrap();
let server_handle = tokio::spawn(async move {
let _ = server.run().await;
});
sleep(Duration::from_millis(500)).await;
let mut client = Client::connect(format!("http://{}", api_addr))
.await
.unwrap();
let status = client.status().await.unwrap();
assert_eq!(status.leader, 1);
assert!(status.raft_term > 0);
server_handle.abort();
}
#[tokio::test]
async fn test_string_convenience_methods() {
let (config, _temp_dir) = test_config(23810);
let api_addr = config.network.api_addr;
let server = Server::new(config).await.unwrap();
let server_handle = tokio::spawn(async move {
let _ = server.run().await;
});
sleep(Duration::from_millis(500)).await;
let mut client = Client::connect(format!("http://{}", api_addr))
.await
.unwrap();
// Test string methods
client.put_str("/config/name", "chainfire").await.unwrap();
let value = client.get_str("/config/name").await.unwrap();
assert_eq!(value, Some("chainfire".to_string()));
server_handle.abort();
}