@@ -7,12 +7,14 @@ import (
7
7
"sort"
8
8
"testing"
9
9
10
+ "github.com/hashicorp/nomad/ci"
10
11
"github.com/hashicorp/nomad/client/lib/idset"
11
12
"github.com/hashicorp/nomad/client/lib/numalib"
12
13
"github.com/hashicorp/nomad/client/lib/numalib/hw"
13
14
"github.com/hashicorp/nomad/helper/uuid"
14
15
"github.com/hashicorp/nomad/nomad/mock"
15
16
"github.com/hashicorp/nomad/nomad/structs"
17
+ "github.com/shoenig/test"
16
18
"github.com/shoenig/test/must"
17
19
"github.com/stretchr/testify/require"
18
20
)
@@ -2261,18 +2263,29 @@ func TestScoreNormalizationIterator(t *testing.T) {
2261
2263
}
2262
2264
2263
2265
func TestNodeAffinityIterator (t * testing.T ) {
2266
+ ci .Parallel (t )
2264
2267
_ , ctx := testContext (t )
2265
- nodes := []* RankedNode {
2266
- {Node : mock .Node ()},
2267
- {Node : mock .Node ()},
2268
- {Node : mock .Node ()},
2269
- {Node : mock .Node ()},
2270
- }
2271
2268
2272
- nodes [0 ].Node .Attributes ["kernel.version" ] = "4.9"
2273
- nodes [1 ].Node .Datacenter = "dc2"
2274
- nodes [2 ].Node .Datacenter = "dc2"
2275
- nodes [2 ].Node .NodeClass = "large"
2269
+ testNodes := func () []* RankedNode {
2270
+ nodes := []* RankedNode {
2271
+ {Node : mock .Node ()},
2272
+ {Node : mock .Node ()},
2273
+ {Node : mock .Node ()},
2274
+ {Node : mock .Node ()},
2275
+ {Node : mock .Node ()},
2276
+ }
2277
+
2278
+ nodes [0 ].Node .Attributes ["kernel.version" ] = "4.9"
2279
+ nodes [1 ].Node .Datacenter = "dc2"
2280
+ nodes [2 ].Node .Datacenter = "dc2"
2281
+ nodes [2 ].Node .NodeClass = "large"
2282
+
2283
+ // this node should have zero affinity
2284
+ nodes [4 ].Node .Attributes ["kernel.version" ] = "2.6"
2285
+ nodes [4 ].Node .Datacenter = "dc3"
2286
+ nodes [4 ].Node .NodeClass = "weird"
2287
+ return nodes
2288
+ }
2276
2289
2277
2290
affinities := []* structs.Affinity {
2278
2291
{
@@ -2300,37 +2313,80 @@ func TestNodeAffinityIterator(t *testing.T) {
2300
2313
Weight : 50 ,
2301
2314
},
2302
2315
}
2303
-
2304
- static := NewStaticRankIterator (ctx , nodes )
2305
-
2306
2316
job := mock .Job ()
2307
2317
job .ID = "foo"
2308
2318
tg := job .TaskGroups [0 ]
2309
2319
tg .Affinities = affinities
2310
2320
2311
- nodeAffinity := NewNodeAffinityIterator ( ctx , static )
2312
- nodeAffinity . SetTaskGroup ( tg )
2321
+ t . Run ( "affinity alone" , func ( t * testing. T ) {
2322
+ static := NewStaticRankIterator ( ctx , testNodes () )
2313
2323
2314
- scoreNorm := NewScoreNormalizationIterator (ctx , nodeAffinity )
2324
+ nodeAffinity := NewNodeAffinityIterator (ctx , static )
2325
+ nodeAffinity .SetTaskGroup (tg )
2315
2326
2316
- out := collectRanked (scoreNorm )
2317
- expectedScores := make (map [string ]float64 )
2318
- // Total weight = 300
2319
- // Node 0 matches two affinities(dc and kernel version), total weight = 150
2320
- expectedScores [nodes [0 ].Node .ID ] = 0.5
2327
+ scoreNorm := NewScoreNormalizationIterator (ctx , nodeAffinity )
2328
+ out := collectRanked (scoreNorm )
2321
2329
2322
- // Node 1 matches an anti affinity, weight = -100
2323
- expectedScores [nodes [1 ].Node .ID ] = - (1.0 / 3.0 )
2330
+ // Total weight = 300
2331
+ // Node 0 matches two affinities(dc and kernel version), total weight = 150
2332
+ test .Eq (t , 0.5 , out [0 ].FinalScore )
2324
2333
2325
- // Node 2 matches one affinity(node class) with weight 50
2326
- expectedScores [ nodes [ 2 ]. Node . ID ] = - (1.0 / 6.0 )
2334
+ // Node 1 matches an anti affinity, weight = -100
2335
+ test . Eq ( t , - (1.0 / 3.0 ), out [ 1 ]. FinalScore )
2327
2336
2328
- // Node 3 matches one affinity (dc ) with weight = 100
2329
- expectedScores [ nodes [ 3 ]. Node . ID ] = 1.0 / 3.0
2337
+ // Node 2 matches one affinity(node class ) with weight 50
2338
+ test . Eq ( t , - ( 1.0 / 6.0 ), out [ 2 ]. FinalScore )
2330
2339
2331
- require := require .New (t )
2332
- for _ , n := range out {
2333
- require .Equal (expectedScores [n .Node .ID ], n .FinalScore )
2334
- }
2340
+ // Node 3 matches one affinity (dc) with weight = 100
2341
+ test .Eq (t , 1.0 / 3.0 , out [3 ].FinalScore )
2342
+
2343
+ // Node 4 matches no affinities but should still generate a score
2344
+ test .Eq (t , 0 , out [4 ].FinalScore )
2345
+ test .Len (t , 1 , out [4 ].Scores )
2346
+ })
2347
+
2348
+ t .Run ("affinity with binpack" , func (t * testing.T ) {
2349
+ nodes := testNodes ()
2350
+ static := NewStaticRankIterator (ctx , nodes )
2351
+
2352
+ // include a binpack iterator so we can see the impact on including zero
2353
+ // values in final scores. The nodes are all empty so score contribution
2354
+ // from binpacking will be identical
2355
+
2356
+ binp := NewBinPackIterator (ctx , static , false , 0 )
2357
+ binp .SetTaskGroup (tg )
2358
+ fit := structs .ScoreFitBinPack (nodes [0 ].Node , & structs.ComparableResources {
2359
+ Flattened : structs.AllocatedTaskResources {
2360
+ Cpu : structs.AllocatedCpuResources {CpuShares : 500 },
2361
+ Memory : structs.AllocatedMemoryResources {MemoryMB : 256 },
2362
+ },
2363
+ })
2364
+ bp := fit / binPackingMaxFitScore
2365
+
2366
+ nodeAffinity := NewNodeAffinityIterator (ctx , binp )
2367
+ nodeAffinity .SetTaskGroup (tg )
2368
+
2369
+ scoreNorm := NewScoreNormalizationIterator (ctx , nodeAffinity )
2370
+ out := collectRanked (scoreNorm )
2371
+
2372
+ // Total weight = 300
2373
+ // Node 0 matches two affinities(dc and kernel version), total weight = 150
2374
+ test .Eq (t , (0.5 + bp )/ 2 , out [0 ].FinalScore )
2375
+
2376
+ // Node 1 matches an anti affinity, weight = -100
2377
+ test .Eq (t , (- (1.0 / 3.0 )+ bp )/ 2 , out [1 ].FinalScore )
2378
+
2379
+ // Node 2 matches one affinity(node class) with weight 50
2380
+ test .Eq (t , (- (1.0 / 6.0 )+ bp )/ 2 , out [2 ].FinalScore )
2381
+
2382
+ // Node 3 matches one affinity (dc) with weight = 100
2383
+ test .Eq (t , ((1.0 / 3.0 )+ bp )/ 2 , out [3 ].FinalScore )
2335
2384
2385
+ // Node 4 matches no affinities but should still generate a score and
2386
+ // the final score should be lower than any positive score
2387
+ test .Eq (t , (0 + bp )/ 2 , out [4 ].FinalScore )
2388
+ test .Len (t , 2 , out [4 ].Scores )
2389
+ test .Less (t , out [0 ].FinalScore , out [4 ].FinalScore )
2390
+ test .Less (t , out [3 ].FinalScore , out [4 ].FinalScore )
2391
+ })
2336
2392
}
0 commit comments