@@ -57,7 +57,7 @@ func newSuccessCollector(t *testing.T, id string) *craftermocks.Collector {
5757}
5858
5959func TestRunCollectors (t * testing.T ) {
60- t .Run ("reloads state after collectors when digest changes " , func (t * testing.T ) {
60+ t .Run ("always reloads state after collectors" , func (t * testing.T ) {
6161 sm := craftermocks .NewStateManager (t )
6262 setupReadExpectation (sm , "digest-1" )
6363 sm .On ("Info" , mock .Anything , mock .Anything ).Return ("mock://run-1" )
@@ -77,7 +77,7 @@ func TestRunCollectors(t *testing.T) {
7777
7878 cr .RunCollectors (context .Background (), "run-1" , nil )
7979
80- // Read before + Read after (digest changed, so reload triggered)
80+ // Read before collectors + unconditional Read after collectors
8181 sm .AssertNumberOfCalls (t , "Read" , 2 )
8282 c1 .AssertCalled (t , "Collect" , mock .Anything , mock .Anything , "run-1" , mock .Anything )
8383 })
@@ -102,9 +102,10 @@ func TestRunCollectors(t *testing.T) {
102102
103103 c1 .AssertCalled (t , "Collect" , mock .Anything , mock .Anything , mock .Anything , mock .Anything )
104104 c2 .AssertCalled (t , "Collect" , mock .Anything , mock .Anything , mock .Anything , mock .Anything )
105+ sm .AssertNumberOfCalls (t , "Read" , 2 )
105106 })
106107
107- t .Run ("no collectors skips reload when digest unchanged " , func (t * testing.T ) {
108+ t .Run ("reloads state even with no collectors " , func (t * testing.T ) {
108109 sm := craftermocks .NewStateManager (t )
109110 setupReadExpectation (sm , "d" )
110111 sm .On ("Info" , mock .Anything , mock .Anything ).Return ("mock://run-1" )
@@ -114,8 +115,30 @@ func TestRunCollectors(t *testing.T) {
114115
115116 cr .RunCollectors (context .Background (), "run-1" , nil )
116117
117- // Only the initial Read, no reload since digest didn't change
118- sm .AssertNumberOfCalls (t , "Read" , 1 )
118+ // Read before + unconditional Read after, even with no collectors
119+ sm .AssertNumberOfCalls (t , "Read" , 2 )
120+ })
121+
122+ t .Run ("reloads state when digest is stale (old server)" , func (t * testing.T ) {
123+ sm := craftermocks .NewStateManager (t )
124+ setupReadExpectation (sm , "digest-1" )
125+ sm .On ("Info" , mock .Anything , mock .Anything ).Return ("mock://run-1" )
126+
127+ // Collector persists state via Write but the old server doesn't return
128+ // a new digest, so UpdateCheckSum stays unchanged (stale).
129+ c1 := craftermocks .NewCollector (t )
130+ c1 .On ("ID" ).Maybe ().Return ("c1" )
131+ c1 .On ("Collect" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return (nil )
132+
133+ cr , err := crafter .NewCrafter (sm , nil )
134+ require .NoError (t , err )
135+ cr .RegisterCollectors (c1 )
136+
137+ cr .RunCollectors (context .Background (), "run-1" , nil )
138+
139+ // Unconditional reload ensures the stale digest is refreshed
140+ sm .AssertNumberOfCalls (t , "Read" , 2 )
141+ c1 .AssertCalled (t , "Collect" , mock .Anything , mock .Anything , "run-1" , mock .Anything )
119142 })
120143
121144 t .Run ("state load failure aborts before running collectors" , func (t * testing.T ) {
0 commit comments