github.com/quay/claircore@v1.5.28/python/packagescanner_test.go (about) 1 package python_test 2 3 import ( 4 "context" 5 "encoding/gob" 6 "errors" 7 "io/fs" 8 "os" 9 "path" 10 "path/filepath" 11 "sort" 12 "strings" 13 "testing" 14 15 "github.com/google/go-cmp/cmp" 16 "github.com/quay/zlog" 17 18 "github.com/quay/claircore" 19 "github.com/quay/claircore/python" 20 "github.com/quay/claircore/test" 21 ) 22 23 // TestScan runs the python scanner over some layers known to have python 24 // packages installed. 25 func TestScanRemote(t *testing.T) { 26 t.Parallel() 27 gob.Register(claircore.Package{}) 28 ctx := context.Background() 29 for _, tc := range scanTable { 30 // To generate a test fixture, populate the entry in the table below and 31 // then run the tests twice. 32 f, err := os.Open(filepath.Join(`testdata`, strings.Replace(tc.Hash, ":", "_", 1)+".gob")) 33 if err != nil { 34 t.Error(err) 35 } 36 defer f.Close() 37 if decErr := gob.NewDecoder(f).Decode(&tc.Want); decErr != nil { 38 t.Error(decErr) 39 } 40 t.Run(path.Base(tc.Name), tc.Run(ctx)) 41 if t.Failed() && errors.Is(err, fs.ErrNotExist) && tc.Want != nil { 42 f, err := os.Create(filepath.Join(`testdata`, strings.Replace(tc.Hash, ":", "_", 1)+".gob")) 43 if err != nil { 44 t.Error(err) 45 } 46 defer f.Close() 47 if err := gob.NewEncoder(f).Encode(&tc.Want); err != nil { 48 t.Error(err) 49 } 50 } 51 } 52 } 53 54 var scanTable = []test.ScannerTestcase{ 55 { 56 Domain: "docker.io", 57 Name: "library/hylang", 58 Hash: "sha256:a96bd05c55b4e8d8944dbc6567e567dd48442dc65a7e8097fe7510531d4bbb1b", 59 Scanner: &python.Scanner{}, 60 }, 61 { 62 Domain: "docker.io", 63 Name: "pythonpillow/fedora-30-amd64", 64 Hash: "sha256:cb257051a8e2e33f5216524539bc2bf2e7b29c42d11ceb08caee36e446235c00", 65 Scanner: &python.Scanner{}, 66 }, 67 { 68 Domain: "docker.io", 69 Name: "pythondiscord/seasonalbot", 70 Hash: "sha256:109a55eba749c02eb6a4533eba12d8aa02a68417ff96886d049798ed5653a156", 71 Scanner: &python.Scanner{}, 72 }, 73 { 74 Domain: "registry.access.redhat.com", 75 Name: "ubi9/ubi", 76 Hash: "sha256:04dc13843981a3c154bf80963e989347efd76e0b1902f81c1aa2547424209614", 77 Scanner: &python.Scanner{}, 78 }, 79 } 80 81 func TestScanLocal(t *testing.T) { 82 t.Parallel() 83 ctx := zlog.Test(context.Background(), t) 84 85 type testcase struct { 86 Name string 87 Want []*claircore.Package 88 Path string 89 } 90 table := []testcase{ 91 { 92 Name: "BadVersion", 93 Want: nil, 94 Path: "testdata/layer-with-bad-version.tar", 95 }, 96 } 97 98 for _, tt := range table { 99 t.Run(tt.Name, func(t *testing.T) { 100 ctx := zlog.Test(ctx, t) 101 f, err := os.Open(tt.Path) 102 if err != nil { 103 t.Fatal(err) 104 } 105 defer func() { 106 if err := f.Close(); err != nil { 107 t.Error(err) 108 } 109 }() 110 scanner := &python.Scanner{} 111 var l claircore.Layer 112 desc := claircore.LayerDescription{ 113 Digest: `sha256:` + strings.Repeat(`beef`, 16), 114 URI: `file:///dev/null`, 115 MediaType: test.MediaType, 116 Headers: make(map[string][]string), 117 } 118 if err := l.Init(ctx, &desc, f); err != nil { 119 t.Fatal(err) 120 } 121 t.Cleanup(func() { 122 if err := l.Close(); err != nil { 123 t.Error(err) 124 } 125 }) 126 127 got, err := scanner.Scan(ctx, &l) 128 if err != nil { 129 t.Error(err) 130 } 131 sort.Slice(got, func(i, j int) bool { return got[i].Name < got[j].Name }) 132 if !cmp.Equal(got, tt.Want) { 133 t.Error(cmp.Diff(got, tt.Want)) 134 } 135 }) 136 } 137 }