PageRenderTime 31ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/DICK.B1/IronPython/Lib/iptest/assert_util.py

https://bitbucket.org/williamybs/uidipythontool
Python | 622 lines | 477 code | 96 blank | 49 comment | 140 complexity | ed91555ff610eb62e5454c162eb1d103 MD5 | raw file
  1. #####################################################################################
  2. #
  3. # Copyright (c) Microsoft Corporation. All rights reserved.
  4. #
  5. # This source code is subject to terms and conditions of the Microsoft Public License. A
  6. # copy of the license can be found in the License.html file at the root of this distribution. If
  7. # you cannot locate the Microsoft Public License, please send an email to
  8. # ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. # by the terms of the Microsoft Public License.
  10. #
  11. # You must not remove this notice, or any other, from this software.
  12. #
  13. #
  14. #####################################################################################
  15. ### make this file platform neutral as much as possible
  16. import sys
  17. import time
  18. import cStringIO
  19. from iptest.test_env import *
  20. from iptest import options, l
  21. if not is_silverlight:
  22. import nt
  23. from file_util import *
  24. from type_util import types
  25. #------------------------------------------------------------------------------
  26. def usage(code, msg=''):
  27. print sys.modules['__main__'].__doc__ or 'No doc provided'
  28. if msg: print 'Error message: "%s"' % msg
  29. sys.exit(code)
  30. if not is_silverlight:
  31. def get_environ_variable(key):
  32. l = [nt.environ[x] for x in nt.environ.keys() if x.lower() == key.lower()]
  33. if l: return l[0]
  34. else: return None
  35. def get_temp_dir():
  36. temp = get_environ_variable("TMP")
  37. if temp == None: temp = get_environ_variable("TEMP")
  38. if (temp == None) or (' ' in temp) :
  39. temp = r"C:\temp"
  40. return temp
  41. ironpython_dlls = [
  42. "Microsoft.Scripting.Core.dll",
  43. "Microsoft.Scripting.dll",
  44. "Microsoft.Dynamic.dll",
  45. "Microsoft.Scripting.Internal.dll",
  46. "IronPython.Modules.dll",
  47. "IronPython.dll",
  48. ]
  49. def copy_ironpython_dlls(targetdir):
  50. import System
  51. for dll in ironpython_dlls:
  52. src = System.IO.Path.Combine(sys.prefix, dll)
  53. dst = System.IO.Path.Combine(targetdir, dll)
  54. try: System.IO.File.Copy(src, dst, True)
  55. except: pass
  56. def remove_ironpython_dlls(targetdir):
  57. import System
  58. for dll in ironpython_dlls:
  59. dst = System.IO.Path.Combine(targetdir, dll)
  60. try: System.IO.File.Delete(dst)
  61. except: pass
  62. if is_silverlight:
  63. class testpath:
  64. rowan_root = 'E:\\IP\\Main\\' #hack: should be set somewhere else
  65. ip_root = rowan_root + r"Languages\IronPython"
  66. public_testdir = ip_root + r'Tests'
  67. compat_testdir = ip_root + r'Tests\compat'
  68. test_inputs_dir = (ip_root + r'Tests\Inputs')
  69. script_testdir = (ip_root + r'Scripts')
  70. sys.prefix = ip_root
  71. sys.path.append(public_testdir)
  72. else:
  73. class testpath:
  74. # find the ironpython root directory
  75. rowan_root = get_environ_variable("merlin_root")
  76. basePyDir = 'Languages\\IronPython'
  77. if not rowan_root:
  78. rowan_root = sys.prefix
  79. if is_cli:
  80. if System.IO.Directory.Exists(path_combine(rowan_root, r'..\..\Src')):
  81. basePyDir = r'..\..\Src'
  82. # get some directories and files
  83. ip_root = path_combine(rowan_root, basePyDir)
  84. external_dir = path_combine(rowan_root, r'..\External.LCA_RESTRICTED\Languages\IronPython')
  85. clean_external_dir = path_combine(rowan_root, r'..\External.LCA_RESTRICTED\Languages\CPython\26')
  86. public_testdir = path_combine(ip_root, r'Tests')
  87. compat_testdir = path_combine(ip_root, r'Tests\compat')
  88. test_inputs_dir = path_combine(ip_root, r'Tests\Inputs')
  89. script_testdir = path_combine(ip_root, r'Scripts')
  90. math_testdir = path_combine(external_dir, r'Math')
  91. parrot_testdir = path_combine(external_dir, r'parrotbench')
  92. lib_testdir = path_combine(external_dir, r'26\Lib')
  93. private_testdir = path_combine(external_dir, r'26\Lib\test')
  94. temporary_dir = path_combine(get_temp_dir(), "IronPython")
  95. ensure_directory_present(temporary_dir)
  96. iron_python_test_dll = path_combine(sys.prefix, 'IronPythonTest.dll')
  97. if is_cli:
  98. ipython_executable = sys.executable
  99. cpython_executable = path_combine(external_dir, r'26\python.exe')
  100. else:
  101. ipython_executable = path_combine(sys.prefix, r'ipy.exe')
  102. cpython_executable = sys.executable
  103. #team_dir = path_combine(ip_root, r'Team')
  104. #team_profile = path_combine(team_dir, r'settings.py')
  105. #
  106. #my_name = nt.environ.get(r'USERNAME', None)
  107. #my_dir = my_name and path_combine(team_dir, my_name) or None
  108. #my_profile = my_dir and path_combine(my_dir, r'settings.py') or None
  109. class formatter:
  110. Number = 60
  111. TestNameLen = 40
  112. SeparatorEqual = '=' * Number
  113. Separator1 = '#' * Number
  114. SeparatorMinus = '-' * Number
  115. SeparatorStar = '*' * Number
  116. SeparatorPlus = '+' * Number
  117. Space4 = ' ' * 4
  118. Greater4 = '>' * 4
  119. # helper functions for sys.path
  120. _saved_syspath = []
  121. def preserve_syspath():
  122. _saved_syspath[:] = list(set(sys.path))
  123. def restore_syspath():
  124. sys.path = _saved_syspath[:]
  125. if is_cli or is_silverlight:
  126. import clr
  127. clr.AddReference("IronPython")
  128. def is_interactive():
  129. if not is_silverlight:
  130. isInteractive = get_environ_variable("ISINTERACTIVE")
  131. if isInteractive != None:
  132. return True
  133. else:
  134. return False
  135. def is_stdlib():
  136. if is_cli:
  137. clean_lib = System.IO.Path.GetFullPath(testpath.clean_external_dir + r"\lib").lower()
  138. for x in sys.path:
  139. if clean_lib==System.IO.Path.GetFullPath(x).lower():
  140. return True
  141. dirty_lib = clean_lib.replace("cpython", "ironpython")
  142. for x in sys.path:
  143. if dirty_lib==System.IO.Path.GetFullPath(x).lower():
  144. return True
  145. return False
  146. elif is_silverlight:
  147. return False
  148. else:
  149. #CPython should always have access to the standard library
  150. return True
  151. # test support
  152. def Fail(m): raise AssertionError(m)
  153. def Assert(c, m = "Assertion failed"):
  154. if not c: raise AssertionError(m)
  155. def AssertFalse(c, m = "Assertion for False failed"):
  156. if c: raise AssertionError(m)
  157. def AssertUnreachable(m = None):
  158. if m: Assert(False, "Unreachable code reached: "+m)
  159. else: Assert(False, "Unreachable code reached")
  160. def AreEqual(a, b):
  161. Assert(a == b, "expected %r, but found %r" % (b, a))
  162. def AreNotEqual(a, b):
  163. Assert(a <> b, "expected only one of the values to be %r" % a)
  164. def AssertContains(containing_string, substring):
  165. Assert(substring in containing_string, "%s should be in %s" % (substring, containing_string))
  166. def AssertDoesNotContain(containing_string, substring):
  167. Assert(not substring in containing_string, "%s should not be in %s" % (substring, containing_string))
  168. def SequencesAreEqual(a, b, m=None):
  169. Assert(len(a) == len(b), m or 'sequence lengths differ: expected %d, but found %d' % (len(b), len(a)))
  170. for i in xrange(len(a)):
  171. Assert(a[i] == b[i], m or 'sequences differ at index %d: expected %r, but found %r' % (i, b[i], a[i]))
  172. def AlmostEqual(a, b):
  173. Assert(round(a-b, 6) == 0, "expected %r and %r almost same" % (a, b))
  174. def AssertError(exc, func, *args, **kwargs):
  175. try: func(*args, **kwargs)
  176. except exc: return
  177. else : Fail("Expected %r but got no exception" % exc)
  178. def AssertDocEqual(received, expected):
  179. expected = expected.split(newline)
  180. received = received.split(newline)
  181. for x in received:
  182. if not x in expected:
  183. raise AssertionError('Extra doc string: ' + x)
  184. index = expected.index(x)
  185. del expected[index]
  186. if expected: raise AssertionError('Missing doc strings: ' + expected.join(', '))
  187. def AssertInOrNot(l, in_list, not_in_list):
  188. for x in in_list:
  189. Assert(x in l, "%s should be in %s" % (x, l))
  190. for x in not_in_list:
  191. Assert(x not in l, "%s should not be in %s" % (x, l))
  192. # Check that the exception is raised with the provided message
  193. def AssertErrorWithMessage(exc, expectedMessage, func, *args, **kwargs):
  194. Assert(expectedMessage, "expectedMessage cannot be null")
  195. try: func(*args, **kwargs)
  196. except exc, inst:
  197. Assert(expectedMessage == inst.__str__(), \
  198. "Exception %r message (%r) does not match %r" % (type(inst), inst.__str__(), expectedMessage))
  199. else: Assert(False, "Expected %r but got no exception" % exc)
  200. def AssertErrorWithPartialMessage(exc, expectedMessage, func, *args, **kwargs):
  201. Assert(expectedMessage, "expectedMessage cannot be null")
  202. try: func(*args, **kwargs)
  203. except exc, inst:
  204. Assert(expectedMessage in inst.__str__(), \
  205. "Exception %r message (%r) does not contain %r" % (type(inst), inst.__str__(), expectedMessage))
  206. else: Assert(False, "Expected %r but got no exception" % exc)
  207. def AssertErrorWithNumber(exc, expectedErrorNo, func, *args, **kwargs):
  208. try: func(*args, **kwargs)
  209. except exc, e:
  210. AreEqual(e.errno, expectedErrorNo)
  211. else : Fail("Expected %r but got no exception" % exc)
  212. # Check that the exception is raised with the provided message, where the message
  213. # differs on IronPython and CPython
  214. def AssertErrorWithMessages(exc, ironPythonMessage, cpythonMessage, func, *args, **kwargs):
  215. if is_cli or is_silverlight:
  216. expectedMessage = ironPythonMessage
  217. else:
  218. expectedMessage = cpythonMessage
  219. Assert(expectedMessage, "expectedMessage cannot be null")
  220. try: func(*args, **kwargs)
  221. except exc, inst:
  222. Assert(expectedMessage == inst.__str__(), \
  223. "Exception %r message (%r) does not contain %r" % (type(inst), inst.__str__(), expectedMessage))
  224. else: Assert(False, "Expected %r but got no exception" % exc)
  225. # Check that the exception is raised with the provided message, where the message
  226. # is matches using a regular-expression match
  227. if is_silverlight:
  228. def load_iron_python_test(*args):
  229. import clr
  230. AddReferenceToDlrCore()
  231. clr.AddReference("Microsoft.Scripting")
  232. clr.AddReference("Microsoft.Dynamic, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL")
  233. clr.AddReference("IronPython")
  234. ipt_fullname = "IronPythonTest, Version=1.0.0.0, PublicKeyToken=31bf3856ad364e35"
  235. if args:
  236. return clr.LoadAssembly(ipt_fullname)
  237. else:
  238. clr.AddReference(ipt_fullname)
  239. else:
  240. def AssertErrorWithMatch(exc, expectedMessage, func, *args, **kwargs):
  241. import re
  242. Assert(expectedMessage, "expectedMessage cannot be null")
  243. try: func(*args, **kwargs)
  244. except exc, inst:
  245. Assert(re.compile(expectedMessage).match(inst.__str__()), \
  246. "Exception %r message (%r) does not contain %r" % (type(inst), inst.__str__(), expectedMessage))
  247. else: Assert(False, "Expected %r but got no exception" % exc)
  248. def load_iron_python_test(*args):
  249. import clr
  250. AddReferenceToDlrCore()
  251. clr.AddReference("Microsoft.Scripting")
  252. clr.AddReference("Microsoft.Dynamic")
  253. clr.AddReference("IronPython")
  254. if args:
  255. return clr.LoadAssemblyFromFileWithPath(testpath.iron_python_test_dll)
  256. else:
  257. clr.AddReferenceToFileAndPath(testpath.iron_python_test_dll)
  258. def load_iron_python_dll():
  259. import clr
  260. from System.IO import File
  261. #When assemblies are installed into the GAC, we should not expect
  262. #IronPython.dll to exist alongside IronPython.dll
  263. if File.Exists(path_combine(sys.prefix, "IronPython.dll")):
  264. clr.AddReferenceToFileAndPath(path_combine(sys.prefix, "IronPython.dll"))
  265. else:
  266. clr.AddReference("IronPython")
  267. def GetTotalMemory():
  268. import System
  269. # 3 collect calls to ensure collection
  270. for x in range(3):
  271. System.GC.Collect()
  272. System.GC.WaitForPendingFinalizers()
  273. return System.GC.GetTotalMemory(True)
  274. def _do_nothing(*args):
  275. for arg in args:
  276. print arg
  277. pass
  278. def get_num_iterations():
  279. default = 1
  280. if not is_silverlight:
  281. value = get_environ_variable('NUM_TEST_ITERATIONS')
  282. else:
  283. value = None
  284. if value:
  285. num_of_iterations = int(value)
  286. else:
  287. num_of_iterations = default
  288. if num_of_iterations < default :
  289. num_of_iterations = default
  290. return num_of_iterations
  291. class disabled:
  292. def __init__(self, reason):
  293. self.reason = reason
  294. def __call__(self, f):
  295. return _do_nothing("Skipping disabled test %s. (Reason: %s)" % (f.func_name, self.reason))
  296. class skip:
  297. def __init__(self, *platforms):
  298. if len(platforms) == 1 and isinstance(platforms[0], str):
  299. self.platforms = platforms[0].split()
  300. else:
  301. self.platforms = platforms
  302. def silverlight_test(self):
  303. return is_silverlight
  304. def cli64_test(self):
  305. return is_cli64
  306. def orcas_test(self):
  307. return is_orcas
  308. def interactive_test(self):
  309. return is_interactive()
  310. def multiple_execute_test(self):
  311. return get_num_iterations() > 1
  312. def stdlib_test(self):
  313. return is_stdlib()
  314. def __call__(self, f):
  315. #skip questionable tests
  316. if is_silverlight and 'silverlightbug?' in self.platforms:
  317. msg = '... TODO, investigate Silverlight failure @ %s' % f.func_name
  318. return _do_nothing(msg)
  319. elif sys.platform in self.platforms:
  320. msg = '... Decorated with @skip(%s), skipping %s ...' % (
  321. self.platforms, f.func_name)
  322. return _do_nothing(msg)
  323. platforms = 'silverlight', 'cli64', 'orcas', 'interactive', 'multiple_execute', 'stdlib'
  324. for to_skip in platforms:
  325. platform_test = getattr(self, to_skip + '_test')
  326. if to_skip in self.platforms and platform_test():
  327. msg = '... Decorated with @skip(%s), skipping %s ...' % (
  328. self.platforms, f.func_name)
  329. return _do_nothing(msg)
  330. return f
  331. class runonly:
  332. def __init__(self, *platforms):
  333. if len(platforms) == 1 and isinstance(platforms[0], str):
  334. self.platforms = platforms[0].split()
  335. else:
  336. self.platforms = platforms
  337. def __call__(self, f):
  338. if "orcas" in self.platforms and is_orcas:
  339. return f
  340. elif "silverlight" in self.platforms and is_silverlight:
  341. return f
  342. elif "stdlib" in self.platforms and is_stdlib():
  343. return f
  344. elif sys.platform in self.platforms:
  345. return f
  346. else:
  347. return _do_nothing('... Decorated with @runonly(%s), Skipping %s ...' % (self.platforms, f.func_name))
  348. @runonly('win32 silverlight cli')
  349. def _func(): pass
  350. # method could be used to skip rest of test
  351. def skiptest(*args):
  352. #hack: skip questionable tests:
  353. if is_silverlight and 'silverlightbug?' in args:
  354. print '... TODO, whole test module is skipped for Silverlight failure. Need to investigate...'
  355. exit_module()
  356. elif is_silverlight and 'silverlight' in args:
  357. print '... %s, skipping whole test module...' % sys.platform
  358. exit_module()
  359. elif is_interactive() and 'interactive' in args:
  360. print '... %s, skipping whole test module under "interactive" mode...' % sys.platform
  361. exit_module()
  362. elif is_stdlib() and 'stdlib' in args:
  363. print '... %s, skipping whole test module under "stdlib" mode...' % sys.platform
  364. exit_module()
  365. elif is_cli64 and 'cli64' in args:
  366. print '... %s, skipping whole test module on 64-bit CLI...' % sys.platform
  367. exit_module()
  368. elif get_num_iterations() > 1 and 'multiple_execute' in args:
  369. print '... %d invocations, skipping whole test module under "multiple_execute" mode...' % get_num_iterations()
  370. exit_module()
  371. if sys.platform in args:
  372. print '... %s, skipping whole test module...' % sys.platform
  373. exit_module()
  374. def exit_module():
  375. #Have to catch exception for below call. Any better way to exit?
  376. sys.exit(0)
  377. def print_failures(total, failures):
  378. print
  379. for failure in failures:
  380. name, (extype, ex, tb) = failure
  381. print '------------------------------------'
  382. print "Test %s failed throwing %s (%s)" % (name, str(extype), str(ex))
  383. while tb:
  384. print ' ... %s in %s line %d' % (tb.tb_frame.f_code.co_name, tb.tb_frame.f_code.co_filename, tb.tb_lineno)
  385. tb = tb.tb_next
  386. print
  387. if is_cli:
  388. if '-X:ExceptionDetail' in System.Environment.GetCommandLineArgs():
  389. load_iron_python_test()
  390. from IronPythonTest import TestHelpers
  391. print 'CLR Exception: ',
  392. print TestHelpers.GetContext().FormatException(ex.clsException)
  393. print
  394. failcount = len(failures)
  395. print '%d total, %d passed, %d failed' % (total, total - failcount, failcount)
  396. def run_test(mod_name, noOutputPlease=False):
  397. if not options.RUN_TESTS:
  398. l.debug("Will not invoke any test cases from '%s'." % mod_name)
  399. return
  400. import sys
  401. module = sys.modules[mod_name]
  402. stdout = sys.stdout
  403. stderr = sys.stderr
  404. failures = []
  405. total = 0
  406. includedTests = [arg[4:] for arg in sys.argv if arg.startswith('run:test_') and not arg.endswith('.py')]
  407. for name in dir(module):
  408. obj = getattr(module, name)
  409. if isinstance(obj, types.functionType):
  410. if name.endswith("_clionly") and not is_cli: continue
  411. if name.startswith("test_"):
  412. if not includedTests or name in includedTests:
  413. for i in xrange( get_num_iterations()):
  414. if not noOutputPlease:
  415. if hasattr(time, 'clock'):
  416. print ">>> %6.2fs testing %-40s" % (round(time.clock(), 2), name, ),
  417. else:
  418. print ">>> testing %-40s" % name,
  419. #obj()
  420. #catches the error and exit at the end of each test
  421. total += 1
  422. try:
  423. try:
  424. obj()
  425. finally:
  426. # restore std-in / std-err incase the test corrupted it
  427. sys.stdout = stdout
  428. sys.stderr = stderr
  429. print
  430. except:
  431. failures.append( (name, sys.exc_info()) )
  432. print "FAIL (%s)" % str(sys.exc_info()[0])
  433. elif not noOutputPlease:
  434. print ">>> skipping %-40s" % name
  435. if failures:
  436. print_failures(total, failures)
  437. if is_cli:
  438. cmd_line = System.Environment.CurrentDirectory + "> " + System.Environment.CommandLine
  439. print "Please run the following command to repro:"
  440. print "\t" + cmd_line
  441. sys.exit(len(failures))
  442. else:
  443. print
  444. print '%d tests passed' % total
  445. def run_class(mod_name, verbose=False):
  446. pass
  447. def add_clr_assemblies(*dlls):
  448. import clr
  449. prefix = "rowantest."
  450. for x in dlls:
  451. if x.startswith(prefix):
  452. clr.AddReference(x)
  453. else:
  454. clr.AddReference(prefix + x)
  455. def AddReferenceToDlrCore():
  456. import clr
  457. import System
  458. if System.Environment.Version.Major >=4:
  459. clr.AddReference("System.Core")
  460. else:
  461. clr.AddReference("Microsoft.Scripting.Core")
  462. class stderr_trapper(object):
  463. def __init__(self):
  464. self.stderr = cStringIO.StringIO()
  465. def __enter__(self):
  466. self.oldstderr = sys.stderr
  467. sys.stderr = self.stderr
  468. return self
  469. def __exit__(self, *args):
  470. self.stderr.flush()
  471. self.stderr.reset()
  472. self.messages = self.stderr.readlines()
  473. self.messages = [x.rstrip() for x in self.messages]
  474. self.stderr.close()
  475. sys.stderr = self.oldstderr
  476. class stdout_trapper(object):
  477. def __init__(self):
  478. self.stdout = cStringIO.StringIO()
  479. def __enter__(self):
  480. self.oldstdout, sys.stdout = sys.stdout, self.stdout
  481. return self
  482. def __exit__(self, *args):
  483. self.stdout.flush()
  484. self.stdout.reset()
  485. self.messages = self.stdout.readlines()
  486. self.messages = [x.rstrip() for x in self.messages]
  487. self.stdout.close()
  488. sys.stdout = self.oldstdout
  489. #------------------------------------------------------------------------------
  490. MAX_FAILURE_RETRY = 3
  491. def retry_on_failure(f, *args, **kwargs):
  492. '''
  493. Utility function which:
  494. 1. Wraps execution of the input function, f
  495. 2. If f() fails, it retries invoking it MAX_FAILURE_RETRY times
  496. '''
  497. def t(*args, **kwargs):
  498. for i in xrange(MAX_FAILURE_RETRY):
  499. try:
  500. ret_val = f(*args, **kwargs)
  501. return ret_val
  502. except Exception, e:
  503. print "retry_on_failure(%s): failed on attempt '%d':" % (f.__name__, i+1)
  504. print e
  505. excp_info = sys.exc_info()
  506. continue
  507. # raise w/ excep info to preverve the original stack trace
  508. raise excp_info[0], excp_info[1], excp_info[2]
  509. return t
  510. def force_gc():
  511. if is_silverlight:
  512. return
  513. elif is_cpython:
  514. import gc
  515. gc.collect()
  516. else:
  517. import System
  518. for i in xrange(100):
  519. System.GC.Collect()
  520. System.GC.WaitForPendingFinalizers()