@@ -196,10 +196,10 @@ func updateStats(summary *statsSummary, record statsRecord) {
196196}
197197
198198type cicdTestSummary struct {
199- Name string `json:"name"`
200- Unit string `json:"unit"`
201- Value interface {} `json:"value"`
202- Range string `json:"range,omitempty"`
199+ Name string `json:"name"`
200+ Unit string `json:"unit"`
201+ Value any `json:"value"`
202+ Range string `json:"range,omitempty"`
203203}
204204
205205type manifestStruct struct {
@@ -299,15 +299,15 @@ func GetCatalog(
299299
300300 statusRequests = sync.Map {}
301301
302- for count := 0 ; count < requests ; count ++ {
302+ for range requests {
303303 // Push random blob
304304 _ , repos , err = pushMonolithImage (workdir , url , repo , repos , config , client )
305305 if err != nil {
306306 return err
307307 }
308308 }
309309
310- for count := 0 ; count < requests ; count ++ {
310+ for range requests {
311311 func () {
312312 start := time .Now ()
313313
@@ -376,7 +376,7 @@ func PushMonolithStreamed(
376376 statusRequests = sync.Map {}
377377 }
378378
379- for count := 0 ; count < requests ; count ++ {
379+ for count := range requests {
380380 repos = pushMonolithAndCollect (workdir , url , trepo , count ,
381381 repos , config , client , statsCh )
382382 }
@@ -406,7 +406,7 @@ func PushChunkStreamed(
406406 statusRequests = sync.Map {}
407407 }
408408
409- for count := 0 ; count < requests ; count ++ {
409+ for count := range requests {
410410 repos = pushChunkAndCollect (workdir , url , trepo , count ,
411411 repos , config , client , statsCh )
412412 }
@@ -493,7 +493,7 @@ func Pull(
493493 }
494494
495495 // download image
496- for count := 0 ; count < requests ; count ++ {
496+ for range requests {
497497 repos = pullAndCollect (url , repos , manifestItem , config , client , statsCh )
498498 }
499499
@@ -530,7 +530,7 @@ func MixedPullAndPush(
530530 manifestHash : manifestHash ,
531531 }
532532
533- for count := 0 ; count < requests ; count ++ {
533+ for count := range requests {
534534 idx := flipFunc (config .probabilityRange )
535535
536536 readTestIdx := 0
@@ -667,6 +667,16 @@ func Perf(
667667 outFmt string , srcIPs string , srcCIDR string , skipCleanup bool ,
668668) {
669669 json := jsoniter .ConfigCompatibleWithStandardLibrary
670+
671+ // fatalWithCleanup calls teardown then logs fatal, ensuring cleanup happens before exit.
672+ // Uses sync.Once to ensure teardown is only called once, even from goroutines.
673+ var teardownOnce sync.Once
674+ fatalWithCleanup := func (err error ) {
675+ teardownOnce .Do (func () {
676+ teardown (workdir )
677+ })
678+ log .Fatal (err )
679+ }
670680 // logging
671681 log .SetFlags (0 )
672682 log .SetOutput (tabwriter .NewWriter (os .Stdout , 0 , 0 , 1 , ' ' , tabwriter .TabIndent ))
@@ -694,7 +704,6 @@ func Perf(
694704 log .Printf ("Preparing test data ...\n " )
695705
696706 setup (workdir )
697- defer teardown (workdir )
698707
699708 log .Printf ("Starting tests ...\n " )
700709
@@ -709,7 +718,7 @@ func Perf(
709718 } else if len (srcCIDR ) > 0 {
710719 ips , err = getIPsFromCIDR (srcCIDR , maxSourceIPs )
711720 if err != nil {
712- log . Fatal (err ) //nolint: gocritic
721+ fatalWithCleanup (err )
713722 }
714723 }
715724
@@ -722,7 +731,7 @@ func Perf(
722731
723732 start := time .Now ()
724733
725- for c := 0 ; c < concurrency ; c ++ {
734+ for range concurrency {
726735 // parallelize with clients
727736 wg .Add (1 )
728737
@@ -731,12 +740,12 @@ func Perf(
731740
732741 httpClient , err := getRandomClientIPs (auth , url , ips )
733742 if err != nil {
734- log . Fatal (err )
743+ fatalWithCleanup (err )
735744 }
736745
737746 err = tconfig .tfunc (workdir , url , repo , requests / concurrency , tconfig , statsCh , httpClient , skipCleanup )
738747 if err != nil {
739- log . Fatal (err )
748+ fatalWithCleanup (err )
740749 }
741750 }()
742751 }
@@ -754,7 +763,7 @@ func Perf(
754763 summary .mixedType = true
755764 }
756765
757- for count := 0 ; count < requests ; count ++ {
766+ for range requests {
758767 record := <- statsCh
759768 updateStats (& summary , record )
760769 }
@@ -771,14 +780,19 @@ func Perf(
771780 if outFmt == cicdFmt {
772781 jsonOut , err := json .Marshal (cicdSummary )
773782 if err != nil {
774- log . Fatal (err ) // file closed on exit
783+ fatalWithCleanup (err )
775784 }
776785
777786 if err := os .WriteFile (outFmt + ".json" , jsonOut , defaultFilePerms ); err != nil {
778- log . Fatal (err )
787+ fatalWithCleanup (err )
779788 }
780789 }
781790
791+ // Cleanup before exit (sync.Once ensures it only runs once, even if fatalWithCleanup was called)
792+ teardownOnce .Do (func () {
793+ teardown (workdir )
794+ })
795+
782796 if zbError {
783797 os .Exit (1 )
784798 }
0 commit comments