test_datagram.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import pytest
  2. from panda3d import core
  3. import sys
  4. # Fixtures for generating interesting datagrams (and verification functions) on
  5. # the fly...
  6. @pytest.fixture(scope='module',
  7. params=[False, True],
  8. ids=['stdfloat_float', 'stdfloat_double'])
  9. def datagram_small(request):
  10. """Returns a small datagram, along with a verification function."""
  11. dg = core.Datagram()
  12. dg.set_stdfloat_double(request.param)
  13. dg.add_uint8(3)
  14. dg.add_uint16(14159)
  15. dg.add_uint32(0xDEADBEEF)
  16. dg.add_uint64(0x0123456789ABCDEF)
  17. dg.add_int8(-77)
  18. dg.add_int16(-1)
  19. dg.add_int32(-972965890)
  20. dg.add_int64(-1001001001001001)
  21. dg.add_string('this is a string')
  22. dg.add_string32('this is another string')
  23. dg.add_string('this is yet a third string')
  24. dg.add_stdfloat(800.2)
  25. dg.add_stdfloat(3.1415926)
  26. dg.add_stdfloat(2.7182818)
  27. def readback_function(dgi):
  28. assert dgi.get_remaining_size() > 0
  29. assert dgi.get_uint8() == 3
  30. assert dgi.get_uint16() == 14159
  31. assert dgi.get_uint32() == 0xDEADBEEF
  32. assert dgi.get_uint64() == 0x0123456789ABCDEF
  33. assert dgi.get_int8() == -77
  34. assert dgi.get_int16() == -1
  35. assert dgi.get_int32() == -972965890
  36. assert dgi.get_int64() == -1001001001001001
  37. assert dgi.get_string() == 'this is a string'
  38. assert dgi.get_string32() == 'this is another string'
  39. assert dgi.get_string() == 'this is yet a third string'
  40. assert dgi.get_stdfloat() == pytest.approx(800.2)
  41. assert dgi.get_stdfloat() == pytest.approx(3.1415926)
  42. assert dgi.get_stdfloat() == pytest.approx(2.7182818)
  43. assert dgi.get_remaining_size() == 0
  44. return dg, readback_function
  45. @pytest.fixture(scope='module')
  46. def datagram_large():
  47. """Returns a big datagram, along with a verification function."""
  48. dg = core.Datagram()
  49. for x in range(2000000):
  50. dg.add_uint32(x)
  51. dg.add_string('the magic words are squeamish ossifrage')
  52. def readback_function(dgi):
  53. assert dgi.get_remaining_size() > 0
  54. for x in range(2000000):
  55. assert dgi.get_uint32() == x
  56. assert dgi.get_string() == 'the magic words are squeamish ossifrage'
  57. assert dgi.get_remaining_size() == 0
  58. return dg, readback_function
  59. @pytest.mark.skipif(sys.version_info < (3, 0), reason="Requires Python 3")
  60. def test_datagram_bytes():
  61. """Tests that we can put and get a bytes object on Datagram."""
  62. dg = core.Datagram(b'abc\x00')
  63. dg.append_data(b'\xff123')
  64. assert bytes(dg) == b'abc\x00\xff123'
  65. dgi = core.DatagramIterator(dg)
  66. dgi.get_remaining_bytes() == b'abc\x00\xff123'
  67. def test_iterator(datagram_small):
  68. """This tests Datagram/DatagramIterator, and sort of serves as a self-check
  69. of the test fixtures too."""
  70. dg, verify = datagram_small
  71. dgi = core.DatagramIterator(dg)
  72. verify(dgi)
  73. # This tests the copy constructor:
  74. def test_copy(datagram_small):
  75. dg, verify = datagram_small
  76. dg2 = core.Datagram(dg)
  77. dgi = core.DatagramIterator(dg2)
  78. verify(dgi)
  79. def test_assign(datagram_small):
  80. dg, verify = datagram_small
  81. dg2 = core.Datagram()
  82. dg2.assign(dg)
  83. dgi = core.DatagramIterator(dg2)
  84. verify(dgi)
  85. # These test DatagramInputFile/DatagramOutputFile:
  86. def do_file_test(dg, verify, filename):
  87. dof = core.DatagramOutputFile()
  88. dof.open(filename)
  89. dof.put_datagram(dg)
  90. dof.close()
  91. dg2 = core.Datagram()
  92. dif = core.DatagramInputFile()
  93. dif.open(filename)
  94. assert dif.get_datagram(dg2)
  95. dif.close()
  96. # This is normally saved by the DatagramOutputFile header. We cheat here.
  97. dg2.set_stdfloat_double(dg.get_stdfloat_double())
  98. dgi = core.DatagramIterator(dg2)
  99. verify(dgi)
  100. def test_file_small(datagram_small, tmpdir):
  101. """This tests DatagramOutputFile/DatagramInputFile on small datagrams."""
  102. dg, verify = datagram_small
  103. p = tmpdir.join('datagram.bin')
  104. filename = core.Filename.from_os_specific(str(p))
  105. do_file_test(dg, verify, filename)
  106. def test_file_large(datagram_large, tmpdir):
  107. """This tests DatagramOutputFile/DatagramInputFile on very large datagrams."""
  108. dg, verify = datagram_large
  109. p = tmpdir.join('datagram.bin')
  110. filename = core.Filename.from_os_specific(str(p))
  111. do_file_test(dg, verify, filename)
  112. def test_file_corrupt(datagram_small, tmpdir):
  113. """This tests DatagramInputFile's handling of a corrupt size header."""
  114. dg, verify = datagram_small
  115. p = tmpdir.join('datagram.bin')
  116. filename = core.Filename.from_os_specific(str(p))
  117. dof = core.DatagramOutputFile()
  118. dof.open(filename)
  119. dof.put_datagram(dg)
  120. dof.close()
  121. # Corrupt the size header to 1GB
  122. with p.open(mode='r+b') as f:
  123. f.seek(0)
  124. f.write(b'\xFF\xFF\xFF\x4F')
  125. dg2 = core.Datagram()
  126. dif = core.DatagramInputFile()
  127. dif.open(filename)
  128. assert not dif.get_datagram(dg2)
  129. dif.close()
  130. # Truncate the file
  131. for size in [12, 8, 4, 3, 2, 1, 0]:
  132. with p.open(mode='r+b') as f:
  133. f.truncate(size)
  134. dg2 = core.Datagram()
  135. dif = core.DatagramInputFile()
  136. dif.open(filename)
  137. assert not dif.get_datagram(dg2)
  138. dif.close()
  139. # Should we test that dg2 is unmodified?