github.com/quay/claircore@v1.5.28/rhel/rhcc/scanner_test.go (about) 1 package rhcc 2 3 import ( 4 "archive/tar" 5 "context" 6 "encoding/json" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "path" 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/test" 20 ) 21 22 func TestContainerScanner(t *testing.T) { 23 t.Parallel() 24 ctx := zlog.Test(context.Background(), t) 25 clairSourceContainer := &claircore.Package{ 26 Name: "quay-clair-container", 27 Version: "v3.5.5-4", 28 NormalizedVersion: claircore.Version{ 29 Kind: "rhctag", 30 V: [10]int32{3, 5}, 31 }, 32 Kind: claircore.SOURCE, 33 PackageDB: "root/buildinfo/Dockerfile-quay-clair-rhel8-v3.5.5-4", 34 RepositoryHint: "rhcc", 35 Arch: "x86_64", 36 } 37 38 quaySourceContainer := &claircore.Package{ 39 Name: "quay-registry-container", 40 Version: "v3.5.6-4", 41 NormalizedVersion: claircore.Version{ 42 Kind: "rhctag", 43 V: [10]int32{3, 5}, 44 }, 45 Kind: claircore.SOURCE, 46 PackageDB: "root/buildinfo/Dockerfile-quay-quay-rhel8-v3.5.6-4", 47 RepositoryHint: "rhcc", 48 Arch: "x86_64", 49 } 50 51 loggingSourceContainer := &claircore.Package{ 52 Name: "logging-elasticsearch6-container", 53 Version: "v4.6.0-202112132021.p0.g2a13a81.assembly.stream", 54 NormalizedVersion: claircore.Version{ 55 Kind: "rhctag", 56 V: [10]int32{4, 6}, 57 }, 58 Kind: claircore.SOURCE, 59 PackageDB: "root/buildinfo/Dockerfile-openshift-ose-logging-elasticsearch6-v4.6.0-202112132021.p0.g2a13a81.assembly.stream", 60 RepositoryHint: "rhcc", 61 Arch: "x86_64", 62 } 63 name2reposData := map[string]map[string][]string{ 64 "data": {"openshift/ose-logging-elasticsearch6": {"openshift4/ose-logging-elasticsearch6"}}, 65 } 66 67 type testcase struct { 68 Name string 69 Dockerfile string 70 Want []*claircore.Package 71 } 72 table := []testcase{ 73 { 74 Name: "Quay", 75 Dockerfile: "testdata/Dockerfile-quay-quay-rhel8-v3.5.6-4", 76 Want: []*claircore.Package{ 77 quaySourceContainer, 78 { 79 Name: "quay/quay-rhel8", 80 Version: "v3.5.6-4", 81 NormalizedVersion: claircore.Version{ 82 Kind: "rhctag", 83 V: [10]int32{3, 5}, 84 }, 85 Kind: claircore.BINARY, 86 Source: quaySourceContainer, 87 PackageDB: "root/buildinfo/Dockerfile-quay-quay-rhel8-v3.5.6-4", 88 RepositoryHint: "rhcc", 89 Arch: "x86_64", 90 }, 91 }, 92 }, 93 { 94 Name: "Clair", 95 Dockerfile: "testdata/Dockerfile-quay-clair-rhel8-v3.5.5-4", 96 Want: []*claircore.Package{ 97 clairSourceContainer, 98 { 99 Name: "quay/clair-rhel8", 100 Version: "v3.5.5-4", 101 NormalizedVersion: claircore.Version{ 102 Kind: "rhctag", 103 V: [10]int32{3, 5}, 104 }, 105 Kind: claircore.BINARY, 106 Source: clairSourceContainer, 107 PackageDB: "root/buildinfo/Dockerfile-quay-clair-rhel8-v3.5.5-4", 108 RepositoryHint: "rhcc", 109 Arch: "x86_64", 110 }, 111 }, 112 }, 113 { 114 Name: "Elasticsearch", 115 Dockerfile: "testdata/Dockerfile-openshift-ose-logging-elasticsearch6-v4.6.0-202112132021.p0.g2a13a81.assembly.stream", 116 Want: []*claircore.Package{ 117 loggingSourceContainer, 118 { 119 Name: "openshift4/ose-logging-elasticsearch6", 120 Version: "v4.6.0-202112132021.p0.g2a13a81.assembly.stream", 121 NormalizedVersion: claircore.Version{ 122 Kind: "rhctag", 123 V: [10]int32{4, 6}, 124 }, 125 Kind: claircore.BINARY, 126 Source: loggingSourceContainer, 127 PackageDB: "root/buildinfo/Dockerfile-openshift-ose-logging-elasticsearch6-v4.6.0-202112132021.p0.g2a13a81.assembly.stream", 128 RepositoryHint: "rhcc", 129 Arch: "x86_64", 130 }, 131 }, 132 }, 133 } 134 mux := http.NewServeMux() 135 mux.HandleFunc("/container-name-repos-map.json", func(w http.ResponseWriter, _ *http.Request) { 136 w.Header().Set("last-modified", "Mon, 02 Jan 2006 15:04:05 MST") 137 if err := json.NewEncoder(w).Encode(name2reposData); err != nil { 138 t.Fatal(err) 139 } 140 }) 141 srv := httptest.NewServer(mux) 142 defer srv.Close() 143 var cs scanner 144 cf := func(v interface{}) error { 145 cfg := v.(*ScannerConfig) 146 cfg.Name2ReposMappingURL = srv.URL + "/container-name-repos-map.json" 147 return nil 148 } 149 if err := cs.Configure(ctx, cf, srv.Client()); err != nil { 150 t.Error(err) 151 } 152 153 a := test.NewCachedArena(t) 154 t.Cleanup(func() { 155 if err := a.Close(ctx); err != nil { 156 t.Error(err) 157 } 158 }) 159 for _, tt := range table { 160 t.Run(tt.Name, func(t *testing.T) { 161 ctx := zlog.Test(ctx, t) 162 mod := test.Modtime(t, tt.Dockerfile) 163 a.GenerateLayer(t, tt.Name, mod, func(t testing.TB, w *os.File) { 164 dockerfile, err := os.Open(tt.Dockerfile) 165 if err != nil { 166 t.Fatal(err) 167 } 168 defer dockerfile.Close() 169 fi, err := dockerfile.Stat() 170 if err != nil { 171 t.Fatal(err) 172 } 173 tw := tar.NewWriter(w) 174 hdr, err := tar.FileInfoHeader(fi, "") 175 if err != nil { 176 t.Fatal(err) 177 } 178 hdr.Name = path.Join("root/buildinfo", path.Base(tt.Dockerfile)) 179 if err := tw.WriteHeader(hdr); err != nil { 180 t.Error(err) 181 } 182 if _, err := io.Copy(tw, dockerfile); err != nil { 183 t.Error(err) 184 } 185 if err := tw.Close(); err != nil { 186 t.Error(err) 187 } 188 t.Logf("wrote tar to: %s", w.Name()) 189 }) 190 191 r := a.Realizer(ctx).(*test.CachedRealizer) 192 defer func() { 193 if err := r.Close(); err != nil { 194 t.Error(err) 195 } 196 }() 197 ls, err := r.RealizeDescriptions(ctx, []claircore.LayerDescription{{ 198 Digest: "sha256:" + strings.Repeat("beef", 16), 199 URI: "file:" + tt.Name, 200 MediaType: test.MediaType, 201 Headers: make(map[string][]string), 202 }}) 203 if err != nil { 204 t.Error(err) 205 } 206 207 got, err := cs.Scan(ctx, &ls[0]) 208 if err != nil { 209 t.Error(err) 210 } 211 t.Logf("found %d packages", len(got)) 212 if !cmp.Equal(got, tt.Want) { 213 t.Error(cmp.Diff(got, tt.Want)) 214 } 215 }) 216 } 217 }