图片解析应用
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.

139 lines
3.8 KiB

  1. ##############################################################################
  2. #
  3. # Copyright Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. import logging
  15. import os
  16. import time
  17. CI = os.environ.get("CI", False)
  18. CI_ZK_VERSION = CI and os.environ.get("ZOOKEEPER_VERSION", None)
  19. if CI_ZK_VERSION:
  20. if "-" in CI_ZK_VERSION:
  21. # Ignore pre-release markers like -alpha
  22. CI_ZK_VERSION = CI_ZK_VERSION.split("-")[0]
  23. CI_ZK_VERSION = tuple([int(n) for n in CI_ZK_VERSION.split(".")])
  24. class Handler(logging.Handler):
  25. def __init__(self, *names, **kw):
  26. logging.Handler.__init__(self)
  27. self.names = names
  28. self.records = []
  29. self.setLoggerLevel(**kw)
  30. def setLoggerLevel(self, level=1):
  31. self.level = level
  32. self.oldlevels = {}
  33. def emit(self, record):
  34. self.records.append(record)
  35. def clear(self):
  36. del self.records[:]
  37. def install(self):
  38. for name in self.names:
  39. logger = logging.getLogger(name)
  40. self.oldlevels[name] = logger.level
  41. logger.setLevel(self.level)
  42. logger.addHandler(self)
  43. def uninstall(self):
  44. for name in self.names:
  45. logger = logging.getLogger(name)
  46. logger.setLevel(self.oldlevels[name])
  47. logger.removeHandler(self)
  48. def __str__(self):
  49. return "\n".join(
  50. [
  51. (
  52. "%s %s\n %s"
  53. % (
  54. record.name,
  55. record.levelname,
  56. "\n".join(
  57. [
  58. line
  59. for line in record.getMessage().split("\n")
  60. if line.strip()
  61. ]
  62. ),
  63. )
  64. )
  65. for record in self.records
  66. ]
  67. )
  68. class InstalledHandler(Handler):
  69. def __init__(self, *names, **kw):
  70. Handler.__init__(self, *names, **kw)
  71. self.install()
  72. class Wait(object):
  73. class TimeOutWaitingFor(Exception):
  74. "A test condition timed out"
  75. timeout = 9
  76. wait = 0.01
  77. def __init__(
  78. self,
  79. timeout=None,
  80. wait=None,
  81. exception=None,
  82. getnow=(lambda: time.time),
  83. getsleep=(lambda: time.sleep),
  84. ):
  85. if timeout is not None:
  86. self.timeout = timeout
  87. if wait is not None:
  88. self.wait = wait
  89. if exception is not None:
  90. self.TimeOutWaitingFor = exception
  91. self.getnow = getnow
  92. self.getsleep = getsleep
  93. def __call__(self, func=None, timeout=None, wait=None, message=None):
  94. if func is None:
  95. return lambda func: self(func, timeout, wait, message)
  96. if func():
  97. return
  98. now = self.getnow()
  99. sleep = self.getsleep()
  100. if timeout is None:
  101. timeout = self.timeout
  102. if wait is None:
  103. wait = self.wait
  104. wait = float(wait)
  105. deadline = now() + timeout
  106. while 1:
  107. sleep(wait)
  108. if func():
  109. return
  110. if now() > deadline:
  111. raise self.TimeOutWaitingFor(
  112. message or func.__doc__ or func.__name__
  113. )
  114. wait = Wait()