public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Daniel Kral <d.kral@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH ha-manager v5 13/14] test: rules: add test cases for resource affinity rules
Date: Wed, 30 Jul 2025 20:14:17 +0200	[thread overview]
Message-ID: <20250730181428.392906-14-d.kral@proxmox.com> (raw)
In-Reply-To: <20250730181428.392906-1-d.kral@proxmox.com>

Add test cases to verify that the rule checkers correctly identify and
remove HA Resource Affinity rules from the rules to make the rule set
feasible. The added test cases verify:

- Resource Affinity rules retrieve the correct optional default values
- Resource Affinity rules, which state that two or more resources are to
  be kept together and separate at the same time, are dropped from the
  rule set
- Resource Affinity rules, which specify less than two nodes, are
  dropped from the rule set
- Negative resource affinity rules, which specify more nodes than
  available, are dropped from the rule set
- Positive resource affinity rule resources, which overlap with other
  positive resource affinity rules' resources, are merged into a single
  positive resource affinity rule to make them disjoint from each other
- Positive resource affinity rule resources, which are also in negative
  resource affinity rules, implicitly create negative resource affinity
  rules for the other resources as well
- Resources cannot be referenced by node affinity rules and resource
  affinity rules at the same time

Signed-off-by: Daniel Kral <d.kral@proxmox.com>
---
 .../defaults-for-resource-affinity-rules.cfg  |  16 +++
 ...lts-for-resource-affinity-rules.cfg.expect |  38 +++++
 .../inconsistent-resource-affinity-rules.cfg  |  11 ++
 ...sistent-resource-affinity-rules.cfg.expect |  11 ++
 ...ctive-negative-resource-affinity-rules.cfg |  17 +++
 ...egative-resource-affinity-rules.cfg.expect |  30 ++++
 .../ineffective-resource-affinity-rules.cfg   |   8 ++
 ...fective-resource-affinity-rules.cfg.expect |   9 ++
 ...licit-negative-resource-affinity-rules.cfg |  40 ++++++
 ...egative-resource-affinity-rules.cfg.expect | 131 ++++++++++++++++++
 ...licit-negative-resource-affinity-rules.cfg |  16 +++
 ...egative-resource-affinity-rules.cfg.expect |  73 ++++++++++
 ...ected-positive-resource-affinity-rules.cfg |  42 ++++++
 ...ositive-resource-affinity-rules.cfg.expect |  70 ++++++++++
 .../multiple-resource-refs-in-rules.cfg       |  52 +++++++
 ...multiple-resource-refs-in-rules.cfg.expect | 111 +++++++++++++++
 src/test/test_rules_config.pl                 |   2 +
 17 files changed, 677 insertions(+)
 create mode 100644 src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg
 create mode 100644 src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg.expect
 create mode 100644 src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg
 create mode 100644 src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg.expect

