@@ -2434,3 +2434,349 @@ func TestGetStaticNodeCounts(t *testing.T) {
24342434 })
24352435 }
24362436}
2437+
2438+ func TestGetDynamicNodeCounts (t * testing.T ) {
2439+ tests := []struct {
2440+ name string
2441+ bp config.Blueprint
2442+ kind string
2443+ want string
2444+ }{
2445+ {
2446+ name : "Extracts global dynamic max nodes natively without applying zonal multiplication on GKE" ,
2447+ kind : "max" ,
2448+ bp : config.Blueprint {
2449+ Groups : []config.Group {
2450+ {
2451+ Modules : []config.Module {
2452+ {
2453+ Source : "modules/compute/gke-node-pool" ,
2454+ Settings : config .NewDict (map [string ]cty.Value {
2455+ "machine_type" : cty .StringVal ("e2-standard-4" ),
2456+ "autoscaling_total_max_nodes" : cty .NumberIntVal (15 ),
2457+ "zones" : cty .TupleVal ([]cty.Value {cty .StringVal ("z1" ), cty .StringVal ("z2" )}),
2458+ }),
2459+ },
2460+ },
2461+ },
2462+ },
2463+ },
2464+ want : "e2-standard-4:15" ,
2465+ },
2466+ {
2467+ name : "Skips dynamic max nodes for GKE if static_node_count is set" ,
2468+ kind : "max" ,
2469+ bp : config.Blueprint {
2470+ Groups : []config.Group {
2471+ {
2472+ Modules : []config.Module {
2473+ {
2474+ Source : "modules/compute/gke-node-pool" ,
2475+ Settings : config .NewDict (map [string ]cty.Value {
2476+ "machine_type" : cty .StringVal ("e2-standard-4" ),
2477+ "static_node_count" : cty .NumberIntVal (5 ),
2478+ "autoscaling_total_max_nodes" : cty .NumberIntVal (15 ),
2479+ }),
2480+ },
2481+ },
2482+ },
2483+ },
2484+ },
2485+ want : "" ,
2486+ },
2487+ {
2488+ name : "Extracts global dynamic min nodes natively without applying zonal multiplication on GKE" ,
2489+ kind : "min" ,
2490+ bp : config.Blueprint {
2491+ Groups : []config.Group {
2492+ {
2493+ Modules : []config.Module {
2494+ {
2495+ Source : "modules/compute/gke-node-pool" ,
2496+ Settings : config .NewDict (map [string ]cty.Value {
2497+ "machine_type" : cty .StringVal ("e2-standard-4" ),
2498+ "autoscaling_total_min_nodes" : cty .NumberIntVal (2 ),
2499+ "zones" : cty .TupleVal ([]cty.Value {cty .StringVal ("z1" ), cty .StringVal ("z2" )}),
2500+ }),
2501+ },
2502+ },
2503+ },
2504+ },
2505+ },
2506+ want : "e2-standard-4:2" ,
2507+ },
2508+ {
2509+ name : "Extracts dynamic max nodes for Slurm partition" ,
2510+ kind : "max" ,
2511+ bp : config.Blueprint {
2512+ Groups : []config.Group {
2513+ {
2514+ Modules : []config.Module {
2515+ {
2516+ Source : "community/modules/compute/schedmd-slurm-gcp-v6-partition" ,
2517+ Settings : config .NewDict (map [string ]cty.Value {
2518+ "machine_type" : cty .StringVal ("c2-standard-30" ),
2519+ "node_count_dynamic_max" : cty .NumberIntVal (100 ),
2520+ }),
2521+ },
2522+ },
2523+ },
2524+ },
2525+ },
2526+ want : "c2-standard-30:100" ,
2527+ },
2528+ {
2529+ name : "Skips dynamic extraction for GKE if static_node_count is explicitly set to 0" ,
2530+ kind : "max" ,
2531+ bp : config.Blueprint {
2532+ Groups : []config.Group {
2533+ {
2534+ Modules : []config.Module {
2535+ {
2536+ Source : "modules/compute/gke-node-pool" ,
2537+ Settings : config .NewDict (map [string ]cty.Value {
2538+ "machine_type" : cty .StringVal ("e2-standard-4" ),
2539+ "static_node_count" : cty .NumberIntVal (0 ),
2540+ }),
2541+ },
2542+ },
2543+ },
2544+ },
2545+ },
2546+ want : "" ,
2547+ },
2548+ {
2549+ name : "Aggregates dynamic min nodes across multiple GKE modules for the same machine type" ,
2550+ kind : "min" ,
2551+ bp : config.Blueprint {
2552+ Groups : []config.Group {
2553+ {
2554+ Modules : []config.Module {
2555+ {
2556+ Source : "modules/compute/gke-node-pool" ,
2557+ Settings : config .NewDict (map [string ]cty.Value {
2558+ "machine_type" : cty .StringVal ("n1-standard-8" ),
2559+ "autoscaling_total_min_nodes" : cty .NumberIntVal (5 ),
2560+ }),
2561+ },
2562+ {
2563+ Source : "modules/compute/gke-node-pool" ,
2564+ Settings : config .NewDict (map [string ]cty.Value {
2565+ "machine_type" : cty .StringVal ("n1-standard-8" ),
2566+ "autoscaling_total_min_nodes" : cty .NumberIntVal (10 ),
2567+ }),
2568+ },
2569+ },
2570+ },
2571+ },
2572+ },
2573+ want : "n1-standard-8:15" ,
2574+ },
2575+ {
2576+ name : "Extracts dynamic max nodes from inline partition configuration in Slurm" ,
2577+ kind : "max" ,
2578+ bp : config.Blueprint {
2579+ Groups : []config.Group {
2580+ {
2581+ Modules : []config.Module {
2582+ {
2583+ Source : "community/modules/scheduler/schedmd-slurm-gcp-v6-controller" ,
2584+ Settings : config .NewDict (map [string ]cty.Value {
2585+ "machine_type" : cty .StringVal ("e2-standard-2" ),
2586+ "partition" : cty .TupleVal ([]cty.Value {
2587+ cty .ObjectVal (map [string ]cty.Value {
2588+ "machine_type" : cty .StringVal ("c2d-standard-112" ),
2589+ "node_count_dynamic_max" : cty .NumberIntVal (200 ),
2590+ }),
2591+ cty .ObjectVal (map [string ]cty.Value {
2592+ "node_count_dynamic_max" : cty .NumberIntVal (50 ),
2593+ }),
2594+ }),
2595+ }),
2596+ },
2597+ },
2598+ },
2599+ },
2600+ },
2601+ want : "c2d-standard-112:200,e2-standard-2:50" ,
2602+ },
2603+ {
2604+ name : "Extracts max_size for dynamic bounded modules like HTCondor" ,
2605+ kind : "max" ,
2606+ bp : config.Blueprint {
2607+ Groups : []config.Group {
2608+ {
2609+ Modules : []config.Module {
2610+ {
2611+ Source : "modules/compute/htcondor-execute-point" ,
2612+ Settings : config .NewDict (map [string ]cty.Value {
2613+ "machine_type" : cty .StringVal ("n2-standard-4" ),
2614+ "max_size" : cty .NumberIntVal (50 ),
2615+ }),
2616+ },
2617+ },
2618+ },
2619+ },
2620+ },
2621+ want : "n2-standard-4:50" ,
2622+ },
2623+ {
2624+ name : "Skips dynamic max nodes for VM instance since there are none" ,
2625+ kind : "max" ,
2626+ bp : config.Blueprint {
2627+ Groups : []config.Group {
2628+ {
2629+ Modules : []config.Module {
2630+ {
2631+ Source : "modules/compute/vm-instance" ,
2632+ Settings : config .NewDict (map [string ]cty.Value {
2633+ "machine_type" : cty .StringVal ("n1-standard-1" ),
2634+ "instance_count" : cty .NumberIntVal (10 ),
2635+ }),
2636+ },
2637+ },
2638+ },
2639+ },
2640+ },
2641+ want : "" ,
2642+ },
2643+ {
2644+ name : "Extracts dot notation nested keys like system_node_pool_node_count.total_max_nodes" ,
2645+ kind : "max" ,
2646+ bp : config.Blueprint {
2647+ Groups : []config.Group {
2648+ {
2649+ Modules : []config.Module {
2650+ {
2651+ Source : "modules/compute/gke-cluster" ,
2652+ Settings : config .NewDict (map [string ]cty.Value {
2653+ "machine_type" : cty .StringVal ("c3-standard-4" ),
2654+ "system_node_pool_node_count" : cty .ObjectVal (map [string ]cty.Value {
2655+ "total_min_nodes" : cty .NumberIntVal (2 ),
2656+ "total_max_nodes" : cty .NumberIntVal (10 ),
2657+ }),
2658+ }),
2659+ },
2660+ },
2661+ },
2662+ },
2663+ },
2664+ want : "c3-standard-4:10" ,
2665+ },
2666+ {
2667+ name : "Zonal multiplier multiplies dynamic zonal bounds by number of elements in zones list" ,
2668+ kind : "max" ,
2669+ bp : config.Blueprint {
2670+ Groups : []config.Group {
2671+ {
2672+ Modules : []config.Module {
2673+ {
2674+ Source : "modules/compute/gke-node-pool" ,
2675+ Settings : config .NewDict (map [string ]cty.Value {
2676+ "machine_type" : cty .StringVal ("n2d-standard-32" ),
2677+ "autoscaling_max_node_count" : cty .NumberIntVal (5 ),
2678+ "zones" : cty .TupleVal ([]cty.Value {cty .StringVal ("z1" ), cty .StringVal ("z2" )}),
2679+ }),
2680+ },
2681+ },
2682+ },
2683+ },
2684+ },
2685+ want : "n2d-standard-32:10" , // 5 bound max * 2 zones
2686+ },
2687+ {
2688+ name : "Skips zonal multiplier for global default auto-scaling limits" ,
2689+ kind : "max" ,
2690+ bp : config.Blueprint {
2691+ Groups : []config.Group {
2692+ {
2693+ Modules : []config.Module {
2694+ {
2695+ Source : "../../modules/compute/gke-node-pool" ,
2696+ Settings : config .NewDict (map [string ]cty.Value {
2697+ "machine_type" : cty .StringVal ("e2-standard-4" ),
2698+ "zones" : cty .TupleVal ([]cty.Value {cty .StringVal ("z1" ), cty .StringVal ("z2" )}),
2699+ }),
2700+ },
2701+ },
2702+ },
2703+ },
2704+ },
2705+ want : "e2-standard-4:1000" ,
2706+ },
2707+
2708+ {
2709+ name : "Skips tracking missing machine types completely when collecting properties organically" ,
2710+ kind : "max" ,
2711+ bp : config.Blueprint {
2712+ Groups : []config.Group {
2713+ {
2714+ Modules : []config.Module {
2715+ {
2716+ Source : "modules/compute/gke-node-pool" ,
2717+ Settings : config .NewDict (map [string ]cty.Value {
2718+ "node_count_dynamic_max" : cty .NumberIntVal (5 ),
2719+ }),
2720+ },
2721+ },
2722+ },
2723+ },
2724+ },
2725+ want : "" ,
2726+ },
2727+ {
2728+ name : "Blueprint variable evaluation correctly proxies node count limits as safely omitted unknown integers" ,
2729+ kind : "min" ,
2730+ bp : config.Blueprint {
2731+ Vars : config .NewDict (map [string ]cty.Value {
2732+ "min_cluster_nodes" : cty .NumberIntVal (7 ),
2733+ }),
2734+ Groups : []config.Group {
2735+ {
2736+ Modules : []config.Module {
2737+ {
2738+ Source : "modules/compute/gke-node-pool" ,
2739+ Settings : config .NewDict (map [string ]cty.Value {
2740+ "machine_type" : cty .StringVal ("a2-highgpu-1g" ),
2741+ "autoscaling_total_min_nodes" : cty .StringVal ("$(vars.min_cluster_nodes)" ),
2742+ }),
2743+ },
2744+ },
2745+ },
2746+ },
2747+ },
2748+ want : "" ,
2749+ },
2750+ {
2751+ name : "Prioritizes first configured bounds correctly when conflicting definitions coexist" ,
2752+ kind : "max" ,
2753+ bp : config.Blueprint {
2754+ Groups : []config.Group {
2755+ {
2756+ Modules : []config.Module {
2757+ {
2758+ Source : "modules/compute/gke-node-pool" ,
2759+ Settings : config .NewDict (map [string ]cty.Value {
2760+ "machine_type" : cty .StringVal ("n2d-standard-8" ),
2761+ "autoscaling_total_max_nodes" : cty .NumberIntVal (100 ),
2762+ "autoscaling_max_node_count" : cty .NumberIntVal (5 ),
2763+ "zones" : cty .TupleVal ([]cty.Value {cty .StringVal ("z1" ), cty .StringVal ("z2" )}),
2764+ }),
2765+ },
2766+ },
2767+ },
2768+ },
2769+ },
2770+ want : "n2d-standard-8:10" ,
2771+ },
2772+ }
2773+
2774+ for _ , tc := range tests {
2775+ t .Run (tc .name , func (t * testing.T ) {
2776+ got := getDynamicNodeCounts (tc .bp , tc .kind )
2777+ if got != tc .want {
2778+ t .Errorf ("getDynamicNodeCounts() = %q; want %q" , got , tc .want )
2779+ }
2780+ })
2781+ }
2782+ }
0 commit comments