Fast IFS using RPN notation
python
c
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tests_rpn_copy.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/python3
  2. # Copyright 2023 Weber Yann
  3. #
  4. # This file is part of rpnifs.
  5. #
  6. # geneifs is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # geneifs is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with geneifs. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import copy
  20. import pickle
  21. import sys
  22. import unittest
  23. try:
  24. import pyrpn
  25. except (ImportError, NameError) as e:
  26. print("Error importing pyrpn. Try to run make.",
  27. file=sys.stderr)
  28. raise e
  29. ## TODO : move this function somewhere or implement it in C
  30. def decode_state(state):
  31. """ Return a dict containing rpn state dump fields
  32. """
  33. res = dict()
  34. res['real_sz'] = len(state)
  35. res['total_sz'] = int.from_bytes(state[0:8], byteorder="little")
  36. res['argc'] = int.from_bytes(state[8:16], byteorder="little")
  37. res['stack_sz_bytes'] = state[16:24]
  38. res['stack_sz'] = state[16]
  39. res['token_sz'] = int.from_bytes(state[24:32], byteorder="little", signed=True)
  40. res['stack'] = [int.from_bytes(state[i:i+8], byteorder="little")
  41. for i in range(32, 32 + (8*res['stack_sz']),8)]
  42. res['tokens_off'] = 32 + (8*res['stack_sz'])
  43. res['tokens_real_sz'] = res['real_sz'] - res['tokens_off']
  44. res['tokens'] = [state[i:i+24]
  45. for i in range(res['tokens_off'],
  46. res['tokens_off'] + (24*res['token_sz']),
  47. 24)]
  48. return res
  49. class TestRpnExprState(unittest.TestCase):
  50. """ Testing RPNExpr "state" related methods (__copy__, __get/setstate__)
  51. """
  52. def test_pickle_state(self):
  53. """ Testing pickling/unpickling """
  54. e = pyrpn.RPNExpr('0x42 + A0', 2)
  55. e2 = pickle.loads(pickle.dumps(e))
  56. ds_e = decode_state(e.__getstate__())
  57. ds_e2 = decode_state(e2.__getstate__())
  58. self.assertEqual(e.__getstate__(), e2.__getstate__(),
  59. msg="EXPR: %r != %r (%r != %r)" % (e, e2, ds_e, ds_e2))
  60. for i in range(100):
  61. e = pyrpn.RPNExpr(pyrpn.random_expr(0), 2)
  62. e.mutate(n_mutations=15);
  63. e2 = pickle.loads(pickle.dumps(e))
  64. self.assertEqual(e.__getstate__(), e2.__getstate__(),
  65. msg="EXPR#%d : %r != %r" % (i,e, e2))
  66. e3 = pickle.loads(pickle.dumps(e2))
  67. self.assertEqual(e.__getstate__(), e3.__getstate__(), msg=e)
  68. self.assertEqual(e2.__getstate__(), e3.__getstate__(), msg=e)
  69. def test_copy(self):
  70. """ Basic copy test based on pickling """
  71. e = pyrpn.RPNExpr('0x42 + A0', 2)
  72. e2 = copy.copy(e)
  73. ds_e = decode_state(e.__getstate__())
  74. ds_e2 = decode_state(e2.__getstate__())
  75. self.assertEqual(e.__getstate__(), e2.__getstate__(),
  76. msg="EXPR: %r != %r (%r != %r)" % (e, e2, ds_e, ds_e2))
  77. for i in range(100):
  78. e = pyrpn.RPNExpr(pyrpn.random_expr(0), 2)
  79. e2 = copy.copy(e)
  80. self.assertEqual(e.__getstate__(), e2.__getstate__(),
  81. msg="EXPR#%d : %r != %r" % (i,e, e2))
  82. e3 = pickle.loads(pickle.dumps(e2))
  83. self.assertEqual(e.__getstate__(), e3.__getstate__(), msg=e)
  84. self.assertEqual(e2.__getstate__(), e3.__getstate__(), msg=e)
  85. if __name__ == '__main__':
  86. unittest.main()