feat(cluster): implement distributed clustering with etcd coordination
- Integrate etcd-client for distributed coordination and leader election - Add remote client macros with proper formatting for all services - Implement RequestMetrics for tracking RPC performance and errors - Add rate limiting mechanism across all service endpoints - Create ElectionRequest and ElectionResult message types for leader election - Add role management with primary/replica switching capabilities - Implement health checker with automatic failover detection - Add repository count metrics for cluster monitoring - Update Cargo.toml with etcd-client and dashmap dependencies - Modify RepoEntry to include read_only flag for replica handling - Implement should_accept_election logic to prevent duplicate elections - Add RoleChangedEvent handling for cluster role updates
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
//! Tests for hooks system.
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use gitks::hooks::manager::{HookLevel, HookManager};
|
||||
use gitks::hooks::sanitize::{validate_hook_content, validate_hook_name};
|
||||
|
||||
fn temp_repo() -> PathBuf {
|
||||
let dir = tempfile::tempdir().unwrap().path().to_path_buf();
|
||||
// Create a bare git repo
|
||||
let _ = std::process::Command::new("git")
|
||||
.args(["init", "--bare"])
|
||||
.arg(&dir)
|
||||
.output();
|
||||
dir
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_hook_name() {
|
||||
assert!(validate_hook_name("pre-receive").is_ok());
|
||||
assert!(validate_hook_name("update").is_ok());
|
||||
assert!(validate_hook_name("post-receive").is_ok());
|
||||
assert!(validate_hook_name("commit-msg").is_ok());
|
||||
assert!(validate_hook_name("invalid-hook").is_err());
|
||||
assert!(validate_hook_name("").is_err());
|
||||
assert!(validate_hook_name("random-name").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_hook_content_safe() {
|
||||
assert!(validate_hook_content("#!/bin/sh\nexit 0").is_ok());
|
||||
assert!(validate_hook_content("#!/bin/sh\necho 'hello'").is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_hook_content_dangerous() {
|
||||
assert!(validate_hook_content("rm -rf /").is_err());
|
||||
assert!(validate_hook_content("shutdown now").is_err());
|
||||
assert!(validate_hook_content("chmod 777 /etc/passwd").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_hook_content_size() {
|
||||
let large_content = "x".repeat(70000);
|
||||
assert!(validate_hook_content(&large_content).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_hook_content_null_bytes() {
|
||||
assert!(validate_hook_content("test\0content").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hook_manager_install_hooks() {
|
||||
let repo = temp_repo();
|
||||
let prefix = repo.parent().unwrap().to_path_buf();
|
||||
let hm = HookManager::new(prefix, None, None, Duration::from_secs(30), true);
|
||||
|
||||
// Install hooks
|
||||
let result = hm.install_hooks(&repo);
|
||||
if result.is_ok() {
|
||||
// Check that hook files were created
|
||||
assert!(repo.join("hooks/pre-receive").exists());
|
||||
assert!(repo.join("hooks/update").exists());
|
||||
assert!(repo.join("hooks/post-receive").exists());
|
||||
}
|
||||
// Installation may fail if git is not available; just check no panic
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hook_manager_custom_hooks() {
|
||||
let repo = temp_repo();
|
||||
let prefix = repo.parent().unwrap().to_path_buf();
|
||||
let hm = HookManager::new(prefix, None, None, Duration::from_secs(30), true);
|
||||
|
||||
// Set a custom hook
|
||||
let result = hm.set_custom_hook(&repo, "pre-receive", "#!/bin/sh\nexit 0");
|
||||
if result.is_ok() {
|
||||
assert!(repo.join("custom_hooks/pre-receive/d").exists());
|
||||
}
|
||||
|
||||
// Remove custom hook
|
||||
let result = hm.remove_custom_hook(&repo, "pre-receive");
|
||||
assert!(result.is_ok() || result.is_err()); // Just no panic
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hook_manager_disallow_custom() {
|
||||
let repo = temp_repo();
|
||||
let prefix = repo.parent().unwrap().to_path_buf();
|
||||
let hm = HookManager::new(
|
||||
prefix,
|
||||
None,
|
||||
None,
|
||||
Duration::from_secs(30),
|
||||
false, // Disallow custom hooks
|
||||
);
|
||||
|
||||
let result = hm.set_custom_hook(&repo, "pre-receive", "#!/bin/sh\nexit 0");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hook_level_display() {
|
||||
assert_eq!(HookLevel::Server.to_string(), "server");
|
||||
assert_eq!(HookLevel::Custom.to_string(), "custom");
|
||||
}
|
||||
Reference in New Issue
Block a user