pbacsko commented on code in PR #563:
URL: https://github.com/apache/yunikorn-core/pull/563#discussion_r1228165826


##########
pkg/common/configs/configvalidator.go:
##########
@@ -153,6 +219,56 @@ func checkQueueMaxApplications(cur QueueConfig) error {
        return nil
 }
 
+func checkLimitMaxApplications(cur QueueConfig, parent *QueueConfig, users 
map[string]uint64, groups map[string]uint64) error {
+       // Collect user and group limits of parent queue
+       if parent != nil {
+               for _, limit := range parent.Limits {
+                       for _, user := range limit.Users {
+                               users[user] = limit.MaxApplications
+                       }
+                       for _, group := range limit.Groups {
+                               groups[group] = limit.MaxApplications
+                       }
+               }
+       }
+
+       // compare user & group limit setting between the current queue and 
parent queue
+       for _, limit := range cur.Limits {
+               for _, user := range limit.Users {
+                       curM := limit.MaxApplications
+                       // Is user limit setting exists?
+                       if _, ok := users[user]; ok {
+                               if users[user] != 0 && (users[user] < curM || 
curM == 0) {
+                                       return fmt.Errorf("user %s max 
applications %v of queue %s is greater than immediate or ancestor parent max 
applications %v", user, curM, cur.Name, users[user])
+                               }
+                               users[user] = uint64(math.Min(float64(curM), 
float64(users[user])))
+                       } else {
+                               users[user] = curM
+                       }
+               }
+               for _, group := range limit.Groups {
+                       curM := limit.MaxApplications
+                       // Is group limit setting exists?
+                       if _, ok := groups[group]; ok {
+                               if groups[group] != 0 && (groups[group] < curM 
|| curM == 0) {
+                                       return fmt.Errorf("group %s max 
applications %v of queue %s is greater than immediate or ancestor parent max 
applications %v", group, curM, cur.Name, groups[group])
+                               }
+                               groups[group] = uint64(math.Min(float64(curM), 
float64(groups[group])))

Review Comment:
   `Min()` as Wilfred asked.



##########
pkg/common/configs/config_test.go:
##########
@@ -1721,3 +1722,418 @@ func TestGetConfigurationString(t *testing.T) {
                })
        }
 }
+
+func prepareUserLimitsConfig(leafQueueMaxApps uint64, leafQueueMaxResource 
string) string {
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            users: 
+            - user1
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+          - limit:
+            users:
+            - user2
+            groups:
+            - prod
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 300
+        queues:
+          - name: level1
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 50
+                maxresources: {memory: 1000, vcore: 100}
+            queues:
+              - name: leaf
+                maxapplications: 100
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    {memory: 10000, vcore: 1000}
+                limits:
+                  - limit:
+                    users: 
+                    - user1
+                    maxapplications: ` + strconv.Itoa(int(leafQueueMaxApps)) + 
`
+                    maxresources: ` + leafQueueMaxResource + `
+          - name: level2
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 10
+                maxresources: {memory: 1000, vcore: 100}
+`
+       return data
+}
+
+func prepareUserLimitsWithTwoLevelsConfig(leafQueueMaxApps uint64, 
leafQueueMaxResource string, userMaxResource string) string {
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            users: 
+            - user1
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+          - limit:
+            users:
+            - user2
+            groups:
+            - prod
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 300
+        queues:
+          - name: level1
+            maxapplications: 900
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                ` + leafQueueMaxResource + `
+            queues:
+              - name: leaf
+                maxapplications: 900
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    ` + leafQueueMaxResource + `
+                limits:
+                  - limit:
+                    users: 
+                    - user1
+                    maxapplications: ` + strconv.Itoa(int(leafQueueMaxApps)) + 
`
+                    maxresources: ` + userMaxResource + `
+          - name: level2
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 10
+                maxresources: {memory: 1000, vcore: 100}
+`
+       return data
+}
+func TestUserLimitsWithHierarchicalQueue(t *testing.T) {
+       // Make sure parent queue user max apps should not less than the child 
queue max resource
+       // validate the config and check after the update
+       _, err := CreateConfig(prepareUserLimitsConfig(50, "{memory: 10000, 
vcore: 100}"))
+       assert.ErrorContains(t, err, "user user1 max resource map[memory:10000 
vcore:100000] of queue leaf is greater than immediate or ancestor parent 
maximum resource map[memory:1000 vcore:100000]")
+
+       // Make sure parent queue user max apps should not less than the child 
queue max apps
+       // validate the config and check after the update
+       _, err = CreateConfig(prepareUserLimitsConfig(90, "{memory: 1000, 
vcore: 100}"))
+       assert.ErrorContains(t, err, "user user1 max applications 90 of queue 
leaf is greater than immediate or ancestor parent max applications 50")
+
+       // (More than one level check)
+       // Make sure hierarchical queue user max resource should not less than 
the child queue max resource
+       // validate the config and check after the update
+       _, err = CreateConfig(prepareUserLimitsWithTwoLevelsConfig(90, 
"{memory: 100000, vcore: 100}", "{memory: 90000, vcore: 100}"))
+       assert.ErrorContains(t, err, "user user1 max resource map[memory:90000 
vcore:100000] of queue leaf is greater than immediate or ancestor parent 
maximum resource map[memory:10000 vcore:10000000]")
+
+       // (More than one level check)
+       // Make sure hierarchical queue user max apps should not less than the 
child queue max apps
+       // validate the config and check after the update
+       _, err = CreateConfig(prepareUserLimitsWithTwoLevelsConfig(900, 
"{memory: 10000, vcore: 1000}", "{memory: 1000, vcore: 100}"))
+       assert.ErrorContains(t, err, "user user1 max applications 900 of queue 
leaf is greater than immediate or ancestor parent max applications 500")
+
+       // Special case: make sure wildcard user with hierarchical queue check
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            users: 
+            - "*"
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+        queues:
+          - name: level1
+            maxapplications: 900
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 100000, vcore: 1000}
+            queues:
+              - name: leaf
+                maxapplications: 900
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    {memory: 100000, vcore: 1000}
+                limits:
+                  - limit:
+                    users: 
+                    - "*"
+                    maxapplications: 90
+                    maxresources: {memory: 90000, vcore: 100}
+          - name: level2
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 10
+                maxresources: {memory: 1000, vcore: 100}
+`
+       // validate the config and check after the update
+       _, err = CreateConfig(data)
+       assert.ErrorContains(t, err, "user * max resource map[memory:90000 
vcore:100000] of queue leaf is greater than immediate or ancestor parent 
maximum resource map[memory:10000 vcore:10000000]")
+}
+
+func prepareGroupLimitsConfig(leafQueueMaxApps uint64, leafQueueMaxResource 
string) string {
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            groups: 
+            - group1
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+          - limit:
+            users:
+            - user2
+            groups:
+            - prod
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 300
+        queues:
+          - name: level1
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                groups: 
+                - group1
+                maxapplications: 50
+                maxresources: {memory: 1000, vcore: 100}
+            queues:
+              - name: leaf
+                maxapplications: 100
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    {memory: 10000, vcore: 1000}
+                limits:
+                  - limit:
+                    groups: 
+                    - group1
+                    maxapplications: ` + strconv.Itoa(int(leafQueueMaxApps)) + 
`
+                    maxresources: ` + leafQueueMaxResource + `

Review Comment:
   Placeholders



##########
pkg/common/configs/config_test.go:
##########
@@ -1721,3 +1722,418 @@ func TestGetConfigurationString(t *testing.T) {
                })
        }
 }
+
+func prepareUserLimitsConfig(leafQueueMaxApps uint64, leafQueueMaxResource 
string) string {
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            users: 
+            - user1
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+          - limit:
+            users:
+            - user2
+            groups:
+            - prod
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 300
+        queues:
+          - name: level1
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 50
+                maxresources: {memory: 1000, vcore: 100}
+            queues:
+              - name: leaf
+                maxapplications: 100
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    {memory: 10000, vcore: 1000}
+                limits:
+                  - limit:
+                    users: 
+                    - user1
+                    maxapplications: ` + strconv.Itoa(int(leafQueueMaxApps)) + 
`
+                    maxresources: ` + leafQueueMaxResource + `
+          - name: level2
+            maxapplications: 100
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                {memory: 10000, vcore: 1000}
+            limits:
+              - limit:
+                users: 
+                - user1
+                maxapplications: 10
+                maxresources: {memory: 1000, vcore: 100}
+`
+       return data
+}
+
+func prepareUserLimitsWithTwoLevelsConfig(leafQueueMaxApps uint64, 
leafQueueMaxResource string, userMaxResource string) string {
+       data := `
+partitions:
+  - name: default
+    queues:
+      - name: root
+        maxapplications: 3000
+        limits:
+          - limit:
+            users: 
+            - user1
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 500
+          - limit:
+            users:
+            - user2
+            groups:
+            - prod
+            maxresources: {memory: 10000, vcore: 10000}
+            maxapplications: 300
+        queues:
+          - name: level1
+            maxapplications: 900
+            resources:
+              guaranteed:
+                {memory: 1000, vcore: 10}
+              max:
+                ` + leafQueueMaxResource + `
+            queues:
+              - name: leaf
+                maxapplications: 900
+                resources:
+                  guaranteed:
+                    {memory: 1000, vcore: 10}
+                  max:
+                    ` + leafQueueMaxResource + `
+                limits:
+                  - limit:
+                    users: 
+                    - user1
+                    maxapplications: ` + strconv.Itoa(int(leafQueueMaxApps)) + 
`
+                    maxresources: ` + userMaxResource + `

Review Comment:
   Placeholders



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to