Skip to content

Commit 77e6eb4

Browse files
committed
ci: test for coverage
Signed-off-by: imeoer <yansong.ys@antgroup.com>
1 parent a8e0342 commit 77e6eb4

46 files changed

Lines changed: 5238 additions & 100 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/src/config.rs

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,6 +2558,261 @@ mod tests {
25582558
assert_eq!(default_prefetch_threads_count(), 8);
25592559
}
25602560

2561+
#[test]
2562+
fn test_clone_without_secrets() {
2563+
let content = r#"version=2
2564+
[backend]
2565+
type = "oss"
2566+
[backend.oss]
2567+
endpoint = "my_endpoint"
2568+
bucket_name = "my_bucket"
2569+
access_key_id = "my_ak_id"
2570+
access_key_secret = "my_ak_secret"
2571+
[backend.registry]
2572+
host = "localhost"
2573+
repo = "nydus"
2574+
auth = "my_auth_token"
2575+
registry_token = "my_bearer_token"
2576+
"#;
2577+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2578+
let clean = cfg.clone_without_secrets();
2579+
2580+
// Secrets must be erased.
2581+
let backend = clean.backend.as_ref().unwrap();
2582+
let oss = backend.oss.as_ref().unwrap();
2583+
assert!(oss.access_key_id.is_empty());
2584+
assert!(oss.access_key_secret.is_empty());
2585+
// Non-secret field must be preserved.
2586+
assert_eq!(&oss.endpoint, "my_endpoint");
2587+
2588+
let registry = backend.registry.as_ref().unwrap();
2589+
assert!(registry.auth.is_none());
2590+
assert!(registry.registry_token.is_none());
2591+
// Non-secret field must be preserved.
2592+
assert_eq!(&registry.host, "localhost");
2593+
2594+
// Original must be untouched.
2595+
let orig_backend = cfg.backend.as_ref().unwrap();
2596+
assert_eq!(
2597+
&orig_backend.oss.as_ref().unwrap().access_key_id,
2598+
"my_ak_id"
2599+
);
2600+
}
2601+
2602+
#[test]
2603+
fn test_clone_without_secrets_no_backend() {
2604+
let cfg = ConfigV2::new("id1");
2605+
// Should not panic even when backend is None.
2606+
let clean = cfg.clone_without_secrets();
2607+
assert!(clean.backend.is_none());
2608+
}
2609+
2610+
#[test]
2611+
fn test_is_chunk_validation_enabled() {
2612+
// Both absent → false.
2613+
let cfg = ConfigV2::new("id1");
2614+
assert!(!cfg.is_chunk_validation_enabled());
2615+
2616+
// Only cache.validate = true → true.
2617+
let content = r#"version=2
2618+
[cache]
2619+
type = "filecache"
2620+
validate = true
2621+
"#;
2622+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2623+
assert!(cfg.is_chunk_validation_enabled());
2624+
2625+
// Only rafs.validate = true → true.
2626+
let content = r#"version=2
2627+
[rafs]
2628+
validate = true
2629+
"#;
2630+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2631+
assert!(cfg.is_chunk_validation_enabled());
2632+
2633+
// Both false → false.
2634+
let content = r#"version=2
2635+
[cache]
2636+
type = "filecache"
2637+
validate = false
2638+
[rafs]
2639+
validate = false
2640+
"#;
2641+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2642+
assert!(!cfg.is_chunk_validation_enabled());
2643+
}
2644+
2645+
#[test]
2646+
fn test_is_fs_cache() {
2647+
// No cache → false.
2648+
let cfg = ConfigV2::new("id1");
2649+
assert!(!cfg.is_fs_cache());
2650+
2651+
// Cache with fscache sub-config → true.
2652+
let content = r#"version=2
2653+
[cache]
2654+
type = "fscache"
2655+
[cache.fscache]
2656+
work_dir = "/tmp"
2657+
"#;
2658+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2659+
assert!(cfg.is_fs_cache());
2660+
2661+
// Cache with only filecache sub-config → false.
2662+
let content = r#"version=2
2663+
[cache]
2664+
type = "filecache"
2665+
[cache.filecache]
2666+
work_dir = "/tmp"
2667+
"#;
2668+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2669+
assert!(!cfg.is_fs_cache());
2670+
}
2671+
2672+
#[test]
2673+
fn test_get_cache_working_directory_missing_sub_config() {
2674+
// filecache type but no [cache.filecache] section → error.
2675+
let content = r#"version=2
2676+
[cache]
2677+
type = "filecache"
2678+
"#;
2679+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2680+
assert!(cfg.get_cache_working_directory().is_err());
2681+
2682+
// fscache type but no [cache.fscache] section → error.
2683+
let content = r#"version=2
2684+
[cache]
2685+
type = "fscache"
2686+
"#;
2687+
let cfg: ConfigV2 = toml::from_str(content).unwrap();
2688+
assert!(cfg.get_cache_working_directory().is_err());
2689+
}
2690+
2691+
#[test]
2692+
fn test_backend_get_config_success_and_type_mismatch() {
2693+
// localdisk: success path and "wrong accessor" path.
2694+
let cfg = BackendConfigV2 {
2695+
backend_type: "localdisk".to_string(),
2696+
localdisk: Some(LocalDiskConfig {
2697+
device_path: "/dev/sda".to_string(),
2698+
disable_gpt: false,
2699+
}),
2700+
..Default::default()
2701+
};
2702+
assert!(cfg.get_localdisk_config().is_ok());
2703+
// Wrong accessor on localdisk config → wrong-type error.
2704+
assert!(cfg.get_localfs_config().is_err());
2705+
2706+
// localfs: success path.
2707+
let cfg = BackendConfigV2 {
2708+
backend_type: "localfs".to_string(),
2709+
localfs: Some(LocalFsConfig {
2710+
dir: "/tmp".to_string(),
2711+
..Default::default()
2712+
}),
2713+
..Default::default()
2714+
};
2715+
assert!(cfg.get_localfs_config().is_ok());
2716+
assert!(cfg.get_oss_config().is_err());
2717+
2718+
// oss: success path.
2719+
let cfg = BackendConfigV2 {
2720+
backend_type: "oss".to_string(),
2721+
oss: Some(OssConfig {
2722+
endpoint: "ep".to_string(),
2723+
bucket_name: "bkt".to_string(),
2724+
..Default::default()
2725+
}),
2726+
..Default::default()
2727+
};
2728+
assert!(cfg.get_oss_config().is_ok());
2729+
assert!(cfg.get_s3_config().is_err());
2730+
2731+
// s3: success path.
2732+
let cfg = BackendConfigV2 {
2733+
backend_type: "s3".to_string(),
2734+
s3: Some(S3Config {
2735+
region: "us-east-1".to_string(),
2736+
bucket_name: "bkt".to_string(),
2737+
..Default::default()
2738+
}),
2739+
..Default::default()
2740+
};
2741+
assert!(cfg.get_s3_config().is_ok());
2742+
assert!(cfg.get_registry_config().is_err());
2743+
2744+
// registry: success path.
2745+
let cfg = BackendConfigV2 {
2746+
backend_type: "registry".to_string(),
2747+
registry: Some(RegistryConfig {
2748+
host: "localhost".to_string(),
2749+
repo: "nydus".to_string(),
2750+
..Default::default()
2751+
}),
2752+
..Default::default()
2753+
};
2754+
assert!(cfg.get_registry_config().is_ok());
2755+
assert!(cfg.get_http_proxy_config().is_err());
2756+
2757+
// http-proxy: success path.
2758+
let cfg = BackendConfigV2 {
2759+
backend_type: "http-proxy".to_string(),
2760+
http_proxy: Some(HttpProxyConfig {
2761+
addr: "http://localhost:8080".to_string(),
2762+
..Default::default()
2763+
}),
2764+
..Default::default()
2765+
};
2766+
assert!(cfg.get_http_proxy_config().is_ok());
2767+
assert!(cfg.get_localdisk_config().is_err());
2768+
}
2769+
2770+
#[test]
2771+
fn test_backend_get_config_correct_type_missing_sub_config() {
2772+
// Correct type, but sub-config struct is None → InvalidData error.
2773+
let cfg = BackendConfigV2 {
2774+
backend_type: "localdisk".to_string(),
2775+
..Default::default()
2776+
};
2777+
let err = cfg.get_localdisk_config().unwrap_err();
2778+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2779+
2780+
let cfg = BackendConfigV2 {
2781+
backend_type: "localfs".to_string(),
2782+
..Default::default()
2783+
};
2784+
let err = cfg.get_localfs_config().unwrap_err();
2785+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2786+
2787+
let cfg = BackendConfigV2 {
2788+
backend_type: "oss".to_string(),
2789+
..Default::default()
2790+
};
2791+
let err = cfg.get_oss_config().unwrap_err();
2792+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2793+
2794+
let cfg = BackendConfigV2 {
2795+
backend_type: "s3".to_string(),
2796+
..Default::default()
2797+
};
2798+
let err = cfg.get_s3_config().unwrap_err();
2799+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2800+
2801+
let cfg = BackendConfigV2 {
2802+
backend_type: "registry".to_string(),
2803+
..Default::default()
2804+
};
2805+
let err = cfg.get_registry_config().unwrap_err();
2806+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2807+
2808+
let cfg = BackendConfigV2 {
2809+
backend_type: "http-proxy".to_string(),
2810+
..Default::default()
2811+
};
2812+
let err = cfg.get_http_proxy_config().unwrap_err();
2813+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
2814+
}
2815+
25612816
#[test]
25622817
fn test_backend_config_try_from() {
25632818
let config = BackendConfig {

api/src/http_handler.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,4 +405,75 @@ mod tests {
405405
assert!(msg.is_none());
406406
let _ = thread.join().unwrap();
407407
}
408+
409+
#[test]
410+
fn test_translate_status_code() {
411+
use crate::{ApiError, DaemonErrorKind, MetricsError, MetricsErrorKind};
412+
413+
assert_eq!(
414+
translate_status_code(&ApiError::DaemonAbnormal(DaemonErrorKind::NotReady)),
415+
StatusCode::ServiceUnavailable
416+
);
417+
assert_eq!(
418+
translate_status_code(&ApiError::DaemonAbnormal(DaemonErrorKind::Unsupported)),
419+
StatusCode::NotImplemented
420+
);
421+
assert_eq!(
422+
translate_status_code(&ApiError::DaemonAbnormal(DaemonErrorKind::UnexpectedEvent(
423+
"ev".into()
424+
))),
425+
StatusCode::BadRequest
426+
);
427+
// Other DaemonErrorKind → InternalServerError
428+
assert_eq!(
429+
translate_status_code(&ApiError::DaemonAbnormal(DaemonErrorKind::Other(
430+
"x".into()
431+
))),
432+
StatusCode::InternalServerError
433+
);
434+
// Metrics NoCounter → NotFound
435+
assert_eq!(
436+
translate_status_code(&ApiError::Metrics(MetricsErrorKind::Stats(
437+
MetricsError::NoCounter
438+
))),
439+
StatusCode::NotFound
440+
);
441+
// Catch-all → InternalServerError
442+
assert_eq!(
443+
translate_status_code(&ApiError::ResponsePayloadType),
444+
StatusCode::InternalServerError
445+
);
446+
// MountFilesystem variant
447+
assert_eq!(
448+
translate_status_code(&ApiError::MountFilesystem(DaemonErrorKind::Unsupported)),
449+
StatusCode::NotImplemented
450+
);
451+
}
452+
453+
#[test]
454+
fn test_success_response() {
455+
let resp_with_body = success_response(Some("hello".into()));
456+
assert_eq!(resp_with_body.status(), StatusCode::OK);
457+
458+
let resp_no_body = success_response(None);
459+
assert_eq!(resp_no_body.status(), StatusCode::NoContent);
460+
}
461+
462+
#[test]
463+
fn test_error_response() {
464+
let resp = error_response(HttpError::NoRoute, StatusCode::NotFound);
465+
assert_eq!(resp.status(), StatusCode::NotFound);
466+
}
467+
468+
#[test]
469+
fn test_parse_body() {
470+
let body = Body::new(r#"{"key":"value"}"#.to_string());
471+
let result: std::result::Result<serde_json::Value, HttpError> = parse_body(&body);
472+
assert!(result.is_ok());
473+
474+
let bad_body = Body::new("not json".to_string());
475+
let result: std::result::Result<serde_json::Value, HttpError> = parse_body(&bad_body);
476+
assert!(result.is_err());
477+
assert!(matches!(result.unwrap_err(), HttpError::ParseBody(_)));
478+
}
408479
}

0 commit comments

Comments
 (0)