[pve-devel] [PATCH ha-manager v2 20/26] test: add test cases for rules config
Daniel Kral
d.kral at proxmox.com
Fri Jun 20 16:31:32 CEST 2025
Add test cases to verify that the rule checkers correctly identify and
remove ill-defined location and colocation rules from the rules:
- Set defaults when reading location and colocation rules
- Dropping location rules, which specify the same service multiple times
- Dropping colocation rules, which state that two or more services are
to be kept together and separate at the same time
- Dropping colocation rules, which cannot be fullfilled because of the
constraints of the location rules of their services
- Dropping colocation rules, which specify less than two services
Signed-off-by: Daniel Kral <d.kral at proxmox.com>
---
changes since v1:
- dropped connected positive colocation rules check
- rename illdefined-colocations to ineffective-colocation-rules
- rename inner-inconsistent-colocations to
inconsistent-colocation-rules
- introduced rule set tests for default values
- introduced rule set tests for duplicate service reference in
location rules
- introduced rule set tests for multi-priority location with
colocation rules
.gitignore | 1 +
src/test/Makefile | 4 +-
.../defaults-for-colocation-rules.cfg | 10 ++
.../defaults-for-colocation-rules.cfg.expect | 29 ++++
.../defaults-for-location-rules.cfg | 16 +++
.../defaults-for-location-rules.cfg.expect | 49 +++++++
.../duplicate-service-in-location-rules.cfg | 31 +++++
...icate-service-in-location-rules.cfg.expect | 66 +++++++++
.../inconsistent-colocation-rules.cfg | 11 ++
.../inconsistent-colocation-rules.cfg.expect | 11 ++
...inconsistent-location-colocation-rules.cfg | 54 ++++++++
...stent-location-colocation-rules.cfg.expect | 130 ++++++++++++++++++
.../ineffective-colocation-rules.cfg | 7 +
.../ineffective-colocation-rules.cfg.expect | 9 ++
...ulti-priority-location-with-colocation.cfg | 19 +++
...iority-location-with-colocation.cfg.expect | 47 +++++++
src/test/test_rules_config.pl | 102 ++++++++++++++
17 files changed, 595 insertions(+), 1 deletion(-)
create mode 100644 src/test/rules_cfgs/defaults-for-colocation-rules.cfg
create mode 100644 src/test/rules_cfgs/defaults-for-colocation-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/defaults-for-location-rules.cfg
create mode 100644 src/test/rules_cfgs/defaults-for-location-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/duplicate-service-in-location-rules.cfg
create mode 100644 src/test/rules_cfgs/duplicate-service-in-location-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/inconsistent-colocation-rules.cfg
create mode 100644 src/test/rules_cfgs/inconsistent-colocation-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg
create mode 100644 src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/ineffective-colocation-rules.cfg
create mode 100644 src/test/rules_cfgs/ineffective-colocation-rules.cfg.expect
create mode 100644 src/test/rules_cfgs/multi-priority-location-with-colocation.cfg
create mode 100644 src/test/rules_cfgs/multi-priority-location-with-colocation.cfg.expect
create mode 100755 src/test/test_rules_config.pl
diff --git a/.gitignore b/.gitignore
index c35280e..35de63f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
/src/test/test-*/status/*
/src/test/fence_cfgs/*.cfg.commands
/src/test/fence_cfgs/*.cfg.write
+/src/test/rules_cfgs/*.cfg.output
diff --git a/src/test/Makefile b/src/test/Makefile
index e54959f..6da9e10 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -5,6 +5,7 @@ all:
test:
@echo "-- start regression tests --"
./test_failover1.pl
+ ./test_rules_config.pl
./ha-tester.pl
./test_fence_config.pl
@echo "-- end regression tests (success) --"
@@ -12,4 +13,5 @@ test:
.PHONY: clean
clean:
rm -rf *~ test-*/log test-*/*~ test-*/status \
- fence_cfgs/*.cfg.commands fence_cfgs/*.write
+ fence_cfgs/*.cfg.commands fence_cfgs/*.write \
+ rules_cfgs/*.cfg.output
diff --git a/src/test/rules_cfgs/defaults-for-colocation-rules.cfg b/src/test/rules_cfgs/defaults-for-colocation-rules.cfg
new file mode 100644
index 0000000..8e68030
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-colocation-rules.cfg
@@ -0,0 +1,10 @@
+# Case 1: Colocation rules are enabled by default, so set it so if it isn't yet.
+colocation: colocation-defaults
+ services vm:101,vm:102
+ affinity separate
+
+# Case 2: Colocation rule is disabled, it shouldn't be enabled afterwards.
+colocation: colocation-disabled
+ services vm:201,vm:202
+ affinity separate
+ state disabled
diff --git a/src/test/rules_cfgs/defaults-for-colocation-rules.cfg.expect b/src/test/rules_cfgs/defaults-for-colocation-rules.cfg.expect
new file mode 100644
index 0000000..faafec8
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-colocation-rules.cfg.expect
@@ -0,0 +1,29 @@
+--- Log ---
+--- Config ---
+$VAR1 = {
+ 'digest' => '692081df1aaf03092f67cd415f5c66222b1d55e2',
+ 'ids' => {
+ 'colocation-defaults' => {
+ 'affinity' => 'separate',
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1
+ },
+ 'state' => 'enabled',
+ 'type' => 'colocation'
+ },
+ 'colocation-disabled' => {
+ 'affinity' => 'separate',
+ 'services' => {
+ 'vm:201' => 1,
+ 'vm:202' => 1
+ },
+ 'state' => 'disabled',
+ 'type' => 'colocation'
+ }
+ },
+ 'order' => {
+ 'colocation-defaults' => 1,
+ 'colocation-disabled' => 2
+ }
+ };
diff --git a/src/test/rules_cfgs/defaults-for-location-rules.cfg b/src/test/rules_cfgs/defaults-for-location-rules.cfg
new file mode 100644
index 0000000..728558d
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-location-rules.cfg
@@ -0,0 +1,16 @@
+# Case 1: Location rules are enabled and loose by default, so set it so if it isn't yet.
+location: location-defaults
+ services vm:101
+ nodes node1
+
+# Case 2: Location rule is disabled, it shouldn't be enabled afterwards.
+location: location-disabled
+ services vm:102
+ nodes node2
+ state disabled
+
+# Case 3: Location rule is set to strict, so it shouldn't be loose afterwards.
+location: location-strict
+ services vm:103
+ nodes node3
+ strict 1
diff --git a/src/test/rules_cfgs/defaults-for-location-rules.cfg.expect b/src/test/rules_cfgs/defaults-for-location-rules.cfg.expect
new file mode 100644
index 0000000..d534deb
--- /dev/null
+++ b/src/test/rules_cfgs/defaults-for-location-rules.cfg.expect
@@ -0,0 +1,49 @@
+--- Log ---
+--- Config ---
+$VAR1 = {
+ 'digest' => '27c1704d1a5497b314f8f5717b633184c1a1aacf',
+ 'ids' => {
+ 'location-defaults' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:101' => 1
+ },
+ 'state' => 'enabled',
+ 'type' => 'location'
+ },
+ 'location-disabled' => {
+ 'nodes' => {
+ 'node2' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:102' => 1
+ },
+ 'state' => 'disabled',
+ 'type' => 'location'
+ },
+ 'location-strict' => {
+ 'nodes' => {
+ 'node3' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:103' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ }
+ },
+ 'order' => {
+ 'location-defaults' => 1,
+ 'location-disabled' => 2,
+ 'location-strict' => 3
+ }
+ };
diff --git a/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg b/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg
new file mode 100644
index 0000000..7409bd7
--- /dev/null
+++ b/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg
@@ -0,0 +1,31 @@
+# Case 1: Do not remove two location rules, which do not share services.
+location: no-same-service1
+ services vm:101,vm:102,vm:103
+ nodes node1,node2:2
+ strict 0
+
+location: no-same-service2
+ services vm:104,vm:105
+ nodes node1,node2:2
+ strict 0
+
+location: no-same-service3
+ services vm:106
+ nodes node1,node2:2
+ strict 1
+
+# Case 2: Remove location rules, which share the same service between them.
+location: same-service1
+ services vm:201
+ nodes node1,node2:2
+ strict 0
+
+location: same-service2
+ services vm:201,vm:202
+ nodes node3
+ strict 1
+
+location: same-service3
+ services vm:201,vm:203,vm:204
+ nodes node1:2,node3:3
+ strict 0
diff --git a/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg.expect b/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg.expect
new file mode 100644
index 0000000..39b95bd
--- /dev/null
+++ b/src/test/rules_cfgs/duplicate-service-in-location-rules.cfg.expect
@@ -0,0 +1,66 @@
+--- Log ---
+Drop rule 'same-service1', because service 'vm:201' is already used in another location rule.
+Drop rule 'same-service2', because service 'vm:201' is already used in another location rule.
+Drop rule 'same-service3', because service 'vm:201' is already used in another location rule.
+--- Config ---
+$VAR1 = {
+ 'digest' => '07ee7a87159672339144fb9d1021b54905e09632',
+ 'ids' => {
+ 'no-same-service1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ },
+ 'node2' => {
+ 'priority' => 2
+ }
+ },
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1,
+ 'vm:103' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 0,
+ 'type' => 'location'
+ },
+ 'no-same-service2' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ },
+ 'node2' => {
+ 'priority' => 2
+ }
+ },
+ 'services' => {
+ 'vm:104' => 1,
+ 'vm:105' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 0,
+ 'type' => 'location'
+ },
+ 'no-same-service3' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ },
+ 'node2' => {
+ 'priority' => 2
+ }
+ },
+ 'services' => {
+ 'vm:106' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ }
+ },
+ 'order' => {
+ 'no-same-service1' => 1,
+ 'no-same-service2' => 2,
+ 'no-same-service3' => 3
+ }
+ };
diff --git a/src/test/rules_cfgs/inconsistent-colocation-rules.cfg b/src/test/rules_cfgs/inconsistent-colocation-rules.cfg
new file mode 100644
index 0000000..3199bfb
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-colocation-rules.cfg
@@ -0,0 +1,11 @@
+colocation: keep-apart1
+ services vm:102,vm:103
+ affinity separate
+
+colocation: keep-apart2
+ services vm:102,vm:104,vm:106
+ affinity separate
+
+colocation: stick-together1
+ services vm:101,vm:102,vm:103,vm:104,vm:106
+ affinity together
diff --git a/src/test/rules_cfgs/inconsistent-colocation-rules.cfg.expect b/src/test/rules_cfgs/inconsistent-colocation-rules.cfg.expect
new file mode 100644
index 0000000..b1989a8
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-colocation-rules.cfg.expect
@@ -0,0 +1,11 @@
+--- Log ---
+Drop rule 'keep-apart1', because rule shares two or more services with 'stick-together1'.
+Drop rule 'keep-apart2', because rule shares two or more services with 'stick-together1'.
+Drop rule 'stick-together1', because rule shares two or more services with 'keep-apart1'.
+Drop rule 'stick-together1', because rule shares two or more services with 'keep-apart2'.
+--- Config ---
+$VAR1 = {
+ 'digest' => '469bc45c05ffbb123a277fc0fda48e0132fc9046',
+ 'ids' => {},
+ 'order' => {}
+ };
diff --git a/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg b/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg
new file mode 100644
index 0000000..ed6b82d
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg
@@ -0,0 +1,54 @@
+# Case 1: Remove no positive colocation rule, where there is exactly one node to keep them together.
+location: vm101-vm102-must-be-on-node1
+ services vm:101,vm:102
+ nodes node1
+ strict 1
+
+colocation: vm101-vm102-must-be-kept-together
+ services vm:101,vm:102
+ affinity together
+
+# Case 2: Remove no negative colocation rule, where there are exactly enough nodes available to keep them apart.
+location: vm201-must-be-on-node1
+ services vm:201
+ nodes node1
+ strict 1
+
+location: vm202-must-be-on-node2
+ services vm:202
+ nodes node2
+ strict 1
+
+colocation: vm201-vm202-must-be-kept-separate
+ services vm:201,vm:202
+ affinity separate
+
+# Case 1: Remove the positive colocation rules, where two services are restricted to a different node.
+location: vm301-must-be-on-node1
+ services vm:301
+ nodes node1
+ strict 1
+
+location: vm301-must-be-on-node2
+ services vm:302
+ nodes node2
+ strict 1
+
+colocation: vm301-vm302-must-be-kept-together
+ services vm:301,vm:302
+ affinity together
+
+# Case 2: Remove the negative colocation rule, where two services are restricted to less nodes than needed to keep them apart.
+location: vm401-must-be-on-node1
+ services vm:401
+ nodes node1
+ strict 1
+
+location: vm402-must-be-on-node1
+ services vm:402
+ nodes node1
+ strict 1
+
+colocation: vm401-vm402-must-be-kept-separate
+ services vm:401,vm:402
+ affinity separate
diff --git a/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg.expect b/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg.expect
new file mode 100644
index 0000000..bed4668
--- /dev/null
+++ b/src/test/rules_cfgs/inconsistent-location-colocation-rules.cfg.expect
@@ -0,0 +1,130 @@
+--- Log ---
+Drop rule 'vm301-vm302-must-be-kept-together', because two or more services are restricted to different nodes.
+Drop rule 'vm401-vm402-must-be-kept-separate', because two or more services are restricted to less nodes than available to the services.
+--- Config ---
+$VAR1 = {
+ 'digest' => '27e76e13c20a1d11c5cbcf14434bcd54655fdd40',
+ 'ids' => {
+ 'vm101-vm102-must-be-kept-together' => {
+ 'affinity' => 'together',
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1
+ },
+ 'state' => 'enabled',
+ 'type' => 'colocation'
+ },
+ 'vm101-vm102-must-be-on-node1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm201-must-be-on-node1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:201' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm201-vm202-must-be-kept-separate' => {
+ 'affinity' => 'separate',
+ 'services' => {
+ 'vm:201' => 1,
+ 'vm:202' => 1
+ },
+ 'state' => 'enabled',
+ 'type' => 'colocation'
+ },
+ 'vm202-must-be-on-node2' => {
+ 'nodes' => {
+ 'node2' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:202' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm301-must-be-on-node1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:301' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm301-must-be-on-node2' => {
+ 'nodes' => {
+ 'node2' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:302' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm401-must-be-on-node1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:401' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ },
+ 'vm402-must-be-on-node1' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 0
+ }
+ },
+ 'services' => {
+ 'vm:402' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ }
+ },
+ 'order' => {
+ 'vm101-vm102-must-be-kept-together' => 2,
+ 'vm101-vm102-must-be-on-node1' => 1,
+ 'vm201-must-be-on-node1' => 3,
+ 'vm201-vm202-must-be-kept-separate' => 5,
+ 'vm202-must-be-on-node2' => 4,
+ 'vm301-must-be-on-node1' => 6,
+ 'vm301-must-be-on-node2' => 7,
+ 'vm401-must-be-on-node1' => 9,
+ 'vm402-must-be-on-node1' => 10
+ }
+ };
diff --git a/src/test/rules_cfgs/ineffective-colocation-rules.cfg b/src/test/rules_cfgs/ineffective-colocation-rules.cfg
new file mode 100644
index 0000000..4f2338e
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-colocation-rules.cfg
@@ -0,0 +1,7 @@
+colocation: lonely-service1
+ services vm:101
+ affinity together
+
+colocation: lonely-service2
+ services vm:101
+ affinity separate
diff --git a/src/test/rules_cfgs/ineffective-colocation-rules.cfg.expect b/src/test/rules_cfgs/ineffective-colocation-rules.cfg.expect
new file mode 100644
index 0000000..3741ba7
--- /dev/null
+++ b/src/test/rules_cfgs/ineffective-colocation-rules.cfg.expect
@@ -0,0 +1,9 @@
+--- Log ---
+Drop rule 'lonely-service1', because rule is ineffective as there are less than two services.
+Drop rule 'lonely-service2', because rule is ineffective as there are less than two services.
+--- Config ---
+$VAR1 = {
+ 'digest' => '47bdd78898e4193aa113ab05b0fd7aaaeb08109d',
+ 'ids' => {},
+ 'order' => {}
+ };
diff --git a/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg b/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg
new file mode 100644
index 0000000..889fe47
--- /dev/null
+++ b/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg
@@ -0,0 +1,19 @@
+# Case 1: Remove colocation rules, where there is a loose location rule with multiple priority groups set for the nodes.
+location: vm101-vm102-should-be-on-node1-or-node2
+ services vm:101,vm:102
+ nodes node1:1,node2:2
+ strict 0
+
+colocation: vm101-vm102-must-be-kept-separate
+ services vm:101,vm:102
+ affinity separate
+
+# Case 2: Remove colocation rules, where there is a strict location rule with multiple priority groups set for the nodes.
+location: vm201-vm202-must-be-on-node1-or-node2
+ services vm:201,vm:202
+ nodes node1:1,node2:2
+ strict 1
+
+colocation: vm201-vm202-must-be-kept-together
+ services vm:201,vm:202
+ affinity together
diff --git a/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg.expect b/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg.expect
new file mode 100644
index 0000000..47c7af5
--- /dev/null
+++ b/src/test/rules_cfgs/multi-priority-location-with-colocation.cfg.expect
@@ -0,0 +1,47 @@
+--- Log ---
+Drop rule 'vm101-vm102-must-be-kept-separate', because services are in location rules with multiple priorities.
+Drop rule 'vm201-vm202-must-be-kept-together', because services are in location rules with multiple priorities.
+--- Config ---
+$VAR1 = {
+ 'digest' => '30292457018bf1ae4fcf9bea92199233c877bf28',
+ 'ids' => {
+ 'vm101-vm102-should-be-on-node1-or-node2' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 1
+ },
+ 'node2' => {
+ 'priority' => 2
+ }
+ },
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 0,
+ 'type' => 'location'
+ },
+ 'vm201-vm202-must-be-on-node1-or-node2' => {
+ 'nodes' => {
+ 'node1' => {
+ 'priority' => 1
+ },
+ 'node2' => {
+ 'priority' => 2
+ }
+ },
+ 'services' => {
+ 'vm:201' => 1,
+ 'vm:202' => 1
+ },
+ 'state' => 'enabled',
+ 'strict' => 1,
+ 'type' => 'location'
+ }
+ },
+ 'order' => {
+ 'vm101-vm102-should-be-on-node1-or-node2' => 1,
+ 'vm201-vm202-must-be-on-node1-or-node2' => 3
+ }
+ };
diff --git a/src/test/test_rules_config.pl b/src/test/test_rules_config.pl
new file mode 100755
index 0000000..6e6b7de
--- /dev/null
+++ b/src/test/test_rules_config.pl
@@ -0,0 +1,102 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+use lib qw(..);
+
+use Test::More;
+use Test::MockModule;
+
+use Data::Dumper;
+
+use PVE::HA::Rules;
+use PVE::HA::Rules::Location;
+use PVE::HA::Rules::Colocation;
+
+PVE::HA::Rules::Location->register();
+PVE::HA::Rules::Colocation->register();
+
+PVE::HA::Rules->init(property_isolation => 1);
+
+my $opt_nodiff;
+
+if (!GetOptions("nodiff" => \$opt_nodiff)) {
+ print "usage: $0 [test.cfg] [--nodiff]\n";
+ exit -1;
+}
+
+sub _log {
+ my ($fh, $source, $message) = @_;
+
+ chomp $message;
+ $message = "[$source] $message" if $source;
+
+ print "$message\n";
+
+ $fh->print("$message\n");
+ $fh->flush();
+}
+
+sub check_cfg {
+ my ($cfg_fn, $outfile) = @_;
+
+ my $raw = PVE::Tools::file_get_contents($cfg_fn);
+
+ open(my $LOG, '>', "$outfile");
+ select($LOG);
+ $| = 1;
+
+ print "--- Log ---\n";
+ my $cfg = PVE::HA::Rules->parse_config($cfg_fn, $raw);
+ PVE::HA::Rules->set_rule_defaults($_) for values %{ $cfg->{ids} };
+ my $messages = PVE::HA::Rules->canonicalize($cfg);
+ print $_ for @$messages;
+ print "--- Config ---\n";
+ {
+ local $Data::Dumper::Sortkeys = 1;
+ print Dumper($cfg);
+ }
+
+ select(STDOUT);
+}
+
+sub run_test {
+ my ($cfg_fn) = @_;
+
+ print "* check: $cfg_fn\n";
+
+ my $outfile = "$cfg_fn.output";
+ my $expect = "$cfg_fn.expect";
+
+ eval { check_cfg($cfg_fn, $outfile); };
+ if (my $err = $@) {
+ die "Test '$cfg_fn' failed:\n$err\n";
+ }
+
+ return if $opt_nodiff;
+
+ my $res;
+
+ if (-f $expect) {
+ my $cmd = ['diff', '-u', $expect, $outfile];
+ $res = system(@$cmd);
+ die "test '$cfg_fn' failed\n" if $res != 0;
+ } else {
+ $res = system('cp', $outfile, $expect);
+ die "test '$cfg_fn' failed\n" if $res != 0;
+ }
+
+ print "* end rules test: $cfg_fn (success)\n\n";
+}
+
+# exec tests
+
+if (my $testcfg = shift) {
+ run_test($testcfg);
+} else {
+ for my $cfg (<rules_cfgs/*cfg>) {
+ run_test($cfg);
+ }
+}
--
2.39.5
More information about the pve-devel
mailing list