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 }