@@ -2029,3 +2029,88 @@ func TestApplyCompositeReady_PreservesExistingComposite(t *testing.T) {
20292029 t .Error ("Composite.Resource was clobbered by ApplyCompositeReady" )
20302030 }
20312031}
2032+
2033+ func TestApplyCompositeReady_DefersOnly (t * testing.T ) {
2034+ cc := NewConditionCollector ()
2035+ c := NewCollector (cc , "test.star" , nil , nil )
2036+
2037+ c .AddGatingDefers ([]GatingDefer {
2038+ {Name : "app" , Reason : `waiting for "db" to have Ready=True` },
2039+ })
2040+
2041+ rsp := & fnv1.RunFunctionResponse {}
2042+ ApplyCompositeReady (rsp , c , cc )
2043+
2044+ if got := rsp .Desired .Composite .Ready ; got != fnv1 .Ready_READY_FALSE {
2045+ t .Errorf ("Composite.Ready = %v, want READY_FALSE" , got )
2046+ }
2047+ conds := cc .Conditions ()
2048+ if len (conds ) != 1 {
2049+ t .Fatalf ("expected 1 condition, got %d" , len (conds ))
2050+ }
2051+ if conds [0 ].Type != CompositeReadyConditionType ||
2052+ conds [0 ].Status != "False" ||
2053+ conds [0 ].Reason != "WaitingForDependencies" {
2054+ t .Errorf ("condition = %+v, want WaitingForDependencies/False" , conds [0 ])
2055+ }
2056+ if ! strings .Contains (conds [0 ].Message , "app" ) ||
2057+ ! strings .Contains (conds [0 ].Message , "Waiting on dependencies" ) {
2058+ t .Errorf ("condition message = %q, want it to mention 'app' under 'Waiting on dependencies'" , conds [0 ].Message )
2059+ }
2060+ }
2061+
2062+ func TestApplyCompositeReady_SkipsAndDefers (t * testing.T ) {
2063+ cc := NewConditionCollector ()
2064+ c := NewCollector (cc , "test.star" , nil , nil )
2065+
2066+ c .recordSkip ("backup" , "feature pending" , true )
2067+ c .AddGatingDefers ([]GatingDefer {
2068+ {Name : "app" , Reason : `waiting for "db" to have Ready=True` },
2069+ })
2070+
2071+ rsp := & fnv1.RunFunctionResponse {}
2072+ ApplyCompositeReady (rsp , c , cc )
2073+
2074+ if got := rsp .Desired .Composite .Ready ; got != fnv1 .Ready_READY_FALSE {
2075+ t .Errorf ("Composite.Ready = %v, want READY_FALSE" , got )
2076+ }
2077+ conds := cc .Conditions ()
2078+ if len (conds ) != 1 {
2079+ t .Fatalf ("expected 1 aggregated condition, got %d" , len (conds ))
2080+ }
2081+ if conds [0 ].Reason != "CompositeNotReady" {
2082+ t .Errorf ("Reason = %q, want CompositeNotReady when both skips and defers are present" , conds [0 ].Reason )
2083+ }
2084+ msg := conds [0 ].Message
2085+ if ! strings .Contains (msg , "Pending resources" ) || ! strings .Contains (msg , "backup" ) {
2086+ t .Errorf ("message = %q, want to include 'Pending resources' and 'backup'" , msg )
2087+ }
2088+ if ! strings .Contains (msg , "Waiting on dependencies" ) || ! strings .Contains (msg , "app" ) {
2089+ t .Errorf ("message = %q, want to include 'Waiting on dependencies' and 'app'" , msg )
2090+ }
2091+ }
2092+
2093+ func TestApplyCompositeReady_OverrideStillWinsOverDefers (t * testing.T ) {
2094+ cc := NewConditionCollector ()
2095+ c := NewCollector (cc , "test.star" , nil , nil )
2096+
2097+ c .AddGatingDefers ([]GatingDefer {{Name : "app" , Reason : "waiting" }})
2098+
2099+ thread := new (starlark.Thread )
2100+ _ , err := starlark .Call (thread , c .SetCompositeReadyBuiltin (), starlark.Tuple {
2101+ starlark .True ,
2102+ }, nil )
2103+ if err != nil {
2104+ t .Fatalf ("set_composite_ready() error: %v" , err )
2105+ }
2106+
2107+ rsp := & fnv1.RunFunctionResponse {}
2108+ ApplyCompositeReady (rsp , c , cc )
2109+
2110+ if got := rsp .Desired .Composite .Ready ; got != fnv1 .Ready_READY_TRUE {
2111+ t .Errorf ("Composite.Ready = %v, want READY_TRUE (override wins over defers)" , got )
2112+ }
2113+ if got := cc .Conditions (); len (got ) != 0 {
2114+ t .Errorf ("expected no conditions (override True with no reason), got %+v" , got )
2115+ }
2116+ }
0 commit comments