@@ -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 {
0 commit comments