test_test_resource.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. # testresources: extensions to python unittest to allow declaritive use
  2. # of resources by test cases.
  3. #
  4. # Copyright (c) 2005-2010 Testresources Contributors
  5. #
  6. # Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
  7. # license at the users choice. A copy of both licenses are available in the
  8. # project source as Apache-2.0 and BSD. You may not use this file except in
  9. # compliance with one of these two licences.
  10. #
  11. # Unless required by applicable law or agreed to in writing, software distributed
  12. # under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. # CONDITIONS OF ANY KIND, either express or implied. See the license you chose
  14. # for the specific language governing permissions and limitations under that
  15. # license.
  16. #
  17. from fixtures.tests.helpers import LoggingFixture
  18. import testtools
  19. import testresources
  20. from testresources.tests import (
  21. ResultWithResourceExtensions,
  22. ResultWithoutResourceExtensions,
  23. )
  24. def test_suite():
  25. loader = testresources.tests.TestUtil.TestLoader()
  26. result = loader.loadTestsFromName(__name__)
  27. return result
  28. class MockResourceInstance(object):
  29. def __init__(self, name):
  30. self._name = name
  31. def __eq__(self, other):
  32. return self.__dict__ == other.__dict__
  33. def __cmp__(self, other):
  34. return cmp(self.__dict__, other.__dict__)
  35. def __repr__(self):
  36. return self._name
  37. class MockResource(testresources.TestResourceManager):
  38. """Mock resource that logs the number of make and clean calls."""
  39. def __init__(self):
  40. super(MockResource, self).__init__()
  41. self.makes = 0
  42. self.cleans = 0
  43. def clean(self, resource):
  44. self.cleans += 1
  45. def make(self, dependency_resources):
  46. self.makes += 1
  47. return MockResourceInstance("Boo!")
  48. class MockResettableResource(MockResource):
  49. """Mock resource that logs the number of reset calls too."""
  50. def __init__(self):
  51. super(MockResettableResource, self).__init__()
  52. self.resets = 0
  53. def _reset(self, resource, dependency_resources):
  54. self.resets += 1
  55. resource._name += "!"
  56. self._dirty = False
  57. return resource
  58. class TestTestResource(testtools.TestCase):
  59. def testUnimplementedGetResource(self):
  60. # By default, TestResource raises NotImplementedError on getResource
  61. # because make is not defined initially.
  62. resource_manager = testresources.TestResource()
  63. self.assertRaises(NotImplementedError, resource_manager.getResource)
  64. def testInitiallyNotDirty(self):
  65. resource_manager = testresources.TestResource()
  66. self.assertEqual(False, resource_manager._dirty)
  67. def testInitiallyUnused(self):
  68. resource_manager = testresources.TestResource()
  69. self.assertEqual(0, resource_manager._uses)
  70. def testInitiallyNoCurrentResource(self):
  71. resource_manager = testresources.TestResource()
  72. self.assertEqual(None, resource_manager._currentResource)
  73. def testneededResourcesDefault(self):
  74. # Calling neededResources on a default TestResource returns the
  75. # resource.
  76. resource = testresources.TestResource()
  77. self.assertEqual([resource], resource.neededResources())
  78. def testneededResourcesDependenciesFirst(self):
  79. # Calling neededResources on a TestResource with dependencies puts the
  80. # dependencies first.
  81. resource = testresources.TestResource()
  82. dep1 = testresources.TestResource()
  83. dep2 = testresources.TestResource()
  84. resource.resources.append(("dep1", dep1))
  85. resource.resources.append(("dep2", dep2))
  86. self.assertEqual([dep1, dep2, resource], resource.neededResources())
  87. def testneededResourcesClosure(self):
  88. # Calling neededResources on a TestResource with dependencies includes
  89. # the needed resources of the needed resources.
  90. resource = testresources.TestResource()
  91. dep1 = testresources.TestResource()
  92. dep2 = testresources.TestResource()
  93. resource.resources.append(("dep1", dep1))
  94. dep1.resources.append(("dep2", dep2))
  95. self.assertEqual([dep2, dep1, resource], resource.neededResources())
  96. def testDefaultCosts(self):
  97. # The base TestResource costs 1 to set up and to tear down.
  98. resource_manager = testresources.TestResource()
  99. self.assertEqual(resource_manager.setUpCost, 1)
  100. self.assertEqual(resource_manager.tearDownCost, 1)
  101. def testGetResourceReturnsMakeResource(self):
  102. resource_manager = MockResource()
  103. resource = resource_manager.getResource()
  104. self.assertEqual(resource_manager.make({}), resource)
  105. def testGetResourceIncrementsUses(self):
  106. resource_manager = MockResource()
  107. resource_manager.getResource()
  108. self.assertEqual(1, resource_manager._uses)
  109. resource_manager.getResource()
  110. self.assertEqual(2, resource_manager._uses)
  111. def testGetResourceDoesntDirty(self):
  112. resource_manager = MockResource()
  113. resource_manager.getResource()
  114. self.assertEqual(resource_manager._dirty, False)
  115. def testGetResourceSetsCurrentResource(self):
  116. resource_manager = MockResource()
  117. resource = resource_manager.getResource()
  118. self.assertIs(resource_manager._currentResource, resource)
  119. def testGetResourceTwiceReturnsIdenticalResource(self):
  120. resource_manager = MockResource()
  121. resource1 = resource_manager.getResource()
  122. resource2 = resource_manager.getResource()
  123. self.assertIs(resource1, resource2)
  124. def testGetResourceCallsMakeResource(self):
  125. resource_manager = MockResource()
  126. resource_manager.getResource()
  127. self.assertEqual(1, resource_manager.makes)
  128. def testIsDirty(self):
  129. resource_manager = MockResource()
  130. r = resource_manager.getResource()
  131. resource_manager.dirtied(r)
  132. self.assertTrue(resource_manager.isDirty())
  133. resource_manager.finishedWith(r)
  134. def testIsDirtyIsTrueIfDependenciesChanged(self):
  135. resource_manager = MockResource()
  136. dep1 = MockResource()
  137. dep2 = MockResource()
  138. dep3 = MockResource()
  139. resource_manager.resources.append(("dep1", dep1))
  140. resource_manager.resources.append(("dep2", dep2))
  141. resource_manager.resources.append(("dep3", dep3))
  142. r = resource_manager.getResource()
  143. dep2.dirtied(r.dep2)
  144. r2 =dep2.getResource()
  145. self.assertTrue(resource_manager.isDirty())
  146. resource_manager.finishedWith(r)
  147. dep2.finishedWith(r2)
  148. def testIsDirtyIsTrueIfDependenciesAreDirty(self):
  149. resource_manager = MockResource()
  150. dep1 = MockResource()
  151. dep2 = MockResource()
  152. dep3 = MockResource()
  153. resource_manager.resources.append(("dep1", dep1))
  154. resource_manager.resources.append(("dep2", dep2))
  155. resource_manager.resources.append(("dep3", dep3))
  156. r = resource_manager.getResource()
  157. dep2.dirtied(r.dep2)
  158. self.assertTrue(resource_manager.isDirty())
  159. resource_manager.finishedWith(r)
  160. def testRepeatedGetResourceCallsMakeResourceOnceOnly(self):
  161. resource_manager = MockResource()
  162. resource_manager.getResource()
  163. resource_manager.getResource()
  164. self.assertEqual(1, resource_manager.makes)
  165. def testGetResourceResetsUsedResource(self):
  166. resource_manager = MockResettableResource()
  167. resource_manager.getResource()
  168. resource = resource_manager.getResource()
  169. self.assertEqual(1, resource_manager.makes)
  170. resource_manager.dirtied(resource)
  171. resource_manager.getResource()
  172. self.assertEqual(1, resource_manager.makes)
  173. self.assertEqual(1, resource_manager.resets)
  174. resource_manager.finishedWith(resource)
  175. def testIsResetIfDependenciesAreDirty(self):
  176. resource_manager = MockResource()
  177. dep1 = MockResettableResource()
  178. resource_manager.resources.append(("dep1", dep1))
  179. r = resource_manager.getResource()
  180. dep1.dirtied(r.dep1)
  181. # if we get the resource again, it should be cleaned.
  182. r = resource_manager.getResource()
  183. self.assertFalse(resource_manager.isDirty())
  184. self.assertFalse(dep1.isDirty())
  185. resource_manager.finishedWith(r)
  186. resource_manager.finishedWith(r)
  187. def testUsedResourceResetBetweenUses(self):
  188. resource_manager = MockResettableResource()
  189. # take two refs; like happens with OptimisingTestSuite.
  190. resource_manager.getResource()
  191. resource = resource_manager.getResource()
  192. resource_manager.dirtied(resource)
  193. resource_manager.finishedWith(resource)
  194. # Get again, but its been dirtied.
  195. resource = resource_manager.getResource()
  196. resource_manager.finishedWith(resource)
  197. resource_manager.finishedWith(resource)
  198. # The resource is made once, reset once and cleaned once.
  199. self.assertEqual(1, resource_manager.makes)
  200. self.assertEqual(1, resource_manager.resets)
  201. self.assertEqual(1, resource_manager.cleans)
  202. def testFinishedWithDecrementsUses(self):
  203. resource_manager = MockResource()
  204. resource = resource_manager.getResource()
  205. resource = resource_manager.getResource()
  206. self.assertEqual(2, resource_manager._uses)
  207. resource_manager.finishedWith(resource)
  208. self.assertEqual(1, resource_manager._uses)
  209. resource_manager.finishedWith(resource)
  210. self.assertEqual(0, resource_manager._uses)
  211. def testFinishedWithResetsCurrentResource(self):
  212. resource_manager = MockResource()
  213. resource = resource_manager.getResource()
  214. resource_manager.finishedWith(resource)
  215. self.assertIs(None, resource_manager._currentResource)
  216. def testFinishedWithCallsCleanResource(self):
  217. resource_manager = MockResource()
  218. resource = resource_manager.getResource()
  219. resource_manager.finishedWith(resource)
  220. self.assertEqual(1, resource_manager.cleans)
  221. def testUsingTwiceMakesAndCleansTwice(self):
  222. resource_manager = MockResource()
  223. resource = resource_manager.getResource()
  224. resource_manager.finishedWith(resource)
  225. resource = resource_manager.getResource()
  226. resource_manager.finishedWith(resource)
  227. self.assertEqual(2, resource_manager.makes)
  228. self.assertEqual(2, resource_manager.cleans)
  229. def testFinishedWithCallsCleanResourceOnceOnly(self):
  230. resource_manager = MockResource()
  231. resource = resource_manager.getResource()
  232. resource = resource_manager.getResource()
  233. resource_manager.finishedWith(resource)
  234. self.assertEqual(0, resource_manager.cleans)
  235. resource_manager.finishedWith(resource)
  236. self.assertEqual(1, resource_manager.cleans)
  237. def testFinishedWithMarksNonDirty(self):
  238. resource_manager = MockResource()
  239. resource = resource_manager.getResource()
  240. resource_manager.dirtied(resource)
  241. resource_manager.finishedWith(resource)
  242. self.assertEqual(False, resource_manager._dirty)
  243. def testResourceAvailableBetweenFinishedWithCalls(self):
  244. resource_manager = MockResource()
  245. resource = resource_manager.getResource()
  246. resource = resource_manager.getResource()
  247. resource_manager.finishedWith(resource)
  248. self.assertIs(resource, resource_manager._currentResource)
  249. resource_manager.finishedWith(resource)
  250. def testDirtiedSetsDirty(self):
  251. resource_manager = MockResource()
  252. resource = resource_manager.getResource()
  253. self.assertEqual(False, resource_manager._dirty)
  254. resource_manager.dirtied(resource)
  255. self.assertEqual(True, resource_manager._dirty)
  256. def testDirtyingResourceTriggersCleanOnGet(self):
  257. resource_manager = MockResource()
  258. resource1 = resource_manager.getResource()
  259. resource2 = resource_manager.getResource()
  260. resource_manager.dirtied(resource2)
  261. resource_manager.finishedWith(resource2)
  262. self.assertEqual(0, resource_manager.cleans)
  263. resource3 = resource_manager.getResource()
  264. self.assertEqual(1, resource_manager.cleans)
  265. resource_manager.finishedWith(resource3)
  266. resource_manager.finishedWith(resource1)
  267. self.assertEqual(2, resource_manager.cleans)
  268. def testDefaultResetMethodPreservesCleanResource(self):
  269. resource_manager = MockResource()
  270. resource = resource_manager.getResource()
  271. self.assertEqual(1, resource_manager.makes)
  272. self.assertEqual(False, resource_manager._dirty)
  273. resource_manager.reset(resource)
  274. self.assertEqual(1, resource_manager.makes)
  275. self.assertEqual(0, resource_manager.cleans)
  276. def testDefaultResetMethodRecreatesDirtyResource(self):
  277. resource_manager = MockResource()
  278. resource = resource_manager.getResource()
  279. self.assertEqual(1, resource_manager.makes)
  280. resource_manager.dirtied(resource)
  281. resource_manager.reset(resource)
  282. self.assertEqual(2, resource_manager.makes)
  283. self.assertEqual(1, resource_manager.cleans)
  284. def testDefaultResetResetsDependencies(self):
  285. resource_manager = MockResettableResource()
  286. dep1 = MockResettableResource()
  287. dep2 = MockResettableResource()
  288. resource_manager.resources.append(("dep1", dep1))
  289. resource_manager.resources.append(("dep2", dep2))
  290. # A typical OptimisingTestSuite workflow
  291. r_outer = resource_manager.getResource()
  292. # test 1
  293. r_inner = resource_manager.getResource()
  294. dep2.dirtied(r_inner.dep2)
  295. resource_manager.finishedWith(r_inner)
  296. # test 2
  297. r_inner = resource_manager.getResource()
  298. dep2.dirtied(r_inner.dep2)
  299. resource_manager.finishedWith(r_inner)
  300. resource_manager.finishedWith(r_outer)
  301. # Dep 1 was clean, doesn't do a reset, and should only have one
  302. # make+clean.
  303. self.assertEqual(1, dep1.makes)
  304. self.assertEqual(1, dep1.cleans)
  305. self.assertEqual(0, dep1.resets)
  306. # Dep 2 was dirty, so _reset happens, and likewise only one make and
  307. # clean.
  308. self.assertEqual(1, dep2.makes)
  309. self.assertEqual(1, dep2.cleans)
  310. self.assertEqual(1, dep2.resets)
  311. # The top layer should have had a reset happen, and only one make and
  312. # clean.
  313. self.assertEqual(1, resource_manager.makes)
  314. self.assertEqual(1, resource_manager.cleans)
  315. self.assertEqual(1, resource_manager.resets)
  316. def testDirtyingWhenUnused(self):
  317. resource_manager = MockResource()
  318. resource = resource_manager.getResource()
  319. resource_manager.finishedWith(resource)
  320. resource_manager.dirtied(resource)
  321. self.assertEqual(1, resource_manager.makes)
  322. resource = resource_manager.getResource()
  323. self.assertEqual(2, resource_manager.makes)
  324. def testFinishedActivityForResourceWithoutExtensions(self):
  325. result = ResultWithoutResourceExtensions()
  326. resource_manager = MockResource()
  327. r = resource_manager.getResource()
  328. resource_manager.finishedWith(r, result)
  329. def testFinishedActivityForResourceWithExtensions(self):
  330. result = ResultWithResourceExtensions()
  331. resource_manager = MockResource()
  332. r = resource_manager.getResource()
  333. expected = [("clean", "start", resource_manager),
  334. ("clean", "stop", resource_manager)]
  335. resource_manager.finishedWith(r, result)
  336. self.assertEqual(expected, result._calls)
  337. def testGetActivityForResourceWithoutExtensions(self):
  338. result = ResultWithoutResourceExtensions()
  339. resource_manager = MockResource()
  340. r = resource_manager.getResource(result)
  341. resource_manager.finishedWith(r)
  342. def testGetActivityForResourceWithExtensions(self):
  343. result = ResultWithResourceExtensions()
  344. resource_manager = MockResource()
  345. r = resource_manager.getResource(result)
  346. expected = [("make", "start", resource_manager),
  347. ("make", "stop", resource_manager)]
  348. resource_manager.finishedWith(r)
  349. self.assertEqual(expected, result._calls)
  350. def testResetActivityForResourceWithoutExtensions(self):
  351. result = ResultWithoutResourceExtensions()
  352. resource_manager = MockResource()
  353. resource_manager.getResource()
  354. r = resource_manager.getResource()
  355. resource_manager.dirtied(r)
  356. resource_manager.finishedWith(r)
  357. r = resource_manager.getResource(result)
  358. resource_manager.dirtied(r)
  359. resource_manager.finishedWith(r)
  360. resource_manager.finishedWith(resource_manager._currentResource)
  361. def testResetActivityForResourceWithExtensions(self):
  362. result = ResultWithResourceExtensions()
  363. resource_manager = MockResource()
  364. expected = [("reset", "start", resource_manager),
  365. ("reset", "stop", resource_manager),
  366. ]
  367. resource_manager.getResource()
  368. r = resource_manager.getResource()
  369. resource_manager.dirtied(r)
  370. resource_manager.finishedWith(r)
  371. r = resource_manager.getResource(result)
  372. resource_manager.dirtied(r)
  373. resource_manager.finishedWith(r)
  374. resource_manager.finishedWith(resource_manager._currentResource)
  375. self.assertEqual(expected, result._calls)
  376. class TestGenericResource(testtools.TestCase):
  377. def test_default_uses_setUp_tearDown(self):
  378. calls = []
  379. class Wrapped:
  380. def setUp(self):
  381. calls.append('setUp')
  382. def tearDown(self):
  383. calls.append('tearDown')
  384. mgr = testresources.GenericResource(Wrapped)
  385. resource = mgr.getResource()
  386. self.assertEqual(['setUp'], calls)
  387. mgr.finishedWith(resource)
  388. self.assertEqual(['setUp', 'tearDown'], calls)
  389. self.assertIsInstance(resource, Wrapped)
  390. def test_dependencies_passed_to_factory(self):
  391. calls = []
  392. class Wrapped:
  393. def __init__(self, **args):
  394. calls.append(args)
  395. def setUp(self):pass
  396. def tearDown(self):pass
  397. class Trivial(testresources.TestResource):
  398. def __init__(self, thing):
  399. testresources.TestResource.__init__(self)
  400. self.thing = thing
  401. def make(self, dependency_resources):return self.thing
  402. def clean(self, resource):pass
  403. mgr = testresources.GenericResource(Wrapped)
  404. mgr.resources = [('foo', Trivial('foo')), ('bar', Trivial('bar'))]
  405. resource = mgr.getResource()
  406. self.assertEqual([{'foo':'foo', 'bar':'bar'}], calls)
  407. mgr.finishedWith(resource)
  408. def test_setup_teardown_controllable(self):
  409. calls = []
  410. class Wrapped:
  411. def start(self):
  412. calls.append('setUp')
  413. def stop(self):
  414. calls.append('tearDown')
  415. mgr = testresources.GenericResource(Wrapped,
  416. setup_method_name='start', teardown_method_name='stop')
  417. resource = mgr.getResource()
  418. self.assertEqual(['setUp'], calls)
  419. mgr.finishedWith(resource)
  420. self.assertEqual(['setUp', 'tearDown'], calls)
  421. self.assertIsInstance(resource, Wrapped)
  422. def test_always_dirty(self):
  423. class Wrapped:
  424. def setUp(self):pass
  425. def tearDown(self):pass
  426. mgr = testresources.GenericResource(Wrapped)
  427. resource = mgr.getResource()
  428. self.assertTrue(mgr.isDirty())
  429. mgr.finishedWith(resource)
  430. class TestFixtureResource(testtools.TestCase):
  431. def test_uses_setUp_cleanUp(self):
  432. fixture = LoggingFixture()
  433. mgr = testresources.FixtureResource(fixture)
  434. resource = mgr.getResource()
  435. self.assertEqual(fixture, resource)
  436. self.assertEqual(['setUp'], fixture.calls)
  437. mgr.finishedWith(resource)
  438. self.assertEqual(['setUp', 'cleanUp'], fixture.calls)
  439. def test_always_dirty(self):
  440. fixture = LoggingFixture()
  441. mgr = testresources.FixtureResource(fixture)
  442. resource = mgr.getResource()
  443. self.assertTrue(mgr.isDirty())
  444. mgr.finishedWith(resource)
  445. def test_reset_called(self):
  446. fixture = LoggingFixture()
  447. mgr = testresources.FixtureResource(fixture)
  448. resource = mgr.getResource()
  449. mgr.reset(resource)
  450. mgr.finishedWith(resource)
  451. self.assertEqual(
  452. ['setUp', 'reset', 'cleanUp'], fixture.calls)