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

343 lines
9.1 KiB

  1. import datetime
  2. import uuid
  3. from kazoo.recipe.lease import NonBlockingLease
  4. from kazoo.recipe.lease import MultiNonBlockingLease
  5. from kazoo.testing import KazooTestCase
  6. class MockClock(object):
  7. def __init__(self, epoch=0):
  8. self.epoch = epoch
  9. def forward(self, seconds):
  10. self.epoch += seconds
  11. def __call__(self):
  12. return datetime.datetime.utcfromtimestamp(self.epoch)
  13. class KazooLeaseTests(KazooTestCase):
  14. def setUp(self):
  15. super(KazooLeaseTests, self).setUp()
  16. self.client2 = self._get_client(timeout=0.8)
  17. self.client2.start()
  18. self.client3 = self._get_client(timeout=0.8)
  19. self.client3.start()
  20. self.path = "/" + uuid.uuid4().hex
  21. self.clock = MockClock(10)
  22. def tearDown(self):
  23. for cl in [self.client2, self.client3]:
  24. if cl.connected:
  25. cl.stop()
  26. cl.close()
  27. del self.client2
  28. del self.client3
  29. class NonBlockingLeaseTests(KazooLeaseTests):
  30. def test_renew(self):
  31. # Use client convenience method here to test it at least once. Use
  32. # class directly in
  33. # other tests in order to get better IDE support.
  34. lease = self.client.NonBlockingLease(
  35. self.path, datetime.timedelta(seconds=3), utcnow=self.clock
  36. )
  37. assert lease
  38. assert lease.obtained is True
  39. self.clock.forward(2)
  40. renewed_lease = self.client.NonBlockingLease(
  41. self.path, datetime.timedelta(seconds=3), utcnow=self.clock
  42. )
  43. assert renewed_lease
  44. def test_busy(self):
  45. lease = NonBlockingLease(
  46. self.client,
  47. self.path,
  48. datetime.timedelta(seconds=3),
  49. utcnow=self.clock,
  50. )
  51. assert lease
  52. self.clock.forward(2)
  53. foreigner_lease = NonBlockingLease(
  54. self.client2,
  55. self.path,
  56. datetime.timedelta(seconds=3),
  57. identifier="some.other.host",
  58. utcnow=self.clock,
  59. )
  60. assert not foreigner_lease
  61. assert foreigner_lease.obtained is False
  62. def test_overtake(self):
  63. lease = NonBlockingLease(
  64. self.client,
  65. self.path,
  66. datetime.timedelta(seconds=3),
  67. utcnow=self.clock,
  68. )
  69. assert lease
  70. self.clock.forward(4)
  71. foreigner_lease = NonBlockingLease(
  72. self.client2,
  73. self.path,
  74. datetime.timedelta(seconds=3),
  75. identifier="some.other.host",
  76. utcnow=self.clock,
  77. )
  78. assert foreigner_lease
  79. def test_renew_no_overtake(self):
  80. lease = self.client.NonBlockingLease(
  81. self.path, datetime.timedelta(seconds=3), utcnow=self.clock
  82. )
  83. assert lease
  84. assert lease.obtained is True
  85. self.clock.forward(2)
  86. renewed_lease = self.client.NonBlockingLease(
  87. self.path, datetime.timedelta(seconds=3), utcnow=self.clock
  88. )
  89. assert renewed_lease
  90. self.clock.forward(2)
  91. foreigner_lease = NonBlockingLease(
  92. self.client2,
  93. self.path,
  94. datetime.timedelta(seconds=3),
  95. identifier="some.other.host",
  96. utcnow=self.clock,
  97. )
  98. assert not foreigner_lease
  99. def test_overtaker_renews(self):
  100. lease = NonBlockingLease(
  101. self.client,
  102. self.path,
  103. datetime.timedelta(seconds=3),
  104. utcnow=self.clock,
  105. )
  106. assert lease
  107. self.clock.forward(4)
  108. foreigner_lease = NonBlockingLease(
  109. self.client2,
  110. self.path,
  111. datetime.timedelta(seconds=3),
  112. identifier="some.other.host",
  113. utcnow=self.clock,
  114. )
  115. assert foreigner_lease
  116. self.clock.forward(2)
  117. foreigner_renew = NonBlockingLease(
  118. self.client2,
  119. self.path,
  120. datetime.timedelta(seconds=3),
  121. identifier="some.other.host",
  122. utcnow=self.clock,
  123. )
  124. assert foreigner_renew
  125. def test_overtake_refuse_first(self):
  126. lease = NonBlockingLease(
  127. self.client,
  128. self.path,
  129. datetime.timedelta(seconds=3),
  130. utcnow=self.clock,
  131. )
  132. assert lease
  133. self.clock.forward(4)
  134. foreigner_lease = NonBlockingLease(
  135. self.client2,
  136. self.path,
  137. datetime.timedelta(seconds=3),
  138. identifier="some.other.host",
  139. utcnow=self.clock,
  140. )
  141. assert foreigner_lease
  142. self.clock.forward(2)
  143. first_again_lease = NonBlockingLease(
  144. self.client,
  145. self.path,
  146. datetime.timedelta(seconds=3),
  147. utcnow=self.clock,
  148. )
  149. assert not first_again_lease
  150. def test_old_version(self):
  151. # Skip to a future version
  152. NonBlockingLease._version += 1
  153. lease = NonBlockingLease(
  154. self.client,
  155. self.path,
  156. datetime.timedelta(seconds=3),
  157. utcnow=self.clock,
  158. )
  159. assert lease
  160. # Then back to today.
  161. NonBlockingLease._version -= 1
  162. self.clock.forward(4)
  163. foreigner_lease = NonBlockingLease(
  164. self.client2,
  165. self.path,
  166. datetime.timedelta(seconds=3),
  167. identifier="some.other.host",
  168. utcnow=self.clock,
  169. )
  170. # Since a newer version wrote the lease file, the lease is not taken.
  171. assert not foreigner_lease
  172. class MultiNonBlockingLeaseTest(KazooLeaseTests):
  173. def test_1_renew(self):
  174. ls = self.client.MultiNonBlockingLease(
  175. 1, self.path, datetime.timedelta(seconds=4), utcnow=self.clock
  176. )
  177. assert ls
  178. self.clock.forward(2)
  179. ls2 = MultiNonBlockingLease(
  180. self.client,
  181. 1,
  182. self.path,
  183. datetime.timedelta(seconds=4),
  184. utcnow=self.clock,
  185. )
  186. assert ls2
  187. def test_1_reject(self):
  188. ls = MultiNonBlockingLease(
  189. self.client,
  190. 1,
  191. self.path,
  192. datetime.timedelta(seconds=4),
  193. utcnow=self.clock,
  194. )
  195. assert ls
  196. self.clock.forward(2)
  197. ls2 = MultiNonBlockingLease(
  198. self.client2,
  199. 1,
  200. self.path,
  201. datetime.timedelta(seconds=4),
  202. identifier="some.other.host",
  203. utcnow=self.clock,
  204. )
  205. assert not ls2
  206. def test_2_renew(self):
  207. ls = MultiNonBlockingLease(
  208. self.client,
  209. 2,
  210. self.path,
  211. datetime.timedelta(seconds=7),
  212. utcnow=self.clock,
  213. )
  214. assert ls
  215. self.clock.forward(2)
  216. ls2 = MultiNonBlockingLease(
  217. self.client2,
  218. 2,
  219. self.path,
  220. datetime.timedelta(seconds=7),
  221. identifier="host2",
  222. utcnow=self.clock,
  223. )
  224. assert ls2
  225. self.clock.forward(2)
  226. ls3 = MultiNonBlockingLease(
  227. self.client,
  228. 2,
  229. self.path,
  230. datetime.timedelta(seconds=7),
  231. utcnow=self.clock,
  232. )
  233. assert ls3
  234. self.clock.forward(2)
  235. ls4 = MultiNonBlockingLease(
  236. self.client2,
  237. 2,
  238. self.path,
  239. datetime.timedelta(seconds=7),
  240. identifier="host2",
  241. utcnow=self.clock,
  242. )
  243. assert ls4
  244. def test_2_reject(self):
  245. ls = MultiNonBlockingLease(
  246. self.client,
  247. 2,
  248. self.path,
  249. datetime.timedelta(seconds=7),
  250. utcnow=self.clock,
  251. )
  252. assert ls
  253. self.clock.forward(2)
  254. ls2 = MultiNonBlockingLease(
  255. self.client2,
  256. 2,
  257. self.path,
  258. datetime.timedelta(seconds=7),
  259. identifier="host2",
  260. utcnow=self.clock,
  261. )
  262. assert ls2
  263. self.clock.forward(2)
  264. ls3 = MultiNonBlockingLease(
  265. self.client3,
  266. 2,
  267. self.path,
  268. datetime.timedelta(seconds=7),
  269. identifier="host3",
  270. utcnow=self.clock,
  271. )
  272. assert not ls3
  273. def test_2_handover(self):
  274. ls = MultiNonBlockingLease(
  275. self.client,
  276. 2,
  277. self.path,
  278. datetime.timedelta(seconds=4),
  279. utcnow=self.clock,
  280. )
  281. assert ls
  282. self.clock.forward(2)
  283. ls2 = MultiNonBlockingLease(
  284. self.client2,
  285. 2,
  286. self.path,
  287. datetime.timedelta(seconds=4),
  288. identifier="host2",
  289. utcnow=self.clock,
  290. )
  291. assert ls2
  292. self.clock.forward(3)
  293. ls3 = MultiNonBlockingLease(
  294. self.client3,
  295. 2,
  296. self.path,
  297. datetime.timedelta(seconds=4),
  298. identifier="host3",
  299. utcnow=self.clock,
  300. )
  301. assert ls3
  302. self.clock.forward(2)
  303. ls4 = MultiNonBlockingLease(
  304. self.client,
  305. 2,
  306. self.path,
  307. datetime.timedelta(seconds=4),
  308. utcnow=self.clock,
  309. )
  310. assert ls4