[96] | 1 | from datetime import datetime, timedelta
|
---|
| 2 | import time
|
---|
| 3 | import unittest
|
---|
| 4 | from unittest.mock import Mock
|
---|
| 5 |
|
---|
| 6 | from tudelft.utilities.listener.Listener import Listener
|
---|
| 7 | from tudelft.utilities.repository.NoResourcesNowException import NoResourcesNowException
|
---|
| 8 | from tudelft_utilities_logging.ReportToLogger import ReportToLogger
|
---|
| 9 | from uri.uri import URI
|
---|
| 10 |
|
---|
| 11 | from geniusweb.actions.Accept import Accept
|
---|
| 12 | from geniusweb.actions.Action import Action
|
---|
| 13 | from geniusweb.actions.EndNegotiation import EndNegotiation
|
---|
| 14 | from geniusweb.actions.Offer import Offer
|
---|
| 15 | from geniusweb.actions.PartyId import PartyId
|
---|
| 16 | from geniusweb.deadline.Deadline import Deadline
|
---|
| 17 | from geniusweb.deadline.DeadlineTime import DeadlineTime
|
---|
| 18 | from geniusweb.events.CurrentState import CurrentState
|
---|
| 19 | from geniusweb.inform.ActionDone import ActionDone
|
---|
| 20 | from geniusweb.inform.Agreements import Agreements
|
---|
| 21 | from geniusweb.inform.Finished import Finished
|
---|
| 22 | from geniusweb.inform.Inform import Inform
|
---|
| 23 | from geniusweb.inform.Settings import Settings
|
---|
| 24 | from geniusweb.inform.YourTurn import YourTurn
|
---|
| 25 | from geniusweb.progress.Progress import Progress
|
---|
| 26 | from geniusweb.protocol.ProtocolException import ProtocolException
|
---|
| 27 | from geniusweb.protocol.partyconnection.ProtocolToPartyConn import ProtocolToPartyConn
|
---|
| 28 | from geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory import ProtocolToPartyConnFactory
|
---|
| 29 | from geniusweb.protocol.partyconnection.ProtocolToPartyConnections import ProtocolToPartyConnections
|
---|
| 30 | from geniusweb.protocol.session.TeamInfo import TeamInfo
|
---|
| 31 | from geniusweb.protocol.session.saop.SAOP import SAOP
|
---|
| 32 | from geniusweb.protocol.session.saop.SAOPSettings import SAOPSettings
|
---|
| 33 | from geniusweb.protocol.session.saop.SAOPState import SAOPState
|
---|
| 34 | from geniusweb.references.Parameters import Parameters
|
---|
| 35 | from geniusweb.references.PartyRef import PartyRef
|
---|
| 36 | from geniusweb.references.PartyWithParameters import PartyWithParameters
|
---|
| 37 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
| 38 | from geniusweb.references.ProfileRef import ProfileRef
|
---|
| 39 | from geniusweb.references.ProtocolRef import ProtocolRef
|
---|
| 40 |
|
---|
| 41 |
|
---|
| 42 | class SAOPTest(unittest.TestCase):
|
---|
| 43 | '''
|
---|
| 44 | This test tests inner workings of the SAOP protocol, AKA 'white box' testing.
|
---|
| 45 | This adds brittleness to this test, because these internal workings may be
|
---|
| 46 | modified as long as the public API remains working. This approach was
|
---|
| 47 | necessary because fully testing the public API directly would lead to
|
---|
| 48 | excessive amounts of Mocking and unfocused tests. (with "focused test" we
|
---|
| 49 | mean that a junit test should test a small part of the code and thus aid in
|
---|
| 50 | locating the actual issue).
|
---|
| 51 | '''
|
---|
| 52 | PARTY2ID = PartyId("party2")
|
---|
| 53 | PARTY1ID = PartyId("party1")
|
---|
| 54 | parameters = Parameters()
|
---|
| 55 | SAOPPROTOCOL = ProtocolRef(URI("SAOP"))
|
---|
| 56 |
|
---|
| 57 | NOW = 1000
|
---|
| 58 | DEADLINE =1000
|
---|
| 59 | party1ref = PartyRef(URI("party1"))
|
---|
| 60 | party2ref = PartyRef(URI("party2"))
|
---|
| 61 | partywithparam1 = PartyWithParameters(party1ref, parameters)
|
---|
| 62 | partywithparam2 = PartyWithParameters(party2ref, parameters)
|
---|
| 63 |
|
---|
| 64 |
|
---|
| 65 | def setUp(self):
|
---|
| 66 | self.state = Mock(SAOPState)
|
---|
| 67 | self.connectedstate = Mock(SAOPState)
|
---|
| 68 | self.failstate = Mock(SAOPState)
|
---|
| 69 | self.finalstate = Mock(SAOPState)
|
---|
| 70 |
|
---|
| 71 | self.settings = Mock(SAOPSettings)
|
---|
| 72 | self.team1 = Mock(TeamInfo)
|
---|
| 73 | self.team2 = Mock(TeamInfo)
|
---|
| 74 | self.conn1 = Mock(ProtocolToPartyConn)
|
---|
| 75 | self.conn2 = Mock(ProtocolToPartyConn);
|
---|
| 76 | self.progress = Mock(Progress)
|
---|
| 77 | self.testlistener = Mock(Listener)
|
---|
| 78 |
|
---|
| 79 | self.deadlinetime = Mock(DeadlineTime)
|
---|
| 80 |
|
---|
| 81 |
|
---|
| 82 | self.profile1 = Mock(ProfileRef)
|
---|
| 83 | self.profile2 = Mock(ProfileRef)
|
---|
| 84 |
|
---|
| 85 | pwp1 = PartyWithProfile(self.partywithparam1, self.profile1);
|
---|
| 86 | pwp2 = PartyWithProfile(self.partywithparam2, self.profile2);
|
---|
| 87 | self.team1.getParties=Mock(return_value=[pwp1])
|
---|
| 88 | self.team2.getParties=Mock(return_value=[pwp2])
|
---|
| 89 |
|
---|
| 90 | partyprofiles = {}
|
---|
| 91 | partyprofiles[self.PARTY1ID]= self.team1
|
---|
| 92 | partyprofiles[self.PARTY2ID]= self.team2
|
---|
| 93 |
|
---|
| 94 |
|
---|
| 95 | self.pwpmap = {}
|
---|
| 96 | self.pwpmap[self.PARTY1ID]=pwp1
|
---|
| 97 | self.pwpmap[self.PARTY2ID]=pwp2
|
---|
| 98 | self.deadlinetime.getDuration=Mock(return_value=self.DEADLINE)
|
---|
| 99 |
|
---|
| 100 | teams = []
|
---|
| 101 | teams.append(self.team1);
|
---|
| 102 | teams.append(self.team2);
|
---|
| 103 | self.settings.getTeams=Mock(return_value=teams)
|
---|
| 104 | self.settings.getAllParties=Mock(return_value=[pwp1, pwp2])
|
---|
| 105 | self.settings.getDeadline=Mock(return_value=self.deadlinetime)
|
---|
| 106 |
|
---|
| 107 | self.factory = Mock(ProtocolToPartyConnFactory)
|
---|
| 108 | # connections = Mock(List);
|
---|
| 109 | connections = [self.conn1, self.conn2]
|
---|
| 110 | self.factory.connectAll=Mock(return_value=connections)
|
---|
| 111 |
|
---|
| 112 | # hack the state.with(connection) stuff simplistically
|
---|
| 113 |
|
---|
| 114 | self.conn1.getParty=Mock(return_value=self.PARTY1ID)
|
---|
| 115 | self.conn2.getParty=Mock(return_value=self.PARTY2ID)
|
---|
| 116 |
|
---|
| 117 | self.MockState(self.connectedstate, "connected state", True)
|
---|
| 118 | self.MockState(self.state, "running state",True);
|
---|
| 119 |
|
---|
| 120 | self.MockState(self.finalstate, "final state",True);
|
---|
| 121 | self.finalstate.isFinal=Mock(return_value=True)
|
---|
| 122 | self.MockState(self.failstate, "fail state", True);
|
---|
| 123 | self.failstate.isFinal=Mock(return_value=True)
|
---|
| 124 |
|
---|
| 125 | self.connectionswithparties = ProtocolToPartyConnections([self.conn1, self.conn2])
|
---|
| 126 |
|
---|
| 127 | # HACK thenReturn twice, so that 2nd call to iterator() returns new
|
---|
| 128 | # iterator instead of the old one
|
---|
| 129 | profilesmap = {}
|
---|
| 130 | profilesmap[self.PARTY1ID]= pwp1
|
---|
| 131 | profilesmap[self.PARTY2ID]= pwp2
|
---|
| 132 | self.state.getPartyProfiles=Mock(return_value=profilesmap)
|
---|
| 133 |
|
---|
| 134 | self.saop = SAOP(self.state, ReportToLogger("test"),
|
---|
| 135 | self.connectionswithparties)
|
---|
| 136 | self.saop.addListener(self.testlistener)
|
---|
| 137 |
|
---|
| 138 |
|
---|
| 139 | def MockState(self, state:SAOPState , asText:str, isConnected:bool ) :
|
---|
| 140 | '''
|
---|
| 141 | All states are more or less the same, but are slightly modified
|
---|
| 142 |
|
---|
| 143 | @param state the state to Mock (must be already
|
---|
| 144 | @param asText short name for the state, for debugging
|
---|
| 145 | @param bool true if parties are connected
|
---|
| 146 | '''
|
---|
| 147 | state.getSettings=Mock(return_value=self.settings) #type:ignore
|
---|
| 148 | if isConnected:
|
---|
| 149 | state.getConnections=Mock(return_value=[self.PARTY1ID, self.PARTY2ID]) #type:ignore
|
---|
| 150 | else:
|
---|
| 151 | state.getConnections=Mock(return_value=[]) #type:ignore
|
---|
| 152 | # when(state.getConnections()).thenReturn(connectionswithparties);
|
---|
| 153 |
|
---|
| 154 | state.getProgress=Mock(return_value=self.progress) #type:ignore
|
---|
| 155 | state.WithParty=Mock(return_value=self.connectedstate) #type:ignore
|
---|
| 156 | state._getNextActor=Mock(return_value=self.PARTY1ID) #type:ignore
|
---|
| 157 | state.WithAction= Mock(side_effect=lambda pid, act: #type:ignore
|
---|
| 158 | self.finalstate if isinstance(act, EndNegotiation) else\
|
---|
| 159 | state )
|
---|
| 160 |
|
---|
| 161 | state.WithProgress=Mock(return_value=state) #type:ignore
|
---|
| 162 | state.__repr__=Mock(return_value=asText) #type:ignore
|
---|
| 163 | state.WithException=Mock(return_value=self.failstate) #type:ignore
|
---|
| 164 | state.getAgreements=Mock(return_value=Agreements()) #type:ignore
|
---|
| 165 |
|
---|
| 166 | #explicit default. This differs from Java, where default bools to false
|
---|
| 167 | state.isFinal=Mock(return_value=False) #type:ignore
|
---|
| 168 | state.getPartyProfiles = Mock(return_value=self.pwpmap) #type:ignore
|
---|
| 169 |
|
---|
| 170 | def testConstructor(self):
|
---|
| 171 | state1 = Mock(SAOPState)
|
---|
| 172 | dl = Mock(Deadline)
|
---|
| 173 | set = Mock(SAOPSettings)
|
---|
| 174 | state1.getSettings=Mock(return_value=set)
|
---|
| 175 | set.getDeadline=Mock(return_value=dl)
|
---|
| 176 | dl.getDuration=Mock(return_value=1000)
|
---|
| 177 | SAOP(state1, ReportToLogger("test"), self.connectionswithparties)
|
---|
| 178 | self.assertEqual([], self.state.WithException.call_args_list)
|
---|
| 179 | self.assertEqual([], self. testlistener.notifyChange.call_args_list)
|
---|
| 180 |
|
---|
| 181 |
|
---|
| 182 | def testConnect(self):
|
---|
| 183 | self.saop._connect(self.factory)
|
---|
| 184 |
|
---|
| 185 | self.assertEqual(self.connectedstate, self.saop.getState())
|
---|
| 186 | self.assertEqual([], self.state.WithException.call_args_list)
|
---|
| 187 | self.assertEqual([], self.testlistener.notifyChange.call_args_list)
|
---|
| 188 |
|
---|
| 189 |
|
---|
| 190 | def testConnectFailingConnection(self):
|
---|
| 191 | # override the factory connect to throw IOException. This exception
|
---|
| 192 | # should boil up and cause the connect to fail.
|
---|
| 193 | def __raise(refs):
|
---|
| 194 | raise ConnectionError("Refusing connection")
|
---|
| 195 | self.factory.connectAll=Mock(side_effect=__raise)
|
---|
| 196 | this=self
|
---|
| 197 | self.assertRaises(ConnectionError, lambda:this.saop._connect(this.factory))
|
---|
| 198 | # following was never reached?
|
---|
| 199 | #verify(state, times(0)).with(any(ProtocolException));
|
---|
| 200 | #verify(testlistener, times(0)).notifyChange(any(CurrentState));
|
---|
| 201 |
|
---|
| 202 | def testConnectRetry(self):
|
---|
| 203 | # override the factory connect to throw NoResourcesNowException and
|
---|
| 204 | # then succeed 2nd time.
|
---|
| 205 | this=self
|
---|
| 206 |
|
---|
| 207 | firsttime=True
|
---|
| 208 | def __throwsThenSucceeds():
|
---|
| 209 | if firsttime:
|
---|
| 210 | firsttime=False
|
---|
| 211 | raise NoResourcesNowException("Refusing connection",\
|
---|
| 212 | datetime.now() + timedelta(seconds=0.5))
|
---|
| 213 | return this.connections
|
---|
| 214 | self.factory.connect=Mock(side_effect=__throwsThenSucceeds)
|
---|
| 215 |
|
---|
| 216 | self.saop._connect(self.factory)
|
---|
| 217 |
|
---|
| 218 | self.assertEqual(self.connectedstate, self.saop.getState())
|
---|
| 219 | #verify(state, times(0)).with(any(ProtocolException));
|
---|
| 220 | self.assertEqual([], [e \
|
---|
| 221 | for e in self.state.WithException.call_args_list\
|
---|
| 222 | if not isinstance( e,ProtocolException)])
|
---|
| 223 | self.assertEqual([],self.testlistener.notifyChange.call_args_list)
|
---|
| 224 |
|
---|
| 225 | def testSetup(self) :
|
---|
| 226 | self.saop._setupParties()
|
---|
| 227 |
|
---|
| 228 | # were the connections attached properly?
|
---|
| 229 | self.assertEqual(1, len(self.conn1.addListener.call_args_list))
|
---|
| 230 | self.assertEqual(1, len(self.conn2.addListener.call_args_list))
|
---|
| 231 |
|
---|
| 232 | # were the settings send to each party?
|
---|
| 233 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list \
|
---|
| 234 | if isinstance(call[0][0],Settings)]))
|
---|
| 235 | self.assertEqual(
|
---|
| 236 | Settings(self.PARTY1ID, self.profile1, self.SAOPPROTOCOL, self.progress, self.parameters),
|
---|
| 237 | self.conn1.send.call_args_list[0][0][0])
|
---|
| 238 |
|
---|
| 239 | self.assertEqual(1, len([call for call in self.conn2.send.call_args_list \
|
---|
| 240 | if isinstance(call[0][0],Settings)]))
|
---|
| 241 | self.assertEqual(
|
---|
| 242 | Settings(self.PARTY2ID, self.profile2, self.SAOPPROTOCOL, self.progress, self.parameters),
|
---|
| 243 | self.conn2.send.call_args_list[0][0][0])
|
---|
| 244 |
|
---|
| 245 | self.assertEqual([], self.state.WithException.call_args_list)
|
---|
| 246 | self.assertEqual([], [v for v in self.testlistener.notifyChange.call_args_list if isinstance(v, CurrentState)])
|
---|
| 247 |
|
---|
| 248 |
|
---|
| 249 | def testActionRequestWrongActor(self):
|
---|
| 250 | self.saop._actionRequest(self.conn2, Mock(EndNegotiation))
|
---|
| 251 | self.assertEqual(1, len([call for call in self.state.WithException.call_args_list\
|
---|
| 252 | if isinstance(call[0][0], ProtocolException) ]))
|
---|
| 253 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 254 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 255 |
|
---|
| 256 | def testActionRequest(self):
|
---|
| 257 | self.saop._nextTurn()
|
---|
| 258 |
|
---|
| 259 | self.state._getNextActor=Mock(return_value=self.PARTY1ID)
|
---|
| 260 | self.state.withAction = Mock(return_value=self.finalstate)
|
---|
| 261 |
|
---|
| 262 | self.saop._actionRequest(self.conn1, Mock(EndNegotiation))
|
---|
| 263 |
|
---|
| 264 | self.assertEqual([] , [call for call in self.state.WithException.call_args_list
|
---|
| 265 | if isinstance(call[0][0], ProtocolException)])
|
---|
| 266 | #verify(state, times(1)).with(eq(PARTY1ID), any(EndNegotiation));
|
---|
| 267 | self.assertEqual(1, len([call for call in self.state.WithAction.call_args_list
|
---|
| 268 | if call[0][0]==self.PARTY1ID and\
|
---|
| 269 | isinstance(call[0][1], EndNegotiation)]))
|
---|
| 270 | # verify broadcast
|
---|
| 271 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 272 | if isinstance(call[0][0], ActionDone)]))
|
---|
| 273 | self.assertEqual(1, len([call for call in self.conn2.send.call_args_list
|
---|
| 274 | if isinstance(call[0][0], ActionDone)]))
|
---|
| 275 |
|
---|
| 276 | # state.getNextActor() is frozen to PARTY1 by our Mocking
|
---|
| 277 | #verify(conn1, times(1)).send(isA(YourTurn));
|
---|
| 278 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 279 | if isinstance(call[0][0], YourTurn)]))
|
---|
| 280 | #verify(conn2, times(0)).send(isA(YourTurn));
|
---|
| 281 | self.assertEqual(0, len([call for call in self.conn2.send.call_args_list
|
---|
| 282 | if isinstance(call[0][0], YourTurn)]))
|
---|
| 283 | #listener should be informed about final state.
|
---|
| 284 | #verify(testlistener, times(0)).notifyChange(any(CurrentState));
|
---|
| 285 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 286 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 287 |
|
---|
| 288 | def testFinalActionRequest(self):
|
---|
| 289 | this=self
|
---|
| 290 | #FIXME double mock??
|
---|
| 291 | #self.state.getNextActor=Mock(return_value=self.PARTY1ID)
|
---|
| 292 | def __nextstate(pid:PartyId, act:Action):
|
---|
| 293 | if isinstance(act, EndNegotiation):
|
---|
| 294 | return this.finalstate
|
---|
| 295 |
|
---|
| 296 | self.state.withAction=Mock(side_effect=__nextstate)
|
---|
| 297 | # when(finalstate.getAgreements()).thenReturn(Mock(Agreements));
|
---|
| 298 |
|
---|
| 299 | self.saop._nextTurn() # ensure we send YourTurn to party1.
|
---|
| 300 | self.saop._actionRequest(self.conn1, Mock(EndNegotiation))
|
---|
| 301 |
|
---|
| 302 | #verify(state, times(0)).with(any(ProtocolException));
|
---|
| 303 | self.assertEqual([], [call for call in self.state.WithException.call_args_list
|
---|
| 304 | if isinstance(call[0][0], ProtocolException) ])
|
---|
| 305 | #verify(state, times(1)).with(eq(PARTY1ID), any(EndNegotiation));
|
---|
| 306 | self.assertEqual(1, len([call for call in self.state.WithAction.call_args_list\
|
---|
| 307 | if isinstance(call[0][1], EndNegotiation)]))
|
---|
| 308 |
|
---|
| 309 | # verify broadcast
|
---|
| 310 | #erify(conn1, times(1)).send(isA(Finished));
|
---|
| 311 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 312 | if isinstance(call[0][0], Finished)]))
|
---|
| 313 |
|
---|
| 314 | #verify(conn2, times(1)).send(isA(Finished));
|
---|
| 315 | self.assertEqual(1, len([call for call in self.conn2.send.call_args_list
|
---|
| 316 | if isinstance(call[0][0], Finished)]))
|
---|
| 317 |
|
---|
| 318 | #verify(testlistener, times(1)).notifyChange(any(CurrentState));
|
---|
| 319 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 320 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 321 |
|
---|
| 322 | #verify(conn1, times(1)).send(isA(YourTurn));
|
---|
| 323 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 324 | if isinstance(call[0][0], YourTurn)]))
|
---|
| 325 | #verify(conn2, times(0)).send(isA(YourTurn));
|
---|
| 326 | self.assertEqual( [] , [call for call in self.conn2.send.call_args_list
|
---|
| 327 | if isinstance(call[0][0], YourTurn)])
|
---|
| 328 |
|
---|
| 329 | def testStart(self):
|
---|
| 330 | self.saop.start(self.factory)
|
---|
| 331 |
|
---|
| 332 | def testActionFailNextYourturn(self):
|
---|
| 333 | this=self
|
---|
| 334 | def __throwExc(inf:Inform):
|
---|
| 335 | if isinstance(inf, YourTurn):
|
---|
| 336 | raise ConnectionError("fail sending yourturn")
|
---|
| 337 | self.conn1.send=Mock(side_effect=__throwExc)
|
---|
| 338 | # CHECK is the state really final after an exception?
|
---|
| 339 | self.state.WithException=Mock(return_value=this.finalstate)
|
---|
| 340 | # when(state.getAgreements()).thenReturn(Mock(Agreements));
|
---|
| 341 | self.saop._actionRequest(self.conn1, Mock(Accept))
|
---|
| 342 |
|
---|
| 343 |
|
---|
| 344 | #verify(state, times(1)).with(any(ProtocolException));
|
---|
| 345 | self.assertEqual( 1, len([call for call in self.state.WithException.call_args_list
|
---|
| 346 | if isinstance(call[0][0], ProtocolException) ]))
|
---|
| 347 | #verify(testlistener, times(1)).notifyChange(any(CurrentState));
|
---|
| 348 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 349 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 350 |
|
---|
| 351 | def testActionNotTheTurn(self) :
|
---|
| 352 | def __throwExc(inf:Inform):
|
---|
| 353 | if isinstance(inf, YourTurn):
|
---|
| 354 | raise ConnectionError("fail sending yourturn")
|
---|
| 355 | self.conn1.send=Mock(side_effect=__throwExc)
|
---|
| 356 |
|
---|
| 357 | # when(failstate.getAgreements()).thenReturn(Mock(Agreements));
|
---|
| 358 | # not turn of conn2.
|
---|
| 359 | self.saop._actionRequest(self.conn2, Mock(EndNegotiation))
|
---|
| 360 |
|
---|
| 361 | #verify(state, times(1)).with(any(ProtocolException));
|
---|
| 362 | self.assertEqual( 1, len([call for call in self.state.WithException.call_args_list
|
---|
| 363 | if isinstance(call[0][0], ProtocolException) ]))
|
---|
| 364 | #verify(testlistener, times(1)).notifyChange(any(CurrentState));
|
---|
| 365 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 366 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 367 |
|
---|
| 368 |
|
---|
| 369 | def testActionInFinalState(self):
|
---|
| 370 | saop = SAOP(self.finalstate, ReportToLogger("test"),
|
---|
| 371 | self.connectionswithparties);
|
---|
| 372 | # when(finalstate.getAgreements()).thenReturn(Mock(Agreements));
|
---|
| 373 |
|
---|
| 374 | saop._actionRequest(self.conn1, Mock(Offer))
|
---|
| 375 |
|
---|
| 376 | #verify(finalstate, times(0)).with(any(ProtocolException));
|
---|
| 377 | self.assertEqual( [], [call for call in self.state.WithException.call_args_list
|
---|
| 378 | if isinstance(call[0][0], ProtocolException) ])
|
---|
| 379 | #verify(testlistener, times(0)).notifyChange(any());
|
---|
| 380 | self.assertEqual([], self.testlistener.notifyChange.call_args_list)
|
---|
| 381 |
|
---|
| 382 | def testDescription(self):
|
---|
| 383 | self.assertNotEquals(None,self.saop.getDescription())
|
---|
| 384 |
|
---|
| 385 | def testAddParticipant(self):
|
---|
| 386 | self.assertRaises(ValueError, lambda:self.saop.addParticipant(None))
|
---|
| 387 |
|
---|
| 388 | def testDeadlineTimer(self):
|
---|
| 389 | unconnectedstate = Mock(SAOPState)
|
---|
| 390 | self.MockState(unconnectedstate, "unconnected state", False)
|
---|
| 391 | saopempty = SAOP(unconnectedstate, ReportToLogger("test"),
|
---|
| 392 | ProtocolToPartyConnections([]))
|
---|
| 393 | saopempty.addListener(self.testlistener)
|
---|
| 394 |
|
---|
| 395 | saopempty.start(self.factory);
|
---|
| 396 | # verify(testlistener, times(0)).notifyChange(any(CurrentState.class));
|
---|
| 397 | self.assertEqual([], [call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 398 | if isinstance(call[0][0], CurrentState) ])
|
---|
| 399 |
|
---|
| 400 | #verify(conn1, times(1)).send(isA(YourTurn.class));
|
---|
| 401 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 402 | if isinstance(call[0][0], YourTurn)]))
|
---|
| 403 | time.sleep( (self.DEADLINE + SAOP._TIME_MARGIN + 100)/1000.)
|
---|
| 404 | #verify(testlistener, times(1)).notifyChange(any(CurrentState.class));
|
---|
| 405 | self.assertEqual(1, len([call for call in self.testlistener.notifyChange.call_args_list
|
---|
| 406 | if isinstance(call[0][0], CurrentState)]))
|
---|
| 407 | #verify(conn1, times(1)).send(isA(Finished.class));
|
---|
| 408 | self.assertEqual(1, len([call for call in self.conn1.send.call_args_list
|
---|
| 409 | if isinstance(call[0][0], Finished)]))
|
---|
| 410 |
|
---|
| 411 |
|
---|