papi: add wrapper to validate crc manifest 25/22725/7
authorOle Troan <ot@cisco.com>
Mon, 14 Oct 2019 21:07:06 +0000 (23:07 +0200)
committerPaul Vinciguerra <pvinci@vinciconsulting.com>
Tue, 12 Nov 2019 17:59:18 +0000 (17:59 +0000)
If a client application is built against 19.08, it can dump the "manifest" of API signatures.
Either the all APIs (--dump) or the APIs it is interested in (--dumpfiltered).

When the developers of said client application wants to verify that it works with VPP 20.01.
It can connect to VPP and --validate the old mainfest file, and will be told a list of
messages (both request and reply) that has changed.

import argparse
from vpp_papi import VPP
import sys
import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("--dump", action="store_true")
group.add_argument("--dumpfiltered", action="store_true")
group.add_argument("--validate", action="store_true")
args = parser.parse_args()

vpp = VPP(use_socket=True)

vpp.connect(name='apimanifest')

if args.validate:
    # Verify manifest
    message_table = eval(sys.stdin.read())
    missing = vpp.validate_message_table(message_table)
    print ('Changed message signatures: {}'.format(missing))
elif args.dump:
    # Output manifest to stdout
    print('{}'.format(vpp.dump_message_table()))
elif args.dumpfiltered:
    # Output manifest to stdout
    filterlist = eval(sys.stdin.read())
    print('{}'.format(vpp.dump_message_table_filtered(filterlist)))

vpp.disconnect()

Type: feature
Change-Id: I7e708b36f599ed88e4864970c8593cc2fe5fbf61
Signed-off-by: Ole Troan <ot@cisco.com>
src/vpp-api/python/vpp_papi/vpp_papi.py

index 05688ce..0ac86bb 100644 (file)
@@ -759,6 +759,34 @@ class VPPApiClient(object):
             if self.event_callback:
                 self.event_callback(msgname, r)
 
+    def validate_message_table(self, namecrctable):
+        """Take a dictionary of name_crc message names
+        and returns an array of missing messages"""
+
+        missing_table = []
+        for name_crc in namecrctable:
+            i = self.transport.get_msg_index(name_crc)
+            if i <= 0:
+                missing_table.append(name_crc)
+        return missing_table
+
+    def dump_message_table(self):
+        """Return VPPs API message table as name_crc dictionary"""
+        return self.transport.message_table
+
+    def dump_message_table_filtered(self, msglist):
+        """Return VPPs API message table as name_crc dictionary,
+        filtered by message name list."""
+
+        replies = [self.services[n]['reply'] for n in msglist]
+        message_table_filtered = {}
+        for name in msglist + replies:
+            for k,v in self.transport.message_table.items():
+                if k.startswith(name):
+                    message_table_filtered[k] = v
+                    break
+        return message_table_filtered
+
     def __repr__(self):
         return "<VPPApiClient apifiles=%s, testmode=%s, async_thread=%s, " \
                "logger=%s, read_timeout=%s, use_socket=%s, " \