test-lockfile: Provide better diagnostics on failure.
[sliver-openvswitch.git] / tests / compare-odp-actions.pl
1 # -*- perl -*-
2
3 use strict;
4 use warnings;
5
6 if (@ARGV < 2) {
7     print <<EOF;
8 $0: to check ODP sets of actions for equivalence
9 usage: $0 ACTIONS1 ACTIONS2 [NAME=NUMBER]...
10 where ACTIONS1 and ACTIONS2 are sets of ODP actions as output by, e.g.
11       "ovs-dpctl dump-flows" and each NAME=NUMBER pair identifies an ODP
12       port's name-to-number mapping.
13
14 Exits with status 0 if ACTIONS1 and ACTIONS2 are equivalent, with
15 status 1 if they differ.
16 EOF
17     exit 1;
18 }
19
20 # Construct mappings between port numbers and names.
21 our (%name_to_number);
22 our (%number_to_name);
23 for (@ARGV[2..$#ARGV]) {
24     my ($name, $number) = /([^=]+)=([0-9]+)/
25       or die "$_: bad syntax (use --help for help)\n";
26     $number_to_name{$number} = $name;
27     $name_to_number{$name} = $number;
28 }
29
30 my $n1 = normalize_odp_actions($ARGV[0]);
31 my $n2 = normalize_odp_actions($ARGV[1]);
32 print "Normalized action set 1: $n1\n";
33 print "Normalized action set 2: $n2\n";
34 exit($n1 ne $n2);
35
36 sub normalize_odp_actions {
37     my ($actions) = @_;
38
39     # Transliterate all commas inside parentheses into semicolons.
40     undef while $actions =~ s/(\([^),]*),([^)]*\))/$1;$2/g;
41
42     # Split on commas.
43     my (@actions) = split(',', $actions);
44
45     # Map port numbers into port names.
46     foreach my $s (@actions) {
47         $s = $number_to_name{$s} if exists($number_to_name{$s});
48     }
49
50     # Sort sequential groups of port names into alphabetical order.
51     for (my $i = 0; $i <= $#actions; ) {
52         my $j = $i + 1;
53         if (exists($name_to_number{$actions[$i]})) {
54             for (; $j <= $#actions; $j++) {
55                 last if !exists($name_to_number{$actions[$j]});
56             }
57         }
58         @actions[$i..($j - 1)] = sort(@actions[$i..($j - 1)]);
59         $i = $j;
60     }
61
62     # Now compose a string again and transliterate semicolons back to commas.
63     $actions = join(',', @actions);
64     $actions =~ tr/;/,/;
65     return $actions;
66 }