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  }