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)
|
---|