class Test(unittest.TestCase): def setUp(self): globallock._lock.acquire() self._hosts = Hosts() self.tested = FreePool(self._hosts) def tearDown(self): globallock._lock.release() def test_OneHost(self): host = HostStateMachine('host1') self.tested.put(host) self.assertIn(host, self.tested.all()) self.tested.takeOut(host) self.assertNotIn(host, self.tested.all()) def test_DestroyCallback(self): host = HostStateMachine('host1') self._hosts.add(host) self.tested.put(host) host._destroyCallback(host) self.assertNotIn(host, self.tested.all()) def test_All(self): hosts = [HostStateMachine(str(i)) for i in xrange(10)] for host in hosts: self._hosts.add(host) for host in hosts: self.tested.put(host) actualAll = self.tested.all() self.assertEquals(set(actualAll), set(hosts))
def setUp(self): self.addCleanup(globallock._lock.release) globallock._lock.acquire() self.currentTimer = None self.currentTimerTag = None timer.scheduleIn = self.scheduleTimerIn timer.cancelAllByTag = self.cancelAllTimersByTag requirements = dict(node0=dict(imageHint='alpha-bravo', imageLabel='tango-lima'), node1=dict(imageHint='charlie-delta', imageLabel='kilo-juliet'), node2=dict(imageHint='echo-foxtrot', imageLabel='zooloo-papa')) self.index = random.randint(1, sys.maxint) self.allocationInfo = 'This allocation has got swag.' allocated = dict((hostName, HostStateMachine(Host(hostName))) for hostName in requirements.keys()) self.originalAllocated = copy.copy(allocated) self.expectedStates = dict(allocatedButNotInaugurated=set(allocated.values()), inaugurated=set()) self.expectedDestroyed = set() self.expectedDetached = set() self.expectedReleased = set() self.wasAllocationDoneAtSomePoint = False self.broadcaster.reset_mock() self.hosts = Hosts() self.freepool = FreePool(self.hosts) for stateMachine in allocated.values(): self.hosts.add(stateMachine) self.tested = allocation.Allocation(self.index, requirements, self.allocationInfo, allocated, self.broadcaster, self.freepool, self.hosts)
def setUp(self): self.broadcaster.reset_mock() hostNames = ["alpha", "bravo", "charlie", "delta"] self.hosts = Hosts() self.freePool = freepool.FreePool(self.hosts) self.allocationInfo = dict(purpose='forfun', nice=0) for hostName in hostNames: stateMachine = HostStateMachine(Host(hostName)) self.hosts.add(stateMachine) self.freePool.put(stateMachine) self.tested = Allocations(self.broadcaster, self.hosts, self.freePool, self.osmosisServer) self.expectedCreationBroadcasts = list() self.expectedRequestBroadcasts = list() self.expectedRejectedBroadcasts = list()
def setUp(self): globallock._lock.acquire() self.broadcaster = mock.Mock() hostNames = ["alpha", "bravo", "charlie", "delta"] self.hosts = Hosts() self.freePool = FreePool(self.hosts) self.osmosisServer = 'what-a-cool-osmosis-server' self.allocationInfo = dict(purpose='forfun', nice=0) timer.scheduleIn = mock.Mock() timer.cancelAllByTag = mock.Mock() self.currentTimer = None self.currentTimerTag = None for hostName in hostNames: stateMachine = HostStateMachine(Host(hostName)) self.hosts.add(stateMachine) self.freePool.put(stateMachine) self.tested = Allocations(self.broadcaster, self.hosts, self.freePool, self.osmosisServer) self.requirements = dict(node0=dict(imageLabel="echo-foxtrot", imageHint="golf"), node1=dict(imageLabel="hotel-india", imageHint="juliet"))
def setUp(self): globallock._lock.acquire() self._hosts = Hosts() self.tested = FreePool(self._hosts)
class Test(unittest.TestCase): @classmethod def setUpClass(cls): cls.broadcaster = Publish() def setUp(self): self.addCleanup(globallock._lock.release) globallock._lock.acquire() self.currentTimer = None self.currentTimerTag = None timer.scheduleIn = self.scheduleTimerIn timer.cancelAllByTag = self.cancelAllTimersByTag requirements = dict(node0=dict(imageHint='alpha-bravo', imageLabel='tango-lima'), node1=dict(imageHint='charlie-delta', imageLabel='kilo-juliet'), node2=dict(imageHint='echo-foxtrot', imageLabel='zooloo-papa')) self.index = random.randint(1, sys.maxint) self.allocationInfo = 'This allocation has got swag.' allocated = dict((hostName, HostStateMachine(Host(hostName))) for hostName in requirements.keys()) self.originalAllocated = copy.copy(allocated) self.expectedStates = dict(allocatedButNotInaugurated=set(allocated.values()), inaugurated=set()) self.expectedDestroyed = set() self.expectedDetached = set() self.expectedReleased = set() self.wasAllocationDoneAtSomePoint = False self.broadcaster.reset_mock() self.hosts = Hosts() self.freepool = FreePool(self.hosts) for stateMachine in allocated.values(): self.hosts.add(stateMachine) self.tested = allocation.Allocation(self.index, requirements, self.allocationInfo, allocated, self.broadcaster, self.freepool, self.hosts) def test_Index(self): self.assertEquals(self.tested.index(), self.index) def test_AllocationInfo(self): self.assertEquals(self.allocationInfo, self.tested.allocationInfo()) def test_InauguratedWhenNotDoneRaisesAssertionError(self): self.assertRaises(AssertionError, self.tested.inaugurated) def test_InauguratedWhenDone(self): self.fakeInaugurationDoneForAll() expected = {stateMachine.hostImplementation().id(): stateMachine for stateMachine in self.expectedStates["inaugurated"]} self.assertEquals(expected, self.tested.inaugurated()) def test_Allocated(self): self.assertEquals(self.originalAllocated, self.tested.allocated()) def test_Free(self): self.tested.free() self.assertEquals(self.tested.dead(), "freed") self.validate() def test_CantFreeDeadAllocation(self): self.tested.free() self.assertEquals(self.tested.dead(), "freed") self.assertRaises(Exception, self.tested.free) self.validate() def test_Withdraw(self): self.tested.withdraw("Don't want this allocation anymore") self.assertEquals(self.tested.dead(), "withdrawn") self.validate() def test_HeartBeatWhenDeadDoesNothing(self): self.assertIsNotNone(self.currentTimer) self.tested.free() self.assertIsNone(self.currentTimer) self.tested.heartbeat() self.assertIsNone(self.currentTimer) self.validate() def test_NotDeadForAWhileIfNotDead(self): self.assertFalse(self.tested.deadForAWhile()) def test_NoCrashWhenGotMoreThanOneInaugurationDoneForSameMachine(self): self.fakeInaugurationDoneForAll() self.fakeInaugurationDoneForAll() self.fakeInaugurationDoneForAll() self.fakeInaugurationDoneForAll() self.fakeInaugurationDoneForAll() def test_DeadForAWhile(self): self.tested.free() executeCodeWhileAllocationIsDeadOfHeartbeatTimeout(self.tested, lambda: None) def test_NotDeadForAWhile(self): orig_time = time.time self.tested.free() timeInWhichAllocationIsDeadNotForAWhile = \ time.time() + self.tested._LIMBO_AFTER_DEATH_DURATION * 0.9 try: time.time = mock.Mock(return_value=timeInWhichAllocationIsDeadNotForAWhile) self.assertFalse(self.tested.deadForAWhile()) finally: time.time = orig_time def test_HeartBeatTimeout(self): self.currentTimer() self.assertEquals(self.tested.dead(), "heartbeat timeout") self.validate() def test_DieUponSelfDestructionOfMachine(self): self.destroyMachineByName('node0') self.assertIn("Unable to inaugurate ", self.tested.dead()) self.validate() def test_NoCrashIfStateMachineSelfDestructedWhileAllocationIsDead(self): machine = self.originalAllocated['node0'] destroyCallback = machine._destroyCallback stateChangeCallback = self.originalAllocated['node0']._destroyCallback self.tested.free() self.assertEquals(self.tested.dead(), "freed") self.validate() machine.setDestroyCallback(destroyCallback) self.destroyMachineByName('node0') machine.setDestroyCallback(None) self.freepool.takeOut(machine) # todo: fix the following (which is a bug); The state machine should unassign in case it deetroys # itself. machine.assign(stateChangeCallback, None, None) self.validate() def test_DetachHostBeforeInaugurated(self): machine = self.originalAllocated['node0'] self.detachHost(machine) self.validate() self.fakeInaugurationDoneForAll() self.validate() def test_DetachHostAfterInaugurated(self): machine = self.originalAllocated['node0'] self.fakeInaugurationDoneForAll() self.validate() self.detachHost(machine) self.validate() def test_CannotDetachHostAfterDestroyed(self): machine = self.originalAllocated['node0'] self.destroyMachineByName('node0') self.validate() self.assertRaises(Exception, self.tested.detachHost, machine) self.validate() def test_CannotDetachHostAfterInauguratedAndDestroyed(self): machine = self.originalAllocated['node0'] self.fakeInaugurationDoneForAll() self.assertIn(machine, self.tested.allocated().values()) self.destroyMachineByName('node0') self.validate() self.assertRaises(Exception, self.tested.detachHost, machine) self.validate() def test_CannotDetachUnAllocatedHost(self): machine = HostStateMachine("whatIsThisMachine") self.assertRaises(Exception, self.detachHost, machine) def test_DetachingLastHostKillsAllocation(self): for machine in self.originalAllocated.values(): self.detachHost(machine) self.validate() isDead = self.tested.dead() is not None self.assertTrue(isDead) def test_ReleaseHostBeforeInaugurated(self): machine = self.originalAllocated['node0'] self.releaseHost(machine) self.validate() self.fakeInaugurationDoneForAll() self.validate() def test_ReleaseHostAfterInaugurated(self): machine = self.originalAllocated['node0'] self.fakeInaugurationDoneForAll() self.validate() self.releaseHost(machine) self.validate() def test_CannotRelaseHostAfterDestroyed(self): machine = self.originalAllocated['node0'] self.destroyMachineByName('node0') self.validate() self.assertRaises(Exception, self.tested.releaseHost, machine) self.validate() def test_CannotReleaseHostAfterInauguratedAndDestroyed(self): machine = self.originalAllocated['node0'] self.fakeInaugurationDoneForAll() self.assertIn(machine, self.tested.allocated().values()) self.destroyMachineByName('node0') self.validate() self.assertRaises(Exception, self.tested.releaseHost, machine) self.validate() def test_CannotReleaseUnAllocatedHost(self): machine = HostStateMachine("whatIsThisMachine") self.assertRaises(Exception, self.releaseHost, machine) def test_ReleasingLastHostKillsAllocation(self): for machine in self.originalAllocated.values(): self.releaseHost(machine) self.validate() isDead = self.tested.dead() is not None self.assertTrue(isDead) def test_CannotReleaseDetachedHost(self): machine = self.originalAllocated['node0'] self.detachHost(machine) self.assertRaises(Exception, self.releaseHost, machine) def test_CannotDetachReleasedHost(self): machine = self.originalAllocated['node0'] self.releaseHost(machine) self.assertRaises(Exception, self.detachHost, machine) def test_AllocationCreationReported(self): self.validateBroadcastCalls() def test_AllocationDoneBroadcasted(self): self.fakeInaugurationDoneForAll() self.validateBroadcastCalls() def test_AllocationDeathBroadcasted(self): self.fakeInaugurationDoneForAll() self.tested.free() self.validateBroadcastCalls() def fakeInaugurationDoneForAll(self): self.wasAllocationDoneAtSomePoint = True collection = self.expectedStates["allocatedButNotInaugurated"] for stateMachine in self.originalAllocated.values(): stateMachine.fakeInaugurationDone() if stateMachine in collection: collection.remove(stateMachine) self.expectedStates["inaugurated"].add(stateMachine) def scheduleTimerIn(self, timeout, callback, tag): self.assertIs(self.currentTimer, None) self.assertIs(self.currentTimerTag, None) self.currentTimer = callback self.currentTimerTag = tag def cancelAllTimersByTag(self, tag): if self.currentTimerTag is not None: self.assertIsNot(self.currentTimer, None) self.assertIs(self.currentTimerTag, tag) self.currentTimer = None self.currentTimerTag = None def _validateFreePool(self): isDead = self.tested.dead() is not None expectedHostsInFreePool = set() if isDead: expectedHostsInFreePool = self.expectedStates["allocatedButNotInaugurated"].union( self.expectedStates["inaugurated"]).union(self.expectedReleased) else: expectedHostsInFreePool = self.expectedReleased expectedHostsInFreePool = [host for host in expectedHostsInFreePool if host not in self.expectedDestroyed] for stateMachine in expectedHostsInFreePool: self.assertIn(stateMachine, self.freepool.all()) expectedHostsNotInFreePool = [stateMachine for stateMachine in self.originalAllocated.values() if stateMachine not in expectedHostsInFreePool] for stateMachine in expectedHostsNotInFreePool: self.assertNotIn(stateMachine, self.freepool.all()) def _validateAllocated(self): actual = self.tested.allocated() expected = self.expectedStates["allocatedButNotInaugurated"] isDead = self.tested.dead() is not None if not isDead: expected = expected.union(self.expectedStates["inaugurated"]) expected = {stateMachine.hostImplementation().id(): stateMachine for stateMachine in expected} self.assertEquals(expected, actual) def _validateInaugurated(self): isDead = self.tested.dead() is not None if isDead: self.assertRaises(AssertionError, self.tested.inaugurated) else: if self.tested.done(): expected = {stateMachine.hostImplementation().id(): stateMachine for stateMachine in self.expectedStates["inaugurated"]} self.assertEquals(self.tested.inaugurated(), expected) else: self.assertRaises(AssertionError, self.tested.inaugurated) def validateBroadcastCalls(self): expectedMethodsNames = list() expectedMethodsNames.append("allocationCreated") if self.wasAllocationDoneAtSomePoint: expectedMethodsNames.append("allocationDone") deathReason = self.tested.dead() if deathReason is not None: expectedMethodsNames.append("allocationDied") expectedMethodsNames.append("cleanupAllocationPublishResources") actualCalls = \ [call for call in self.broadcaster.method_calls if call[0] != "allocationProviderMessage"] while expectedMethodsNames: expectedMethodName = expectedMethodsNames.pop(0) actualCall = actualCalls.pop(0) actualMethodName = actualCall[0] args = actualCall[1] kwargs = actualCall[2] if expectedMethodName == "allocationCreated": allocationID = kwargs["allocationID"] expectedAllocate = {name: self.originalAllocated[name].hostImplementation().id() for name in self.originalAllocated} elif expectedMethodName == "allocationDone": allocationID = args[0] elif expectedMethodName == "allocationDied": allocationID = args[0] reason = kwargs["reason"] self.assertEquals(self.tested.dead(), reason) elif expectedMethodName == "cleanupAllocationPublishResources": allocationID = args[0] else: self.assertTrue(False) self.assertEquals(allocationID, self.tested.index()) self.assertEquals(actualMethodName, expectedMethodName) self.assertFalse(actualCalls) def _validateDone(self): isDead = self.tested.dead() is not None if isDead: self.assertRaises(AssertionError, self.tested.done) else: allowedNotToBeInaugurated = self.expectedDetached expected = \ self.expectedStates["allocatedButNotInaugurated"].issubset(allowedNotToBeInaugurated) actual = self.tested.done() self.assertEquals(expected, actual) def _validateHosts(self): hosts = self.hosts.all() notExpected = self.expectedDestroyed.union(self.expectedDetached) for host in notExpected: self.assertNotIn(host, hosts) expected = [host for host in self.originalAllocated.values() if host not in notExpected] for host in expected: self.assertIn(host, hosts) def validateAllocationIsNotEmpty(self): self.assertTrue(self.tested.allocated()) def validate(self): self._validateAllocated() self._validateInaugurated() self._validateFreePool() self._validateHosts() self._validateDone() isDead = self.tested.dead() is not None if not isDead: self.validateAllocationIsNotEmpty() self.validateBroadcastCalls() def destroyMachineByName(self, name): stateMachine = self.originalAllocated[name] stateMachine.destroy() self.expectedDestroyed.add(stateMachine) def detachHost(self, machine): self.tested.detachHost(machine) self._removeFromCollections(machine) self.expectedDetached.add(machine) def releaseHost(self, machine): self.tested.releaseHost(machine) self._removeFromCollections(machine) self.expectedReleased.add(machine) def _removeFromCollections(self, machine): for collection in self.expectedStates.values(): if machine in collection: collection.remove(machine)
class Test(unittest.TestCase): @classmethod def setUpClass(self): globallock._lock.acquire() self.broadcaster = Publish() timer.scheduleIn = mock.Mock() timer.cancelAllByTag = mock.Mock() self.requirements = dict(node0=dict(imageLabel="echo-foxtrot", imageHint="golf"), node1=dict(imageLabel="hotel-india", imageHint="juliet")) self.currentTimer = None self.currentTimerTag = None self.osmosisServer = 'what-a-cool-osmosis-server' def setUp(self): self.broadcaster.reset_mock() hostNames = ["alpha", "bravo", "charlie", "delta"] self.hosts = Hosts() self.freePool = freepool.FreePool(self.hosts) self.allocationInfo = dict(purpose='forfun', nice=0) for hostName in hostNames: stateMachine = HostStateMachine(Host(hostName)) self.hosts.add(stateMachine) self.freePool.put(stateMachine) self.tested = Allocations(self.broadcaster, self.hosts, self.freePool, self.osmosisServer) self.expectedCreationBroadcasts = list() self.expectedRequestBroadcasts = list() self.expectedRejectedBroadcasts = list() @classmethod def tearDownClass(self): globallock._lock.release() def test_Create(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) self.assertEquals(_allocation, self.tested.byIndex(_allocation.index())) self.assertEquals(self.allocationInfo, _allocation.allocationInfo()) def test_AllocationCreationFails(self): origAllocation = allocation.Allocation try: allocation.Allocation = mock.Mock(side_effect=ValueError("don't wanna")) self.assertRaises(ValueError, self.createAllocation, self.requirements, self.allocationInfo) finally: allocation.Allocation = origAllocation def test_NoSuchAllocation(self): self.assertRaises(IndexError, self.tested.byIndex, 1) def test_OsmosisListLabelsReturnsAnotherLabel(self): abused = False def anotherLabelMock(cmd): if cmd[0:2] == ['osmosis', 'listlabels']: return cmd[2] + "_not" abused = True self.assertRaises(Exception, self.createAllocation, self.requirements, self.allocationInfo, listLabelsMock=anotherLabelMock) self.assertFalse(abused) def test_CreateCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() def createCallback(): self.createAllocation(self.requirements, self.allocationInfo) executeCodeWhileAllocationIsDeadOfHeartbeatTimeout(_allocation, createCallback) self.assertNotIn(_allocation, self.tested.all()) def test_byIndexCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() idx = _allocation.index() self.assertRaises(IndexError, executeCodeWhileAllocationIsDeadOfHeartbeatTimeout, _allocation, lambda: self.tested.byIndex(idx)) def test_AllCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() def validateNotInAll(): self.assertNotIn(_allocation, self.tested.all()) executeCodeWhileAllocationIsDeadOfHeartbeatTimeout(_allocation, validateNotInAll) def test_All(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) self.assertEquals(self.tested.all(), [_allocation]) def test_RequestBroadcasted(self): self.createAllocation(self.requirements, self.allocationInfo) self.validateRequestBroadcasts() def test_CreationBroadcasted(self): self.createAllocation(self.requirements, self.allocationInfo) self.validateCreationBroadcasts() def test_OutOfResourcesBroadcasted(self): tooBigOfRequirements = dict(self.requirements, node3=dict(imageLabel="kilo-lima", imageHint="mike"), node4=dict(imageLabel="november-oscar", imageHint="papa"), node5=dict(imageLabel="quebec-romeo", imageHint="sierra")) try: self.createAllocation(tooBigOfRequirements, self.allocationInfo, outOfResourcesExpected=True) except priority.OutOfResourcesError: pass self.expectedRejectedBroadcasts.append(dict(reason="noResources")) self.validateRejectedBroadcasts() def test_OutOfResourcesRaisedWhenOutOfResources(self): tooBigOfRequirements = dict(self.requirements, node3=dict(imageLabel="kilo-lima", imageHint="mike"), node4=dict(imageLabel="november-oscar", imageHint="papa"), node5=dict(imageLabel="quebec-romeo", imageHint="sierra")) self.assertRaises(priority.OutOfResourcesError, self.createAllocation, tooBigOfRequirements, self.allocationInfo, outOfResourcesExpected=True) def test_OutOfResourcesReturnsHostsTooFreePool(self): tooBigOfRequirements = dict(self.requirements, node3=dict(imageLabel="kilo-lima", imageHint="mike"), node4=dict(imageLabel="november-oscar", imageHint="papa"), node5=dict(imageLabel="quebec-romeo", imageHint="sierra")) nrFreeHostsBefore = len(list(self.freePool.all())) self.assertRaises(priority.OutOfResourcesError, self.createAllocation, tooBigOfRequirements, self.allocationInfo, outOfResourcesExpected=True) self.assertEquals(len(list(self.freePool.all())), nrFreeHostsBefore) def test_AllocationCreationErrorBroadcasted(self): origAllocation = allocation.Allocation class IgnoreMe(Exception): pass try: allocation.Allocation = mock.Mock(side_effect=IgnoreMe) self.createAllocation(self.requirements, self.allocationInfo) except IgnoreMe: pass finally: allocation.Allocation = origAllocation self.expectedRejectedBroadcasts.append(dict(reason="unknown")) self.validateRejectedBroadcasts() def test_LabelDoesNotExistInObjectStoreBroadcasted(self): def noLabelMock(cmd): return "" self.assertRaises(Exception, self.createAllocation, self.requirements, self.allocationInfo, listLabelsMock=noLabelMock) self.expectedRejectedBroadcasts.append(dict(reason="labelDoesNotExist")) self.validateRejectedBroadcasts() def createAllocation(self, requirements, allocationInfo, listLabelsMock=osmosisListLabelsFoundMock, outOfResourcesExpected=False): origRun = sh.run nrFreeHostsBefore = len(list(self.freePool.all())) self.expectedRequestBroadcasts.append((requirements, allocationInfo)) if len(requirements) > len(list(self.freePool.all())): self.assertTrue(outOfResourcesExpected) try: sh.run = listLabelsMock _allocation = self.tested.create(requirements, self.allocationInfo) self.expectedCreationBroadcasts.append(dict(allocationID=_allocation.index(), allocated=_allocation.allocated())) except priority.OutOfResourcesError: raise finally: sh.run = origRun self.assertEquals(len(list(self.freePool.all())), nrFreeHostsBefore - len(requirements)) return _allocation def validateRequestBroadcasts(self): for idx, expectedCall in enumerate(self.expectedRequestBroadcasts): actualCall = self.broadcaster.allocationRequested.call_args_list[idx][0] self.assertEquals(expectedCall, actualCall) self.assertEquals(len(self.expectedRequestBroadcasts), len(self.broadcaster.allocationRequested.call_args_list)) def validateCreationBroadcasts(self): for idx, expectedCall in enumerate(self.expectedCreationBroadcasts): actualCall = self.broadcaster.allocationCreated.call_args_list[idx][1] self.assertEquals(expectedCall, actualCall) self.assertEquals(len(self.expectedCreationBroadcasts), len(self.broadcaster.allocationCreated.call_args_list)) def validateRejectedBroadcasts(self): for idx, expectedCall in enumerate(self.expectedRejectedBroadcasts): actualCall = self.broadcaster.allocationRejected.call_args_list[idx][1] self.assertEquals(expectedCall, actualCall) self.assertEquals(len(self.expectedRejectedBroadcasts), len(self.broadcaster.allocationRejected.call_args_list))
class Test(unittest.TestCase): def setUp(self): globallock._lock.acquire() self.broadcaster = mock.Mock() hostNames = ["alpha", "bravo", "charlie", "delta"] self.hosts = Hosts() self.freePool = FreePool(self.hosts) self.osmosisServer = 'what-a-cool-osmosis-server' self.allocationInfo = dict(purpose='forfun', nice=0) timer.scheduleIn = mock.Mock() timer.cancelAllByTag = mock.Mock() self.currentTimer = None self.currentTimerTag = None for hostName in hostNames: stateMachine = HostStateMachine(Host(hostName)) self.hosts.add(stateMachine) self.freePool.put(stateMachine) self.tested = Allocations(self.broadcaster, self.hosts, self.freePool, self.osmosisServer) self.requirements = dict(node0=dict(imageLabel="echo-foxtrot", imageHint="golf"), node1=dict(imageLabel="hotel-india", imageHint="juliet")) def tearDown(self): globallock._lock.release() def test_Create(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) self.assertEquals(_allocation, self.tested.byIndex(_allocation.index())) self.assertEquals(self.allocationInfo, _allocation.allocationInfo()) def test_AllocationCreationFails(self): origAllocation = allocation.Allocation try: allocation.Allocation = mock.Mock(side_effect=ValueError("don't wanna")) self.assertRaises(ValueError, self.createAllocation, self.requirements, self.allocationInfo) finally: allocation.Allocation = origAllocation def test_NoSuchAllocation(self): self.assertRaises(IndexError, self.tested.byIndex, 1) def test_OsmosisListLabelsReturnsAnotherLabel(self): abused = False def anotherLabelMock(cmd): if cmd[0:2] == ['osmosis', 'listlabels']: return cmd[2] + "_not" abused = True self.assertRaises(Exception, self.createAllocation, self.requirements, self.allocationInfo, listLabelsMock=anotherLabelMock) self.assertFalse(abused) def test_CreateCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() def createCallback(): self.createAllocation(self.requirements, self.allocationInfo) executeCodeWhileAllocationIsDeadOfHeartbeatTimeout(_allocation, createCallback) self.assertNotIn(_allocation, self.tested.all()) def test_byIndexCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() idx = _allocation.index() self.assertRaises(IndexError, executeCodeWhileAllocationIsDeadOfHeartbeatTimeout, _allocation, lambda: self.tested.byIndex(idx)) def test_AllCleansUp(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) _allocation.free() def validateNotInAll(): self.assertNotIn(_allocation, self.tested.all()) executeCodeWhileAllocationIsDeadOfHeartbeatTimeout(_allocation, validateNotInAll) def test_All(self): _allocation = self.createAllocation(self.requirements, self.allocationInfo) self.assertEquals(self.tested.all(), [_allocation]) def createAllocation(self, requirements, allocationInfo, listLabelsMock=osmosisListLabelsFoundMock): origRun = sh.run nrFreeHostsBefore = len(self.freePool.all()) try: sh.run = listLabelsMock _allocation = self.tested.create(requirements, self.allocationInfo) finally: sh.run = origRun self.assertEquals(len(self.freePool.all()), nrFreeHostsBefore - len(requirements)) return _allocation