@@ -2380,3 +2380,126 @@ func TestNewOperatorFromCSV(t *testing.T) {
2380
2380
})
2381
2381
}
2382
2382
}
2383
+
2384
+ func TestSolveOperators_GenericConstraint (t * testing.T ) {
2385
+ Provides1 := cache.APISet {opregistry.APIKey {"g" , "v" , "k" , "ks" }: struct {}{}}
2386
+ namespace := "olm"
2387
+ catalog := cache.SourceKey {Name : "community" , Namespace : namespace }
2388
+
2389
+ deps1 := []* api.Dependency {
2390
+ {
2391
+ Type : "olm.constraint" ,
2392
+ Value : `{"message":"gvk-constraint",
2393
+ "cel":{"rule":"properties.exists(p, p.type == 'olm.gvk' && p.value == {'group': 'g', 'version': 'v', 'kind': 'k'})"}}` ,
2394
+ },
2395
+ }
2396
+ deps2 := []* api.Dependency {
2397
+ {
2398
+ Type : "olm.constraint" ,
2399
+ Value : `{"message":"gvk2-constraint",
2400
+ "cel":{"rule":"properties.exists(p, p.type == 'olm.gvk' && p.value == {'group': 'g2', 'version': 'v', 'kind': 'k'})"}}` ,
2401
+ },
2402
+ }
2403
+ deps3 := []* api.Dependency {
2404
+ {
2405
+ Type : "olm.constraint" ,
2406
+ Value : `{"message":"package-constraint",
2407
+ "cel":{"rule":"properties.exists(p, p.type == 'olm.package' && p.value.packageName == 'packageB' && (semver_compare(p.value.version, '1.0.1') == 0))"}}` ,
2408
+ },
2409
+ }
2410
+
2411
+ tests := []struct {
2412
+ name string
2413
+ isErr bool
2414
+ subs []* v1alpha1.Subscription
2415
+ catalog cache.Source
2416
+ expected cache.OperatorSet
2417
+ message string
2418
+ }{
2419
+ {
2420
+ // generic constraint for satisfiable gvk dependency
2421
+ name : "Generic Constraint/Satisfiable GVK Dependency" ,
2422
+ isErr : false ,
2423
+ subs : []* v1alpha1.Subscription {
2424
+ newSub (namespace , "packageA" , "stable" , catalog ),
2425
+ },
2426
+ catalog : & cache.Snapshot {
2427
+ Entries : []* cache.Entry {
2428
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps1 , "" , false ),
2429
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides1 , nil , "stable" , false ),
2430
+ },
2431
+ },
2432
+ expected : cache.OperatorSet {
2433
+ "opA.v1.0.0" : genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps1 , "" , false ),
2434
+ "opB.v1.0.0" : genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides1 , nil , "stable" , false ),
2435
+ },
2436
+ },
2437
+ {
2438
+ // generic constraint for NotSatisfiable gvk dependency
2439
+ name : "Generic Constraint/NotSatisfiable GVK Dependency" ,
2440
+ isErr : true ,
2441
+ subs : []* v1alpha1.Subscription {
2442
+ newSub (namespace , "packageA" , "stable" , catalog ),
2443
+ },
2444
+ catalog : & cache.Snapshot {
2445
+ Entries : []* cache.Entry {
2446
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps2 , "" , false ),
2447
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides1 , nil , "" , false ),
2448
+ },
2449
+ },
2450
+ // unable to find satisfiable gvk dependency
2451
+ // resolve into nothing
2452
+ expected : cache.OperatorSet {},
2453
+ message : "gvk2-constraint" ,
2454
+ },
2455
+ {
2456
+ // generic constraint for package constraint
2457
+ name : "Generic Constraint/Satisfiable Package Dependency" ,
2458
+ isErr : false ,
2459
+ subs : []* v1alpha1.Subscription {
2460
+ newSub (namespace , "packageA" , "stable" , catalog ),
2461
+ },
2462
+ catalog : & cache.Snapshot {
2463
+ Entries : []* cache.Entry {
2464
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps3 , "" , false ),
2465
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "" , false ),
2466
+ genOperator ("opB.v1.0.1" , "1.0.1" , "opB.v1.0.0" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "stable" , false ),
2467
+ genOperator ("opB.v1.0.2" , "1.0.2" , "opB.v1.0.1" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "stable" , false ),
2468
+ },
2469
+ },
2470
+ expected : cache.OperatorSet {
2471
+ "opA.v1.0.0" : genOperator ("opA.v1.0.1" , "1.0.1" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps3 , "" , false ),
2472
+ "opB.v1.0.1" : genOperator ("opB.v1.0.1" , "1.0.1" , "opB.v1.0.0" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "stable" , false ),
2473
+ },
2474
+ },
2475
+ }
2476
+
2477
+ for _ , tt := range tests {
2478
+ t .Run (tt .name , func (t * testing.T ) {
2479
+ var err error
2480
+ var operators cache.OperatorSet
2481
+ satResolver := SatResolver {
2482
+ cache : cache .New (cache.StaticSourceProvider {
2483
+ catalog : tt .catalog ,
2484
+ }),
2485
+ log : logrus .New (),
2486
+ pc : & predicateConverter {
2487
+ celEnv : constraints .NewCelEnvironment (),
2488
+ },
2489
+ }
2490
+
2491
+ operators , err = satResolver .SolveOperators ([]string {namespace }, nil , tt .subs )
2492
+ if tt .isErr {
2493
+ assert .Error (t , err )
2494
+ assert .Contains (t , err .Error (), tt .message )
2495
+ } else {
2496
+ assert .NoError (t , err )
2497
+ for k := range tt .expected {
2498
+ require .NotNil (t , operators [k ])
2499
+ assert .EqualValues (t , k , operators [k ].Name )
2500
+ }
2501
+ }
2502
+ assert .Equal (t , len (tt .expected ), len (operators ))
2503
+ })
2504
+ }
2505
+ }
0 commit comments