@@ -10,9 +10,11 @@ import (
10
10
"encoding/hex"
11
11
"fmt"
12
12
"io"
13
+ "io/fs"
13
14
"net/http"
14
15
"os"
15
16
"path/filepath"
17
+ "runtime"
16
18
"testing"
17
19
18
20
"github.com/stretchr/testify/assert"
@@ -192,6 +194,117 @@ func TestVerifySHA512HashWithCleanup_failure(t *testing.T) {
192
194
}
193
195
}
194
196
197
+ func TestVerifySHA512HashWithCleanup_BrokenHashFile (t * testing.T ) {
198
+
199
+ const data = "" +
200
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
201
+ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " +
202
+ "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
203
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
204
+ // if you change data, the constant below should be updated
205
+ const correct_data_hash = "8ba760cac29cb2b2ce66858ead169174057aa1298ccd581514e6db6dee3285280ee6e3a54c9319071dc8165ff061d77783100d449c937ff1fb4cd1bb516a69b9"
206
+
207
+ const filename = "lorem_ipsum.txt"
208
+ const hashFileName = filename + ".sha512"
209
+
210
+ type skipFunc func (t * testing.T )
211
+
212
+ type testcase struct {
213
+ name string
214
+ skip skipFunc
215
+ hash []byte
216
+ hashPermissions fs.FileMode
217
+ wantErr assert.ErrorAssertionFunc
218
+ wantLogSnippets []string
219
+ }
220
+
221
+ testcases := []testcase {
222
+ {
223
+ name : "happy path - correct hash and format" ,
224
+ hash : []byte (correct_data_hash + " " + filename ),
225
+ hashPermissions : 0o640 ,
226
+ wantErr : assert .NoError ,
227
+ },
228
+ {
229
+ name : "happy path - broken lines before correct hash and format" ,
230
+ hash : []byte ("this_is just_filler\n " + "some_more_filler\n " + correct_data_hash + " " + filename ),
231
+ hashPermissions : 0o640 ,
232
+ wantErr : assert .NoError ,
233
+ },
234
+ {
235
+ name : "truncated hash line - no filename" ,
236
+ hash : []byte (correct_data_hash ),
237
+ hashPermissions : 0o640 ,
238
+ wantErr : assert .Error ,
239
+ wantLogSnippets : []string {`contents: "` + correct_data_hash + `"` },
240
+ },
241
+ {
242
+ name : "truncated hash" ,
243
+ hash : []byte (correct_data_hash [:8 ] + " " + filename ),
244
+ hashPermissions : 0o640 ,
245
+ wantErr : func (t assert.TestingT , err error , i ... interface {}) bool {
246
+ target := new (ChecksumMismatchError )
247
+ return assert .ErrorAs (t , err , & target , "mismatched hash has a specific error type" , i )
248
+ },
249
+ },
250
+ {
251
+ name : "empty hash file" ,
252
+ hash : []byte {},
253
+ hashPermissions : 0o640 ,
254
+ wantErr : assert .Error ,
255
+ wantLogSnippets : []string {`contents: ""` },
256
+ },
257
+ {
258
+ name : "non-existing hash file" ,
259
+ hash : nil ,
260
+ wantErr : func (t assert.TestingT , err error , i ... interface {}) bool {
261
+ return assert .ErrorIs (t , err , fs .ErrNotExist , i )
262
+ },
263
+ },
264
+ {
265
+ name : "unreadable hash file" ,
266
+ skip : func (t * testing.T ) {
267
+ if runtime .GOOS == "windows" {
268
+ t .Skip ("write-only permissions cannot be set on windows" )
269
+ }
270
+ },
271
+ hash : []byte (correct_data_hash + " " + filename ),
272
+ hashPermissions : 0o222 ,
273
+ wantErr : func (t assert.TestingT , err error , i ... interface {}) bool {
274
+ return assert .ErrorIs (t , err , fs .ErrPermission , i )
275
+ },
276
+ wantLogSnippets : []string {hashFileName + `", unable do read contents for logging:` },
277
+ },
278
+ }
279
+
280
+ for _ , tt := range testcases {
281
+ t .Run (tt .name , func (t * testing.T ) {
282
+ if tt .skip != nil {
283
+ tt .skip (t )
284
+ }
285
+
286
+ dir := t .TempDir ()
287
+ dataFilePath := filepath .Join (dir , filename )
288
+ err := os .WriteFile (dataFilePath , []byte (data ), 0o750 )
289
+ require .NoError (t , err , "could not write sample data file" )
290
+
291
+ if tt .hash != nil {
292
+ hashFilePath := filepath .Join (dir , hashFileName )
293
+ err = os .WriteFile (hashFilePath , tt .hash , tt .hashPermissions )
294
+ require .NoError (t , err , "could not write test hash file" )
295
+ }
296
+
297
+ testLogger , obsLogs := logger .NewTesting (tt .name )
298
+ err = VerifySHA512HashWithCleanup (testLogger , dataFilePath )
299
+ tt .wantErr (t , err )
300
+ for _ , log := range tt .wantLogSnippets {
301
+ filteredLogs := obsLogs .FilterMessageSnippet (log )
302
+ assert .NotEmptyf (t , filteredLogs , "there should be logs matching snippet %q" , log )
303
+ }
304
+ })
305
+ }
306
+ }
307
+
195
308
type testlogger struct {
196
309
t * testing.T
197
310
}
0 commit comments