[88] | 1 | from datetime import datetime
|
---|
| 2 | import json
|
---|
| 3 | import time
|
---|
| 4 | from typing import List
|
---|
| 5 | import unittest
|
---|
| 6 | from unittest.mock import Mock
|
---|
| 7 |
|
---|
| 8 | from pyson.ObjectMapper import ObjectMapper
|
---|
| 9 | from unitpy.GeneralTests import GeneralTests
|
---|
| 10 | from uri.uri import URI
|
---|
| 11 |
|
---|
| 12 | from geniusweb.actions.Accept import Accept
|
---|
| 13 | from geniusweb.actions.Action import Action
|
---|
| 14 | from geniusweb.actions.EndNegotiation import EndNegotiation
|
---|
| 15 | from geniusweb.actions.Offer import Offer
|
---|
| 16 | from geniusweb.actions.PartyId import PartyId
|
---|
| 17 | from geniusweb.deadline.DeadlineTime import DeadlineTime
|
---|
| 18 | from geniusweb.issuevalue.Bid import Bid
|
---|
| 19 | from geniusweb.progress.ProgressRounds import ProgressRounds
|
---|
| 20 | from geniusweb.progress.ProgressTime import ProgressTime
|
---|
| 21 | from geniusweb.protocol.NegoState import NegoState
|
---|
| 22 | from geniusweb.protocol.ProtocolException import ProtocolException
|
---|
| 23 | from geniusweb.protocol.partyconnection.ProtocolToPartyConn import ProtocolToPartyConn
|
---|
| 24 | from geniusweb.protocol.session.TeamInfo import TeamInfo
|
---|
| 25 | from geniusweb.protocol.session.saop.SAOPSettings import SAOPSettings
|
---|
| 26 | from geniusweb.protocol.session.saop.SAOPState import SAOPState
|
---|
| 27 | from geniusweb.references.Parameters import Parameters
|
---|
| 28 | from geniusweb.references.PartyRef import PartyRef
|
---|
| 29 | from geniusweb.references.PartyWithParameters import PartyWithParameters
|
---|
| 30 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
| 31 | from geniusweb.references.ProfileRef import ProfileRef
|
---|
| 32 |
|
---|
| 33 |
|
---|
| 34 | class SAOPStateTest (unittest.TestCase, GeneralTests[SAOPState]):
|
---|
| 35 | maxDiff =None
|
---|
| 36 |
|
---|
| 37 | NOW = 1000
|
---|
| 38 | party1 = PartyId("party1")
|
---|
| 39 | party2 = PartyId("party2")
|
---|
| 40 | party3 = PartyId("party3")
|
---|
| 41 | actions1:List[Action] = []
|
---|
| 42 | action = Mock(Action)
|
---|
| 43 | actions2:List[Action] = [action]
|
---|
| 44 |
|
---|
| 45 | party1conn = Mock(ProtocolToPartyConn)
|
---|
| 46 | party2conn = Mock(ProtocolToPartyConn)
|
---|
| 47 | party3conn = Mock(ProtocolToPartyConn)
|
---|
| 48 |
|
---|
| 49 | connections = [party1, party2]
|
---|
| 50 | connections2 = [party1, party3]
|
---|
| 51 | connections3 = [party1, party2, party3]
|
---|
| 52 |
|
---|
| 53 | progresstime = Mock(ProgressTime)
|
---|
| 54 | progressrounds = Mock(ProgressRounds)
|
---|
| 55 | progressrounds1 = Mock(ProgressRounds)
|
---|
| 56 | settings = Mock(SAOPSettings)
|
---|
| 57 |
|
---|
| 58 | bid1 = Mock(Bid)
|
---|
| 59 | otherbid = Mock(Bid)
|
---|
| 60 | accept1 = Accept(party1, bid1)
|
---|
| 61 | accept2 = Accept(party2, bid1)
|
---|
| 62 | acceptother = Accept(party2, otherbid)
|
---|
| 63 | offer1 = Offer(party1, bid1)
|
---|
| 64 | endNegotiation1 = EndNegotiation(party1)
|
---|
| 65 |
|
---|
| 66 | jackson = ObjectMapper()
|
---|
| 67 |
|
---|
| 68 | serialized = "{\"SAOPState\":{\"actions\":[],\"connections\":[\"party1\",\"party2\"],\"progress\":{\"ProgressTime\":{\"duration\":1000000,\"start\":2000000}},\"settings\":{\"SAOPSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"party1ref\",\"parameters\":{}},\"profile\":\"prof1\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":123000}}}},\"partyprofiles\":{},\"error\":null}}"
|
---|
| 69 |
|
---|
| 70 | party1conn.getParty=Mock(return_value=party1)
|
---|
| 71 | party2conn.getParty=Mock(return_value=party2)
|
---|
| 72 | party3conn.getParty=Mock(return_value=party3)
|
---|
| 73 | # workaround https://github.com/python/mypy/issues/2427
|
---|
| 74 | party1conn.__repr__= Mock(return_value="conn1") #type:ignore
|
---|
| 75 | party2conn.__repr__=Mock(return_value="conn2") #type:ignore
|
---|
| 76 | party3conn.__repr__=Mock(return_value="conn3") #type:ignore
|
---|
| 77 | action.__repr__=Mock(return_value="act1") #type:ignore
|
---|
| 78 |
|
---|
| 79 | progresstime.isPastDeadline=Mock(return_value=False) # is default in java
|
---|
| 80 | progressrounds.getTerminationTime=\
|
---|
| 81 | Mock(return_value=datetime.utcfromtimestamp(time.time() + 36000))
|
---|
| 82 | progressrounds1.getTerminationTime=\
|
---|
| 83 | Mock(return_value=datetime.utcfromtimestamp(time.time() + 36000))
|
---|
| 84 | progressrounds.advance=Mock(return_value=progressrounds1)
|
---|
| 85 |
|
---|
| 86 | state1 = SAOPState(actions1, connections, progresstime, settings)
|
---|
| 87 | state1a = SAOPState(actions1, connections, progresstime, settings)
|
---|
| 88 | state2 = SAOPState(actions2, connections, progresstime, settings)
|
---|
| 89 | state3 = SAOPState(actions1, connections2, progresstime, settings)
|
---|
| 90 | state4 = SAOPState(actions1, connections, progressrounds, settings)
|
---|
| 91 |
|
---|
| 92 | conns = [party1, party2]
|
---|
| 93 | pwithp = PartyWithParameters(PartyRef(URI("party1ref")), Parameters())
|
---|
| 94 | teams = [PartyWithProfile(pwithp, ProfileRef(URI("prof1")))]
|
---|
| 95 | participants = [ TeamInfo(teams)]
|
---|
| 96 | deadline = DeadlineTime(123000)
|
---|
| 97 | setts = SAOPSettings(participants, deadline)
|
---|
| 98 | state = SAOPState(actions1, conns,
|
---|
| 99 | ProgressTime(1000000, datetime.fromtimestamp(2000000/1000.)), setts)
|
---|
| 100 |
|
---|
| 101 | def getGeneralTestData(self)->List[List[SAOPState]] :
|
---|
| 102 | return [[self.state1, self.state1a],
|
---|
| 103 | [self.state2], [self.state3],
|
---|
| 104 | [self.state4]]
|
---|
| 105 |
|
---|
| 106 | def getGeneralTestStrings(self)->List[str] :
|
---|
| 107 | return [
|
---|
| 108 | "SAOPState.*\\[\\].*party1.*party2.*ProgressTime.*",
|
---|
| 109 | "SAOPState.*\\[act1\\].*party1.*party2.*ProgressTime.*",
|
---|
| 110 | "SAOPState.*party1.*party3.*ProgressTime.*",
|
---|
| 111 | "SAOPState.*party1.*party2.*ProgressRounds.*"]
|
---|
| 112 |
|
---|
| 113 | def constructWith0Connection(self) :
|
---|
| 114 | SAOPState(self.actions1, [], self.progresstime, self.settings, None,
|
---|
| 115 | None)
|
---|
| 116 |
|
---|
| 117 | def constructWithNoneConnection(self):
|
---|
| 118 | state = SAOPState(self.actions1, None, self.progresstime, self.settings,
|
---|
| 119 | None, None)
|
---|
| 120 | self.assertEqual(0, len(state.getConnections()))
|
---|
| 121 |
|
---|
| 122 | def testNextActor(self):
|
---|
| 123 | self.assertEqual(self.party1, self.state1._getNextActor())
|
---|
| 124 |
|
---|
| 125 | def testNextActor2(self):
|
---|
| 126 | conns = [self.party2, self.party3]
|
---|
| 127 | state = SAOPState(self.actions1, conns, self.progresstime, self.settings,
|
---|
| 128 | None, None)
|
---|
| 129 | self.assertEqual(self.party2, state._getNextActor())
|
---|
| 130 |
|
---|
| 131 | def testNextActorAfterAction(self):
|
---|
| 132 | actions = [self.action]
|
---|
| 133 | state = SAOPState(actions, self.connections, self.progresstime,
|
---|
| 134 | self.settings, None, None)
|
---|
| 135 | self.assertEqual(self.party2, state._getNextActor())
|
---|
| 136 |
|
---|
| 137 | def testNextActorAfter2Actions(self):
|
---|
| 138 | actions = [self.action, self.action]
|
---|
| 139 | state = SAOPState(actions, self.connections, self.progresstime,
|
---|
| 140 | self.settings, None, None)
|
---|
| 141 | self.assertEqual(self.party1, state._getNextActor())
|
---|
| 142 |
|
---|
| 143 | def testIsFinal(self):
|
---|
| 144 | self.assertFalse(self.state1.isFinal(self.NOW))
|
---|
| 145 | state = SAOPState(self.actions1, self.connections, self.progresstime,
|
---|
| 146 | self.settings, None, Mock(ProtocolException))
|
---|
| 147 | self.assertTrue(state.isFinal(self.NOW))
|
---|
| 148 |
|
---|
| 149 | def testWithException(self):
|
---|
| 150 | finalstate1 = self.state1.WithException(Mock(ProtocolException))
|
---|
| 151 | self.assertTrue(finalstate1.isFinal(self.NOW))
|
---|
| 152 | finalstate2 = finalstate1.WithException(Mock(ProtocolException))
|
---|
| 153 | self.assertTrue(finalstate2.isFinal(self.NOW))
|
---|
| 154 |
|
---|
| 155 | def testIsOfferAgreement1(self):
|
---|
| 156 | actions = [self.offer1]
|
---|
| 157 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 158 | self.settings, None, None)
|
---|
| 159 | self.assertEqual({}, state.getAgreements().getMap())
|
---|
| 160 |
|
---|
| 161 | def testIsOfferAcceptAgreement(self):
|
---|
| 162 | actions = [self.offer1, self.accept2]
|
---|
| 163 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 164 | self.settings, None, None);
|
---|
| 165 | self.assertEqual({}, state.getAgreements().getMap())
|
---|
| 166 |
|
---|
| 167 | def testIsOfferAcceptOfferAgreement(self):
|
---|
| 168 | actions = [self.offer1, self.accept1, self.offer1]
|
---|
| 169 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 170 | self.settings, None, None);
|
---|
| 171 | self.assertEqual({},state.getAgreements().getMap())
|
---|
| 172 |
|
---|
| 173 | def testIsOfferAcceptAcceptAgreement(self) :
|
---|
| 174 | actions = [self.offer1, self.accept1, self.accept2]
|
---|
| 175 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 176 | self.settings, None, None);
|
---|
| 177 | self.assertEquals(self.bid1, state.getAgreements().getMap()[self.party1])
|
---|
| 178 | self.assertTrue(state.isFinal(self.NOW))
|
---|
| 179 |
|
---|
| 180 | def testIsAcceptOfferAcceptAgreement(self):
|
---|
| 181 | actions = [self.accept1, self.offer1, self.accept2]
|
---|
| 182 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 183 | self.settings, None, None);
|
---|
| 184 | self.assertEqual({},state.getAgreements().getMap())
|
---|
| 185 |
|
---|
| 186 | def testIsOfferAcceptAcceptotherAgreement(self) :
|
---|
| 187 | actions = [self.offer1, self.accept1, self.acceptother]
|
---|
| 188 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 189 | self.settings, None, None);
|
---|
| 190 | self.assertEqual({},state.getAgreements().getMap())
|
---|
| 191 |
|
---|
| 192 |
|
---|
| 193 | def testWithAction(self):
|
---|
| 194 | actn = self.action
|
---|
| 195 | actn.getActor=Mock(return_value=self.party1)
|
---|
| 196 | self.assertRaises(ValueError, lambda:self.state1.WithAction(self.party1, actn))
|
---|
| 197 |
|
---|
| 198 | def testWithConnection(self):
|
---|
| 199 | state = self.state1.WithParty(self.party3, Mock(PartyWithProfile))
|
---|
| 200 | self.assertEqual(3, len(state.getConnections()))
|
---|
| 201 |
|
---|
| 202 | def testIsEndNegotiationFinal(self):
|
---|
| 203 | actions = [self.endNegotiation1]
|
---|
| 204 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 205 | self.settings, None, None)
|
---|
| 206 | self.assertEqual({},state.getAgreements().getMap())
|
---|
| 207 | self.assertEqual(None,state.getError())
|
---|
| 208 | self.assertTrue(state.isFinal(self.NOW))
|
---|
| 209 |
|
---|
| 210 | def testIsProtocolErrorFinal(self):
|
---|
| 211 | state = SAOPState(self.actions1, self.connections3, self.progressrounds,
|
---|
| 212 | self.settings, None,
|
---|
| 213 | ProtocolException("test error", PartyId("test")));
|
---|
| 214 | self.assertTrue(state.isFinal(self.NOW))
|
---|
| 215 | self.assertNotEqual(None, state.getError())
|
---|
| 216 |
|
---|
| 217 | def testRefuseImmediateAccept(self):
|
---|
| 218 | Noneaccept = Accept(self.party1, None)
|
---|
| 219 | self.assertRaises(ValueError, lambda:self.state1.WithAction(self.party1, Noneaccept))
|
---|
| 220 |
|
---|
| 221 | def testRefuseNotMyTurn(self):
|
---|
| 222 | actions = [self.offer1]
|
---|
| 223 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 224 | self.settings, None, None)
|
---|
| 225 | self.assertRaises(ValueError, lambda: state.WithAction(self.party1, self.offer1))
|
---|
| 226 |
|
---|
| 227 | def testRefuseNoneAccept(self):
|
---|
| 228 | actions = [self.offer1]
|
---|
| 229 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 230 | self.settings, None, None);
|
---|
| 231 |
|
---|
| 232 | Noneaccept = Accept(self.party2, None)
|
---|
| 233 | self.assertRaises(ValueError, lambda:state.WithAction(self.party2, Noneaccept))
|
---|
| 234 |
|
---|
| 235 | def testRefuseNoneAction(self):
|
---|
| 236 | actions = [self.offer1]
|
---|
| 237 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 238 | self.settings, None, None)
|
---|
| 239 | self.assertRaises(ValueError, lambda:state.WithAction(self.party2, None))
|
---|
| 240 |
|
---|
| 241 | def testCheckGoodAccept(self):
|
---|
| 242 | actions = [self.offer1, self.accept2]
|
---|
| 243 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 244 | self.settings, None, None)
|
---|
| 245 |
|
---|
| 246 | accept = Accept(self.party3, self.bid1)
|
---|
| 247 | state = state.WithAction(self.party3, accept)
|
---|
| 248 | self.assertTrue(state.isFinal(self.NOW))
|
---|
| 249 | self.assertEqual(None,state.getError())
|
---|
| 250 | self.assertEqual(self.bid1, state.getAgreements().getMap().get(self.party1))
|
---|
| 251 |
|
---|
| 252 | def testCheckGoodSecondAccept(self):
|
---|
| 253 | bid2 = Mock(Bid)
|
---|
| 254 | actions = [self.offer1, Offer(self.party2, bid2),
|
---|
| 255 | Accept(self.party3, bid2)]
|
---|
| 256 | state = SAOPState(actions, self.connections3, self.progressrounds,
|
---|
| 257 | self.settings, None, None)
|
---|
| 258 | accept = Accept(self.party1, bid2)
|
---|
| 259 | state = state.WithAction(self.party1, accept)
|
---|
| 260 | self.assertTrue(state.isFinal(self.NOW));
|
---|
| 261 | self.assertEqual(None,state.getError())
|
---|
| 262 | self.assertEqual(bid2, state.getAgreements().getMap().get(self.party1))
|
---|
| 263 |
|
---|
| 264 | def testDeserialize(self):
|
---|
| 265 | obj:NegoState = self.jackson.parse(json.loads(self.serialized), NegoState)
|
---|
| 266 | print(obj)
|
---|
| 267 | self.assertEqual(self.state, obj)
|
---|
| 268 |
|
---|
| 269 | def testSerialize(self):
|
---|
| 270 | jsob = self.jackson.toJson(self.state)
|
---|
| 271 | print(jsob)
|
---|
| 272 | self.assertEqual(json.loads(self.serialized), jsob)
|
---|