feat: Phase 2 feature modules + comprehensive test suite (142 tests)
services.rs: - Pod status with unicode icons, grouped by namespace - VSO sync status (VaultStaticSecret/VaultDynamicSecret via kube-rs DynamicObject) - Log streaming via kube-rs log_stream + futures::AsyncBufReadExt - Pod get in YAML/JSON format - Rollout restart with namespace/service filtering checks.rs: - 11 health check functions (gitea, postgres, valkey, openbao, seaweedfs, kratos, hydra, people, livekit) - AWS4-HMAC-SHA256 S3 auth header generation using sha2 + hmac - Concurrent execution via tokio JoinSet - mkcert root CA trust for local TLS secrets.rs: - Stub with cmd_seed/cmd_verify (requires live cluster for full impl) users.rs: - All 10 Kratos identity operations via reqwest + kubectl port-forward - Welcome email via lettre SMTP through port-forwarded postfix - Employee onboarding with auto-assigned ID, HR metadata - Offboarding with Kratos + Hydra session revocation gitea.rs: - Bootstrap without Lima VM: admin password, org creation, OIDC auth source - Gitea API via kubectl exec curl images.rs: - BuildEnv detection, buildctl build + push via port-forward - Per-service builders for all 17 build targets - Deploy rollout, node image pull, uv Dockerfile patching - Mirror scaffolding (containerd operations marked TODO) cluster.rs: - Pure K8s cmd_up: cert-manager, linkerd, rcgen TLS certs, core service wait - No Lima VM operations manifests.rs: - Full cmd_apply: kustomize build, two-pass convergence, ConfigMap restart detection - Pre-apply cleanup, webhook wait, mkcert CA, tuwunel OAuth2 redirect patch Test coverage: 142 tests across 14 modules (44 in checks, 27 in cli, 13 in images, 12 in tools, 12 in services, 11 in users, 10 in manifests, 9 in kube, 9 in cluster, 7 in update, 6 in gitea, 4 in openbao, 3 in output, 2 in config).
This commit is contained in:
129
src/tools.rs
129
src/tools.rs
@@ -49,3 +49,132 @@ pub fn ensure_kustomize() -> Result<PathBuf> {
|
||||
pub fn ensure_helm() -> Result<PathBuf> {
|
||||
extract_embedded(HELM_BIN, "helm")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn kustomize_bin_is_non_empty() {
|
||||
assert!(
|
||||
KUSTOMIZE_BIN.len() > 0,
|
||||
"Embedded kustomize binary should not be empty"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn helm_bin_is_non_empty() {
|
||||
assert!(
|
||||
HELM_BIN.len() > 0,
|
||||
"Embedded helm binary should not be empty"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kustomize_bin_has_reasonable_size() {
|
||||
// kustomize binary should be at least 1 MB
|
||||
assert!(
|
||||
KUSTOMIZE_BIN.len() > 1_000_000,
|
||||
"Embedded kustomize binary seems too small: {} bytes",
|
||||
KUSTOMIZE_BIN.len()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn helm_bin_has_reasonable_size() {
|
||||
// helm binary should be at least 1 MB
|
||||
assert!(
|
||||
HELM_BIN.len() > 1_000_000,
|
||||
"Embedded helm binary seems too small: {} bytes",
|
||||
HELM_BIN.len()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cache_dir_ends_with_sunbeam_bin() {
|
||||
let dir = cache_dir();
|
||||
assert!(
|
||||
dir.ends_with("sunbeam/bin"),
|
||||
"cache_dir() should end with sunbeam/bin, got: {}",
|
||||
dir.display()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cache_dir_is_absolute() {
|
||||
let dir = cache_dir();
|
||||
assert!(
|
||||
dir.is_absolute(),
|
||||
"cache_dir() should return an absolute path, got: {}",
|
||||
dir.display()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_kustomize_returns_valid_path() {
|
||||
let path = ensure_kustomize().expect("ensure_kustomize should succeed");
|
||||
assert!(
|
||||
path.ends_with("kustomize"),
|
||||
"ensure_kustomize path should end with 'kustomize', got: {}",
|
||||
path.display()
|
||||
);
|
||||
assert!(path.exists(), "kustomize binary should exist at: {}", path.display());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_helm_returns_valid_path() {
|
||||
let path = ensure_helm().expect("ensure_helm should succeed");
|
||||
assert!(
|
||||
path.ends_with("helm"),
|
||||
"ensure_helm path should end with 'helm', got: {}",
|
||||
path.display()
|
||||
);
|
||||
assert!(path.exists(), "helm binary should exist at: {}", path.display());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_kustomize_is_idempotent() {
|
||||
let path1 = ensure_kustomize().expect("first call should succeed");
|
||||
let path2 = ensure_kustomize().expect("second call should succeed");
|
||||
assert_eq!(path1, path2, "ensure_kustomize should return the same path on repeated calls");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_helm_is_idempotent() {
|
||||
let path1 = ensure_helm().expect("first call should succeed");
|
||||
let path2 = ensure_helm().expect("second call should succeed");
|
||||
assert_eq!(path1, path2, "ensure_helm should return the same path on repeated calls");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extracted_kustomize_is_executable() {
|
||||
let path = ensure_kustomize().expect("ensure_kustomize should succeed");
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let perms = std::fs::metadata(&path)
|
||||
.expect("should read metadata")
|
||||
.permissions();
|
||||
assert!(
|
||||
perms.mode() & 0o111 != 0,
|
||||
"kustomize binary should be executable"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extracted_helm_is_executable() {
|
||||
let path = ensure_helm().expect("ensure_helm should succeed");
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let perms = std::fs::metadata(&path)
|
||||
.expect("should read metadata")
|
||||
.permissions();
|
||||
assert!(
|
||||
perms.mode() & 0o111 != 0,
|
||||
"helm binary should be executable"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user