[pve-devel] [PATCH ha-manager 4/7] add parser self check regression test
Thomas Lamprecht
t.lamprecht at proxmox.com
Thu Jul 14 14:41:50 CEST 2016
This test does a read -> write -> read cycle and then checks if the
config generated from the first read and the config generated from
the second read are equivalent (semantically).
This tests mainly the FenceConfig::write_config method, the
parse_config method gets checked with the already implemented config
regression tests.
To compare both configs we add a deep object compare method,
it can compare Objects with arbitrary nested data structures from the
types: hash, array and scalar.
It makes an depth first search with some early abortion checks on
the roots of subtrees (i.e. is the length and type the same).
Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
src/test/test_fence_config.pl | 108 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/src/test/test_fence_config.pl b/src/test/test_fence_config.pl
index 662ceae..7ca7e7f 100755
--- a/src/test/test_fence_config.pl
+++ b/src/test/test_fence_config.pl
@@ -38,6 +38,68 @@ sub get_nodes {
return ('node1', 'node2', 'node3');
};
+# compares if two data structures are equivalent.
+# the may contain hashes, arrays, scalars. May be nested also, we travel
+# through the structure recursively
+sub deep_cmp {
+ my ($a, $b, $noerr) = @_;
+
+ eval {
+ if (ref($a) ne ref($b)) {
+ die "variables not the same ref: " . ref($a) ." != " . ref($b) . "\n";
+ }
+
+ if (ref($a) eq 'HASH') {
+ if (scalar(keys %$a) != scalar(keys %$b)) {
+ die "variables are not of the same length\n";
+ }
+
+ my %cmp = map { $_ => 1 } keys %$a;
+ for my $key (keys %$b) {
+ if (!exists $cmp{$key}) {
+ die "variables not equal";
+ }
+ if(!deep_cmp($a->{$key}, $b->{$key})) {
+ die "variables not equal";
+ }
+ delete $cmp{$key};
+ }
+
+ die "variables not equal" if %cmp;
+
+ } elsif (ref($a) eq 'ARRAY') {
+ if (scalar(@$a) != scalar(@$b)) {
+ die "variables are not of the same length\n";
+ }
+
+ for (my $i = 0; $i < scalar(@$a); $i++) {
+ if(!deep_cmp(@$a[$i], @$b[$i])) {
+ die "variables not equal";
+ }
+ }
+
+ } elsif (ref($a) eq 'SCALAR' || ref($a) eq '') {
+
+ if(defined $a && defined $b) {
+ return $a eq $b;
+ } else {
+ return !(defined $a || defined $b);
+ }
+
+ } else {
+ die "unimplemented ref type: '" . ref($a) . "'\n";
+ }
+ };
+ if (my $err = $@) {
+ $err = "deep_cmp: $err";
+ die $err if !$noerr;
+ warn $err;
+ return undef;
+ }
+
+ return 1;
+}
+
sub check_cfg {
my ($cfg_fn, $outfile) = @_;
@@ -82,6 +144,50 @@ sub check_cfg {
}
};
+sub parser_self_check {
+ my $cfg_fn = shift;
+
+ print "* parser self check: $cfg_fn\n";
+
+ my $outfile = "$cfg_fn.write";
+ my ($config1, $config2, $raw);
+
+ eval {
+ # read first time
+ $raw = PVE::Tools::file_get_contents($cfg_fn);
+ $config1 = PVE::HA::FenceConfig::parse_config($cfg_fn, $raw);
+ };
+ if (my $err = $@) {
+ print "* initial parse failed, skip parser self check\n\n";
+ return;
+ }
+
+ eval {
+ # write config
+ $raw = PVE::HA::FenceConfig::write_config($outfile, $config1);
+ PVE::Tools::file_set_contents($outfile, $raw);
+
+ # reread written config (must be the same as config1)
+ $raw = PVE::Tools::file_get_contents($outfile);
+ $config2 = PVE::HA::FenceConfig::parse_config($outfile, $raw);
+
+ };
+ if (my $err = $@) {
+ die "parser_self_check test error: $err";
+ }
+
+ my $res;
+ eval {
+ $res = deep_cmp($config1, $config2);
+ };
+ if (my $err = $@ || !$res) {
+ die "parser_self_check test failed! Configs not equivalent\n" .
+ Dumper($config1, $config2) . "\n";
+ }
+
+ print "* end parser_self_check: $cfg_fn (success)\n\n";
+}
+
sub run_test {
my $cfg_fn = shift;
@@ -117,8 +223,10 @@ sub run_test {
if (my $testcfg = shift) {
run_test($testcfg);
+ parser_self_check($testcfg);
} else {
foreach my $cfg (<fence_cfgs/*.cfg>) {
run_test($cfg);
+ parser_self_check($cfg);
}
}
--
2.1.4
More information about the pve-devel
mailing list