test.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from math import *
  2. from ctypes import *
  3. import os
  4. #
  5. # Where is the DLL? If missing, build using: `odin build . -build-mode:dll`
  6. #
  7. LIB_PATH = os.getcwd() + os.sep + "big.dll"
  8. #
  9. # Result values will be passed in a struct { res: cstring, err: Error }
  10. #
  11. class Res(Structure):
  12. _fields_ = [("res", c_char_p), ("err", c_byte)]
  13. #
  14. # Error enum values
  15. #
  16. E_None = 0
  17. E_Out_Of_Memory = 1
  18. E_Invalid_Pointer = 2
  19. E_Invalid_Argument = 3
  20. E_Unknown_Error = 4
  21. E_Max_Iterations_Reached = 5
  22. E_Buffer_Overflow = 6
  23. E_Integer_Overflow = 7
  24. E_Division_by_Zero = 8
  25. E_Math_Domain_Error = 9
  26. E_Unimplemented = 127
  27. #
  28. # Set up exported procedures
  29. #
  30. try:
  31. l = cdll.LoadLibrary(LIB_PATH)
  32. except:
  33. print("Couldn't find or load " + LIB_PATH + ".")
  34. exit(1)
  35. try:
  36. l.test_add_two.argtypes = [c_char_p, c_char_p, c_longlong]
  37. l.test_add_two.restype = Res
  38. except:
  39. print("Couldn't find exported function 'test_add_two'")
  40. exit(2)
  41. add_two = l.test_add_two
  42. try:
  43. l.test_error_string.argtypes = [c_byte]
  44. l.test_error_string.restype = c_char_p
  45. except:
  46. print("Couldn't find exported function 'test_error_string'")
  47. exit(2)
  48. def test(test_name: "", res: Res, param=[], expected_error = E_None, expected_result = ""):
  49. passed = True
  50. r = None
  51. if res.err != expected_error:
  52. error_type = l.test_error_string(res.err).decode('utf-8')
  53. error_loc = res.res.decode('utf-8')
  54. error_string = "{}: '{}' error in '{}'".format(test_name, error_type, error_loc)
  55. if len(param):
  56. error_string += " with params {}".format(param)
  57. print(error_string, flush=True)
  58. passed = False
  59. elif res.err == E_None:
  60. try:
  61. r = res.res.decode('utf-8')
  62. except:
  63. pass
  64. r = eval(res.res)
  65. if r != expected_result:
  66. error_string = "{}: Result was '{}', expected '{}'".format(test_name, r, expected_result)
  67. if len(param):
  68. error_string += " with params {}".format(param)
  69. print(error_string, flush=True)
  70. passed = False
  71. return passed
  72. def test_add_two(a = 0, b = 0, radix = 10, expected_error = E_None, expected_result = None):
  73. res = add_two(str(a).encode('utf-8'), str(b).encode('utf-8'), radix)
  74. if expected_result == None:
  75. expected_result = a + b
  76. return test("test_add_two", res, [str(a), str(b), radix], expected_error, expected_result)
  77. TESTS = {
  78. test_add_two: [
  79. [ 1234, 5432, 10, ],
  80. [ 1234, 5432, 110, E_Invalid_Argument, ],
  81. ],
  82. }
  83. if __name__ == '__main__':
  84. print("---- core:math/big tests ----")
  85. print()
  86. for test_proc in TESTS:
  87. count_pass = 0
  88. count_fail = 0
  89. for t in TESTS[test_proc]:
  90. if test_proc(*t):
  91. count_pass += 1
  92. else:
  93. count_fail += 1
  94. print("{}: {} passes, {} failures.".format(test_proc.__name__, count_pass, count_fail))