[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