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.
 
 
 

122 lines
3.0 KiB

  1. import nilmdb
  2. from nilmdb.utils.printf import *
  3. import nose
  4. from nose.tools import *
  5. from nose.tools import assert_raises
  6. from testutil.helpers import *
  7. import sys
  8. import io
  9. import gc
  10. import inspect
  11. err = io.StringIO()
  12. @nilmdb.utils.must_close(errorfile = err)
  13. class Foo:
  14. def __init__(self, arg):
  15. fprintf(err, "Init %s\n", arg)
  16. def __del__(self):
  17. fprintf(err, "Deleting\n")
  18. def close(self):
  19. fprintf(err, "Closing\n")
  20. @nilmdb.utils.must_close(errorfile = err, wrap_verify = True)
  21. class Bar:
  22. def __init__(self):
  23. fprintf(err, "Init\n")
  24. def __del__(self):
  25. fprintf(err, "Deleting\n")
  26. @classmethod
  27. def baz(self):
  28. fprintf(err, "Baz\n")
  29. def close(self):
  30. fprintf(err, "Closing\n")
  31. def blah(self, arg):
  32. fprintf(err, "Blah %s\n", arg)
  33. @nilmdb.utils.must_close(errorfile = err)
  34. class Baz:
  35. pass
  36. class TestMustClose(object):
  37. def test(self):
  38. # Note: this test might fail if the Python interpreter doesn't
  39. # garbage collect the object (and call its __del__ function)
  40. # right after a "del x".
  41. # Trigger error
  42. err.truncate()
  43. x = Foo("hi")
  44. # Verify that the arg spec was maintained
  45. eq_(inspect.getargspec(x.__init__),
  46. inspect.ArgSpec(args = ['self', 'arg'],
  47. varargs = None, keywords = None, defaults = None))
  48. del x
  49. gc.collect()
  50. eq_(err.getvalue(),
  51. "Init hi\n"
  52. "error: Foo.close() wasn't called!\n"
  53. "Deleting\n")
  54. # No error
  55. err.truncate(0)
  56. err.seek(0)
  57. y = Foo("bye")
  58. y.close()
  59. del y
  60. gc.collect()
  61. eq_(err.getvalue(),
  62. "Init bye\n"
  63. "Closing\n"
  64. "Deleting\n")
  65. # Verify function calls when wrap_verify is True
  66. err.truncate(0)
  67. err.seek(0)
  68. z = Bar()
  69. eq_(inspect.getargspec(z.blah),
  70. inspect.ArgSpec(args = ['self', 'arg'],
  71. varargs = None, keywords = None, defaults = None))
  72. z.blah("boo")
  73. z.close()
  74. with assert_raises(AssertionError) as e:
  75. z.blah("hello")
  76. in_("called <function Bar.blah at 0x", str(e.exception))
  77. in_("> after close", str(e.exception))
  78. # Since the most recent assertion references 'z',
  79. # we need to raise another assertion here so that
  80. # 'z' will get properly deleted.
  81. with assert_raises(AssertionError):
  82. raise AssertionError()
  83. del z
  84. gc.collect()
  85. eq_(err.getvalue(),
  86. "Init\n"
  87. "Blah boo\n"
  88. "Closing\n"
  89. "Deleting\n")
  90. # Class with missing methods
  91. err.truncate(0)
  92. err.seek(0)
  93. w = Baz()
  94. w.close()
  95. del w
  96. eq_(err.getvalue(), "")
  97. # Test errors during __del__, by closing stderr so the fprintf fails
  98. r = Foo("hi")
  99. err.close()
  100. del r