diff mbox series

[ovs-dev,2/9] tests: Convert ovsdb-monitor-sort utility from Perl to Python.

Message ID 20171115185318.26841-2-blp@ovn.org
State Superseded
Headers show
Series [ovs-dev,1/9] tests: Convert uuidfilt utility from Perl to Python. | expand

Commit Message

Ben Pfaff Nov. 15, 2017, 6:53 p.m. UTC
Perl is unfashionable and Python is more widely available and understood,
so this commit converts one of the OVS uses of Perl into Python.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 tests/automake.mk           |  2 +-
 tests/ovsdb-monitor-sort.pl | 52 ---------------------------
 tests/ovsdb-monitor-sort.py | 85 +++++++++++++++++++++++++++++++++++++++++++++
 tests/ovsdb-monitor.at      |  4 +--
 4 files changed, 88 insertions(+), 55 deletions(-)
 delete mode 100755 tests/ovsdb-monitor-sort.pl
 create mode 100755 tests/ovsdb-monitor-sort.py

Comments

Aaron Conole Nov. 16, 2017, 2:35 p.m. UTC | #1
Hi Ben,

Ben Pfaff <blp@ovn.org> writes:

> Perl is unfashionable and Python is more widely available and understood,
> so this commit converts one of the OVS uses of Perl into Python.
>
> Signed-off-by: Ben Pfaff <blp@ovn.org>
> ---
>  tests/automake.mk           |  2 +-
>  tests/ovsdb-monitor-sort.pl | 52 ---------------------------
>  tests/ovsdb-monitor-sort.py | 85 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/ovsdb-monitor.at      |  4 +--
>  4 files changed, 88 insertions(+), 55 deletions(-)
>  delete mode 100755 tests/ovsdb-monitor-sort.pl
>  create mode 100755 tests/ovsdb-monitor-sort.py
>
> diff --git a/tests/automake.mk b/tests/automake.mk
> index 3ca60e2ea450..1ea08fef850d 100644
> --- a/tests/automake.mk
> +++ b/tests/automake.mk
> @@ -290,7 +290,6 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
>  noinst_PROGRAMS += tests/test-ovsdb
>  tests_test_ovsdb_SOURCES = tests/test-ovsdb.c
>  nodist_tests_test_ovsdb_SOURCES = tests/idltest.c tests/idltest.h
> -EXTRA_DIST += tests/ovsdb-monitor-sort.pl
>  tests_test_ovsdb_LDADD = ovsdb/libovsdb.la lib/libopenvswitch.la
>  
>  noinst_PROGRAMS += tests/test-lib
> @@ -380,6 +379,7 @@ tests_test_type_props_SOURCES = tests/test-type-props.c
>  # Python tests.
>  CHECK_PYFILES = \
>  	tests/appctl.py \
> +	tests/ovsdb-monitor-sort.py \
>  	tests/test-daemon.py \
>  	tests/test-json.py \
>  	tests/test-jsonrpc.py \
> diff --git a/tests/ovsdb-monitor-sort.pl b/tests/ovsdb-monitor-sort.pl
> deleted file mode 100755
> index 24f3ffcd6162..000000000000
> --- a/tests/ovsdb-monitor-sort.pl
> +++ /dev/null
> @@ -1,52 +0,0 @@
> -#! /usr/bin/perl
> -
> -use strict;
> -use warnings;
> -
> -# Breaks lines read from <STDIN> into groups using blank lines as
> -# group separators, then sorts lines within the groups for
> -# reproducibility.
> -
> -sub compare_lines {
> -    my ($a, $b) = @_;
> -
> -    my $u = '[0-9a-fA-F]';
> -    my $uuid_re = "${u}{8}-${u}{4}-${u}{4}-${u}{4}-${u}{12}";
> -    if ($a =~ /^$uuid_re/) {
> -        if ($b =~ /^$uuid_re/) {
> -            return substr($a, 36) cmp substr($b, 36);
> -        } else {
> -            return 1;
> -        }
> -    } elsif ($b =~ /^$uuid_re/) {
> -        return -1;
> -    } else {
> -        return $a cmp $b;
> -    }
> -}
> -
> -sub output_group {
> -    my (@group) = @_;
> -    print "$_\n" foreach sort { compare_lines($a, $b) } @group;
> -}
> -
> -if ("$^O" eq "msys") {
> -    $/ = "\r\n";
> -}
> -my @group = ();
> -while (<STDIN>) {
> -    chomp;
> -    if ($_ eq '') {
> -        output_group(@group);
> -        @group = ();
> -        print "\n";
> -    } else {
> -        if (/^,/ && @group) {
> -            $group[$#group] .= "\n" . $_;
> -        } else {
> -            push(@group, $_);
> -        }
> -    }
> -}
> -
> -output_group(@group) if @group;
> diff --git a/tests/ovsdb-monitor-sort.py b/tests/ovsdb-monitor-sort.py
> new file mode 100755
> index 000000000000..c538d9d6b573
> --- /dev/null
> +++ b/tests/ovsdb-monitor-sort.py
> @@ -0,0 +1,85 @@
> +#! /usr/bin/env python
> +
> +# Breaks lines read from stdin into groups using blank lines as
> +# group separators, then sorts lines within the groups for
> +# reproducibility.
> +
> +import re
> +import sys
> +
> +
> +# This is copied out of the Python Sorting HOWTO at
> +# https://docs.python.org/3/howto/sorting.html#sortinghowto
> +def cmp_to_key(mycmp):
> +    'Convert a cmp= function into a key= function'
> +    class K:

I get a flake8 complaint for this - I think it should be:

 class K(object):
 ...

> +
> +        def __init__(self, obj, *args):
> +            self.obj = obj
> +
> +        def __lt__(self, other):
> +            return mycmp(self.obj, other.obj) < 0
> +
> +        def __gt__(self, other):
> +            return mycmp(self.obj, other.obj) > 0
> +
> +        def __eq__(self, other):
> +            return mycmp(self.obj, other.obj) == 0
> +
> +        def __le__(self, other):
> +            return mycmp(self.obj, other.obj) <= 0
> +
> +        def __ge__(self, other):
> +            return mycmp(self.obj, other.obj) >= 0
> +
> +        def __ne__(self, other):
> +            return mycmp(self.obj, other.obj) != 0
> +
> +    return K
> +
> +
> +u = '[0-9a-fA-F]'
> +uuid_re = re.compile(r'%s{8}-%s{4}-%s{4}-%s{4}-%s{12}' % ((u,) * 5))
> +
> +
> +def cmp(a, b):
> +    return (a > b) - (a < b)
> +
> +
> +def compare_lines(a, b):
> +    if uuid_re.match(a):
> +        if uuid_re.match(b):
> +            return cmp(a[36:], b[36:])
> +        else:
> +            return 1
> +    elif uuid_re.match(b):
> +        return -1
> +    else:
> +        return cmp(a, b)
> +
> +
> +def output_group(group, dst):
> +    for x in sorted(group, key=cmp_to_key(compare_lines)):
> +        dst.write(x)
> +
> +
> +def ovsdb_monitor_sort(src, dst):
> +    group = []
> +    while True:
> +        line = src.readline()
> +        if not line:
> +            break
> +        if line.rstrip() == '':
> +            output_group(group, dst)
> +            group = []
> +            dst.write(line)
> +        elif line.startswith(',') and group:
> +            group[len(group) - 1] += line
> +        else:
> +            group.append(line)
> +    if group:
> +        output_group(group, dst)
> +
> +
> +if __name__ == '__main__':
> +    ovsdb_monitor_sort(sys.stdin, sys.stdout)
> diff --git a/tests/ovsdb-monitor.at b/tests/ovsdb-monitor.at
> index 65c595645b14..2434f43cb761 100644
> --- a/tests/ovsdb-monitor.at
> +++ b/tests/ovsdb-monitor.at
> @@ -44,7 +44,7 @@ m4_define([OVSDB_CHECK_MONITOR],
>              [ignore], [ignore])
>     OVS_APP_EXIT_AND_WAIT_BY_TARGET([ovsdb-server], [ovsdb-server.pid])
>     OVS_WAIT_UNTIL([test ! -e ovsdb-client.pid])
> -   AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | uuidfilt], [0], [$7], [ignore])
> +   AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$7], [ignore])
>     AT_CLEANUP])
>  
>  # OVSDB_CHECK_MONITOR_COND(TITLE, SCHEMA, [PRE-MONITOR-TXN], DB, TABLE,
> @@ -86,7 +86,7 @@ m4_define([OVSDB_CHECK_MONITOR_COND],
>              [ignore], [ignore])
>     AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore])
>     OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
> -   AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | uuidfilt], [0], [$7], [ignore])
> +   AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$7], [ignore])
>     AT_CLEANUP])
>  
>  OVSDB_CHECK_MONITOR([monitor insert into empty table],
Ben Pfaff Nov. 20, 2017, 6:03 p.m. UTC | #2
On Thu, Nov 16, 2017 at 09:35:48AM -0500, Aaron Conole wrote:
> Ben Pfaff <blp@ovn.org> writes:
> 
> > Perl is unfashionable and Python is more widely available and understood,
> > so this commit converts one of the OVS uses of Perl into Python.
> >
> > Signed-off-by: Ben Pfaff <blp@ovn.org>
> > +# This is copied out of the Python Sorting HOWTO at
> > +# https://docs.python.org/3/howto/sorting.html#sortinghowto
> > +def cmp_to_key(mycmp):
> > +    'Convert a cmp= function into a key= function'
> > +    class K:
> 
> I get a flake8 complaint for this - I think it should be:
> 
>  class K(object):
>  ...

Thanks, fixed.

(It is somewhat hilarious that Python documentation doesn't follow
Python standards, though.)
diff mbox series

Patch

diff --git a/tests/automake.mk b/tests/automake.mk
index 3ca60e2ea450..1ea08fef850d 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -290,7 +290,6 @@  $(srcdir)/package.m4: $(top_srcdir)/configure.ac
 noinst_PROGRAMS += tests/test-ovsdb
 tests_test_ovsdb_SOURCES = tests/test-ovsdb.c
 nodist_tests_test_ovsdb_SOURCES = tests/idltest.c tests/idltest.h
-EXTRA_DIST += tests/ovsdb-monitor-sort.pl
 tests_test_ovsdb_LDADD = ovsdb/libovsdb.la lib/libopenvswitch.la
 
 noinst_PROGRAMS += tests/test-lib
@@ -380,6 +379,7 @@  tests_test_type_props_SOURCES = tests/test-type-props.c
 # Python tests.
 CHECK_PYFILES = \
 	tests/appctl.py \
+	tests/ovsdb-monitor-sort.py \
 	tests/test-daemon.py \
 	tests/test-json.py \
 	tests/test-jsonrpc.py \
diff --git a/tests/ovsdb-monitor-sort.pl b/tests/ovsdb-monitor-sort.pl
deleted file mode 100755
index 24f3ffcd6162..000000000000
--- a/tests/ovsdb-monitor-sort.pl
+++ /dev/null
@@ -1,52 +0,0 @@ 
-#! /usr/bin/perl
-
-use strict;
-use warnings;
-
-# Breaks lines read from <STDIN> into groups using blank lines as
-# group separators, then sorts lines within the groups for
-# reproducibility.
-
-sub compare_lines {
-    my ($a, $b) = @_;
-
-    my $u = '[0-9a-fA-F]';
-    my $uuid_re = "${u}{8}-${u}{4}-${u}{4}-${u}{4}-${u}{12}";
-    if ($a =~ /^$uuid_re/) {
-        if ($b =~ /^$uuid_re/) {
-            return substr($a, 36) cmp substr($b, 36);
-        } else {
-            return 1;
-        }
-    } elsif ($b =~ /^$uuid_re/) {
-        return -1;
-    } else {
-        return $a cmp $b;
-    }
-}
-
-sub output_group {
-    my (@group) = @_;
-    print "$_\n" foreach sort { compare_lines($a, $b) } @group;
-}
-
-if ("$^O" eq "msys") {
-    $/ = "\r\n";
-}
-my @group = ();
-while (<STDIN>) {
-    chomp;
-    if ($_ eq '') {
-        output_group(@group);
-        @group = ();
-        print "\n";
-    } else {
-        if (/^,/ && @group) {
-            $group[$#group] .= "\n" . $_;
-        } else {
-            push(@group, $_);
-        }
-    }
-}
-
-output_group(@group) if @group;
diff --git a/tests/ovsdb-monitor-sort.py b/tests/ovsdb-monitor-sort.py
new file mode 100755
index 000000000000..c538d9d6b573
--- /dev/null
+++ b/tests/ovsdb-monitor-sort.py
@@ -0,0 +1,85 @@ 
+#! /usr/bin/env python
+
+# Breaks lines read from stdin into groups using blank lines as
+# group separators, then sorts lines within the groups for
+# reproducibility.
+
+import re
+import sys
+
+
+# This is copied out of the Python Sorting HOWTO at
+# https://docs.python.org/3/howto/sorting.html#sortinghowto
+def cmp_to_key(mycmp):
+    'Convert a cmp= function into a key= function'
+    class K:
+
+        def __init__(self, obj, *args):
+            self.obj = obj
+
+        def __lt__(self, other):
+            return mycmp(self.obj, other.obj) < 0
+
+        def __gt__(self, other):
+            return mycmp(self.obj, other.obj) > 0
+
+        def __eq__(self, other):
+            return mycmp(self.obj, other.obj) == 0
+
+        def __le__(self, other):
+            return mycmp(self.obj, other.obj) <= 0
+
+        def __ge__(self, other):
+            return mycmp(self.obj, other.obj) >= 0
+
+        def __ne__(self, other):
+            return mycmp(self.obj, other.obj) != 0
+
+    return K
+
+
+u = '[0-9a-fA-F]'
+uuid_re = re.compile(r'%s{8}-%s{4}-%s{4}-%s{4}-%s{12}' % ((u,) * 5))
+
+
+def cmp(a, b):
+    return (a > b) - (a < b)
+
+
+def compare_lines(a, b):
+    if uuid_re.match(a):
+        if uuid_re.match(b):
+            return cmp(a[36:], b[36:])
+        else:
+            return 1
+    elif uuid_re.match(b):
+        return -1
+    else:
+        return cmp(a, b)
+
+
+def output_group(group, dst):
+    for x in sorted(group, key=cmp_to_key(compare_lines)):
+        dst.write(x)
+
+
+def ovsdb_monitor_sort(src, dst):
+    group = []
+    while True:
+        line = src.readline()
+        if not line:
+            break
+        if line.rstrip() == '':
+            output_group(group, dst)
+            group = []
+            dst.write(line)
+        elif line.startswith(',') and group:
+            group[len(group) - 1] += line
+        else:
+            group.append(line)
+    if group:
+        output_group(group, dst)
+
+
+if __name__ == '__main__':
+    ovsdb_monitor_sort(sys.stdin, sys.stdout)
diff --git a/tests/ovsdb-monitor.at b/tests/ovsdb-monitor.at
index 65c595645b14..2434f43cb761 100644
--- a/tests/ovsdb-monitor.at
+++ b/tests/ovsdb-monitor.at
@@ -44,7 +44,7 @@  m4_define([OVSDB_CHECK_MONITOR],
             [ignore], [ignore])
    OVS_APP_EXIT_AND_WAIT_BY_TARGET([ovsdb-server], [ovsdb-server.pid])
    OVS_WAIT_UNTIL([test ! -e ovsdb-client.pid])
-   AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | uuidfilt], [0], [$7], [ignore])
+   AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$7], [ignore])
    AT_CLEANUP])
 
 # OVSDB_CHECK_MONITOR_COND(TITLE, SCHEMA, [PRE-MONITOR-TXN], DB, TABLE,
@@ -86,7 +86,7 @@  m4_define([OVSDB_CHECK_MONITOR_COND],
             [ignore], [ignore])
    AT_CHECK([ovs-appctl -t ovsdb-server -e exit], [0], [ignore], [ignore])
    OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
-   AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | uuidfilt], [0], [$7], [ignore])
+   AT_CHECK([$PYTHON $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$7], [ignore])
    AT_CLEANUP])
 
 OVSDB_CHECK_MONITOR([monitor insert into empty table],