diff --git a/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg b/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg
new file mode 100644
index 00000000..a0fb4e0d
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg
@@ -0,0 +1,16 @@
+# Case 1: Resource Affinity rules are enabled by default, so set it so if it isn't yet.
+resource-affinity: resource-affinity-defaults
+	resources vm:101,vm:102
+	affinity negative
+
+# Case 2: Resource Affinity rule is disabled, it shouldn't be enabled afterwards.
+resource-affinity: resource-affinity-disabled
+	resources vm:201,vm:202
+	affinity negative
+	disable
+
+# Case 3: Resource Affinity rule is disabled with explicit 1 set, it shouldn't be enabled afterwards.
+resource-affinity: resource-affinity-disabled-explicit
+	resources vm:301,vm:302
+	affinity negative
+	disable 1
diff --git a/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..7384b0b8
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-resource-affinity-rules.cfg.expect
@@ -0,0 +1,38 @@
+--- Log ---
+--- Config ---
+$VAR1 = {
+          'digest' => '9ac7cc517f02c41e3403085ec02f6a9259f2ac94',
+          'ids' => {
+                     'resource-affinity-defaults' => {
+                                                       'affinity' => 'negative',
+                                                       'resources' => {
+                                                                        'vm:101' => 1,
+                                                                        'vm:102' => 1
+                                                                      },
+                                                       'type' => 'resource-affinity'
+                                                     },
+                     'resource-affinity-disabled' => {
+                                                       'affinity' => 'negative',
+                                                       'disable' => 1,
+                                                       'resources' => {
+                                                                        'vm:201' => 1,
+                                                                        'vm:202' => 1
+                                                                      },
+                                                       'type' => 'resource-affinity'
+                                                     },
+                     'resource-affinity-disabled-explicit' => {
+                                                                'affinity' => 'negative',
+                                                                'disable' => 1,
+                                                                'resources' => {
+                                                                                 'vm:301' => 1,
+                                                                                 'vm:302' => 1
+                                                                               },
+                                                                'type' => 'resource-affinity'
+                                                              }
+                   },
+          'order' => {
+                       'resource-affinity-defaults' => 1,
+                       'resource-affinity-disabled' => 2,
+                       'resource-affinity-disabled-explicit' => 3
+                     }
+        };
diff --git a/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg b/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg
new file mode 100644
index 00000000..a620e293
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg
@@ -0,0 +1,11 @@
+resource-affinity: keep-apart1
+	resources vm:102,vm:103
+	affinity negative
+
+resource-affinity: keep-apart2
+	resources vm:102,vm:104,vm:106
+	affinity negative
+
+resource-affinity: stick-together1
+	resources vm:101,vm:102,vm:103,vm:104,vm:106
+	affinity positive
diff --git a/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..b0cde0f8
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-resource-affinity-rules.cfg.expect
@@ -0,0 +1,11 @@
+--- Log ---
+Drop rule 'keep-apart1', because rule shares two or more resources with 'stick-together1'.
+Drop rule 'keep-apart2', because rule shares two or more resources with 'stick-together1'.
+Drop rule 'stick-together1', because rule shares two or more resources with 'keep-apart1'.
+Drop rule 'stick-together1', because rule shares two or more resources with 'keep-apart2'.
+--- Config ---
+$VAR1 = {
+          'digest' => '50875b320034d8ac7dded185e590f5f87c4e2bb6',
+          'ids' => {},
+          'order' => {}
+        };
diff --git a/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg b/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg
new file mode 100644
index 00000000..c0f18d27
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg
@@ -0,0 +1,17 @@
+# Case 1: Do not remove negative resource affinity rules, which do define less resources than available nodes (3).
+resource-affinity: do-not-remove-me1
+	resources vm:101,vm:102
+	affinity negative
+
+resource-affinity: do-not-remove-me2
+	resources vm:101,vm:102,vm:103
+	affinity negative
+
+# Case 1: Remove negative resource affinity rules, which do define more resources than available nodes (3).
+resource-affinity: remove-me1
+	resources vm:101,vm:102,vm:103,vm:104
+	affinity negative
+
+resource-affinity: remove-me2
+	resources vm:101,vm:102,vm:103,vm:104,vm:105
+	affinity negative
diff --git a/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..8a2b8797
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-negative-resource-affinity-rules.cfg.expect
@@ -0,0 +1,30 @@
+--- Log ---
+Drop rule 'remove-me1', because rule defines more resources than available nodes.
+Drop rule 'remove-me2', because rule defines more resources than available nodes.
+--- Config ---
+$VAR1 = {
+          'digest' => '68633cedeeb355ef78fe28221ef3f16537b3e788',
+          'ids' => {
+                     'do-not-remove-me1' => {
+                                              'affinity' => 'negative',
+                                              'resources' => {
+                                                               'vm:101' => 1,
+                                                               'vm:102' => 1
+                                                             },
+                                              'type' => 'resource-affinity'
+                                            },
+                     'do-not-remove-me2' => {
+                                              'affinity' => 'negative',
+                                              'resources' => {
+                                                               'vm:101' => 1,
+                                                               'vm:102' => 1,
+                                                               'vm:103' => 1
+                                                             },
+                                              'type' => 'resource-affinity'
+                                            }
+                   },
+          'order' => {
+                       'do-not-remove-me1' => 1,
+                       'do-not-remove-me2' => 2
+                     }
+        };
diff --git a/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg b/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg
new file mode 100644
index 00000000..32f977be
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg
@@ -0,0 +1,8 @@
+# Case 1: Remove resource affinity rules, which do not have enough resources to be effective.
+resource-affinity: lonely-resource1
+	resources vm:101
+	affinity positive
+
+resource-affinity: lonely-resource2
+	resources vm:101
+	affinity negative
diff --git a/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..b2d468b2
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-resource-affinity-rules.cfg.expect
@@ -0,0 +1,9 @@
+--- Log ---
+Drop rule 'lonely-resource1', because rule is ineffective as there are less than two resources.
+Drop rule 'lonely-resource2', because rule is ineffective as there are less than two resources.
+--- Config ---
+$VAR1 = {
+          'digest' => 'fe89f8c8f5acc29f807eaa0cec5974b6e957a596',
+          'ids' => {},
+          'order' => {}
+        };
diff --git a/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg b/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg
new file mode 100644
index 00000000..db26286c
--- /dev/null
+++ b/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg
@@ -0,0 +1,40 @@
+# Case 1: Do not infer any negative resource affinity rules, if there are no resources of a positive
+#         resource affinity rule in any negative resource affinity rules.
+resource-affinity: do-not-infer-positive1
+	resources vm:101,vm:102,vm:103
+	affinity positive
+
+# Case 2: Infer negative resource affinity rules with one resource in a negative resource affinity rule.
+resource-affinity: infer-simple-positive1
+	resources vm:201,vm:202,vm:203
+	affinity positive
+
+resource-affinity: infer-simple-negative1
+	resources vm:201,vm:204
+	affinity negative
+
+# Case 3: Infer negative resource affinity rules with two resources in different negative resource affinity rules.
+resource-affinity: infer-two-positive1
+	resources vm:301,vm:302,vm:303
+	affinity positive
+
+resource-affinity: infer-two-negative1
+	resources vm:303,vm:304
+	affinity negative
+
+resource-affinity: infer-two-negative2
+	resources vm:302,vm:305
+	affinity negative
+
+# Case 4: Do not infer negative resource affinity rules from inconsistent resource affinity rules.
+resource-affinity: do-not-infer-inconsistent-positive1
+	resources vm:401,vm:402,vm:403
+	affinity positive
+
+resource-affinity: do-not-infer-inconsistent-negative1
+	resources vm:401,vm:404
+	affinity negative
+
+resource-affinity: do-not-infer-inconsistent-negative2
+	resources vm:402,vm:403,vm:405
+	affinity negative
diff --git a/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..bcd368ab
--- /dev/null
+++ b/src/test/rules_cfgs/infer-implicit-negative-resource-affinity-rules.cfg.expect
@@ -0,0 +1,131 @@
+--- Log ---
+Drop rule 'do-not-infer-inconsistent-negative2', because rule shares two or more resources with 'do-not-infer-inconsistent-positive1'.
+Drop rule 'do-not-infer-inconsistent-positive1', because rule shares two or more resources with 'do-not-infer-inconsistent-negative2'.
+--- Config ---
+$VAR1 = {
+          'digest' => 'd8724dfe2130bb642b98e021da973aa0ec0695f0',
+          'ids' => {
+                     '_implicit-negative-infer-simple-positive1-vm:202-vm:204' => {
+                                                                                    'affinity' => 'negative',
+                                                                                    'resources' => {
+                                                                                                     'vm:202' => 1,
+                                                                                                     'vm:204' => 1
+                                                                                                   },
+                                                                                    'type' => 'resource-affinity'
+                                                                                  },
+                     '_implicit-negative-infer-simple-positive1-vm:203-vm:204' => {
+                                                                                    'affinity' => 'negative',
+                                                                                    'resources' => {
+                                                                                                     'vm:203' => 1,
+                                                                                                     'vm:204' => 1
+                                                                                                   },
+                                                                                    'type' => 'resource-affinity'
+                                                                                  },
+                     '_implicit-negative-infer-two-positive1-vm:301-vm:304' => {
+                                                                                 'affinity' => 'negative',
+                                                                                 'resources' => {
+                                                                                                  'vm:301' => 1,
+                                                                                                  'vm:304' => 1
+                                                                                                },
+                                                                                 'type' => 'resource-affinity'
+                                                                               },
+                     '_implicit-negative-infer-two-positive1-vm:301-vm:305' => {
+                                                                                 'affinity' => 'negative',
+                                                                                 'resources' => {
+                                                                                                  'vm:301' => 1,
+                                                                                                  'vm:305' => 1
+                                                                                                },
+                                                                                 'type' => 'resource-affinity'
+                                                                               },
+                     '_implicit-negative-infer-two-positive1-vm:302-vm:304' => {
+                                                                                 'affinity' => 'negative',
+                                                                                 'resources' => {
+                                                                                                  'vm:302' => 1,
+                                                                                                  'vm:304' => 1
+                                                                                                },
+                                                                                 'type' => 'resource-affinity'
+                                                                               },
+                     '_implicit-negative-infer-two-positive1-vm:303-vm:305' => {
+                                                                                 'affinity' => 'negative',
+                                                                                 'resources' => {
+                                                                                                  'vm:303' => 1,
+                                                                                                  'vm:305' => 1
+                                                                                                },
+                                                                                 'type' => 'resource-affinity'
+                                                                               },
+                     'do-not-infer-inconsistent-negative1' => {
+                                                                'affinity' => 'negative',
+                                                                'resources' => {
+                                                                                 'vm:401' => 1,
+                                                                                 'vm:404' => 1
+                                                                               },
+                                                                'type' => 'resource-affinity'
+                                                              },
+                     'do-not-infer-positive1' => {
+                                                   'affinity' => 'positive',
+                                                   'resources' => {
+                                                                    'vm:101' => 1,
+                                                                    'vm:102' => 1,
+                                                                    'vm:103' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'infer-simple-negative1' => {
+                                                   'affinity' => 'negative',
+                                                   'resources' => {
+                                                                    'vm:201' => 1,
+                                                                    'vm:204' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'infer-simple-positive1' => {
+                                                   'affinity' => 'positive',
+                                                   'resources' => {
+                                                                    'vm:201' => 1,
+                                                                    'vm:202' => 1,
+                                                                    'vm:203' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'infer-two-negative1' => {
+                                                'affinity' => 'negative',
+                                                'resources' => {
+                                                                 'vm:303' => 1,
+                                                                 'vm:304' => 1
+                                                               },
+                                                'type' => 'resource-affinity'
+                                              },
+                     'infer-two-negative2' => {
+                                                'affinity' => 'negative',
+                                                'resources' => {
+                                                                 'vm:302' => 1,
+                                                                 'vm:305' => 1
+                                                               },
+                                                'type' => 'resource-affinity'
+                                              },
+                     'infer-two-positive1' => {
+                                                'affinity' => 'positive',
+                                                'resources' => {
+                                                                 'vm:301' => 1,
+                                                                 'vm:302' => 1,
+                                                                 'vm:303' => 1
+                                                               },
+                                                'type' => 'resource-affinity'
+                                              }
+                   },
+          'order' => {
+                       '_implicit-negative-infer-simple-positive1-vm:202-vm:204' => 2,
+                       '_implicit-negative-infer-simple-positive1-vm:203-vm:204' => 2,
+                       '_implicit-negative-infer-two-positive1-vm:301-vm:304' => 2,
+                       '_implicit-negative-infer-two-positive1-vm:301-vm:305' => 2,
+                       '_implicit-negative-infer-two-positive1-vm:302-vm:304' => 2,
+                       '_implicit-negative-infer-two-positive1-vm:303-vm:305' => 2,
+                       'do-not-infer-inconsistent-negative1' => 8,
+                       'do-not-infer-positive1' => 1,
+                       'infer-simple-negative1' => 3,
+                       'infer-simple-positive1' => 2,
+                       'infer-two-negative1' => 5,
+                       'infer-two-negative2' => 6,
+                       'infer-two-positive1' => 4
+                     }
+        };
diff --git a/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg b/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg
new file mode 100644
index 00000000..5694bde8
--- /dev/null
+++ b/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg
@@ -0,0 +1,16 @@
+# Case 1: Infer negative resource affinity rules from connected positive resource affinity rules.
+resource-affinity: infer-connected-positive1
+	resources vm:101,vm:102
+	affinity positive
+
+resource-affinity: infer-connected-positive2
+	resources vm:102,vm:103
+	affinity positive
+
+resource-affinity: infer-connected-negative1
+	resources vm:101,vm:104
+	affinity negative
+
+resource-affinity: infer-connected-negative2
+	resources vm:102,vm:105
+	affinity negative
diff --git a/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..876c2030
--- /dev/null
+++ b/src/test/rules_cfgs/merge-and-infer-implicit-negative-resource-affinity-rules.cfg.expect
@@ -0,0 +1,73 @@
+--- Log ---
+--- Config ---
+$VAR1 = {
+          'digest' => '5695bd62a65966a275a62a01d2d8fbc370d91668',
+          'ids' => {
+                     '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:101-vm:105' => {
+                                                                                                                         'affinity' => 'negative',
+                                                                                                                         'resources' => {
+                                                                                                                                          'vm:101' => 1,
+                                                                                                                                          'vm:105' => 1
+                                                                                                                                        },
+                                                                                                                         'type' => 'resource-affinity'
+                                                                                                                       },
+                     '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:102-vm:104' => {
+                                                                                                                         'affinity' => 'negative',
+                                                                                                                         'resources' => {
+                                                                                                                                          'vm:102' => 1,
+                                                                                                                                          'vm:104' => 1
+                                                                                                                                        },
+                                                                                                                         'type' => 'resource-affinity'
+                                                                                                                       },
+                     '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:103-vm:104' => {
+                                                                                                                         'affinity' => 'negative',
+                                                                                                                         'resources' => {
+                                                                                                                                          'vm:103' => 1,
+                                                                                                                                          'vm:104' => 1
+                                                                                                                                        },
+                                                                                                                         'type' => 'resource-affinity'
+                                                                                                                       },
+                     '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:103-vm:105' => {
+                                                                                                                         'affinity' => 'negative',
+                                                                                                                         'resources' => {
+                                                                                                                                          'vm:103' => 1,
+                                                                                                                                          'vm:105' => 1
+                                                                                                                                        },
+                                                                                                                         'type' => 'resource-affinity'
+                                                                                                                       },
+                     '_merged-infer-connected-positive1-infer-connected-positive2' => {
+                                                                                        'affinity' => 'positive',
+                                                                                        'resources' => {
+                                                                                                         'vm:101' => 1,
+                                                                                                         'vm:102' => 1,
+                                                                                                         'vm:103' => 1
+                                                                                                       },
+                                                                                        'type' => 'resource-affinity'
+                                                                                      },
+                     'infer-connected-negative1' => {
+                                                      'affinity' => 'negative',
+                                                      'resources' => {
+                                                                       'vm:101' => 1,
+                                                                       'vm:104' => 1
+                                                                     },
+                                                      'type' => 'resource-affinity'
+                                                    },
+                     'infer-connected-negative2' => {
+                                                      'affinity' => 'negative',
+                                                      'resources' => {
+                                                                       'vm:102' => 1,
+                                                                       'vm:105' => 1
+                                                                     },
+                                                      'type' => 'resource-affinity'
+                                                    }
+                   },
+          'order' => {
+                       '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:101-vm:105' => 2,
+                       '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:102-vm:104' => 2,
+                       '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:103-vm:104' => 2,
+                       '_implicit-negative-_merged-infer-connected-positive1-infer-connected-positive2-vm:103-vm:105' => 2,
+                       '_merged-infer-connected-positive1-infer-connected-positive2' => 1,
+                       'infer-connected-negative1' => 3,
+                       'infer-connected-negative2' => 4
+                     }
+        };
diff --git a/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg b/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg
new file mode 100644
index 00000000..8954a27b
--- /dev/null
+++ b/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg
@@ -0,0 +1,42 @@
+# Case 1: Do not merge any negative resource affinity rules.
+resource-affinity: do-not-merge-negative1
+	resources vm:101,vm:102
+	affinity negative
+
+resource-affinity: do-not-merge-negative2
+	resources vm:102,vm:103
+	affinity negative
+
+resource-affinity: do-not-merge-negative3
+	resources vm:104,vm:105
+	affinity negative
+
+# Case 2: Do not merge unconnected positive resource affinity rules.
+resource-affinity: do-not-merge-positive1
+	resources vm:201,vm:202
+	affinity positive
+
+resource-affinity: do-not-merge-positive2
+	resources vm:203,vm:204
+	affinity positive
+
+# Case 3: Merge connected positive resource affinity rules.
+resource-affinity: merge-positive1
+	resources vm:301,vm:302
+	affinity positive
+
+resource-affinity: merge-positive2
+	resources vm:303,vm:305,vm:307
+	affinity positive
+
+resource-affinity: merge-positive3
+	resources vm:302,vm:303
+	affinity positive
+
+resource-affinity: merge-positive4
+	resources vm:302,vm:304,vm:306
+	affinity positive
+
+resource-affinity: merge-positive5
+	resources vm:307,vm:308,vm:309
+	affinity positive
diff --git a/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg.expect b/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg.expect
new file mode 100644
index 00000000..e57a792b
--- /dev/null
+++ b/src/test/rules_cfgs/merge-connected-positive-resource-affinity-rules.cfg.expect
@@ -0,0 +1,70 @@
+--- Log ---
+--- Config ---
+$VAR1 = {
+          'digest' => '920d9caac206fc0dd893753bfb2cab3e6d6a9b9b',
+          'ids' => {
+                     '_merged-merge-positive1-merge-positive3-merge-positive4-merge-positive2-merge-positive5' => {
+                                                                                                                    'affinity' => 'positive',
+                                                                                                                    'resources' => {
+                                                                                                                                     'vm:301' => 1,
+                                                                                                                                     'vm:302' => 1,
+                                                                                                                                     'vm:303' => 1,
+                                                                                                                                     'vm:304' => 1,
+                                                                                                                                     'vm:305' => 1,
+                                                                                                                                     'vm:306' => 1,
+                                                                                                                                     'vm:307' => 1,
+                                                                                                                                     'vm:308' => 1,
+                                                                                                                                     'vm:309' => 1
+                                                                                                                                   },
+                                                                                                                    'type' => 'resource-affinity'
+                                                                                                                  },
+                     'do-not-merge-negative1' => {
+                                                   'affinity' => 'negative',
+                                                   'resources' => {
+                                                                    'vm:101' => 1,
+                                                                    'vm:102' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'do-not-merge-negative2' => {
+                                                   'affinity' => 'negative',
+                                                   'resources' => {
+                                                                    'vm:102' => 1,
+                                                                    'vm:103' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'do-not-merge-negative3' => {
+                                                   'affinity' => 'negative',
+                                                   'resources' => {
+                                                                    'vm:104' => 1,
+                                                                    'vm:105' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'do-not-merge-positive1' => {
+                                                   'affinity' => 'positive',
+                                                   'resources' => {
+                                                                    'vm:201' => 1,
+                                                                    'vm:202' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 },
+                     'do-not-merge-positive2' => {
+                                                   'affinity' => 'positive',
+                                                   'resources' => {
+                                                                    'vm:203' => 1,
+                                                                    'vm:204' => 1
+                                                                  },
+                                                   'type' => 'resource-affinity'
+                                                 }
+                   },
+          'order' => {
+                       '_merged-merge-positive1-merge-positive3-merge-positive4-merge-positive2-merge-positive5' => 6,
+                       'do-not-merge-negative1' => 1,
+                       'do-not-merge-negative2' => 2,
+                       'do-not-merge-negative3' => 3,
+                       'do-not-merge-positive1' => 4,
+                       'do-not-merge-positive2' => 5
+                     }
+        };
diff --git a/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg b/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg
new file mode 100644
index 00000000..6608a5c3
--- /dev/null
+++ b/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg
@@ -0,0 +1,52 @@
+# Case 1: Do not remove node/resource affinity rules, which do not share resources between these types.
+node-affinity: different-resource1
+	resources vm:101,vm:102,vm:103
+	nodes node1,node2:2
+	strict 0
+
+resource-affinity: different-resource2
+	resources vm:104,vm:105
+	affinity positive
+
+node-affinity: different-resource3
+	resources vm:106
+	nodes node1,node2:2
+	strict 1
+
+resource-affinity: different-resource4
+	resources vm:107,vm:109
+	affinity negative
+
+# Case 2: Remove rules, which share the same resource(s) between different rule types.
+node-affinity: same-resource1
+	resources vm:201
+	nodes node1,node2:2
+	strict 0
+
+resource-affinity: same-resource2
+	resources vm:201,vm:205
+	affinity negative
+
+resource-affinity: same-resource3
+	resources vm:201,vm:203,vm:204
+	affinity negative
+
+node-affinity: same-resource4
+	resources vm:205,vm:206,vm:207
+	nodes node1:2,node3:3
+	strict 1
+
+# Case 3: Do not remove rules, which do not share resources between them.
+node-affinity: other-different-resource1
+	resources vm:301,vm:308
+	nodes node1,node2:2
+	strict 0
+
+resource-affinity: other-different-resource2
+	resources vm:302,vm:304,vm:305
+	affinity positive
+
+node-affinity: other-different-resource3
+	resources vm:303,vm:306,vm:309
+	nodes node1,node2:2
+	strict 1
diff --git a/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg.expect b/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg.expect
new file mode 100644
index 00000000..972c042d
--- /dev/null
+++ b/src/test/rules_cfgs/multiple-resource-refs-in-rules.cfg.expect
@@ -0,0 +1,111 @@
+--- Log ---
+Drop rule 'same-resource1', because resource 'vm:201' cannot be used in both a node affinity rule and a resource affinity rule at the same time.
+Drop rule 'same-resource2', because resource 'vm:201' cannot be used in both a node affinity rule and a resource affinity rule at the same time.
+Drop rule 'same-resource2', because resource 'vm:205' cannot be used in both a node affinity rule and a resource affinity rule at the same time.
+Drop rule 'same-resource3', because resource 'vm:201' cannot be used in both a node affinity rule and a resource affinity rule at the same time.
+Drop rule 'same-resource4', because resource 'vm:205' cannot be used in both a node affinity rule and a resource affinity rule at the same time.
+--- Config ---
+$VAR1 = {
+          'digest' => 'fcbdf84d442d38b4c901d989c211fb62024c5515',
+          'ids' => {
+                     'different-resource1' => {
+                                                'nodes' => {
+                                                             'node1' => {
+                                                                          'priority' => 0
+                                                                        },
+                                                             'node2' => {
+                                                                          'priority' => 2
+                                                                        }
+                                                           },
+                                                'resources' => {
+                                                                 'vm:101' => 1,
+                                                                 'vm:102' => 1,
+                                                                 'vm:103' => 1
+                                                               },
+                                                'strict' => 0,
+                                                'type' => 'node-affinity'
+                                              },
+                     'different-resource2' => {
+                                                'affinity' => 'positive',
+                                                'resources' => {
+                                                                 'vm:104' => 1,
+                                                                 'vm:105' => 1
+                                                               },
+                                                'type' => 'resource-affinity'
+                                              },
+                     'different-resource3' => {
+                                                'nodes' => {
+                                                             'node1' => {
+                                                                          'priority' => 0
+                                                                        },
+                                                             'node2' => {
+                                                                          'priority' => 2
+                                                                        }
+                                                           },
+                                                'resources' => {
+                                                                 'vm:106' => 1
+                                                               },
+                                                'strict' => 1,
+                                                'type' => 'node-affinity'
+                                              },
+                     'different-resource4' => {
+                                                'affinity' => 'negative',
+                                                'resources' => {
+                                                                 'vm:107' => 1,
+                                                                 'vm:109' => 1
+                                                               },
+                                                'type' => 'resource-affinity'
+                                              },
+                     'other-different-resource1' => {
+                                                      'nodes' => {
+                                                                   'node1' => {
+                                                                                'priority' => 0
+                                                                              },
+                                                                   'node2' => {
+                                                                                'priority' => 2
+                                                                              }
+                                                                 },
+                                                      'resources' => {
+                                                                       'vm:301' => 1,
+                                                                       'vm:308' => 1
+                                                                     },
+                                                      'strict' => 0,
+                                                      'type' => 'node-affinity'
+                                                    },
+                     'other-different-resource2' => {
+                                                      'affinity' => 'positive',
+                                                      'resources' => {
+                                                                       'vm:302' => 1,
+                                                                       'vm:304' => 1,
+                                                                       'vm:305' => 1
+                                                                     },
+                                                      'type' => 'resource-affinity'
+                                                    },
+                     'other-different-resource3' => {
+                                                      'nodes' => {
+                                                                   'node1' => {
+                                                                                'priority' => 0
+                                                                              },
+                                                                   'node2' => {
+                                                                                'priority' => 2
+                                                                              }
+                                                                 },
+                                                      'resources' => {
+                                                                       'vm:303' => 1,
+                                                                       'vm:306' => 1,
+                                                                       'vm:309' => 1
+                                                                     },
+                                                      'strict' => 1,
+                                                      'type' => 'node-affinity'
+                                                    }
+                   },
+          'order' => {
+                       'different-resource1' => 1,
+                       'different-resource2' => 2,
+                       'different-resource3' => 3,
+                       'different-resource4' => 4,
+                       'other-different-resource1' => 9,
+                       'other-different-resource2' => 10,
+                       'other-different-resource3' => 11
+                     }
+        };
diff --git a/src/test/test_rules_config.pl b/src/test/test_rules_config.pl
index d49d14f1..c2a7af43 100755
--- a/src/test/test_rules_config.pl
+++ b/src/test/test_rules_config.pl
@@ -13,8 +13,10 @@ use Data::Dumper;
 
 use PVE::HA::Rules;
 use PVE::HA::Rules::NodeAffinity;
+use PVE::HA::Rules::ResourceAffinity;
 
 PVE::HA::Rules::NodeAffinity->register();
+PVE::HA::Rules::ResourceAffinity->register();
 
 PVE::HA::Rules->init(property_isolation => 1);
 
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  parent reply	other threads:[~2025-07-30 18:14 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-30 18:14 [pve-devel] [PATCH container/docs/ha-manager/manager/qemu-server v5 00/20] HA " Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 01/14] introduce PVE::HA::HashTools module Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 02/14] rules: introduce plugin-specific canonicalize routines Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 03/14] rules: add haenv node list to the rules' canonicalization stage Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 04/14] rules: introduce resource affinity rule plugin Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 05/14] rules: add global checks between node and resource affinity rules Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 06/14] usage: add information about a service's assigned nodes Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 07/14] manager: apply resource affinity rules when selecting service nodes Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 08/14] manager: handle resource affinity rules in manual migrations Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 09/14] sim: resources: add option to limit start and migrate tries to node Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 10/14] test: ha tester: add test cases for negative resource affinity rules Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 11/14] test: ha tester: add test cases for positive " Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 12/14] test: ha tester: add test cases for static scheduler resource affinity Daniel Kral
2025-07-30 18:14 ` Daniel Kral [this message]
2025-07-30 18:14 ` [pve-devel] [PATCH ha-manager v5 14/14] api: resources: add check for resource affinity in resource migrations Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH docs v5 1/1] ha: add documentation about ha resource affinity rules Daniel Kral
2025-08-04 13:00   ` Hannes Duerr
2025-07-30 18:14 ` [pve-devel] [PATCH manager v5 1/3] ui: ha: rules: add " Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH manager v5 2/3] ui: migrate: lxc: display precondition messages for ha resource affinity Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH manager v5 3/3] ui: migrate: vm: " Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH container v5 1/1] api: introduce migration preconditions api endpoint Daniel Kral
2025-07-30 18:14 ` [pve-devel] [PATCH qemu-server v5 1/1] api: migration preconditions: add checks for ha resource affinity rules Daniel Kral
2025-08-04  9:50 ` [pve-devel] applied-series: [PATCH container/docs/ha-manager/manager/qemu-server v5 00/20] HA " Fiona Ebner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250730181428.392906-14-d.kral@proxmox.com \
    --to=d.kral@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal