1 | import unittest
|
---|
2 | from unittest.mock import Mock
|
---|
3 | from geniusweb.actions.PartyId import PartyId
|
---|
4 | from pyson.ObjectMapper import ObjectMapper
|
---|
5 | from geniusweb.references.ProtocolRef import ProtocolRef
|
---|
6 | from geniusweb.progress.ProgressRounds import ProgressRounds
|
---|
7 | from geniusweb.references.Parameters import Parameters
|
---|
8 | from test.TestConnection import TestConnection
|
---|
9 | from timedependentparty.TimeDependentParty import TimeDependentParty
|
---|
10 | from uri.uri import URI
|
---|
11 | from geniusweb.references.ProfileRef import ProfileRef
|
---|
12 | from geniusweb.inform.Settings import Settings
|
---|
13 | from pathlib import Path
|
---|
14 | from geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace import LinearAdditiveUtilitySpace
|
---|
15 | import json
|
---|
16 | from geniusweb.inform.ActionDone import ActionDone
|
---|
17 | from geniusweb.actions.EndNegotiation import EndNegotiation
|
---|
18 | from geniusweb.inform.YourTurn import YourTurn
|
---|
19 | from geniusweb.actions.Offer import Offer
|
---|
20 | from geniusweb.actions.Accept import Accept
|
---|
21 | from tudelft_utilities_logging.Reporter import Reporter
|
---|
22 | from geniusweb.inform.Agreements import Agreements
|
---|
23 | from geniusweb.inform.Finished import Finished
|
---|
24 | import logging
|
---|
25 | from decimal import Decimal
|
---|
26 | from geniusweb.bidspace.AllBidsList import AllBidsList
|
---|
27 | import time
|
---|
28 | from geniusweb.issuevalue.Bid import Bid
|
---|
29 |
|
---|
30 | class TimeDependentPartyTest (unittest.TestCase):
|
---|
31 | otherparty = PartyId("other")
|
---|
32 | SAOP="SAOP"
|
---|
33 | PROFILE = "test/resources/testprofile.json"
|
---|
34 | jackson = ObjectMapper()
|
---|
35 |
|
---|
36 | protocol = ProtocolRef(URI("SAOP"))
|
---|
37 |
|
---|
38 | def setUp(self) :
|
---|
39 | self.connection = TestConnection()
|
---|
40 | self.progress = Mock(ProgressRounds)
|
---|
41 | self.progress.get=Mock(return_value=0)
|
---|
42 | self.parameters = Parameters()
|
---|
43 | class MyTimeDependentParty(TimeDependentParty):
|
---|
44 | #Override
|
---|
45 | def getDescription(self) ->str:
|
---|
46 | return "test"
|
---|
47 |
|
---|
48 | #Override
|
---|
49 | def getE(self) ->float:
|
---|
50 | return 2 # conceder-like
|
---|
51 |
|
---|
52 | self.party = MyTimeDependentParty()
|
---|
53 |
|
---|
54 | self.settings = Settings(PartyId("party1"),
|
---|
55 | ProfileRef(URI("file:" + self.PROFILE)), self.protocol, self.progress,
|
---|
56 | self.parameters)
|
---|
57 |
|
---|
58 | serialized = Path(self.PROFILE).read_text("utf-8")
|
---|
59 | self.profile = self.jackson.parse(json.loads(serialized), LinearAdditiveUtilitySpace)
|
---|
60 |
|
---|
61 |
|
---|
62 | def testsmokeTest(self):
|
---|
63 | pass
|
---|
64 |
|
---|
65 | def testgetDescriptionTest(self):
|
---|
66 | self.assertNotEquals(None, self.party.getDescription())
|
---|
67 |
|
---|
68 | def testgetCapabilitiesTest(self):
|
---|
69 | capabilities = self.party.getCapabilities()
|
---|
70 | self.assertFalse(capabilities.getBehaviours()==set(),
|
---|
71 | "party does not define protocols")
|
---|
72 |
|
---|
73 | def testInformConnection(self):
|
---|
74 | self.party.connect(self.connection)
|
---|
75 | # Party should not start acting just after an inform
|
---|
76 | self.assertEqual(0, len(self.connection.getActions()))
|
---|
77 |
|
---|
78 | def testInformSettings(self):
|
---|
79 | self.party.connect(self.connection)
|
---|
80 | self.connection.notifyListeners(self.settings)
|
---|
81 | self.assertEqual(0, len(self.connection.getActions()))
|
---|
82 |
|
---|
83 | def testInformAndConnection(self):
|
---|
84 | self.party.connect(self.connection)
|
---|
85 | self.party.notifyChange(self.settings)
|
---|
86 | self.assertEqual(0, len(self.connection.getActions()))
|
---|
87 |
|
---|
88 | def testOtherWalksAway(self):
|
---|
89 | self.party.connect(self.connection)
|
---|
90 | self.party.notifyChange(self.settings)
|
---|
91 |
|
---|
92 | self.party.notifyChange(ActionDone(EndNegotiation(self.otherparty)))
|
---|
93 |
|
---|
94 | # party should not act at this point
|
---|
95 | self.assertEqual(0, len(self.connection.getActions()))
|
---|
96 |
|
---|
97 | def testPartyHasFirstTurn(self):
|
---|
98 | self.party.connect(self.connection)
|
---|
99 | self.party.notifyChange(self.settings)
|
---|
100 |
|
---|
101 | self.party.notifyChange(YourTurn())
|
---|
102 | self.assertEqual(1, len(self.connection.getActions()))
|
---|
103 | self.assertTrue(isinstance(self.connection.getActions()[0], Offer))
|
---|
104 |
|
---|
105 | def testPartyAccepts(self):
|
---|
106 | self.party.connect(self.connection)
|
---|
107 | self.party.notifyChange(self.settings)
|
---|
108 |
|
---|
109 | bid = self._findBestBid()
|
---|
110 | self.party.notifyChange(ActionDone(Offer(self.otherparty, bid)))
|
---|
111 | self.party.notifyChange(YourTurn())
|
---|
112 | self.assertEqual(1, len(self.connection.getActions()))
|
---|
113 | self.assertTrue(isinstance(self.connection.getActions()[0], Accept))
|
---|
114 |
|
---|
115 | def testPartyLogsFinal(self):
|
---|
116 | # this log output is optional, this is to show how to check log
|
---|
117 | reporter = Mock(Reporter)
|
---|
118 | class MyTimeDependentParty(TimeDependentParty):
|
---|
119 | def __init__(self, reporter:Reporter):
|
---|
120 | super().__init__(reporter)
|
---|
121 | #Override
|
---|
122 | def getDescription(self) ->str:
|
---|
123 | return "test"
|
---|
124 |
|
---|
125 | #Override
|
---|
126 | def getE(self) ->float:
|
---|
127 | return 2 # conceder-like
|
---|
128 |
|
---|
129 |
|
---|
130 | pty = MyTimeDependentParty(reporter)
|
---|
131 | pty.connect(self.connection)
|
---|
132 | pty.notifyChange(self.settings)
|
---|
133 | agreements = Mock(Agreements)
|
---|
134 | agreements.__str__=Mock(return_value="agree");
|
---|
135 | pty.notifyChange(Finished(agreements))
|
---|
136 | unittest.mock._Call
|
---|
137 |
|
---|
138 | reporter_call_strings = [ a.args[1] for a in reporter.log.call_args_list]
|
---|
139 | self.assertTrue( "Final ourcome:Finished[agree]" in reporter_call_strings)
|
---|
140 |
|
---|
141 | #Test
|
---|
142 | def testPartysUpdatesProgress(self):
|
---|
143 | self.party.connect(self.connection)
|
---|
144 | self.party.notifyChange(self.settings)
|
---|
145 |
|
---|
146 | self.party.notifyChange(YourTurn())
|
---|
147 | self.assertTrue( len(self.progress.advance.call_args_list) >0 )
|
---|
148 |
|
---|
149 | def testGetCapabilities(self):
|
---|
150 | saop=self.SAOP # PYTHON BUG? Why can't I use this directly in assert??
|
---|
151 | self.assertTrue(saop in self.party.getCapabilities().getBehaviours())
|
---|
152 |
|
---|
153 | def testUtilityTarget(self):
|
---|
154 | tdp = TimeDependentParty()
|
---|
155 | N02 = Decimal("0.2")
|
---|
156 | N043 =Decimal("0.42521212")
|
---|
157 | goal = tdp._getUtilityGoal(0.1, 1.2, N02, N043)
|
---|
158 | self.assertTrue(goal> N02)
|
---|
159 | self.assertTrue(goal<N043)
|
---|
160 |
|
---|
161 | def _findBestBid(self)->Bid:
|
---|
162 | bestvalue = Decimal(0)
|
---|
163 | best = None
|
---|
164 | for bid in AllBidsList(self.profile.getDomain()):
|
---|
165 | util = self.profile.getUtility(bid)
|
---|
166 | if util>bestvalue:
|
---|
167 | best = bid
|
---|
168 | bestvalue = util
|
---|
169 | return best #type:ignore
|
---|
170 |
|
---|
171 | def testPartyAcceptsWithDelay(self):
|
---|
172 | '''
|
---|
173 | Check that delay indeed waits
|
---|
174 |
|
---|
175 | @throws URISyntaxException
|
---|
176 | '''
|
---|
177 | self.party.connect(self.connection)
|
---|
178 |
|
---|
179 | settingsdelay = Settings(PartyId("party1"),
|
---|
180 | ProfileRef(URI("file:" + self.PROFILE)), self.protocol, self.progress,
|
---|
181 | self.parameters.With("delay", 2))
|
---|
182 |
|
---|
183 | self.party.notifyChange(settingsdelay);
|
---|
184 |
|
---|
185 | bid = self._findBestBid()
|
---|
186 | self.party.notifyChange(ActionDone(Offer(self.otherparty, bid)))
|
---|
187 | start = round(time.time()*1000)
|
---|
188 | self.party.notifyChange( YourTurn())
|
---|
189 | end = round(time.time()*1000)
|
---|
190 | self.assertEqual(1, len(self.connection.getActions()))
|
---|
191 | self.assertTrue(isinstance(self.connection.getActions()[0] , Accept))
|
---|
192 |
|
---|
193 | dt = end - start
|
---|
194 | self.assertTrue(dt >= 1000)
|
---|
195 | self.assertTrue(dt <= 3000)
|
---|
196 |
|
---|