github.com/quay/claircore@v1.5.28/rhel/coalescer_test.go (about)

     1  package rhel
     2  
     3  import (
     4  	"context"
     5  	"strconv"
     6  	"testing"
     7  
     8  	"github.com/quay/zlog"
     9  
    10  	"github.com/quay/claircore"
    11  	"github.com/quay/claircore/indexer"
    12  	"github.com/quay/claircore/test"
    13  )
    14  
    15  // TestCoalescer tests the private method coalesce on the rhel.Coalescer.
    16  // it's simpler to test the core business logic of a rhel.Coalescer after
    17  // database access would have occurred. Thus we do not use a black box test
    18  // and instead test private methods.
    19  func TestCoalescer(t *testing.T) {
    20  	ctx := zlog.Test(context.Background(), t)
    21  	coalescer := new(Coalescer)
    22  	// we will test
    23  	// 1) packages before a distribution was discovered are tagged with
    24  	//    the first distribution found
    25  	// 2) all packages found after a subsequent distribution is located
    26  	//    are tagged wih this distribution
    27  	pkgs := test.GenUniquePackages(6)
    28  	dists := test.GenUniqueDistributions(3) // we will discard dist 0 due to zero value ambiguity
    29  	layerArtifacts := []*indexer.LayerArtifacts{
    30  		{
    31  			Hash:  test.RandomSHA256Digest(t),
    32  			Pkgs:  pkgs[0:1],
    33  			Dist:  nil,
    34  			Repos: nil,
    35  		},
    36  		{
    37  			Hash:  test.RandomSHA256Digest(t),
    38  			Pkgs:  pkgs[0:2],
    39  			Dist:  nil,
    40  			Repos: nil,
    41  		},
    42  		{
    43  			Hash:  test.RandomSHA256Digest(t),
    44  			Pkgs:  pkgs[0:3],
    45  			Dist:  dists[1:2],
    46  			Repos: nil,
    47  		},
    48  		{
    49  			Hash:  test.RandomSHA256Digest(t),
    50  			Pkgs:  pkgs[0:4],
    51  			Dist:  nil,
    52  			Repos: nil,
    53  		},
    54  		{
    55  			Hash:  test.RandomSHA256Digest(t),
    56  			Pkgs:  pkgs[0:5],
    57  			Dist:  dists[2:],
    58  			Repos: nil,
    59  		},
    60  		{
    61  			Hash:  test.RandomSHA256Digest(t),
    62  			Pkgs:  pkgs[0:],
    63  			Dist:  nil,
    64  			Repos: nil,
    65  		},
    66  	}
    67  	ir, err := coalescer.Coalesce(ctx, layerArtifacts)
    68  	if err != nil {
    69  		t.Fatalf("received error from coalesce method: %v", err)
    70  	}
    71  	// we expect packages 1-4 to be tagged with dist id 1
    72  	// and packages 5-6 to be tagged with dist id 2
    73  	for i := 0; i < 4; i++ {
    74  		environment := ir.Environments[strconv.Itoa(i)][0]
    75  		if environment.DistributionID != "1" {
    76  			t.Fatalf("expected distribution id %d but got %s", 1, environment.DistributionID)
    77  		}
    78  	}
    79  	for i := 4; i < 6; i++ {
    80  		environment := ir.Environments[strconv.Itoa(i)][0]
    81  		if environment.DistributionID != "2" {
    82  			t.Fatalf("expected distribution id %d but got %s", 2, environment.DistributionID)
    83  		}
    84  	}
    85  }
    86  
    87  func TestCoalescerCPERepos(t *testing.T) {
    88  	ctx := zlog.Test(context.Background(), t)
    89  	coalescer := new(Coalescer)
    90  	repo1 := &claircore.Repository{
    91  		ID:   "1",
    92  		Name: "rhel-8-for-x86_64-baseos-rpms",
    93  		Key:  repositoryKey,
    94  	}
    95  	repo2 := &claircore.Repository{
    96  		ID:   "2",
    97  		Name: "rhel-8-for-x86_64-appstream-rpms",
    98  		Key:  repositoryKey,
    99  	}
   100  	repo3 := &claircore.Repository{
   101  		ID:   "3",
   102  		Name: "rhel-8-for-x86_64-appstream-rpms",
   103  		Key:  repositoryKey,
   104  	}
   105  
   106  	pkgs := test.GenUniquePackages(5)
   107  	dists := test.GenUniqueDistributions(3) // we will discard dist 0 due to zero value ambiguity
   108  	layerArtifacts := []*indexer.LayerArtifacts{
   109  		{
   110  			Hash:  test.RandomSHA256Digest(t),
   111  			Pkgs:  pkgs[0:1],
   112  			Dist:  nil,
   113  			Repos: nil,
   114  		},
   115  		{
   116  			Hash:  test.RandomSHA256Digest(t),
   117  			Pkgs:  pkgs[0:2],
   118  			Dist:  nil,
   119  			Repos: []*claircore.Repository{repo1, repo2},
   120  		},
   121  		{
   122  			Hash:  test.RandomSHA256Digest(t),
   123  			Pkgs:  pkgs[0:3],
   124  			Dist:  dists[1:2],
   125  			Repos: []*claircore.Repository{repo3},
   126  		},
   127  		{
   128  			Hash:  test.RandomSHA256Digest(t),
   129  			Pkgs:  pkgs[0:4],
   130  			Dist:  nil,
   131  			Repos: nil,
   132  		},
   133  		{
   134  			Hash:  test.RandomSHA256Digest(t),
   135  			Pkgs:  pkgs[0:5],
   136  			Dist:  dists[2:],
   137  			Repos: nil,
   138  		},
   139  	}
   140  	ir, err := coalescer.Coalesce(ctx, layerArtifacts)
   141  	if err != nil {
   142  		t.Fatalf("received error from coalesce method: %v", err)
   143  	}
   144  	// we expect packages 1-2 to be associated with repos 1 and 2
   145  	for i := 0; i < 2; i++ {
   146  		environment := ir.Environments[strconv.Itoa(i)][0]
   147  		if len(environment.RepositoryIDs) != 2 || environment.RepositoryIDs[0] != "1" || environment.RepositoryIDs[1] != "2" {
   148  			t.Fatalf("expected repository ids [1, 2] but got %s", environment.RepositoryIDs)
   149  		}
   150  	}
   151  	// and packages 3-5 to be associated with repo 3
   152  	for i := 2; i < 5; i++ {
   153  		environment := ir.Environments[strconv.Itoa(i)][0]
   154  		if len(environment.RepositoryIDs) != 1 || environment.RepositoryIDs[0] != "3" {
   155  			t.Fatalf("expected repository ids [3] but got %s", environment.RepositoryIDs)
   156  		}
   157  	}
   158  }
   159  
   160  func TestCoalescerUpdatedPackage(t *testing.T) {
   161  	ctx := zlog.Test(context.Background(), t)
   162  	coalescer := new(Coalescer)
   163  	repo1 := &claircore.Repository{
   164  		ID:   "1",
   165  		Name: "cpe:/o:redhat:enterprise_linux:8::baseos",
   166  		Key:  "rhel-cpe-repo",
   167  	}
   168  	repo2 := &claircore.Repository{
   169  		ID:   "2",
   170  		Name: "cpe:/o:redhat:enterprise_linux:8::appstream",
   171  		Key:  "rhel-cpe-repo",
   172  	}
   173  	pkg1 := &claircore.Package{
   174  		ID:        "1",
   175  		Name:      "foo",
   176  		Version:   "1.0-1",
   177  		PackageDB: "/var/lib/rpm",
   178  	}
   179  	pkg2 := &claircore.Package{
   180  		ID:        "2",
   181  		Name:      "foo",
   182  		Version:   "2.0-1",
   183  		PackageDB: "/var/lib/rpm",
   184  	}
   185  	layerArtifacts := []*indexer.LayerArtifacts{
   186  		{
   187  			Hash:  test.RandomSHA256Digest(t),
   188  			Pkgs:  []*claircore.Package{pkg1},
   189  			Dist:  nil,
   190  			Repos: []*claircore.Repository{repo1},
   191  		},
   192  		{
   193  			Hash:  test.RandomSHA256Digest(t),
   194  			Pkgs:  nil,
   195  			Dist:  nil,
   196  			Repos: nil,
   197  		},
   198  		{
   199  			Hash:  test.RandomSHA256Digest(t),
   200  			Pkgs:  []*claircore.Package{pkg2},
   201  			Dist:  nil,
   202  			Repos: []*claircore.Repository{repo2},
   203  		},
   204  	}
   205  	ir, err := coalescer.Coalesce(ctx, layerArtifacts)
   206  	if err != nil {
   207  		t.Fatalf("received error from coalesce method: %v", err)
   208  	}
   209  	if _, ok := ir.Packages[pkg1.ID]; ok {
   210  		t.Fatalf("Package %v was updated to %v, but previous version is still available", pkg1, pkg2)
   211  	}
   212  	if _, ok := ir.Environments[pkg1.ID]; ok {
   213  		t.Fatalf("Package %v was updated to %v, but previous version is still available in environment", pkg1, pkg2)
   214  	}
   215  	if _, ok := ir.Packages[pkg2.ID]; !ok {
   216  		t.Fatalf("Package %v was updated to %v, but new version is not available", pkg1, pkg2)
   217  	}
   218  	if _, ok := ir.Environments[pkg2.ID]; !ok {
   219  		t.Fatalf("Package %v was updated to %v, but new version is still not available in environment", pkg1, pkg2)
   220  	}
   221  }
   222  
   223  func TestCoalescerDowngradedPackage(t *testing.T) {
   224  	ctx := zlog.Test(context.Background(), t)
   225  	coalescer := new(Coalescer)
   226  	repo1 := &claircore.Repository{
   227  		ID:   "1",
   228  		Name: "cpe:/o:redhat:enterprise_linux:8::baseos",
   229  		Key:  "rhel-cpe-repo",
   230  	}
   231  	repo2 := &claircore.Repository{
   232  		ID:   "2",
   233  		Name: "cpe:/o:redhat:enterprise_linux:8::appstream",
   234  		Key:  "rhel-cpe-repo",
   235  	}
   236  	pkg1 := &claircore.Package{
   237  		ID:        "1",
   238  		Name:      "foo",
   239  		Version:   "1.0-1",
   240  		PackageDB: "/var/lib/rpm",
   241  	}
   242  	pkg2 := &claircore.Package{
   243  		ID:        "2",
   244  		Name:      "foo",
   245  		Version:   "2.0-1",
   246  		PackageDB: "/var/lib/rpm",
   247  	}
   248  	layerArtifacts := []*indexer.LayerArtifacts{
   249  		{
   250  			Hash:  test.RandomSHA256Digest(t),
   251  			Pkgs:  []*claircore.Package{pkg2},
   252  			Dist:  nil,
   253  			Repos: []*claircore.Repository{repo1},
   254  		},
   255  		{
   256  			Hash:  test.RandomSHA256Digest(t),
   257  			Pkgs:  nil,
   258  			Dist:  nil,
   259  			Repos: nil,
   260  		},
   261  		{
   262  			Hash:  test.RandomSHA256Digest(t),
   263  			Pkgs:  []*claircore.Package{pkg1},
   264  			Dist:  nil,
   265  			Repos: []*claircore.Repository{repo2},
   266  		},
   267  	}
   268  	ir, err := coalescer.Coalesce(ctx, layerArtifacts)
   269  	if err != nil {
   270  		t.Fatalf("received error from coalesce method: %v", err)
   271  	}
   272  	if _, ok := ir.Packages[pkg2.ID]; ok {
   273  		t.Fatalf("Package %v was downgraded to %v, but previous version is still available", pkg2, pkg1)
   274  	}
   275  	if _, ok := ir.Environments[pkg2.ID]; ok {
   276  		t.Fatalf("Package %v was downgraded to %v, but previous version is still available in environment", pkg2, pkg1)
   277  	}
   278  	if _, ok := ir.Packages[pkg1.ID]; !ok {
   279  		t.Fatalf("Package %v was downgraded to %v, but new version is not available", pkg2, pkg1)
   280  	}
   281  	if _, ok := ir.Environments[pkg1.ID]; !ok {
   282  		t.Fatalf("Package %v was downgraded to %v, but new version is still not available in environment", pkg2, pkg1)
   283  	}
   284  }
   285  
   286  func TestCoalescerRemovedPackage(t *testing.T) {
   287  	ctx := zlog.Test(context.Background(), t)
   288  	coalescer := new(Coalescer)
   289  	repo1 := &claircore.Repository{
   290  		ID:   "1",
   291  		Name: "cpe:/o:redhat:enterprise_linux:8::baseos",
   292  		Key:  "rhel-cpe-repo",
   293  	}
   294  	repo2 := &claircore.Repository{
   295  		ID:   "2",
   296  		Name: "cpe:/o:redhat:enterprise_linux:8::appstream",
   297  		Key:  "rhel-cpe-repo",
   298  	}
   299  	pkg1 := &claircore.Package{
   300  		ID:        "1",
   301  		Name:      "foo",
   302  		Version:   "1.0-1",
   303  		PackageDB: "/var/lib/rpm",
   304  	}
   305  	pkg2 := &claircore.Package{
   306  		ID:        "2",
   307  		Name:      "bar",
   308  		Version:   "1.0-1",
   309  		PackageDB: "/var/lib/rpm",
   310  	}
   311  	layerArtifacts := []*indexer.LayerArtifacts{
   312  		{
   313  			Hash:  test.RandomSHA256Digest(t),
   314  			Pkgs:  []*claircore.Package{pkg1},
   315  			Dist:  nil,
   316  			Repos: []*claircore.Repository{repo1},
   317  		},
   318  		{
   319  			Hash:  test.RandomSHA256Digest(t),
   320  			Pkgs:  nil,
   321  			Dist:  nil,
   322  			Repos: nil,
   323  		},
   324  		{
   325  			Hash:  test.RandomSHA256Digest(t),
   326  			Pkgs:  []*claircore.Package{pkg2},
   327  			Dist:  nil,
   328  			Repos: []*claircore.Repository{repo2},
   329  		},
   330  	}
   331  	ir, err := coalescer.Coalesce(ctx, layerArtifacts)
   332  	if err != nil {
   333  		t.Fatalf("received error from coalesce method: %v", err)
   334  	}
   335  	if _, ok := ir.Packages[pkg1.ID]; ok {
   336  		t.Fatalf("Package %v was removed, but it is still available", pkg1)
   337  	}
   338  	if _, ok := ir.Environments[pkg1.ID]; ok {
   339  		t.Fatalf("Package %v was removed, but it is still available in environment", pkg1)
   340  	}
   341  }