PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/Python/Lib/site-packages/win32com/test/util.py

https://gitlab.com/orvi2014/rcs-db-ext
Python | 227 lines | 206 code | 6 blank | 15 comment | 34 complexity | fdb483a5370cda249ae348daaf67cc91 MD5 | raw file
  1. import sys, os
  2. import win32api
  3. import tempfile
  4. import unittest
  5. import gc
  6. import pythoncom
  7. import winerror
  8. from pythoncom import _GetInterfaceCount, _GetGatewayCount
  9. import win32com
  10. import logging
  11. import _winreg
  12. import cStringIO as StringIO
  13. import pywin32_testutil
  14. from pywin32_testutil import TestLoader, TestResult, TestRunner, LeakTestCase
  15. def CheckClean():
  16. # Ensure no lingering exceptions - Python should have zero outstanding
  17. # COM objects
  18. try:
  19. sys.exc_clear()
  20. except AttributeError:
  21. pass # py3k
  22. c = _GetInterfaceCount()
  23. if c:
  24. print "Warning - %d com interface objects still alive" % c
  25. c = _GetGatewayCount()
  26. if c:
  27. print "Warning - %d com gateway objects still alive" % c
  28. def RegisterPythonServer(filename, progids=None, verbose=0):
  29. if progids:
  30. if isinstance(progids, basestring):
  31. progids = [progids]
  32. # we know the CLSIDs we need, but we might not be an admin user
  33. # and otherwise unable to register them. So as long as the progids
  34. # exist and the DLL points at our version, assume it already is.
  35. why_not = None
  36. for progid in progids:
  37. try:
  38. clsid = pythoncom.MakeIID(progid)
  39. except pythoncom.com_error:
  40. # no progid - not registered.
  41. break
  42. # have a CLSID - open it.
  43. try:
  44. HKCR = _winreg.HKEY_CLASSES_ROOT
  45. hk = _winreg.OpenKey(HKCR, "CLSID\\%s" % clsid)
  46. dll = _winreg.QueryValue(hk, "InprocServer32")
  47. except WindowsError:
  48. # no CLSID or InProcServer32 - not good!
  49. break
  50. if os.path.basename(dll) != os.path.basename(pythoncom.__file__):
  51. why_not = "%r is registered against a different Python version (%s)" % (progid, dll)
  52. break
  53. else:
  54. #print "Skipping registration of '%s' - already registered" % filename
  55. return
  56. # needs registration - see if its likely!
  57. try:
  58. from win32com.shell.shell import IsUserAnAdmin
  59. except ImportError:
  60. print "Can't import win32com.shell - no idea if you are an admin or not?"
  61. is_admin = False
  62. else:
  63. try:
  64. is_admin = IsUserAnAdmin()
  65. except pythoncom.com_error:
  66. # old, less-secure OS - assume *is* admin.
  67. is_admin = True
  68. if not is_admin:
  69. msg = "%r isn't registered, but I'm not an administrator who can register it." % progids[0]
  70. if why_not:
  71. msg += "\n(registration check failed as %s)" % why_not
  72. # throw a normal "class not registered" exception - we don't report
  73. # them the same way as "real" errors.
  74. raise pythoncom.com_error(winerror.CO_E_CLASSSTRING, msg, None, -1)
  75. # so theoretically we are able to register it.
  76. cmd = '%s "%s" --unattended > nul 2>&1' % (win32api.GetModuleFileName(0), filename)
  77. if verbose:
  78. print "Registering engine", filename
  79. # print cmd
  80. rc = os.system(cmd)
  81. if rc:
  82. print "Registration command was:"
  83. print cmd
  84. raise RuntimeError("Registration of engine '%s' failed" % filename)
  85. def ExecuteShellCommand(cmd, testcase,
  86. expected_output = None, # Set to '' to check for nothing
  87. tracebacks_ok = 0, # OK if the output contains a t/b?
  88. ):
  89. output_name = tempfile.mktemp('win32com_test')
  90. cmd = cmd + ' > "%s" 2>&1' % output_name
  91. rc = os.system(cmd)
  92. output = open(output_name, "r").read().strip()
  93. os.remove(output_name)
  94. class Failed(Exception): pass
  95. try:
  96. if rc:
  97. raise Failed("exit code was " + str(rc))
  98. if expected_output is not None and output != expected_output:
  99. raise Failed("Expected output %r (got %r)" % (expected_output, output))
  100. if not tracebacks_ok and \
  101. output.find("Traceback (most recent call last)")>=0:
  102. raise Failed("traceback in program output")
  103. return output
  104. except Failed, why:
  105. print "Failed to exec command '%r'" % cmd
  106. print "Failed as", why
  107. print "** start of program output **"
  108. print output
  109. print "** end of program output **"
  110. testcase.fail("Executing '%s' failed as %s" % (cmd, why))
  111. def assertRaisesCOM_HRESULT(testcase, hresult, func, *args, **kw):
  112. try:
  113. func(*args, **kw)
  114. except pythoncom.com_error, details:
  115. if details.hresult==hresult:
  116. return
  117. testcase.fail("Excepected COM exception with HRESULT 0x%x" % hresult)
  118. class CaptureWriter:
  119. def __init__(self):
  120. self.old_err = self.old_out = None
  121. self.clear()
  122. def capture(self):
  123. self.clear()
  124. self.old_out = sys.stdout
  125. self.old_err = sys.stderr
  126. sys.stdout = sys.stderr = self
  127. def release(self):
  128. if self.old_out:
  129. sys.stdout = self.old_out
  130. self.old_out = None
  131. if self.old_err:
  132. sys.stderr = self.old_err
  133. self.old_err = None
  134. def clear(self):
  135. self.captured = []
  136. def write(self, msg):
  137. self.captured.append(msg)
  138. def get_captured(self):
  139. return "".join(self.captured)
  140. def get_num_lines_captured(self):
  141. return len("".join(self.captured).split("\n"))
  142. # Utilities to set the win32com logger to something what just captures
  143. # records written and doesn't print them.
  144. class LogHandler(logging.Handler):
  145. def __init__(self):
  146. self.emitted = []
  147. logging.Handler.__init__(self)
  148. def emit(self, record):
  149. self.emitted.append(record)
  150. _win32com_logger = None
  151. def setup_test_logger():
  152. old_log = getattr(win32com, "logger", None)
  153. global _win32com_logger
  154. if _win32com_logger is None:
  155. _win32com_logger = logging.Logger('test')
  156. handler = LogHandler()
  157. _win32com_logger.addHandler(handler)
  158. win32com.logger = _win32com_logger
  159. handler = _win32com_logger.handlers[0]
  160. handler.emitted = []
  161. return handler.emitted, old_log
  162. def restore_test_logger(prev_logger):
  163. assert prev_logger is None, "who needs this?"
  164. if prev_logger is None:
  165. del win32com.logger
  166. else:
  167. win32com.logger = prev_logger
  168. # We used to override some of this (and may later!)
  169. TestCase = unittest.TestCase
  170. def CapturingFunctionTestCase(*args, **kw):
  171. real_test = _CapturingFunctionTestCase(*args, **kw)
  172. return LeakTestCase(real_test)
  173. class _CapturingFunctionTestCase(unittest.FunctionTestCase):#, TestCaseMixin):
  174. def __call__(self, result=None):
  175. if result is None: result = self.defaultTestResult()
  176. writer = CaptureWriter()
  177. #self._preTest()
  178. writer.capture()
  179. try:
  180. unittest.FunctionTestCase.__call__(self, result)
  181. if getattr(self, "do_leak_tests", 0) and hasattr(sys, "gettotalrefcount"):
  182. self.run_leak_tests(result)
  183. finally:
  184. writer.release()
  185. #self._postTest(result)
  186. output = writer.get_captured()
  187. self.checkOutput(output, result)
  188. if result.showAll:
  189. print output
  190. def checkOutput(self, output, result):
  191. if output.find("Traceback")>=0:
  192. msg = "Test output contained a traceback\n---\n%s\n---" % output
  193. result.errors.append((self, msg))
  194. class ShellTestCase(unittest.TestCase):
  195. def __init__(self, cmd, expected_output):
  196. self.__cmd = cmd
  197. self.__eo = expected_output
  198. unittest.TestCase.__init__(self)
  199. def runTest(self):
  200. ExecuteShellCommand(self.__cmd, self, self.__eo)
  201. def __str__(self):
  202. max = 30
  203. if len(self.__cmd)>max:
  204. cmd_repr = self.__cmd[:max] + "..."
  205. else:
  206. cmd_repr = self.__cmd
  207. return "exec: " + cmd_repr
  208. def testmain(*args, **kw):
  209. pywin32_testutil.testmain(*args, **kw)
  210. CheckClean()