1414package store
1515
1616import (
17+ "errors"
1718 "os"
1819 "sync"
20+ "sync/atomic"
1921 "testing"
2022
2123 "github.com/uber/kraken/core"
@@ -31,13 +33,21 @@ func TestCADownloadStoreDownloadAndDeleteFiles(t *testing.T) {
3133
3234 var names []string
3335 var wg sync.WaitGroup
34- for i := 0 ; i < 100 ; i ++ {
35- name := core .DigestFixture ().Hex ()
36+ for range 100 {
37+ blob := core .NewBlobFixture ()
38+ name := blob .Digest .Hex ()
3639 names = append (names , name )
3740 wg .Add (1 )
3841 go func () {
3942 defer wg .Done ()
40- require .NoError (s .CreateDownloadFile (name , 1 ))
43+
44+ require .NoError (s .CreateDownloadFile (name , blob .Length ()))
45+ w , err := s .GetDownloadFileReadWriter (name )
46+ require .NoError (err )
47+ _ , err = w .Write (blob .Content )
48+ require .NoError (err )
49+ require .NoError (w .Close ())
50+
4151 require .NoError (s .MoveDownloadFileToCache (name ))
4252 require .NoError (s .Cache ().DeleteFile (name ))
4353 }()
@@ -49,3 +59,125 @@ func TestCADownloadStoreDownloadAndDeleteFiles(t *testing.T) {
4959 require .True (os .IsNotExist (err ))
5060 }
5161}
62+
63+ func TestCADownloadStoreMoveDownloadFileToCacheConcurrent (t * testing.T ) {
64+ require := require .New (t )
65+
66+ s , cleanup := CADownloadStoreFixture ()
67+ defer cleanup ()
68+
69+ blob := core .NewBlobFixture ()
70+ name := blob .Digest .Hex ()
71+
72+ require .NoError (s .CreateDownloadFile (name , blob .Length ()))
73+ w , err := s .GetDownloadFileReadWriter (name )
74+ require .NoError (err )
75+ _ , err = w .Write (blob .Content )
76+ require .NoError (err )
77+ require .NoError (w .Close ())
78+
79+ var success atomic.Int32
80+ var exists atomic.Int32
81+ var errMu sync.Mutex
82+ var errs error
83+ var wg sync.WaitGroup
84+ for range 10 {
85+ wg .Add (1 )
86+ go func () {
87+ defer wg .Done ()
88+
89+ err := s .MoveDownloadFileToCache (name )
90+ switch err {
91+ case nil :
92+ success .Add (1 )
93+ case os .ErrExist :
94+ exists .Add (1 )
95+ default :
96+ errMu .Lock ()
97+ errs = errors .Join (errs , err )
98+ errMu .Unlock ()
99+ }
100+ }()
101+ }
102+ wg .Wait ()
103+
104+ require .NoError (errs )
105+ require .Equal (int32 (1 ), success .Load ())
106+ require .Equal (int32 (9 ), exists .Load ())
107+ }
108+
109+ func TestCADownloadStoreMoveDownloadFileToCacheNonMatchingDigest (t * testing.T ) {
110+ require := require .New (t )
111+
112+ s , cleanup := CADownloadStoreFixture ()
113+ defer cleanup ()
114+
115+ blob := core .NewBlobFixture ()
116+ name := blob .Digest .Hex ()
117+
118+ require .NoError (s .CreateDownloadFile (name , blob .Length ()))
119+ w , err := s .GetDownloadFileReadWriter (name )
120+ require .NoError (err )
121+ corrupted := make ([]byte , len (blob .Content ))
122+ copy (corrupted , blob .Content )
123+ corrupted [0 ]++
124+ _ , err = w .Write (corrupted )
125+ require .NoError (err )
126+ require .NoError (w .Close ())
127+
128+ err = s .MoveDownloadFileToCache (name )
129+ require .ErrorContains (err , "verify digest: computed digest" )
130+
131+ _ , err = s .Download ().GetFileStat (name )
132+ require .NoError (err )
133+ _ , err = s .Cache ().GetFileStat (name )
134+ require .True (s .InDownloadError (err ))
135+ }
136+
137+ func TestCADownloadStoreMoveDownloadFileToCacheSkipVerification (t * testing.T ) {
138+ require := require .New (t )
139+
140+ s , cleanup := CADownloadStoreFixture ()
141+ s .config .SkipHashVerification = true
142+ defer cleanup ()
143+
144+ blob := core .NewBlobFixture ()
145+ name := blob .Digest .Hex ()
146+
147+ require .NoError (s .CreateDownloadFile (name , blob .Length ()))
148+ w , err := s .GetDownloadFileReadWriter (name )
149+ require .NoError (err )
150+ emptyBlob := make ([]byte , len (blob .Content ))
151+ _ , err = w .Write (emptyBlob )
152+ require .NoError (err )
153+ require .NoError (w .Close ())
154+
155+ err = s .MoveDownloadFileToCache (name )
156+ require .NoError (err )
157+
158+ _ , err = s .Cache ().GetFileStat (name )
159+ require .NoError (err )
160+ }
161+
162+ func TestCADownloadStoreMoveDownloadFileToCacheAlreadyInCache (t * testing.T ) {
163+ require := require .New (t )
164+
165+ s , cleanup := CADownloadStoreFixture ()
166+ defer cleanup ()
167+
168+ blob := core .NewBlobFixture ()
169+ name := blob .Digest .Hex ()
170+
171+ require .NoError (s .CreateDownloadFile (name , blob .Length ()))
172+ w , err := s .GetDownloadFileReadWriter (name )
173+ require .NoError (err )
174+ _ , err = w .Write (blob .Content )
175+ require .NoError (err )
176+ require .NoError (w .Close ())
177+
178+ err = s .MoveDownloadFileToCache (name )
179+ require .NoError (err )
180+
181+ err = s .MoveDownloadFileToCache (name )
182+ require .True (os .IsExist (err ))
183+ }
0 commit comments