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.

test_sob.py 5.5KB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. from __future__ import division, absolute_import
  4. import os
  5. import sys
  6. from textwrap import dedent
  7. from twisted.trial import unittest
  8. from twisted.persisted import sob
  9. from twisted.python import components
  10. from twisted.persisted.styles import Ephemeral
  11. class Dummy(components.Componentized):
  12. pass
  13. objects = [
  14. 1,
  15. "hello",
  16. (1, "hello"),
  17. [1, "hello"],
  18. {1:"hello"},
  19. ]
  20. class FakeModule(object):
  21. pass
  22. class PersistTests(unittest.TestCase):
  23. def testStyles(self):
  24. for o in objects:
  25. p = sob.Persistent(o, '')
  26. for style in 'source pickle'.split():
  27. p.setStyle(style)
  28. p.save(filename='persisttest.'+style)
  29. o1 = sob.load('persisttest.'+style, style)
  30. self.assertEqual(o, o1)
  31. def testStylesBeingSet(self):
  32. o = Dummy()
  33. o.foo = 5
  34. o.setComponent(sob.IPersistable, sob.Persistent(o, 'lala'))
  35. for style in 'source pickle'.split():
  36. sob.IPersistable(o).setStyle(style)
  37. sob.IPersistable(o).save(filename='lala.'+style)
  38. o1 = sob.load('lala.'+style, style)
  39. self.assertEqual(o.foo, o1.foo)
  40. self.assertEqual(sob.IPersistable(o1).style, style)
  41. def testPassphraseError(self):
  42. """
  43. Calling save() with a passphrase is an error.
  44. """
  45. p = sob.Persistant(None, 'object')
  46. self.assertRaises(
  47. TypeError, p.save, 'filename.pickle', passphrase='abc')
  48. def testNames(self):
  49. o = [1,2,3]
  50. p = sob.Persistent(o, 'object')
  51. for style in 'source pickle'.split():
  52. p.setStyle(style)
  53. p.save()
  54. o1 = sob.load('object.ta'+style[0], style)
  55. self.assertEqual(o, o1)
  56. for tag in 'lala lolo'.split():
  57. p.save(tag)
  58. o1 = sob.load('object-'+tag+'.ta'+style[0], style)
  59. self.assertEqual(o, o1)
  60. def testPython(self):
  61. with open("persisttest.python", 'w') as f:
  62. f.write('foo=[1,2,3] ')
  63. o = sob.loadValueFromFile('persisttest.python', 'foo')
  64. self.assertEqual(o, [1,2,3])
  65. def testTypeGuesser(self):
  66. self.assertRaises(KeyError, sob.guessType, "file.blah")
  67. self.assertEqual('python', sob.guessType("file.py"))
  68. self.assertEqual('python', sob.guessType("file.tac"))
  69. self.assertEqual('python', sob.guessType("file.etac"))
  70. self.assertEqual('pickle', sob.guessType("file.tap"))
  71. self.assertEqual('pickle', sob.guessType("file.etap"))
  72. self.assertEqual('source', sob.guessType("file.tas"))
  73. self.assertEqual('source', sob.guessType("file.etas"))
  74. def testEverythingEphemeralGetattr(self):
  75. """
  76. L{_EverythingEphermal.__getattr__} will proxy the __main__ module as an
  77. L{Ephemeral} object, and during load will be transparent, but after
  78. load will return L{Ephemeral} objects from any accessed attributes.
  79. """
  80. self.fakeMain.testMainModGetattr = 1
  81. dirname = self.mktemp()
  82. os.mkdir(dirname)
  83. filename = os.path.join(dirname, 'persisttest.ee_getattr')
  84. global mainWhileLoading
  85. mainWhileLoading = None
  86. with open(filename, "w") as f:
  87. f.write(dedent("""
  88. app = []
  89. import __main__
  90. app.append(__main__.testMainModGetattr == 1)
  91. try:
  92. __main__.somethingElse
  93. except AttributeError:
  94. app.append(True)
  95. else:
  96. app.append(False)
  97. from twisted.test import test_sob
  98. test_sob.mainWhileLoading = __main__
  99. """))
  100. loaded = sob.load(filename, 'source')
  101. self.assertIsInstance(loaded, list)
  102. self.assertTrue(loaded[0], "Expected attribute not set.")
  103. self.assertTrue(loaded[1], "Unexpected attribute set.")
  104. self.assertIsInstance(mainWhileLoading, Ephemeral)
  105. self.assertIsInstance(mainWhileLoading.somethingElse, Ephemeral)
  106. del mainWhileLoading
  107. def testEverythingEphemeralSetattr(self):
  108. """
  109. Verify that _EverythingEphemeral.__setattr__ won't affect __main__.
  110. """
  111. self.fakeMain.testMainModSetattr = 1
  112. dirname = self.mktemp()
  113. os.mkdir(dirname)
  114. filename = os.path.join(dirname, 'persisttest.ee_setattr')
  115. with open(filename, 'w') as f:
  116. f.write('import __main__\n')
  117. f.write('__main__.testMainModSetattr = 2\n')
  118. f.write('app = None\n')
  119. sob.load(filename, 'source')
  120. self.assertEqual(self.fakeMain.testMainModSetattr, 1)
  121. def testEverythingEphemeralException(self):
  122. """
  123. Test that an exception during load() won't cause _EE to mask __main__
  124. """
  125. dirname = self.mktemp()
  126. os.mkdir(dirname)
  127. filename = os.path.join(dirname, 'persisttest.ee_exception')
  128. with open(filename, 'w') as f:
  129. f.write('raise ValueError\n')
  130. self.assertRaises(ValueError, sob.load, filename, 'source')
  131. self.assertEqual(type(sys.modules['__main__']), FakeModule)
  132. def setUp(self):
  133. """
  134. Replace the __main__ module with a fake one, so that it can be mutated
  135. in tests
  136. """
  137. self.realMain = sys.modules['__main__']
  138. self.fakeMain = sys.modules['__main__'] = FakeModule()
  139. def tearDown(self):
  140. """
  141. Restore __main__ to its original value
  142. """
  143. sys.modules['__main__'] = self.realMain