[84] | 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 |
|
---|