github.com/quay/claircore@v1.5.28/datastore/postgres/updatevulnerabilities_test.go (about) 1 package postgres 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/google/uuid" 8 "github.com/quay/zlog" 9 10 "github.com/quay/claircore" 11 "github.com/quay/claircore/datastore" 12 "github.com/quay/claircore/libvuln/driver" 13 "github.com/quay/claircore/test/integration" 14 pgtest "github.com/quay/claircore/test/postgres" 15 ) 16 17 type latestVulnTestCase struct { 18 TestName string 19 Updater string 20 VulnCount int 21 FirstOp, SecondOp *op 22 Records []*claircore.IndexRecord 23 } 24 25 type op struct { 26 vulns []*claircore.Vulnerability 27 deletedVulns []string 28 } 29 30 func TestGetLatestVulnerabilities(t *testing.T) { 31 integration.NeedDB(t) 32 ctx := zlog.Test(context.Background(), t) 33 34 cases := []latestVulnTestCase{ 35 { 36 TestName: "test initial op vuln still relevant", 37 Updater: updater, 38 VulnCount: 1, 39 FirstOp: &op{ 40 deletedVulns: []string{}, 41 vulns: []*claircore.Vulnerability{ 42 { 43 Updater: updater, 44 Name: "CVE-123", 45 Package: &claircore.Package{ 46 Name: "vi", 47 }, 48 }, 49 }, 50 }, 51 SecondOp: &op{ 52 deletedVulns: []string{}, 53 vulns: []*claircore.Vulnerability{ 54 { 55 Updater: updater, 56 Name: "CVE-456", 57 Package: &claircore.Package{ 58 Name: "vim", 59 }, 60 }, 61 { 62 Updater: updater, 63 Name: "CVE-789", 64 Package: &claircore.Package{ 65 Name: "nano", 66 }, 67 }, 68 }, 69 }, 70 Records: []*claircore.IndexRecord{ 71 { 72 Package: &claircore.Package{ 73 Name: "vi", 74 Source: &claircore.Package{ 75 Name: "vi", 76 Version: "v1.0.0", 77 }, 78 }, 79 }, 80 }, 81 }, 82 { 83 TestName: "test vuln is overwritten not duped", 84 Updater: updater, 85 VulnCount: 1, 86 FirstOp: &op{ 87 deletedVulns: []string{}, 88 vulns: []*claircore.Vulnerability{ 89 { 90 Updater: updater, 91 Name: "CVE-123", 92 Package: &claircore.Package{ 93 Name: "grep", 94 }, 95 Severity: "BAD", 96 }, 97 { 98 Updater: updater, 99 Name: "CVE-456", 100 Package: &claircore.Package{ 101 Name: "sed", 102 }, 103 }, 104 }, 105 }, 106 SecondOp: &op{ 107 deletedVulns: []string{}, 108 vulns: []*claircore.Vulnerability{ 109 { 110 Updater: updater, 111 Name: "CVE-123", 112 Package: &claircore.Package{ 113 Name: "grep", 114 }, 115 Severity: "NOT AS BAD AS WE THOUGHT", 116 }, 117 }, 118 }, 119 Records: []*claircore.IndexRecord{ 120 { 121 Package: &claircore.Package{ 122 Name: "grep", 123 Source: &claircore.Package{ 124 Name: "grep", 125 Version: "v1.0.0", 126 }, 127 }, 128 }, 129 }, 130 }, 131 { 132 TestName: "test multiple vulns from same CVE", 133 Updater: updater, 134 VulnCount: 1, 135 FirstOp: &op{ 136 deletedVulns: []string{}, 137 vulns: []*claircore.Vulnerability{ 138 { 139 Updater: updater, 140 Name: "CVE-123", 141 Package: &claircore.Package{ 142 Name: "grep", 143 }, 144 Severity: "BAD", 145 }, 146 { 147 Updater: updater, 148 Name: "CVE-123", 149 Package: &claircore.Package{ 150 Name: "sed", 151 }, 152 Severity: "REALLY BAD", 153 }, 154 }, 155 }, 156 SecondOp: &op{ 157 deletedVulns: []string{}, 158 vulns: []*claircore.Vulnerability{ 159 { 160 Updater: updater, 161 Name: "CVE-123", 162 Package: &claircore.Package{ 163 Name: "grep", 164 }, 165 Severity: "NOT AS BAD AS WE THOUGHT", 166 }, 167 { 168 Updater: updater, 169 Name: "CVE-123", 170 Package: &claircore.Package{ 171 Name: "sed", 172 }, 173 Severity: "FINE", 174 }, 175 }, 176 }, 177 Records: []*claircore.IndexRecord{ 178 { 179 Package: &claircore.Package{ 180 Name: "grep", 181 Source: &claircore.Package{ 182 Name: "grep", 183 Version: "v1.0.0", 184 }, 185 }, 186 }, 187 }, 188 }, 189 190 { 191 TestName: "test two vulns same package different uo", 192 Updater: updater, 193 VulnCount: 2, 194 FirstOp: &op{ 195 deletedVulns: []string{}, 196 vulns: []*claircore.Vulnerability{ 197 { 198 Updater: updater, 199 Name: "CVE-000", 200 Package: &claircore.Package{ 201 Name: "python3", 202 }, 203 }, 204 }, 205 }, 206 SecondOp: &op{ 207 deletedVulns: []string{}, 208 vulns: []*claircore.Vulnerability{ 209 { 210 Updater: updater, 211 Name: "CVE-123", 212 Package: &claircore.Package{ 213 Name: "python3", 214 }, 215 }, 216 { 217 Updater: updater, 218 Name: "CVE-456", 219 Package: &claircore.Package{ 220 Name: "python3-crypto", 221 }, 222 }, 223 { 224 Updater: updater, 225 Name: "CVE-789", 226 Package: &claircore.Package{ 227 Name: "python3-urllib3", 228 }, 229 }, 230 }, 231 }, 232 Records: []*claircore.IndexRecord{ 233 { 234 Package: &claircore.Package{ 235 Name: "python3", 236 Source: &claircore.Package{ 237 Name: "python3", 238 Version: "v1.0.0", 239 }, 240 }, 241 }, 242 }, 243 }, 244 { 245 TestName: "test deleting vuln", 246 Updater: updater, 247 VulnCount: 0, 248 FirstOp: &op{ 249 deletedVulns: []string{}, 250 vulns: []*claircore.Vulnerability{ 251 { 252 Updater: updater, 253 Name: "CVE-000", 254 Package: &claircore.Package{ 255 Name: "jq", 256 }, 257 }, 258 }, 259 }, 260 SecondOp: &op{ 261 deletedVulns: []string{"CVE-000"}, 262 vulns: []*claircore.Vulnerability{ 263 { 264 Updater: updater, 265 Name: "CVE-456", 266 Package: &claircore.Package{ 267 Name: "jq-libs", 268 }, 269 }, 270 { 271 Updater: updater, 272 Name: "CVE-789", 273 Package: &claircore.Package{ 274 Name: "jq-docs", 275 }, 276 }, 277 }, 278 }, 279 Records: []*claircore.IndexRecord{ 280 { 281 Package: &claircore.Package{ 282 Name: "jq", 283 Source: &claircore.Package{ 284 Name: "jq", 285 Version: "v1.0.0", 286 }, 287 }, 288 }, 289 }, 290 }, 291 } 292 293 // prepare DB 294 pool := pgtest.TestMatcherDB(ctx, t) 295 store := NewMatcherStore(pool) 296 297 // run test cases 298 for _, tc := range cases { 299 t.Run(tc.TestName, func(t *testing.T) { 300 _, err := store.DeltaUpdateVulnerabilities(ctx, tc.Updater, driver.Fingerprint(uuid.New().String()), tc.FirstOp.vulns, tc.FirstOp.deletedVulns) 301 if err != nil { 302 t.Fatalf("failed to perform update for first op: %v", err) 303 } 304 _, err = store.DeltaUpdateVulnerabilities(ctx, tc.Updater, driver.Fingerprint(uuid.New().String()), tc.SecondOp.vulns, tc.SecondOp.deletedVulns) 305 if err != nil { 306 t.Fatalf("failed to perform update for second op: %v", err) 307 } 308 309 res, err := store.Get(ctx, tc.Records, datastore.GetOpts{}) 310 if err != nil { 311 t.Fatalf("failed to get vulns: %v", err) 312 } 313 ct := 0 314 for _, vs := range res { 315 ct = ct + len(vs) 316 } 317 318 if ct != tc.VulnCount { 319 t.Fatalf("got %d vulns, want %d", ct, tc.VulnCount) 320 } 321 }) 322 } 323 }