Browse Source

tools/kemi: add support for invoking function pointers

also add a flag to allow generated version of code to be compatible
with older versions of python3
Torrey Searle 5 years ago
parent
commit
773ecfc9ce

+ 11 - 0
misc/tools/kemi/python_mock/README.md

@@ -8,6 +8,13 @@ Usage:
 ./kemi_mock.py api.json > KSR.py
 ./kemi_mock.py api.json > KSR.py
 ```
 ```
 
 
+*Note:* Python 3.2 doesn't support the Union type. To generate KSR.py without
+the Union type add the --no-union flag
+
+```
+./kemi_mock.py api.json --no-union > KSR.py
+```
+
 Return values can be injected through the dictionary \_mock\_data
 Return values can be injected through the dictionary \_mock\_data
 
 
 ```python
 ```python
@@ -17,6 +24,10 @@ _mock_data[module][function] = value
 
 
 #set retun value for specific parameters being passed
 #set retun value for specific parameters being passed
 _mock_data[module][function][param_value] = value
 _mock_data[module][function][param_value] = value
+
+#call the function myFunc when func is passed, return of myFunc will
+#be the value module.function returns
+_mock_data[module][function] = myFunc
 ```
 ```
 
 
 see test.py for example usage
 see test.py for example usage

+ 27 - 6
misc/tools/kemi/python_mock/kemi_mock.py

@@ -3,16 +3,21 @@
 #parses the output of /usr/sbin/kamctl rpc app_python.api_list
 #parses the output of /usr/sbin/kamctl rpc app_python.api_list
 #
 #
 #usage ./kemi_mock.py api.json > KSR.py
 #usage ./kemi_mock.py api.json > KSR.py
+#or for python 3.2
+#./kemi_mock.py api.json --no-union > KSR.py
 
 
 import json
 import json
 import sys
 import sys
 
 
 from collections import defaultdict
 from collections import defaultdict
 
 
+#python 3.2 doesnt support types.Union
+noUnion = False
 
 
 def printMocReturn(module_name, func, indent):
 def printMocReturn(module_name, func, indent):
     param_names = []
     param_names = []
     param_list = []
     param_list = []
+    param_signature = ""
     if (func['params'] != 'none'):
     if (func['params'] != 'none'):
         param_list = func['params'].split(", ")
         param_list = func['params'].split(", ")
     i = 0
     i = 0
@@ -21,18 +26,20 @@ def printMocReturn(module_name, func, indent):
         param_names.append("param"+str(i))
         param_names.append("param"+str(i))
         i = i + 1
         i = i + 1
 
 
+    param_signature = ", ".join(param_names)
+
     prefix = ""
     prefix = ""
     for i in range(indent):
     for i in range(indent):
         prefix = prefix+"\t"
         prefix = prefix+"\t"
 
 
-    print(prefix + "if \""+module_name+"\" not in _mock_data:")
-    printDefaultReturn(func, indent+1)
-
     print(prefix + "if \""+func['name']+"\" not in _mock_data['"+module_name+"']:")
     print(prefix + "if \""+func['name']+"\" not in _mock_data['"+module_name+"']:")
     printDefaultReturn(func, indent+1)
     printDefaultReturn(func, indent+1)
 
 
     print(prefix + "node = _mock_data['"+module_name+"']['"+func['name']+"']")
     print(prefix + "node = _mock_data['"+module_name+"']['"+func['name']+"']")
 
 
+    print(prefix + "if isinstance(node, types.FunctionType):")
+    print(prefix + "\treturn node("+param_signature+")")
+
     for param in param_names:
     for param in param_names:
         print(prefix + "if not isinstance(node, dict):")
         print(prefix + "if not isinstance(node, dict):")
         print(prefix + "\treturn node")
         print(prefix + "\treturn node")
@@ -95,7 +102,10 @@ def printFunction(module_name, func, indent):
     elif (func['ret'] == "str"):
     elif (func['ret'] == "str"):
         print(prefix + "def " + func['name'] + "(" + params + ") -> int:")
         print(prefix + "def " + func['name'] + "(" + params + ") -> int:")
     elif(func['ret'] == "xval"):
     elif(func['ret'] == "xval"):
-        print(prefix + "def " + func['name'] +"("+params+") -> Union[int,str]:")
+        if noUnion:
+            print(prefix + "def " + func['name'] + "(" + params + "):")
+        else:
+            print(prefix + "def " + func['name'] +"("+params+") -> Union[int,str]:")
     else:
     else:
         print(prefix + "def " + func['name'] +"("+params+"):")
         print(prefix + "def " + func['name'] +"("+params+"):")
 
 
@@ -110,7 +120,15 @@ if len(sys.argv) < 2:
     print("Please specify the json file to parse")
     print("Please specify the json file to parse")
     sys.exit(-1)
     sys.exit(-1)
 
 
-print("from typing import Union")
+if len(sys.argv) > 2:
+    for i in range(2,len(sys.argv)):
+        if sys.argv[i] == "--no-union":
+            noUnion = True
+
+if not noUnion:
+    print("from typing import Union")
+
+print("import types")
 print("_mock_data={}")
 print("_mock_data={}")
 
 
 with open(sys.argv[1]) as f:
 with open(sys.argv[1]) as f:
@@ -170,7 +188,10 @@ for func in classes['']:
 
 
 for module_name in classes.keys():
 for module_name in classes.keys():
     if module_name != "":
     if module_name != "":
-        print(module_name + "="+module_name.capitalize()+"()")
+        print(module_name + " = "+module_name.capitalize()+"()")
 
 
+print("")
 
 
+for module_name in classes.keys():
+    print("_mock_data['" + module_name + "'] = {}")
 
 

+ 15 - 2
misc/tools/kemi/python_mock/test.py

@@ -3,13 +3,26 @@
 import KSR
 import KSR
 
 
 #return sip:hello@world only if $ru is passed to pv.get
 #return sip:hello@world only if $ru is passed to pv.get
-KSR._mock_data['pv'] = {}
 KSR._mock_data['pv']['get'] = {}
 KSR._mock_data['pv']['get'] = {}
 KSR._mock_data['pv']['get']['$ru'] = "sip:hello@world"
 KSR._mock_data['pv']['get']['$ru'] = "sip:hello@world"
 print("Got a value of: " + KSR.pv.get("$ru"))
 print("Got a value of: " + KSR.pv.get("$ru"))
 
 
 #return maxfwd.process_maxfwd return 2 regardless of value passed
 #return maxfwd.process_maxfwd return 2 regardless of value passed
-KSR._mock_data['maxfwd'] = {}
 KSR._mock_data['maxfwd']['process_maxfwd'] = 2
 KSR._mock_data['maxfwd']['process_maxfwd'] = 2
 KSR.maxfwd.process_maxfwd(10)
 KSR.maxfwd.process_maxfwd(10)
 print("Got a value of: " + str(KSR.maxfwd.process_maxfwd(10)))
 print("Got a value of: " + str(KSR.maxfwd.process_maxfwd(10)))
+
+#set a function pointer to see if hdr.append is called
+appendCalled = False
+def appendHeader(param0: str):
+    global appendCalled
+    if param0.startswith("X-HDR:"):
+        appendCalled = True
+    return 1
+
+KSR._mock_data['hdr']['append'] = appendHeader
+KSR.hdr.append("X-HDR: my-header")
+if appendCalled:
+    print("hdr.append successfully called!")
+else:
+    print("hdr.append failed to be called")