test_filedescriptor.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Whitebox tests for L{twisted.internet.abstract.FileDescriptor}.
  5. """
  6. from __future__ import division, absolute_import
  7. from zope.interface.verify import verifyClass
  8. from twisted.internet.abstract import FileDescriptor
  9. from twisted.internet.interfaces import IPushProducer
  10. from twisted.trial.unittest import SynchronousTestCase
  11. class MemoryFile(FileDescriptor):
  12. """
  13. A L{FileDescriptor} customization which writes to a Python list in memory
  14. with certain limitations.
  15. @ivar _written: A C{list} of C{bytes} which have been accepted as written.
  16. @ivar _freeSpace: A C{int} giving the number of bytes which will be accepted
  17. by future writes.
  18. """
  19. connected = True
  20. def __init__(self):
  21. FileDescriptor.__init__(self, reactor=object())
  22. self._written = []
  23. self._freeSpace = 0
  24. def startWriting(self):
  25. pass
  26. def stopWriting(self):
  27. pass
  28. def writeSomeData(self, data):
  29. """
  30. Copy at most C{self._freeSpace} bytes from C{data} into C{self._written}.
  31. @return: A C{int} indicating how many bytes were copied from C{data}.
  32. """
  33. acceptLength = min(self._freeSpace, len(data))
  34. if acceptLength:
  35. self._freeSpace -= acceptLength
  36. self._written.append(data[:acceptLength])
  37. return acceptLength
  38. class FileDescriptorTests(SynchronousTestCase):
  39. """
  40. Tests for L{FileDescriptor}.
  41. """
  42. def test_writeWithUnicodeRaisesException(self):
  43. """
  44. L{FileDescriptor.write} doesn't accept unicode data.
  45. """
  46. fileDescriptor = FileDescriptor(reactor=object())
  47. self.assertRaises(TypeError, fileDescriptor.write, u'foo')
  48. def test_writeSequenceWithUnicodeRaisesException(self):
  49. """
  50. L{FileDescriptor.writeSequence} doesn't accept unicode data.
  51. """
  52. fileDescriptor = FileDescriptor(reactor=object())
  53. self.assertRaises(
  54. TypeError, fileDescriptor.writeSequence, [b'foo', u'bar', b'baz'])
  55. def test_implementInterfaceIPushProducer(self):
  56. """
  57. L{FileDescriptor} should implement L{IPushProducer}.
  58. """
  59. self.assertTrue(verifyClass(IPushProducer, FileDescriptor))
  60. class WriteDescriptorTests(SynchronousTestCase):
  61. """
  62. Tests for L{FileDescriptor}'s implementation of L{IWriteDescriptor}.
  63. """
  64. def test_kernelBufferFull(self):
  65. """
  66. When L{FileDescriptor.writeSomeData} returns C{0} to indicate no more
  67. data can be written immediately, L{FileDescriptor.doWrite} returns
  68. L{None}.
  69. """
  70. descriptor = MemoryFile()
  71. descriptor.write(b"hello, world")
  72. self.assertIsNone(descriptor.doWrite())