@@ -2066,3 +2066,121 @@ func TestNewOperatorFromCSV(t *testing.T) {
2066
2066
})
2067
2067
}
2068
2068
}
2069
+
2070
+ func TestSolveOperators_GenericConstraint (t * testing.T ) {
2071
+ Provides1 := cache.APISet {opregistry.APIKey {"g" , "v" , "k" , "ks" }: struct {}{}}
2072
+ Provides2 := cache.APISet {opregistry.APIKey {"g2" , "v" , "k" , "ks" }: struct {}{}}
2073
+
2074
+ namespace := "olm"
2075
+ catalog := cache.SourceKey {Name : "community" , Namespace : namespace }
2076
+
2077
+ phases := []struct {
2078
+ isErr bool
2079
+ subs []* v1alpha1.Subscription
2080
+ deps []* api.Dependency
2081
+ catalog cache.Source
2082
+ expected cache.OperatorSet
2083
+ }{
2084
+ {
2085
+ // generic constraint for satisfiable gvk dependency
2086
+ isErr : false ,
2087
+ subs : []* v1alpha1.Subscription {newSub (namespace , "packageA" , "stable" , catalog )},
2088
+ deps : []* api.Dependency {
2089
+ {
2090
+ Type : "olm.constraint" ,
2091
+ Value : `{"message":"gvk-constraint",
2092
+ "cel":{"rule":"properties.exists(p, p.type == "olm.gvk" && p.value == {"group": "g", 'version': "v", 'kind': "k"})"}}` ,
2093
+ },
2094
+ },
2095
+ catalog : & cache.Snapshot {
2096
+ Entries : []* cache.Entry {
2097
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps , "" , false ),
2098
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides1 , nil , "stable" , false ),
2099
+ },
2100
+ },
2101
+ expected : cache.OperatorSet {
2102
+ "opA.v1.0.0" : genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps , "" , false ),
2103
+ "opB.v1.0.0" : genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides1 , nil , "stable" , false ),
2104
+ },
2105
+ },
2106
+ {
2107
+ // generic constraint for NotSatisfiable gvk dependency
2108
+ isErr : true ,
2109
+ subs : []* v1alpha1.Subscription {
2110
+ subs (namespace , "opA.v1.0.0" , "packageA" , "stable" , catalog ),
2111
+ },
2112
+ deps : []* api.Dependency {
2113
+ {
2114
+ Type : "olm.constraint" ,
2115
+ Value : `{"message":"gvk2-constraint",
2116
+ "cel":{"rule":"properties.exists(p, p.type == "olm.gvk" && p.value == {"group": "g2", 'version': "v", 'kind': "k"})"}}` ,
2117
+ },
2118
+ },
2119
+ catalog : & cache.Snapshot {
2120
+ Entries : []* cache.Entry {
2121
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "" , false ),
2122
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , Provides2 , nil , "" , false ),
2123
+ },
2124
+ },
2125
+ // unable to find satisfiable gvk dependency
2126
+ // resolve into nothing
2127
+ expected : cache.OperatorSet {},
2128
+ },
2129
+ {
2130
+ // generic constraint for package constraint
2131
+ isErr : false ,
2132
+ subs : []* v1alpha1.Subscription {
2133
+ subs (namespace , "opA.v1.0.0" , "packageA" , "stable" , catalog ),
2134
+ },
2135
+ deps : []* api.Dependency {
2136
+ {
2137
+ Type : "olm.constraint" ,
2138
+ Value : `{"message":"compound-constraint",
2139
+ "cel":{"rule":"properties.exists(p, p.type == "olm.package" && (semver_compare(p.value, 1.0.1) == 0))"}}` ,
2140
+ },
2141
+ },
2142
+ catalog : & cache.Snapshot {
2143
+ Entries : []* cache.Entry {
2144
+ genOperator ("opA.v1.0.0" , "1.0.0" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps , "" , false ),
2145
+ genOperator ("opB.v1.0.0" , "1.0.0" , "" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "" , false ),
2146
+ genOperator ("opB.v1.0.1" , "1.0.1" , "opB.v1.0.0" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "stable" , false ),
2147
+ genOperator ("opB.v1.0.2" , "1.0.2" , "opB.v1.0.1" , "packageB" , "stable" , catalog .Name , catalog .Namespace , nil , nil , nil , "stable" , false ),
2148
+ },
2149
+ },
2150
+ expected : cache.OperatorSet {
2151
+ "opA.v1.0.0" : genOperator ("opA.v1.0.1" , "1.0.1" , "" , "packageA" , "stable" , catalog .Name , catalog .Namespace , nil , nil , deps , "" , false ),
2152
+ "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 ),
2153
+ },
2154
+ },
2155
+ }
2156
+
2157
+ var operators cache.OperatorSet
2158
+ for i , p := range phases {
2159
+ t .Run (fmt .Sprintf ("phase %d" , i + 1 ), func (t * testing.T ) {
2160
+ satResolver := SatResolver {
2161
+ cache : cache .New (cache.StaticSourceProvider {
2162
+ catalog : p .catalog ,
2163
+ }),
2164
+ log : logrus .New (),
2165
+ }
2166
+ csvs := make ([]* v1alpha1.ClusterServiceVersion , 0 )
2167
+ for _ , o := range operators {
2168
+ var pkg , channel string
2169
+ if si := o .SourceInfo ; si != nil {
2170
+ pkg = si .Package
2171
+ channel = si .Channel
2172
+ }
2173
+ csvs = append (csvs , existingOperator (namespace , o .Name , pkg , channel , o .Replaces , o .ProvidedAPIs , o .RequiredAPIs , nil , nil ))
2174
+ }
2175
+
2176
+ var err error
2177
+ operators , err = satResolver .SolveOperators ([]string {"olm" }, csvs , p .subs )
2178
+ assert .NoError (t , err )
2179
+ for k := range p .expected {
2180
+ require .NotNil (t , operators [k ])
2181
+ assert .EqualValues (t , k , operators [k ].Name )
2182
+ }
2183
+ assert .Equal (t , len (p .expected ), len (operators ))
2184
+ })
2185
+ }
2186
+ }
0 commit comments