# testresources: extensions to python unittest to allow declaritive use # of resources by test cases. # # Copyright (c) 2005-2010 Testresources Contributors # # Licensed under either the Apache License, Version 2.0 or the BSD 3-clause # license at the users choice. A copy of both licenses are available in the # project source as Apache-2.0 and BSD. You may not use this file except in # compliance with one of these two licences. # # Unless required by applicable law or agreed to in writing, software distributed # under these licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR # CONDITIONS OF ANY KIND, either express or implied. See the license you chose # for the specific language governing permissions and limitations under that # license. # from fixtures.tests.helpers import LoggingFixture import testtools import testresources from testresources.tests import ( ResultWithResourceExtensions, ResultWithoutResourceExtensions, ) def test_suite(): loader = testresources.tests.TestUtil.TestLoader() result = loader.loadTestsFromName(__name__) return result class MockResourceInstance(object): def __init__(self, name): self._name = name def __eq__(self, other): return self.__dict__ == other.__dict__ def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) def __repr__(self): return self._name class MockResource(testresources.TestResourceManager): """Mock resource that logs the number of make and clean calls.""" def __init__(self): super(MockResource, self).__init__() self.makes = 0 self.cleans = 0 def clean(self, resource): self.cleans += 1 def make(self, dependency_resources): self.makes += 1 return MockResourceInstance("Boo!") class MockResettableResource(MockResource): """Mock resource that logs the number of reset calls too.""" def __init__(self): super(MockResettableResource, self).__init__() self.resets = 0 def _reset(self, resource, dependency_resources): self.resets += 1 resource._name += "!" self._dirty = False return resource class TestTestResource(testtools.TestCase): def testUnimplementedGetResource(self): # By default, TestResource raises NotImplementedError on getResource # because make is not defined initially. resource_manager = testresources.TestResource() self.assertRaises(NotImplementedError, resource_manager.getResource) def testInitiallyNotDirty(self): resource_manager = testresources.TestResource() self.assertEqual(False, resource_manager._dirty) def testInitiallyUnused(self): resource_manager = testresources.TestResource() self.assertEqual(0, resource_manager._uses) def testInitiallyNoCurrentResource(self): resource_manager = testresources.TestResource() self.assertEqual(None, resource_manager._currentResource) def testneededResourcesDefault(self): # Calling neededResources on a default TestResource returns the # resource. resource = testresources.TestResource() self.assertEqual([resource], resource.neededResources()) def testneededResourcesDependenciesFirst(self): # Calling neededResources on a TestResource with dependencies puts the # dependencies first. resource = testresources.TestResource() dep1 = testresources.TestResource() dep2 = testresources.TestResource() resource.resources.append(("dep1", dep1)) resource.resources.append(("dep2", dep2)) self.assertEqual([dep1, dep2, resource], resource.neededResources()) def testneededResourcesClosure(self): # Calling neededResources on a TestResource with dependencies includes # the needed resources of the needed resources. resource = testresources.TestResource() dep1 = testresources.TestResource() dep2 = testresources.TestResource() resource.resources.append(("dep1", dep1)) dep1.resources.append(("dep2", dep2)) self.assertEqual([dep2, dep1, resource], resource.neededResources()) def testDefaultCosts(self): # The base TestResource costs 1 to set up and to tear down. resource_manager = testresources.TestResource() self.assertEqual(resource_manager.setUpCost, 1) self.assertEqual(resource_manager.tearDownCost, 1) def testGetResourceReturnsMakeResource(self): resource_manager = MockResource() resource = resource_manager.getResource() self.assertEqual(resource_manager.make({}), resource) def testGetResourceIncrementsUses(self): resource_manager = MockResource() resource_manager.getResource() self.assertEqual(1, resource_manager._uses) resource_manager.getResource() self.assertEqual(2, resource_manager._uses) def testGetResourceDoesntDirty(self): resource_manager = MockResource() resource_manager.getResource() self.assertEqual(resource_manager._dirty, False) def testGetResourceSetsCurrentResource(self): resource_manager = MockResource() resource = resource_manager.getResource() self.assertIs(resource_manager._currentResource, resource) def testGetResourceTwiceReturnsIdenticalResource(self): resource_manager = MockResource() resource1 = resource_manager.getResource() resource2 = resource_manager.getResource() self.assertIs(resource1, resource2) def testGetResourceCallsMakeResource(self): resource_manager = MockResource() resource_manager.getResource() self.assertEqual(1, resource_manager.makes) def testIsDirty(self): resource_manager = MockResource() r = resource_manager.getResource() resource_manager.dirtied(r) self.assertTrue(resource_manager.isDirty()) resource_manager.finishedWith(r) def testIsDirtyIsTrueIfDependenciesChanged(self): resource_manager = MockResource() dep1 = MockResource() dep2 = MockResource() dep3 = MockResource() resource_manager.resources.append(("dep1", dep1)) resource_manager.resources.append(("dep2", dep2)) resource_manager.resources.append(("dep3", dep3)) r = resource_manager.getResource() dep2.dirtied(r.dep2) r2 =dep2.getResource() self.assertTrue(resource_manager.isDirty()) resource_manager.finishedWith(r) dep2.finishedWith(r2) def testIsDirtyIsTrueIfDependenciesAreDirty(self): resource_manager = MockResource() dep1 = MockResource() dep2 = MockResource() dep3 = MockResource() resource_manager.resources.append(("dep1", dep1)) resource_manager.resources.append(("dep2", dep2)) resource_manager.resources.append(("dep3", dep3)) r = resource_manager.getResource() dep2.dirtied(r.dep2) self.assertTrue(resource_manager.isDirty()) resource_manager.finishedWith(r) def testRepeatedGetResourceCallsMakeResourceOnceOnly(self): resource_manager = MockResource() resource_manager.getResource() resource_manager.getResource() self.assertEqual(1, resource_manager.makes) def testGetResourceResetsUsedResource(self): resource_manager = MockResettableResource() resource_manager.getResource() resource = resource_manager.getResource() self.assertEqual(1, resource_manager.makes) resource_manager.dirtied(resource) resource_manager.getResource() self.assertEqual(1, resource_manager.makes) self.assertEqual(1, resource_manager.resets) resource_manager.finishedWith(resource) def testIsResetIfDependenciesAreDirty(self): resource_manager = MockResource() dep1 = MockResettableResource() resource_manager.resources.append(("dep1", dep1)) r = resource_manager.getResource() dep1.dirtied(r.dep1) # if we get the resource again, it should be cleaned. r = resource_manager.getResource() self.assertFalse(resource_manager.isDirty()) self.assertFalse(dep1.isDirty()) resource_manager.finishedWith(r) resource_manager.finishedWith(r) def testUsedResourceResetBetweenUses(self): resource_manager = MockResettableResource() # take two refs; like happens with OptimisingTestSuite. resource_manager.getResource() resource = resource_manager.getResource() resource_manager.dirtied(resource) resource_manager.finishedWith(resource) # Get again, but its been dirtied. resource = resource_manager.getResource() resource_manager.finishedWith(resource) resource_manager.finishedWith(resource) # The resource is made once, reset once and cleaned once. self.assertEqual(1, resource_manager.makes) self.assertEqual(1, resource_manager.resets) self.assertEqual(1, resource_manager.cleans) def testFinishedWithDecrementsUses(self): resource_manager = MockResource() resource = resource_manager.getResource() resource = resource_manager.getResource() self.assertEqual(2, resource_manager._uses) resource_manager.finishedWith(resource) self.assertEqual(1, resource_manager._uses) resource_manager.finishedWith(resource) self.assertEqual(0, resource_manager._uses) def testFinishedWithResetsCurrentResource(self): resource_manager = MockResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) self.assertIs(None, resource_manager._currentResource) def testFinishedWithCallsCleanResource(self): resource_manager = MockResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) self.assertEqual(1, resource_manager.cleans) def testUsingTwiceMakesAndCleansTwice(self): resource_manager = MockResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) resource = resource_manager.getResource() resource_manager.finishedWith(resource) self.assertEqual(2, resource_manager.makes) self.assertEqual(2, resource_manager.cleans) def testFinishedWithCallsCleanResourceOnceOnly(self): resource_manager = MockResource() resource = resource_manager.getResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) self.assertEqual(0, resource_manager.cleans) resource_manager.finishedWith(resource) self.assertEqual(1, resource_manager.cleans) def testFinishedWithMarksNonDirty(self): resource_manager = MockResource() resource = resource_manager.getResource() resource_manager.dirtied(resource) resource_manager.finishedWith(resource) self.assertEqual(False, resource_manager._dirty) def testResourceAvailableBetweenFinishedWithCalls(self): resource_manager = MockResource() resource = resource_manager.getResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) self.assertIs(resource, resource_manager._currentResource) resource_manager.finishedWith(resource) def testDirtiedSetsDirty(self): resource_manager = MockResource() resource = resource_manager.getResource() self.assertEqual(False, resource_manager._dirty) resource_manager.dirtied(resource) self.assertEqual(True, resource_manager._dirty) def testDirtyingResourceTriggersCleanOnGet(self): resource_manager = MockResource() resource1 = resource_manager.getResource() resource2 = resource_manager.getResource() resource_manager.dirtied(resource2) resource_manager.finishedWith(resource2) self.assertEqual(0, resource_manager.cleans) resource3 = resource_manager.getResource() self.assertEqual(1, resource_manager.cleans) resource_manager.finishedWith(resource3) resource_manager.finishedWith(resource1) self.assertEqual(2, resource_manager.cleans) def testDefaultResetMethodPreservesCleanResource(self): resource_manager = MockResource() resource = resource_manager.getResource() self.assertEqual(1, resource_manager.makes) self.assertEqual(False, resource_manager._dirty) resource_manager.reset(resource) self.assertEqual(1, resource_manager.makes) self.assertEqual(0, resource_manager.cleans) def testDefaultResetMethodRecreatesDirtyResource(self): resource_manager = MockResource() resource = resource_manager.getResource() self.assertEqual(1, resource_manager.makes) resource_manager.dirtied(resource) resource_manager.reset(resource) self.assertEqual(2, resource_manager.makes) self.assertEqual(1, resource_manager.cleans) def testDefaultResetResetsDependencies(self): resource_manager = MockResettableResource() dep1 = MockResettableResource() dep2 = MockResettableResource() resource_manager.resources.append(("dep1", dep1)) resource_manager.resources.append(("dep2", dep2)) # A typical OptimisingTestSuite workflow r_outer = resource_manager.getResource() # test 1 r_inner = resource_manager.getResource() dep2.dirtied(r_inner.dep2) resource_manager.finishedWith(r_inner) # test 2 r_inner = resource_manager.getResource() dep2.dirtied(r_inner.dep2) resource_manager.finishedWith(r_inner) resource_manager.finishedWith(r_outer) # Dep 1 was clean, doesn't do a reset, and should only have one # make+clean. self.assertEqual(1, dep1.makes) self.assertEqual(1, dep1.cleans) self.assertEqual(0, dep1.resets) # Dep 2 was dirty, so _reset happens, and likewise only one make and # clean. self.assertEqual(1, dep2.makes) self.assertEqual(1, dep2.cleans) self.assertEqual(1, dep2.resets) # The top layer should have had a reset happen, and only one make and # clean. self.assertEqual(1, resource_manager.makes) self.assertEqual(1, resource_manager.cleans) self.assertEqual(1, resource_manager.resets) def testDirtyingWhenUnused(self): resource_manager = MockResource() resource = resource_manager.getResource() resource_manager.finishedWith(resource) resource_manager.dirtied(resource) self.assertEqual(1, resource_manager.makes) resource = resource_manager.getResource() self.assertEqual(2, resource_manager.makes) def testFinishedActivityForResourceWithoutExtensions(self): result = ResultWithoutResourceExtensions() resource_manager = MockResource() r = resource_manager.getResource() resource_manager.finishedWith(r, result) def testFinishedActivityForResourceWithExtensions(self): result = ResultWithResourceExtensions() resource_manager = MockResource() r = resource_manager.getResource() expected = [("clean", "start", resource_manager), ("clean", "stop", resource_manager)] resource_manager.finishedWith(r, result) self.assertEqual(expected, result._calls) def testGetActivityForResourceWithoutExtensions(self): result = ResultWithoutResourceExtensions() resource_manager = MockResource() r = resource_manager.getResource(result) resource_manager.finishedWith(r) def testGetActivityForResourceWithExtensions(self): result = ResultWithResourceExtensions() resource_manager = MockResource() r = resource_manager.getResource(result) expected = [("make", "start", resource_manager), ("make", "stop", resource_manager)] resource_manager.finishedWith(r) self.assertEqual(expected, result._calls) def testResetActivityForResourceWithoutExtensions(self): result = ResultWithoutResourceExtensions() resource_manager = MockResource() resource_manager.getResource() r = resource_manager.getResource() resource_manager.dirtied(r) resource_manager.finishedWith(r) r = resource_manager.getResource(result) resource_manager.dirtied(r) resource_manager.finishedWith(r) resource_manager.finishedWith(resource_manager._currentResource) def testResetActivityForResourceWithExtensions(self): result = ResultWithResourceExtensions() resource_manager = MockResource() expected = [("reset", "start", resource_manager), ("reset", "stop", resource_manager), ] resource_manager.getResource() r = resource_manager.getResource() resource_manager.dirtied(r) resource_manager.finishedWith(r) r = resource_manager.getResource(result) resource_manager.dirtied(r) resource_manager.finishedWith(r) resource_manager.finishedWith(resource_manager._currentResource) self.assertEqual(expected, result._calls) def testId(self): resource_manager = testresources.TestResource() self.assertEqual( "testresources.TestResourceManager", resource_manager.id()) class TestGenericResource(testtools.TestCase): def test_default_uses_setUp_tearDown(self): calls = [] class Wrapped: def setUp(self): calls.append('setUp') def tearDown(self): calls.append('tearDown') mgr = testresources.GenericResource(Wrapped) resource = mgr.getResource() self.assertEqual(['setUp'], calls) mgr.finishedWith(resource) self.assertEqual(['setUp', 'tearDown'], calls) self.assertIsInstance(resource, Wrapped) def test_dependencies_passed_to_factory(self): calls = [] class Wrapped: def __init__(self, **args): calls.append(args) def setUp(self):pass def tearDown(self):pass class Trivial(testresources.TestResource): def __init__(self, thing): testresources.TestResource.__init__(self) self.thing = thing def make(self, dependency_resources):return self.thing def clean(self, resource):pass mgr = testresources.GenericResource(Wrapped) mgr.resources = [('foo', Trivial('foo')), ('bar', Trivial('bar'))] resource = mgr.getResource() self.assertEqual([{'foo':'foo', 'bar':'bar'}], calls) mgr.finishedWith(resource) def test_setup_teardown_controllable(self): calls = [] class Wrapped: def start(self): calls.append('setUp') def stop(self): calls.append('tearDown') mgr = testresources.GenericResource(Wrapped, setup_method_name='start', teardown_method_name='stop') resource = mgr.getResource() self.assertEqual(['setUp'], calls) mgr.finishedWith(resource) self.assertEqual(['setUp', 'tearDown'], calls) self.assertIsInstance(resource, Wrapped) def test_always_dirty(self): class Wrapped: def setUp(self):pass def tearDown(self):pass mgr = testresources.GenericResource(Wrapped) resource = mgr.getResource() self.assertTrue(mgr.isDirty()) mgr.finishedWith(resource) def testId(self): class Wrapped: def setUp(self):pass def tearDown(self):pass mgr = testresources.GenericResource(Wrapped) self.assertEqual( "testresources.GenericResource[Wrapped]", mgr.id()) class TestFixtureResource(testtools.TestCase): def test_uses_setUp_cleanUp(self): fixture = LoggingFixture() mgr = testresources.FixtureResource(fixture) resource = mgr.getResource() self.assertEqual(fixture, resource) self.assertEqual(['setUp'], fixture.calls) mgr.finishedWith(resource) self.assertEqual(['setUp', 'cleanUp'], fixture.calls) def test_always_dirty(self): fixture = LoggingFixture() mgr = testresources.FixtureResource(fixture) resource = mgr.getResource() self.assertTrue(mgr.isDirty()) mgr.finishedWith(resource) def test_reset_called(self): fixture = LoggingFixture() mgr = testresources.FixtureResource(fixture) resource = mgr.getResource() mgr.reset(resource) mgr.finishedWith(resource) self.assertEqual( ['setUp', 'reset', 'cleanUp'], fixture.calls) def testId(self): class MyLoggingFixture(LoggingFixture): def __str__(self): return "my-logger" mgr = testresources.FixtureResource(MyLoggingFixture()) self.assertEqual( "testresources.FixtureResource[my-logger]", mgr.id())