[pve-devel] [PATCH ha-manager 15/15] test: add test cases for rules config
Daniel Kral
d.kral at proxmox.com
Tue Mar 25 16:12:54 CET 2025
Add test cases to verify the correct transformation of various types of
ill-defined colocation rules:
- Merging multiple, transitive positive colocation rules of the same
strictness level
- Dropping colocation rules with not enough defined services
- Dropping colocation rules which have inner conflicts
Signed-off-by: Daniel Kral <d.kral at proxmox.com>
---
These aren't exhaustive yet since there's no tests in conjunction with
HA groups yet.
.gitignore | 1 +
src/test/Makefile | 4 +-
.../connected-positive-colocations.cfg | 34 ++++++
.../connected-positive-colocations.cfg.expect | 54 ++++++++++
.../rules_cfgs/illdefined-colocations.cfg | 9 ++
.../illdefined-colocations.cfg.expect | 12 +++
.../inner-inconsistent-colocations.cfg | 14 +++
.../inner-inconsistent-colocations.cfg.expect | 13 +++
src/test/test_rules_config.pl | 100 ++++++++++++++++++
9 files changed, 240 insertions(+), 1 deletion(-)
create mode 100644 src/test/rules_cfgs/connected-positive-colocations.cfg
create mode 100644 src/test/rules_cfgs/connected-positive-colocations.cfg.expect
create mode 100644 src/test/rules_cfgs/illdefined-colocations.cfg
create mode 100644 src/test/rules_cfgs/illdefined-colocations.cfg.expect
create mode 100644 src/test/rules_cfgs/inner-inconsistent-colocations.cfg
create mode 100644 src/test/rules_cfgs/inner-inconsistent-colocations.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/connected-positive-colocations.cfg b/src/test/rules_cfgs/connected-positive-colocations.cfg
new file mode 100644
index 0000000..8cd6e0c
--- /dev/null
+++ b/src/test/rules_cfgs/connected-positive-colocations.cfg
@@ -0,0 +1,34 @@
+colocation: positive1
+ services vm:101,vm:106,vm:108
+ affinity together
+ strict 0
+
+colocation: positive2
+ services vm:106,vm:109
+ affinity together
+ strict 0
+
+colocation: positive3
+ services vm:107,vm:105
+ affinity together
+ strict 0
+
+colocation: positive4
+ services vm:101,vm:102,vm:103
+ affinity together
+ strict 0
+
+colocation: positive5
+ services vm:101,vm:104
+ affinity together
+ strict 1
+
+colocation: positive6
+ services vm:105,vm:110
+ affinity together
+ strict 0
+
+colocation: positive7
+ services vm:108,vm:104,vm:109
+ affinity together
+ strict 1
diff --git a/src/test/rules_cfgs/connected-positive-colocations.cfg.expect b/src/test/rules_cfgs/connected-positive-colocations.cfg.expect
new file mode 100644
index 0000000..f20a87e
--- /dev/null
+++ b/src/test/rules_cfgs/connected-positive-colocations.cfg.expect
@@ -0,0 +1,54 @@
+--- Log ---
+Merge services of positive colocation rule 'positive2' into positive colocation rule 'positive1', because they share at least one service.
+Merge services of positive colocation rule 'positive4' into positive colocation rule 'positive1', because they share at least one service.
+Merge services of positive colocation rule 'positive6' into positive colocation rule 'positive3', because they share at least one service.
+Merge services of positive colocation rule 'positive7' into positive colocation rule 'positive5', because they share at least one service.
+--- Config ---
+$VAR1 = {
+ 'digest' => '7781c41891832c7f955d835edcdc38fa6b673bea',
+ 'ids' => {
+ 'positive1' => {
+ 'affinity' => 'together',
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:102' => 1,
+ 'vm:103' => 1,
+ 'vm:106' => 1,
+ 'vm:108' => 1,
+ 'vm:109' => 1
+ },
+ 'strict' => 0,
+ 'type' => 'colocation'
+ },
+ 'positive3' => {
+ 'affinity' => 'together',
+ 'services' => {
+ 'vm:105' => 1,
+ 'vm:107' => 1,
+ 'vm:110' => 1
+ },
+ 'strict' => 0,
+ 'type' => 'colocation'
+ },
+ 'positive5' => {
+ 'affinity' => 'together',
+ 'services' => {
+ 'vm:101' => 1,
+ 'vm:104' => 1,
+ 'vm:108' => 1,
+ 'vm:109' => 1
+ },
+ 'strict' => 1,
+ 'type' => 'colocation'
+ }
+ },
+ 'order' => {
+ 'positive1' => 1,
+ 'positive2' => 2,
+ 'positive3' => 3,
+ 'positive4' => 4,
+ 'positive5' => 5,
+ 'positive6' => 6,
+ 'positive7' => 7
+ }
+ };
diff --git a/src/test/rules_cfgs/illdefined-colocations.cfg b/src/test/rules_cfgs/illdefined-colocations.cfg
new file mode 100644
index 0000000..2a4bf9c
--- /dev/null
+++ b/src/test/rules_cfgs/illdefined-colocations.cfg
@@ -0,0 +1,9 @@
+colocation: lonely-service1
+ services vm:101
+ affinity together
+ strict 1
+
+colocation: lonely-service2
+ services vm:101
+ affinity separate
+ strict 1
diff --git a/src/test/rules_cfgs/illdefined-colocations.cfg.expect b/src/test/rules_cfgs/illdefined-colocations.cfg.expect
new file mode 100644
index 0000000..68ce44a
--- /dev/null
+++ b/src/test/rules_cfgs/illdefined-colocations.cfg.expect
@@ -0,0 +1,12 @@
+--- Log ---
+Drop colocation rule 'lonely-service1', because it does not have enough services defined.
+Drop colocation rule 'lonely-service2', because it does not have enough services defined.
+--- Config ---
+$VAR1 = {
+ 'digest' => 'd174e745359cbc8c2e0f950ab5a4d202ffaf15e2',
+ 'ids' => {},
+ 'order' => {
+ 'lonely-service1' => 1,
+ 'lonely-service2' => 2
+ }
+ };
diff --git a/src/test/rules_cfgs/inner-inconsistent-colocations.cfg b/src/test/rules_cfgs/inner-inconsistent-colocations.cfg
new file mode 100644
index 0000000..70ae352
--- /dev/null
+++ b/src/test/rules_cfgs/inner-inconsistent-colocations.cfg
@@ -0,0 +1,14 @@
+colocation: keep-apart1
+ services vm:102,vm:103
+ affinity separate
+ strict 1
+
+colocation: keep-apart2
+ services vm:102,vm:104,vm:106
+ affinity separate
+ strict 1
+
+colocation: stick-together1
+ services vm:101,vm:102,vm:103,vm:104,vm:106
+ affinity together
+ strict 1
diff --git a/src/test/rules_cfgs/inner-inconsistent-colocations.cfg.expect b/src/test/rules_cfgs/inner-inconsistent-colocations.cfg.expect
new file mode 100644
index 0000000..ea5b96b
--- /dev/null
+++ b/src/test/rules_cfgs/inner-inconsistent-colocations.cfg.expect
@@ -0,0 +1,13 @@
+--- Log ---
+Drop positive colocation rule 'stick-together1' and negative colocation rule 'keep-apart1', because they share two or more services.
+Drop positive colocation rule 'stick-together1' and negative colocation rule 'keep-apart2', because they share two or more services.
+--- Config ---
+$VAR1 = {
+ 'digest' => '1e6a049065bec399e5982d24eb348465eec8520b',
+ 'ids' => {},
+ 'order' => {
+ 'keep-apart1' => 1,
+ 'keep-apart2' => 2,
+ 'stick-together1' => 3
+ }
+ };
diff --git a/src/test/test_rules_config.pl b/src/test/test_rules_config.pl
new file mode 100755
index 0000000..0eb55c3
--- /dev/null
+++ b/src/test/test_rules_config.pl
@@ -0,0 +1,100 @@
+#!/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::Colocation;
+
+PVE::HA::Rules::Colocation->register();
+
+PVE::HA::Rules->init();
+
+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::checked_config($cfg, {}, {});
+ 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