@@ -8,24 +8,27 @@ import (
88 "io"
99 "log"
1010 "reflect"
11+ "strings"
1112 "testing"
1213 "time"
1314
15+ "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/deschedule"
16+ "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/dontschedule"
17+ "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/labeling"
18+ "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/scheduleonmetric"
19+ "k8s.io/apimachinery/pkg/util/rand"
20+
1421 "k8s.io/klog/v2"
1522
1623 "github.com/pkg/errors"
1724
1825 "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/metrics"
19- "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/deschedule"
20- "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/dontschedule"
21- "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/scheduleonmetric"
2226 api "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/telemetrypolicy/api/v1alpha1"
2327 tasclient "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/telemetrypolicy/client/v1alpha1"
2428 v1 "k8s.io/api/core/v1"
2529 "k8s.io/apimachinery/pkg/api/resource"
2630 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2731 "k8s.io/apimachinery/pkg/labels"
28- "k8s.io/apimachinery/pkg/util/rand"
2932 "k8s.io/client-go/kubernetes"
3033 "k8s.io/client-go/tools/clientcmd"
3134 "k8s.io/client-go/util/homedir"
@@ -79,10 +82,19 @@ func init() {
7982}
8083
8184var (
82- prioritize1Policy = getTASPolicy ("prioritize1" , scheduleonmetric .StrategyType , "prioritize1_metric" , "GreaterThan" , 0 )
83- filter1Policy = getTASPolicy ("filter1" , dontschedule .StrategyType , "filter1_metric" , "LessThan" , 20 )
84- filter2Policy = getTASPolicy ("filter2" , dontschedule .StrategyType , "filter2_metric" , "Equals" , 0 )
85- deschedule1Policy = getTASPolicy ("deschedule1" , deschedule .StrategyType , "deschedule1_metric" , "GreaterThan" , 8 )
85+ prioritize1Policy = getTASPolicy ("prioritize1" , scheduleonmetric .StrategyType , []api.TASPolicyRule {{Metricname : "prioritize1_metric" , Operator : "GreaterThan" , Labels : []string {}}})
86+ filter1Policy = getTASPolicy ("filter1" , dontschedule .StrategyType , []api.TASPolicyRule {{Metricname : "filter1_metric" , Operator : "LessThan" , Target : 20 , Labels : []string {}}})
87+ filter2Policy = getTASPolicy ("filter2" , dontschedule .StrategyType , []api.TASPolicyRule {{Metricname : "filter2_metric" , Operator : "Equals" , Labels : []string {}}})
88+ deschedule1Policy = getTASPolicy ("deschedule1" , deschedule .StrategyType , []api.TASPolicyRule {{Metricname : "deschedule1_metric" , Operator : "GreaterThan" , Target : 8 , Labels : []string {}}})
89+ labeling1Policy = getTASPolicy ("labeling1" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling1_metric" , Operator : "LessThan" , Target : 8 , Labels : []string {"card0=true" }}})
90+ labeling2Policy = getTASPolicy ("labeling2" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling2_metric" , Operator : "LessThan" , Target : 8 , Labels : []string {"card1=true" }}})
91+ labeling3Policy = getTASPolicy ("labeling3" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling2_metric" , Operator : "Equals" , Target : 71 , Labels : []string {"card0=false" }}})
92+ labeling4Policy = getTASPolicy ("labeling4" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling2_metric" , Operator : "Equals" , Target : 10 , Labels : []string {"card1=true" }}})
93+ labeling5Policy = getTASPolicy ("labeling5" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling1_metric" , Operator : "GreaterThan" , Target : 8 , Labels : []string {"card0=true" }}, {Metricname : "labeling2_metric" , Operator : "Equals" , Target : - 10 , Labels : []string {"card1=true" }}})
94+ labeling6Policy = getTASPolicy ("labeling6" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling2_metric" , Operator : "GreaterThan" , Target : - 12 , Labels : []string {"card1=true" }}})
95+ labeling7Policy = getTASPolicy ("labeling7" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling2_metric" , Operator : "GreaterThan" , Target : 70 , Labels : []string {"card0=false" , "card1=true" }}})
96+ labeling8Policy = getTASPolicy ("labeling8" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling1_metric" , Operator : "LessThan" , Target : 8 , Labels : []string {"foo=1" }}, {Metricname : "labeling2_metric" , Operator : "LessThan" , Target : 8 , Labels : []string {"foo=2" }}})
97+ labeling9Policy = getTASPolicy ("labeling9" , labeling .StrategyType , []api.TASPolicyRule {{Metricname : "labeling1_metric" , Operator : "GreaterThan" , Target : 8 , Labels : []string {"foo=1" }}, {Metricname : "labeling2_metric" , Operator : "GreaterThan" , Target : 8 , Labels : []string {"foo=2" }}})
8698)
8799
88100// TestTASFilter will test the behaviour of a pod with a listed filter/dontschedule policy in TAS
@@ -199,6 +211,77 @@ func TestTASDeschedule(t *testing.T) {
199211 }
200212}
201213
214+ // TestTASLabeling will test the behaviour of a pod with a listed labling policy in TAS
215+ func TestTASLabeling (t * testing.T ) {
216+ const lbPrefix = "telemetry.aware.scheduling."
217+ // var nodeLabel string
218+ tests := map [string ]struct {
219+ policy * api.TASPolicy
220+ want map [string ]string
221+ }{
222+ "No label node for labeling" : {policy : labeling1Policy , want : map [string ]string {}},
223+ "Single Label on node worker" : {policy : labeling2Policy , want : map [string ]string {"kind-worker" : "true" }},
224+ "Single Label on node worker2" : {policy : labeling3Policy , want : map [string ]string {"kind-worker2" : "true" }},
225+ "Single Label on node worker3" : {policy : labeling4Policy , want : map [string ]string {"kind-worker3" : "true" }},
226+ "Labels on two nodes" : {policy : labeling5Policy , want : map [string ]string {"kind-worker" : "true" , "kind-worker2" : "true" }},
227+ "Labels on three nodes" : {policy : labeling6Policy , want : map [string ]string {"kind-worker" : "true" , "kind-worker2" : "true" , "kind-worker3" : "true" }},
228+ "Double label on node worker2" : {policy : labeling7Policy , want : map [string ]string {"kind-worker2" : "true" }},
229+ "Single same label on node worker" : {policy : labeling8Policy , want : map [string ]string {"kind-worker" : "true" }},
230+ "Single same label on all node worker" : {policy : labeling9Policy , want : map [string ]string {"kind-worker" : "true" , "kind-worker2" : "true" , "kind-worker3" : "true" }},
231+ }
232+ for name , tc := range tests {
233+ var violNodeLabel = []string {}
234+ t .Run (name , func (t * testing.T ) {
235+ res := map [string ]string {}
236+ log .Printf ("Running: %v\n " , name )
237+ //defer the running of a cleanup function to remove the policy and pod after the test case
238+ defer cleanup ("" , tc .policy .Name )
239+ _ , err := tascl .Create (tc .policy )
240+ if err != nil {
241+ log .Print (err )
242+ }
243+ time .Sleep (time .Second * 10 )
244+ log .Printf ("policy strategy rules: %v" , tc .policy .Spec .Strategies )
245+ for _ , str_rule := range tc .policy .Spec .Strategies {
246+ for _ , rule := range str_rule .Rules {
247+ for _ , lb := range rule .Labels {
248+ nameValuePair := strings .Split (lb , "=" )
249+ if len (nameValuePair ) != 2 {
250+ log .Fatal (errors .New ("Invalid label, parsing failed for: " + lb ))
251+ }
252+ nodeLabel := lbPrefix + tc .policy .Name + "/" + nameValuePair [0 ] + ":" + nameValuePair [1 ]
253+ violNodeLabel = append (violNodeLabel , nodeLabel )
254+ }
255+ }
256+ }
257+ for _ , violabel := range violNodeLabel {
258+ key , value := getKeyValue (violabel )
259+ lbls := metav1.LabelSelector {MatchLabels : map [string ]string {key : value }}
260+ nodes , err := cl .CoreV1 ().Nodes ().List (context .TODO (), metav1.ListOptions {LabelSelector : labels .Set (lbls .MatchLabels ).String ()})
261+ if err != nil {
262+ log .Print (err )
263+ }
264+ for _ , n := range nodes .Items {
265+ res [n .Name ] = "true"
266+ }
267+ }
268+ if ! reflect .DeepEqual (tc .want , res ) {
269+ //Log full node specs and TAS Pod log if the test fails
270+ nodes , _ := cl .CoreV1 ().Nodes ().List (context .TODO (), metav1.ListOptions {})
271+ log .Print (tasLog ())
272+ for _ , n := range nodes .Items {
273+ log .Printf ("%v labels: %v" , n .Name , n .ObjectMeta .Labels )
274+ }
275+ t .Errorf ("expected: %v, got: %v" , tc .want , res )
276+ }
277+ })
278+ }
279+ }
280+
281+ func getKeyValue (nodeLabel string ) (key , value string ) {
282+ return strings .Split (nodeLabel , ":" )[0 ], strings .Split (nodeLabel , ":" )[1 ]
283+ }
284+
202285//TestAddAndDeletePolicy repeats a test to show an issue in repeatedly adding and deleting policies
203286func TestAddAndDeletePolicy (t * testing.T ) {
204287 repeatTest (TestTASFilter , t , 5 )
@@ -245,10 +328,10 @@ func waitForMetrics(timeout time.Duration) error {
245328 for time .Now ().Before (t ) {
246329 m , err := cm .GetNodeMetric ("filter1_metric" )
247330 if len (m ) > 0 {
248- log .Printf ("Metrics returned after %v: %v" , t . Sub ( time .Now () ), m )
331+ log .Printf ("Metrics returned after %v: %v" , time .Until ( t ), m )
249332 return nil
250333 }
251- time .Sleep (2 )
334+ time .Sleep (time . Second * 2 )
252335 failureMessage = err
253336 }
254337 return errors .Wrap (failureMessage , "Request for custom metrics has timed out." )
@@ -290,7 +373,7 @@ func tasLog() string {
290373
291374}
292375
293- func getTASPolicy (name string , str string , metric string , operator string , target int64 ) * api.TASPolicy {
376+ func getTASPolicy (name string , str string , metricRule []api. TASPolicyRule ) * api.TASPolicy {
294377 pol := & api.TASPolicy {
295378 TypeMeta : metav1.TypeMeta {},
296379 ObjectMeta : metav1.ObjectMeta {Name : name , Namespace : "default" },
@@ -300,9 +383,7 @@ func getTASPolicy(name string, str string, metric string, operator string, targe
300383 //TODO: This should be considered a bug.
301384 str : {
302385 PolicyName : name ,
303- Rules : []api.TASPolicyRule {
304- {Metricname : metric , Operator : operator , Target : target },
305- },
386+ Rules : metricRule ,
306387 },
307388 },
308389 },
0 commit comments