@@ -2046,54 +2046,224 @@ func TestGetPodMarketType(t *testing.T) {
2046
2046
}
2047
2047
}
2048
2048
2049
- func TestAddDefaultRayNodeLabels_GKESpot (t * testing.T ) {
2050
- pod := & corev1.Pod {
2051
- ObjectMeta : metav1.ObjectMeta {
2052
- Labels : map [string ]string {
2053
- "ray.io/group" : "test-worker-group-1" ,
2054
- "topology.kubernetes.io/region" : "us-central2" ,
2055
- "topology.kubernetes.io/zone" : "us-central2-b" ,
2049
+ func TestAddDefaultRayNodeLabels (t * testing.T ) {
2050
+ tests := []struct {
2051
+ labels map [string ]string
2052
+ nodeSelector map [string ]string
2053
+ nodeAffinity * corev1.NodeAffinity
2054
+ expectedEnv map [string ]string
2055
+ name string
2056
+ }{
2057
+ {
2058
+ name : "Availability zone vars set from region and zone topology labels" ,
2059
+ labels : map [string ]string {
2060
+ utils .K8sTopologyRegionLabel : "us-west4" ,
2061
+ utils .K8sTopologyZoneLabel : "us-west4-a" ,
2062
+ },
2063
+ expectedEnv : map [string ]string {
2064
+ utils .RayNodeRegion : "us-west4" ,
2065
+ utils .RayNodeZone : "us-west4-a" ,
2056
2066
},
2057
2067
},
2058
- Spec : corev1.PodSpec {
2059
- Containers : []corev1.Container {
2060
- {Name : "ray" },
2068
+ {
2069
+ name : "Availability zone vars set from region and zone topology nodeSelectors" ,
2070
+ nodeSelector : map [string ]string {
2071
+ utils .K8sTopologyRegionLabel : "us-central2" ,
2072
+ utils .K8sTopologyZoneLabel : "us-central2-b" ,
2061
2073
},
2062
- NodeSelector : map [string ]string {
2063
- "cloud.google.com/gke-spot" : "true" ,
2074
+ expectedEnv : map [string ]string {
2075
+ utils .RayNodeRegion : "us-central2" ,
2076
+ utils .RayNodeZone : "us-central2-b" ,
2077
+ },
2078
+ },
2079
+ {
2080
+ name : "Availability zone vars set from downward API" ,
2081
+ expectedEnv : map [string ]string {
2082
+ utils .RayNodeRegion : "metadata.labels['topology.kubernetes.io/region']" ,
2083
+ utils .RayNodeZone : "metadata.labels['topology.kubernetes.io/zone']" ,
2084
+ },
2085
+ },
2086
+ {
2087
+ name : "Market type env var set from GKE Spot nodeSelector" ,
2088
+ nodeSelector : map [string ]string {
2089
+ utils .GKESpotLabel : "true" ,
2090
+ utils .K8sTopologyRegionLabel : "me-central1" ,
2091
+ utils .K8sTopologyZoneLabel : "me-central1-a" ,
2092
+ },
2093
+ expectedEnv : map [string ]string {
2094
+ utils .RayNodeMarketType : string (utils .SpotMarketType ),
2095
+ utils .RayNodeRegion : "me-central1" ,
2096
+ utils .RayNodeZone : "me-central1-a" ,
2097
+ },
2098
+ },
2099
+ {
2100
+ name : "Market type env var set from EKS Spot nodeSelector" ,
2101
+ nodeSelector : map [string ]string {
2102
+ utils .EKSCapacityTypeLabel : "SPOT" ,
2103
+ utils .K8sTopologyRegionLabel : "us-central1" ,
2104
+ utils .K8sTopologyZoneLabel : "us-central1-c" ,
2105
+ },
2106
+ expectedEnv : map [string ]string {
2107
+ utils .RayNodeMarketType : string (utils .SpotMarketType ),
2108
+ utils .RayNodeRegion : "us-central1" ,
2109
+ utils .RayNodeZone : "us-central1-c" ,
2110
+ },
2111
+ },
2112
+ {
2113
+ name : "Market type env var set from nodeAffinity" ,
2114
+ nodeAffinity : & corev1.NodeAffinity {
2115
+ RequiredDuringSchedulingIgnoredDuringExecution : & corev1.NodeSelector {
2116
+ NodeSelectorTerms : []corev1.NodeSelectorTerm {
2117
+ {
2118
+ MatchExpressions : []corev1.NodeSelectorRequirement {
2119
+ {
2120
+ Key : utils .EKSCapacityTypeLabel ,
2121
+ Operator : corev1 .NodeSelectorOpIn ,
2122
+ Values : []string {"SPOT" },
2123
+ },
2124
+ },
2125
+ },
2126
+ },
2127
+ },
2128
+ },
2129
+ expectedEnv : map [string ]string {
2130
+ utils .RayNodeMarketType : string (utils .SpotMarketType ),
2131
+ utils .RayNodeRegion : "metadata.labels['topology.kubernetes.io/region']" ,
2132
+ utils .RayNodeZone : "metadata.labels['topology.kubernetes.io/zone']" ,
2064
2133
},
2065
2134
},
2066
2135
}
2067
2136
2068
- addDefaultRayNodeLabels (pod )
2069
- rayContainer := pod .Spec .Containers [utils .RayContainerIndex ]
2070
- checkContainerEnv (t , rayContainer , "RAY_NODE_MARKET_TYPE" , "spot" )
2071
- checkContainerEnv (t , rayContainer , "RAY_NODE_REGION" , "metadata.labels['topology.kubernetes.io/region']" )
2072
- checkContainerEnv (t , rayContainer , "RAY_NODE_ZONE" , "metadata.labels['topology.kubernetes.io/zone']" )
2137
+ for _ , tt := range tests {
2138
+ t .Run (tt .name , func (t * testing.T ) {
2139
+ pod := & corev1.Pod {
2140
+ ObjectMeta : metav1.ObjectMeta {
2141
+ Labels : tt .labels ,
2142
+ },
2143
+ Spec : corev1.PodSpec {
2144
+ Containers : []corev1.Container {{Name : "ray" }},
2145
+ NodeSelector : tt .nodeSelector ,
2146
+ },
2147
+ }
2148
+ if tt .nodeAffinity != nil {
2149
+ pod .Spec .Affinity = & corev1.Affinity {NodeAffinity : tt .nodeAffinity }
2150
+ }
2151
+ // validate default labels are set correctly from Pod spec as env vars
2152
+ addDefaultRayNodeLabels (pod )
2153
+ rayContainer := pod .Spec .Containers [utils .RayContainerIndex ]
2154
+ for key , expectedVar := range tt .expectedEnv {
2155
+ foundVar := false
2156
+ for _ , env := range rayContainer .Env {
2157
+ if env .Name == key {
2158
+ if env .Value != "" {
2159
+ if env .Value != expectedVar {
2160
+ t .Errorf ("%s: got value %q, but expected %q" , key , env .Value , expectedVar )
2161
+ }
2162
+ } else if env .ValueFrom != nil && env .ValueFrom .FieldRef != nil {
2163
+ if env .ValueFrom .FieldRef .FieldPath != expectedVar {
2164
+ t .Errorf ("%s: got FieldPath %q, but expected %q" , key , env .ValueFrom .FieldRef .FieldPath , expectedVar )
2165
+ }
2166
+ } else {
2167
+ t .Errorf ("%s: environment var not set as expected" , key )
2168
+ }
2169
+ foundVar = true
2170
+ break
2171
+ }
2172
+ }
2173
+ if ! foundVar {
2174
+ t .Errorf ("%s: not found in container env" , key )
2175
+ }
2176
+ }
2177
+ })
2178
+ }
2073
2179
}
2074
2180
2075
- func TestAddDefaultRayNodeLabels_EKSSpot (t * testing.T ) {
2076
- pod := & corev1.Pod {
2077
- ObjectMeta : metav1.ObjectMeta {
2078
- Labels : map [string ]string {
2079
- "ray.io/group" : "test-worker-group-2" ,
2080
- "topology.kubernetes.io/region" : "us-west4" ,
2081
- "topology.kubernetes.io/zone" : "us-west4-a" ,
2082
- },
2181
+ func TestGetPodZoneEnvVar (t * testing.T ) {
2182
+ tests := []struct {
2183
+ name string
2184
+ labels map [string ]string
2185
+ nodeSelector map [string ]string
2186
+ expectedVar string
2187
+ }{
2188
+ {
2189
+ name : "Retrieve topology zone from labels" ,
2190
+ labels : map [string ]string {utils .K8sTopologyZoneLabel : "us-west4-a" },
2191
+ expectedVar : "us-west4-a" ,
2083
2192
},
2084
- Spec : corev1.PodSpec {
2085
- Containers : []corev1.Container {
2086
- {Name : "ray" },
2087
- },
2088
- NodeSelector : map [string ]string {
2089
- "eks.amazonaws.com/capacityType" : "SPOT" ,
2090
- },
2193
+ {
2194
+ name : "Retrieve topology zone from nodeSelector" ,
2195
+ nodeSelector : map [string ]string {utils .K8sTopologyZoneLabel : "us-central2-b" },
2196
+ expectedVar : "us-central2-b" ,
2091
2197
},
2198
+ {
2199
+ name : "Zone set using downward API" ,
2200
+ expectedVar : "metadata.labels['topology.kubernetes.io/zone']" ,
2201
+ },
2202
+ }
2203
+ for _ , tt := range tests {
2204
+ t .Run (tt .name , func (t * testing.T ) {
2205
+ pod := & corev1.Pod {
2206
+ ObjectMeta : metav1.ObjectMeta {Labels : tt .labels },
2207
+ Spec : corev1.PodSpec {NodeSelector : tt .nodeSelector },
2208
+ }
2209
+ // validate expected zone env var is parsed from Pod spec
2210
+ result := getPodZoneEnvVar (pod )
2211
+ if result .Value != "" {
2212
+ if result .Value != tt .expectedVar {
2213
+ t .Errorf ("got env var %q, but expected %q" , result .Value , tt .expectedVar )
2214
+ }
2215
+ } else if result .ValueFrom != nil {
2216
+ if result .ValueFrom .FieldRef .FieldPath != tt .expectedVar {
2217
+ t .Errorf ("got FieldPath %q, but expected %q" , result .ValueFrom .FieldRef .FieldPath , tt .expectedVar )
2218
+ }
2219
+ } else {
2220
+ t .Errorf ("getPodZoneEnvVar did not return expected env value" )
2221
+ }
2222
+ })
2092
2223
}
2224
+ }
2093
2225
2094
- addDefaultRayNodeLabels (pod )
2095
- rayContainer := pod .Spec .Containers [utils .RayContainerIndex ]
2096
- checkContainerEnv (t , rayContainer , utils .RayNodeMarketType , "spot" )
2097
- checkContainerEnv (t , rayContainer , utils .RayNodeRegion , "metadata.labels['topology.kubernetes.io/region']" )
2098
- checkContainerEnv (t , rayContainer , utils .RayNodeZone , "metadata.labels['topology.kubernetes.io/zone']" )
2226
+ func TestGetPodRegionEnvVar (t * testing.T ) {
2227
+ tests := []struct {
2228
+ name string
2229
+ labels map [string ]string
2230
+ nodeSelector map [string ]string
2231
+ expectedVar string
2232
+ }{
2233
+ {
2234
+ name : "Retrieve topology region from labels" ,
2235
+ labels : map [string ]string {utils .K8sTopologyRegionLabel : "us-central1" },
2236
+ expectedVar : "us-central1" ,
2237
+ },
2238
+ {
2239
+ name : "Retrieve topology region from nodeSelector" ,
2240
+ nodeSelector : map [string ]string {utils .K8sTopologyRegionLabel : "us-central2" },
2241
+ expectedVar : "us-central2" ,
2242
+ },
2243
+ {
2244
+ name : "Region set using downward API" ,
2245
+ expectedVar : "metadata.labels['topology.kubernetes.io/region']" ,
2246
+ },
2247
+ }
2248
+ for _ , tt := range tests {
2249
+ t .Run (tt .name , func (t * testing.T ) {
2250
+ pod := & corev1.Pod {
2251
+ ObjectMeta : metav1.ObjectMeta {Labels : tt .labels },
2252
+ Spec : corev1.PodSpec {NodeSelector : tt .nodeSelector },
2253
+ }
2254
+ // validate expected region env var is parsed from Pod spec
2255
+ result := getPodRegionEnvVar (pod )
2256
+ if result .Value != "" {
2257
+ if result .Value != tt .expectedVar {
2258
+ t .Errorf ("got env var %q, but expected %q" , result .Value , tt .expectedVar )
2259
+ }
2260
+ } else if result .ValueFrom != nil {
2261
+ if result .ValueFrom .FieldRef .FieldPath != tt .expectedVar {
2262
+ t .Errorf ("got FieldPath %q, but expected %q" , result .ValueFrom .FieldRef .FieldPath , tt .expectedVar )
2263
+ }
2264
+ } else {
2265
+ t .Errorf ("getPodRegionEnvVar did not return expected env value" )
2266
+ }
2267
+ })
2268
+ }
2099
2269
}
0 commit comments