LedgerHarness.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env python
  2. import sys
  3. import os
  4. import re
  5. from subprocess import Popen, PIPE
  6. import copy_reg
  7. import types
  8. def _pickle_method(method):
  9. func_name = method.im_func.__name__
  10. obj = method.im_self
  11. cls = method.im_class
  12. return _unpickle_method, (func_name, obj, cls)
  13. def _unpickle_method(func_name, obj, cls):
  14. for cls in cls.mro():
  15. try:
  16. func = cls.__dict__[func_name]
  17. except KeyError:
  18. pass
  19. else:
  20. break
  21. return func.__get__(obj, cls)
  22. copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
  23. class LedgerHarness:
  24. ledger = None
  25. sourcepath = None
  26. succeeded = 0
  27. failed = 0
  28. verify = False
  29. gmalloc = False
  30. python = False
  31. def __init__(self, argv):
  32. if not os.path.isfile(argv[1]):
  33. print "Cannot find ledger at '%s'" % argv[1]
  34. sys.exit(1)
  35. if not os.path.isdir(argv[2]):
  36. print "Cannot find source path at '%s'" % argv[2]
  37. sys.exit(1)
  38. self.ledger = os.path.abspath(argv[1])
  39. self.sourcepath = os.path.abspath(argv[2])
  40. self.succeeded = 0
  41. self.failed = 0
  42. self.verify = '--verify' in argv
  43. self.gmalloc = '--gmalloc' in argv
  44. self.python = '--python' in argv
  45. def run(self, command, verify=None, gmalloc=None, columns=True):
  46. env = os.environ.copy()
  47. if (gmalloc is not None and gmalloc) or \
  48. (gmalloc is None and self.gmalloc):
  49. env['MallocGuardEdges'] = '1'
  50. env['MallocScribble'] = '1'
  51. env['MallocPreScribble'] = '1'
  52. env['MallocCheckHeapStart'] = '1000'
  53. env['MallocCheckHeapEach'] = '10000'
  54. env['DYLD_INSERT_LIBRARIES'] = '/usr/lib/libgmalloc.dylib'
  55. env['MALLOC_PROTECT_BEFORE'] = '1'
  56. env['MALLOC_FILL_SPACE'] = '1'
  57. env['MALLOC_STRICT_SIZE'] = '1'
  58. if (verify is not None and verify) or \
  59. (verify is None and self.verify):
  60. insert = ' --verify'
  61. else:
  62. insert = ''
  63. if columns:
  64. insert += ' --columns=80'
  65. command = re.sub('\$ledger', '%s%s %s' % \
  66. (self.ledger, insert, '--args-only'), command)
  67. valgrind = '/usr/bin/valgrind'
  68. if not os.path.isfile(valgrind):
  69. valgrind = '/opt/local/bin/valgrind'
  70. if os.path.isfile(valgrind) and '--verify' in insert:
  71. command = valgrind + ' -q ' + command
  72. return Popen(command, shell=True, close_fds=True, env=env,
  73. stdin=PIPE, stdout=PIPE, stderr=PIPE,
  74. cwd=self.sourcepath)
  75. def read(self, fd):
  76. text = ""
  77. text_data = os.read(fd.fileno(), 8192)
  78. while text_data:
  79. if text_data:
  80. text += text_data
  81. text_data = os.read(fd.fileno(), 8192)
  82. return text
  83. def readlines(self, fd):
  84. lines = []
  85. for line in fd.readlines():
  86. if not line.startswith("GuardMalloc"):
  87. lines.append(line)
  88. return lines
  89. def wait(self, process, msg='Ledger invocation failed:'):
  90. if process.wait() != 0:
  91. print msg
  92. print process.stderr.read()
  93. self.failure()
  94. return False
  95. return True
  96. def success(self):
  97. sys.stdout.write(".")
  98. sys.stdout.flush()
  99. self.succeeded += 1
  100. def failure(self, name=None):
  101. sys.stdout.write("E")
  102. if name:
  103. sys.stdout.write("[%s]" % name)
  104. sys.stdout.flush()
  105. self.failed += 1
  106. def exit(self):
  107. print
  108. if self.succeeded > 0:
  109. print "OK (%d) " % self.succeeded,
  110. if self.failed > 0:
  111. print "FAILED (%d)" % self.failed,
  112. print
  113. sys.exit(self.failed)
  114. if __name__ == '__main__':
  115. harness = LedgerHarness(sys.argv)
  116. proc = harness.run('$ledger -f doc/sample.dat reg')
  117. print 'STDOUT:'
  118. print proc.stdout.read()
  119. print 'STDERR:'
  120. print proc.stderr.read()
  121. harness.success()
  122. harness.exit()