github.com/quay/claircore@v1.5.28/rhel/matcher_test.go (about) 1 package rhel 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "path/filepath" 12 "testing" 13 14 "github.com/quay/zlog" 15 16 "github.com/quay/claircore" 17 "github.com/quay/claircore/datastore/postgres" 18 "github.com/quay/claircore/internal/matcher" 19 "github.com/quay/claircore/libvuln/driver" 20 "github.com/quay/claircore/libvuln/updates" 21 "github.com/quay/claircore/pkg/ctxlock" 22 "github.com/quay/claircore/test/integration" 23 pgtest "github.com/quay/claircore/test/postgres" 24 ) 25 26 func TestMain(m *testing.M) { 27 var c int 28 defer func() { os.Exit(c) }() 29 defer integration.DBSetup()() 30 c = m.Run() 31 } 32 33 func serveOVAL(t *testing.T) (string, *http.Client) { 34 srv := httptest.NewServer(http.FileServer(http.Dir("testdata"))) 35 t.Cleanup(srv.Close) 36 return srv.URL, srv.Client() 37 } 38 39 func TestMatcherIntegration(t *testing.T) { 40 t.Parallel() 41 integration.NeedDB(t) 42 ctx := zlog.Test(context.Background(), t) 43 pool := pgtest.TestMatcherDB(ctx, t) 44 store := postgres.NewMatcherStore(pool) 45 m := &Matcher{} 46 fs, err := filepath.Glob("testdata/*.xml") 47 if err != nil { 48 t.Error(err) 49 } 50 root, c := serveOVAL(t) 51 locks, err := ctxlock.New(ctx, pool) 52 if err != nil { 53 t.Error(err) 54 return 55 } 56 defer locks.Close(ctx) 57 58 facs := make(map[string]driver.UpdaterSetFactory, len(fs)) 59 for _, fn := range fs { 60 u, err := NewUpdater( 61 fmt.Sprintf("test-updater-%s", filepath.Base(fn)), 62 1, 63 root+"/"+filepath.Base(fn), 64 false, 65 ) 66 if err != nil { 67 t.Error(err) 68 continue 69 } 70 u.Configure(ctx, func(v interface{}) error { return nil }, c) 71 if err != nil { 72 t.Error(err) 73 continue 74 } 75 s := driver.NewUpdaterSet() 76 if err := s.Add(u); err != nil { 77 t.Error(err) 78 continue 79 } 80 facs[u.Name()] = driver.StaticSet(s) 81 } 82 mgr, err := updates.NewManager(ctx, store, locks, c, updates.WithFactories(facs)) 83 if err != nil { 84 t.Error(err) 85 } 86 // force update 87 if err := mgr.Run(ctx); err != nil { 88 t.Error(err) 89 } 90 91 f, err := os.Open(filepath.Join("testdata", "rhel-report.json")) 92 if err != nil { 93 t.Fatalf("%v", err) 94 } 95 defer f.Close() 96 var ir claircore.IndexReport 97 if err := json.NewDecoder(f).Decode(&ir); err != nil { 98 t.Fatalf("failed to decode IndexReport: %v", err) 99 } 100 vr, err := matcher.Match(ctx, &ir, []driver.Matcher{m}, store) 101 if err != nil { 102 t.Fatal(err) 103 } 104 if err := json.NewEncoder(io.Discard).Encode(&vr); err != nil { 105 t.Fatalf("failed to marshal VR: %v", err) 106 } 107 } 108 109 type vulnerableTestCase struct { 110 ir *claircore.IndexRecord 111 v *claircore.Vulnerability 112 name string 113 want bool 114 } 115 116 func TestVulnerable(t *testing.T) { 117 record := &claircore.IndexRecord{ 118 Package: &claircore.Package{ 119 Version: "0.33.0-6.el8", 120 }, 121 } 122 fixedVulnPast := &claircore.Vulnerability{ 123 Package: &claircore.Package{ 124 Version: "", 125 }, 126 FixedInVersion: "0.33.0-5.el8", 127 } 128 fixedVulnCurrent := &claircore.Vulnerability{ 129 Package: &claircore.Package{ 130 Version: "", 131 }, 132 FixedInVersion: "0.33.0-6.el8", 133 } 134 fixedVulnFuture := &claircore.Vulnerability{ 135 Package: &claircore.Package{ 136 Version: "", 137 }, 138 FixedInVersion: "0.33.0-7.el8", 139 } 140 unfixedVuln := &claircore.Vulnerability{ 141 Package: &claircore.Package{ 142 Version: "", 143 }, 144 FixedInVersion: "", 145 } 146 147 testCases := []vulnerableTestCase{ 148 {ir: record, v: fixedVulnPast, want: false, name: "vuln fixed in past version"}, 149 {ir: record, v: fixedVulnCurrent, want: false, name: "vuln fixed in current version"}, 150 {ir: record, v: fixedVulnFuture, want: true, name: "outdated package"}, 151 {ir: record, v: unfixedVuln, want: true, name: "unfixed vuln"}, 152 } 153 154 m := &Matcher{} 155 156 for _, tc := range testCases { 157 got, err := m.Vulnerable(nil, tc.ir, tc.v) 158 if err != nil { 159 t.Error(err) 160 } 161 if tc.want != got { 162 t.Errorf("%q failed: want %t, got %t", tc.name, tc.want, got) 163 } 164 } 165 }