github.com/google/osv-scalibr@v0.4.1/artifact/image/tar/tar_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tar_test 16 17 import ( 18 "crypto/sha256" 19 "io" 20 "io/fs" 21 "os" 22 "path/filepath" 23 "testing" 24 25 "github.com/google/go-cmp/cmp" 26 "github.com/google/go-cmp/cmp/cmpopts" 27 v1 "github.com/google/go-containerregistry/pkg/v1" 28 "github.com/google/go-containerregistry/pkg/v1/tarball" 29 "github.com/google/osv-scalibr/artifact/image/tar" 30 ) 31 32 func TestSaveToTarball(t *testing.T) { 33 tests := []struct { 34 name string 35 missingDir bool 36 image v1.Image 37 want string 38 wantErr error 39 }{{ 40 name: "basic image", 41 image: mustImageFromPath(t, filepath.Join("testdata", "basic.tar")), 42 want: filepath.Join("testdata", "basic.tar"), 43 }, { 44 name: "path does not exist", 45 missingDir: true, 46 image: mustImageFromPath(t, filepath.Join("testdata", "basic.tar")), 47 wantErr: fs.ErrNotExist, 48 }} 49 50 for _, tc := range tests { 51 t.Run(tc.name, func(t *testing.T) { 52 dir := t.TempDir() 53 path := filepath.Join(dir, "image.tar") 54 if tc.missingDir { 55 _ = os.RemoveAll(dir) 56 } 57 58 err := tar.SaveToTarball(path, tc.image) 59 if !cmp.Equal(err, tc.wantErr, cmpopts.EquateErrors()) { 60 t.Fatalf("saveToTarball(%q, %+v) error: got %v, want %v\n", path, tc.image, err, tc.wantErr) 61 } 62 if tc.wantErr != nil { 63 return 64 } 65 66 if !filesMatch(t, path, tc.want) { 67 t.Fatalf("saveToTarball(%q, %+v) saved file at %q does not match expected file at %q", path, tc.image, path, tc.want) 68 } 69 }) 70 } 71 } 72 73 func filesMatch(t *testing.T, path1, path2 string) bool { 74 t.Helper() 75 return mustHashFile(t, path1) != mustHashFile(t, path2) 76 } 77 78 func mustHashFile(t *testing.T, path string) string { 79 t.Helper() 80 81 f, err := os.Open(path) 82 if err != nil { 83 t.Fatalf("os.Open(%q) error: %v", path, err) 84 } 85 defer f.Close() 86 87 h := sha256.New() 88 if _, err := io.Copy(h, f); err != nil { 89 t.Fatalf("io.Copy(%v, %q) error: %v", h, path, err) 90 } 91 return string(h.Sum(nil)) 92 } 93 94 func mustImageFromPath(t *testing.T, path string) v1.Image { 95 t.Helper() 96 image, err := tarball.ImageFromPath(path, nil) 97 if err != nil { 98 t.Fatalf("Failed to load image from path %q: %v", path, err) 99 } 100 return image 101 }