This is an automated email from the ASF dual-hosted git repository.

mani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 0df1d599 [YUNIKORN-2273] checkLimitMaxApplications fails if there is 
missing limit in a middle queue (#760)
0df1d599 is described below

commit 0df1d599aed6b8797d3ce4575fafa41be9bad6d9
Author: PoAn Yang <[email protected]>
AuthorDate: Thu Jan 18 10:48:46 2024 +0530

    [YUNIKORN-2273] checkLimitMaxApplications fails if there is missing limit 
in a middle queue (#760)
    
    Closes: #760
    
    Signed-off-by: Manikandan R <[email protected]>
---
 pkg/common/configs/configvalidator.go      |  88 +++++----
 pkg/common/configs/configvalidator_test.go | 275 +++++++++++++++++++++++++++--
 2 files changed, 303 insertions(+), 60 deletions(-)

diff --git a/pkg/common/configs/configvalidator.go 
b/pkg/common/configs/configvalidator.go
index 5e7a45b0..13de4fe4 100644
--- a/pkg/common/configs/configvalidator.go
+++ b/pkg/common/configs/configvalidator.go
@@ -171,7 +171,6 @@ func checkLimitResource(cur QueueConfig, users 
map[string]map[string]*resources.
                                if 
!userMaxResource.FitInMaxUndef(limitMaxResources) {
                                        return fmt.Errorf("user %s max resource 
%s of queue %s is greater than immediate or ancestor parent maximum resource 
%s", user, limitMaxResources.String(), cur.Name, userMaxResource.String())
                                }
-                               // Override with min resource
                                users[curQueuePath][user] = 
resources.ComponentWiseMinPermissive(limitMaxResources, userMaxResource)
                        } else if wildcardMaxResource, ok := 
users[queuePath][common.Wildcard]; user != common.Wildcard && ok {
                                if 
!wildcardMaxResource.FitInMaxUndef(limitMaxResources) {
@@ -236,54 +235,53 @@ func checkLimitMaxApplications(cur QueueConfig, users 
map[string]map[string]uint
                curQueuePath = queuePath + DOT + cur.Name
        }
 
-       // Carry forward (populate) the parent limit settings to the next level 
if limits are not configured for the current queue
-       if len(cur.Limits) == 0 {
-               if _, ok := users[queuePath]; ok {
-                       users[curQueuePath] = users[queuePath]
-               }
-               if _, ok := groups[queuePath]; ok {
-                       groups[curQueuePath] = groups[queuePath]
-               }
-       } else {
-               // compare user & group limit setting between the current queue 
and parent queue
-               for _, limit := range cur.Limits {
-                       limitMaxApplications := limit.MaxApplications
-                       for _, user := range limit.Users {
-                               // Is user limit setting exists?
-                               if userMaxApplications, ok := 
users[queuePath][user]; ok {
-                                       if userMaxApplications != 0 && 
(userMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
-                                               return fmt.Errorf("user %s max 
applications %d of queue %s is greater than immediate or ancestor parent max 
applications %d", user, limitMaxApplications, cur.Name, userMaxApplications)
-                                       }
-                                       // Override with min resource
-                                       if _, ok := users[curQueuePath]; !ok {
-                                               users[curQueuePath] = 
make(map[string]uint64)
-                                       }
-                                       users[curQueuePath][user] = 
common.Min(limitMaxApplications, userMaxApplications)
-                               } else {
-                                       if _, ok := users[curQueuePath]; !ok {
-                                               users[curQueuePath] = 
make(map[string]uint64)
-                                       }
-                                       users[curQueuePath][user] = 
limitMaxApplications
+       users[curQueuePath] = make(map[string]uint64)
+       groups[curQueuePath] = make(map[string]uint64)
+
+       // Carry forward (populate) the parent limit settings to the next level
+       // queuePath is the parent queue path and curQueuePath is the current 
queue path.
+       // For example, queuePath is root and curQueuePath is root.current.
+       for u, maxapplications := range users[queuePath] {
+               users[curQueuePath][u] = maxapplications
+       }
+       for g, maxapplications := range groups[queuePath] {
+               groups[curQueuePath][g] = maxapplications
+       }
+
+       // compare user & group limit setting between the current queue and 
parent queue
+       for _, limit := range cur.Limits {
+               limitMaxApplications := limit.MaxApplications
+               for _, user := range limit.Users {
+                       // Is user limit setting exists?
+                       if userMaxApplications, ok := users[queuePath][user]; 
ok {
+                               if userMaxApplications != 0 && 
(userMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
+                                       return fmt.Errorf("user %s max 
applications %d of queue %s is greater than immediate or ancestor parent max 
applications %d", user, limitMaxApplications, cur.Name, userMaxApplications)
                                }
+                               users[curQueuePath][user] = limitMaxApplications
+                       } else if wildcardMaxApplications, ok := 
users[queuePath][common.Wildcard]; user != common.Wildcard && ok {
+                               if wildcardMaxApplications != 0 && 
(wildcardMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
+                                       return fmt.Errorf("user %s max 
applications %d of queue %s is greater than wildcard max applications %d of 
immediate or ancestor parent queue", user, limitMaxApplications, cur.Name, 
wildcardMaxApplications)
+                               }
+                               users[curQueuePath][user] = limitMaxApplications
+                       } else {
+                               users[curQueuePath][user] = limitMaxApplications
                        }
+               }
 
-                       for _, group := range limit.Groups {
-                               // Is user limit setting exists?
-                               if groupMaxApplications, ok := 
groups[queuePath][group]; ok {
-                                       if groupMaxApplications != 0 && 
(groupMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
-                                               return fmt.Errorf("group %s max 
applications %d of queue %s is greater than immediate or ancestor parent max 
applications %d", group, limitMaxApplications, cur.Name, groupMaxApplications)
-                                       }
-                                       // Override with min resource
-                                       if _, ok := groups[curQueuePath]; !ok {
-                                               groups[curQueuePath] = 
make(map[string]uint64)
-                                       }
-                                       groups[curQueuePath][group] = 
common.Min(limitMaxApplications, groupMaxApplications)
-                               } else {
-                                       if _, ok := groups[curQueuePath]; !ok {
-                                               groups[curQueuePath] = 
make(map[string]uint64)
-                                       }
-                                       groups[curQueuePath][group] = 
limitMaxApplications
+               for _, group := range limit.Groups {
+                       // Is user limit setting exists?
+                       if groupMaxApplications, ok := 
groups[queuePath][group]; ok {
+                               if groupMaxApplications != 0 && 
(groupMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
+                                       return fmt.Errorf("group %s max 
applications %d of queue %s is greater than immediate or ancestor parent max 
applications %d", group, limitMaxApplications, cur.Name, groupMaxApplications)
                                }
+                               groups[curQueuePath][group] = 
limitMaxApplications
+                       } else if wildcardMaxApplications, ok := 
groups[queuePath][common.Wildcard]; group != common.Wildcard && ok {
+                               if wildcardMaxApplications != 0 && 
(wildcardMaxApplications < limitMaxApplications || limitMaxApplications == 0) {
+                                       return fmt.Errorf("group %s max 
applications %d of queue %s is greater than wildcard max applications %d of 
immediate or ancestor parent queue", group, limitMaxApplications, cur.Name, 
wildcardMaxApplications)
+                               }
+                               groups[curQueuePath][group] = 
limitMaxApplications
+                       } else {
+                               groups[curQueuePath][group] = 
limitMaxApplications
                        }
                }
        }
diff --git a/pkg/common/configs/configvalidator_test.go 
b/pkg/common/configs/configvalidator_test.go
index 8703ab59..99001dff 100644
--- a/pkg/common/configs/configvalidator_test.go
+++ b/pkg/common/configs/configvalidator_test.go
@@ -1194,12 +1194,37 @@ func createLimitMaxApplications(users 
map[string]uint64, groups map[string]uint6
 
 func TestCheckLimitMaxApplications(t *testing.T) { //nolint:funlen
        testCases := []struct {
-               name     string
-               config   QueueConfig
-               hasError bool
+               name   string
+               config QueueConfig
+               errMsg string
        }{
                {
-                       name: "leaf queue user group maxapplications are within 
parent queue user group maxapplications",
+                       name: "leaf queue user group maxapplications are within 
immediate parent queue user group maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"test-user": 100, 
"*": 100},
+                                       map[string]uint64{"test-group": 100, 
"*": 100}),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       
map[string]uint64{"test-user": 100, "test-user2": 100},
+                                                       
map[string]uint64{"test-group": 100, "test-group2": 100}),
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       
map[string]uint64{"test-user": 100, "test-user2": 100},
+                                                                       
map[string]uint64{"test-group": 100, "test-group2": 100}),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+               {
+                       name: "leaf queue user group maxapplications are within 
ancestor parent queue user group maxapplications",
                        config: QueueConfig{
                                Name: "parent",
                                Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
@@ -1207,22 +1232,24 @@ func TestCheckLimitMaxApplications(t *testing.T) { 
//nolint:funlen
                                Queues: []QueueConfig{
                                        {
                                                Name: "child1",
-                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
-                                                       
map[string]uint64{"test-group": 100}),
                                                Queues: []QueueConfig{
                                                        {
-                                                               Name: "child2",
-                                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
-                                                                       
map[string]uint64{"test-group": 100}),
+                                                               Name: "childA",
+                                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 50},
+                                                                       
map[string]uint64{"test-group": 50}),
+                                                       },
+                                                       {
+                                                               Name: "childB",
+                                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 10},
+                                                                       
map[string]uint64{"test-group": 10}),
                                                        },
                                                },
                                        },
                                },
                        },
-                       hasError: false,
                },
                {
-                       name: "leaf queue user maxapplications exceed parent 
queue user maxapplications",
+                       name: "leaf queue user maxapplications exceed immediate 
parent queue user maxapplications",
                        config: QueueConfig{
                                Name: "parent",
                                Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
@@ -1235,7 +1262,7 @@ func TestCheckLimitMaxApplications(t *testing.T) { 
//nolint:funlen
                                        },
                                },
                        },
-                       hasError: true,
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
                },
                {
                        name: "leaf queue group maxapplications exceed parent 
queue group maxapplications",
@@ -1251,15 +1278,233 @@ func TestCheckLimitMaxApplications(t *testing.T) { 
//nolint:funlen
                                        },
                                },
                        },
-                       hasError: true,
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
+               },
+               {
+                       name: "leaf queue user maxapplications are exceed 
grandparent queue user maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
+                                       map[string]uint64{"test-group": 100}),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 150},
+                                                                       
map[string]uint64{"test-group": 50}),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
+               },
+               {
+                       name: "leaf queue group maxapplications are exceed 
grandparent queue group maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 100},
+                                       map[string]uint64{"test-group": 100}),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(map[string]uint64{"test-user": 50},
+                                                                       
map[string]uint64{"test-group": 150}),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
+               },
+               {
+                       name: "leaf queue user maxapplications exceed parent 
queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"test-user1": 100, 
"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       
map[string]uint64{"test-user1": 50, "test-user2": 150},
+                                                       nil),
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than wildcard max applications",
+               },
+               {
+                       name: "leaf queue group maxapplications exceed parent 
queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       nil,
+                                       map[string]uint64{"test-group1": 100, 
"*": 100}),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       nil,
+                                                       
map[string]uint64{"test-group1": 50, "test-group2": 150}),
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than wildcard max applications",
+               },
+               {
+                       name: "leaf queue user maxapplications exceed 
grandparent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"test-user1": 100, 
"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       
map[string]uint64{"test-user1": 50},
+                                                       nil),
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       
map[string]uint64{"test-user1": 10, "test-user2": 150},
+                                                                       nil),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than wildcard max applications",
+               },
+               {
+                       name: "leaf queue group maxapplications exceed 
grandparent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       nil,
+                                       map[string]uint64{"test-group1": 100, 
"*": 100}),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       nil,
+                                                       
map[string]uint64{"test-group1": 50}),
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       nil,
+                                                                       
map[string]uint64{"test-group1": 10, "test-group2": 150}),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than wildcard max applications",
+               },
+               {
+                       name: "leaf queue wildcard maxapplications is within 
immediate parent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       map[string]uint64{"*": 
50},
+                                                       nil),
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       
map[string]uint64{"*": 10},
+                                                                       nil),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+               {
+                       name: "leaf queue wildcard maxapplications is within 
grandparent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       
map[string]uint64{"*": 10},
+                                                                       nil),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+               {
+                       name: "leaf queue wildcard maxapplications exceed 
immediate parent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Limits: 
createLimitMaxApplications(
+                                                       map[string]uint64{"*": 
150},
+                                                       nil),
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
+               },
+               {
+                       name: "leaf queue wildcard maxapplications exceed 
grandparent queue wildcard maxapplications",
+                       config: QueueConfig{
+                               Name: "parent",
+                               Limits: createLimitMaxApplications(
+                                       map[string]uint64{"*": 100},
+                                       nil),
+                               Queues: []QueueConfig{
+                                       {
+                                               Name: "child1",
+                                               Queues: []QueueConfig{
+                                                       {
+                                                               Name: "child2",
+                                                               Limits: 
createLimitMaxApplications(
+                                                                       
map[string]uint64{"*": 150},
+                                                                       nil),
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       errMsg: "is greater than immediate or ancestor parent 
max applications",
                },
        }
 
        for _, testCase := range testCases {
                t.Run(testCase.name, func(t *testing.T) {
                        err := checkLimitMaxApplications(testCase.config, 
make(map[string]map[string]uint64), make(map[string]map[string]uint64), 
common.Empty)
-                       if testCase.hasError {
-                               assert.ErrorContains(t, err, "is greater than 
immediate or ancestor parent max applications")
+                       if testCase.errMsg != "" {
+                               assert.ErrorContains(t, err, testCase.errMsg)
                        } else {
                                assert.NilError(t, err)
                        }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to