[84] | 1 | from datetime import datetime
|
---|
| 2 | import json
|
---|
| 3 | from typing import List
|
---|
| 4 | import unittest
|
---|
| 5 | from unittest.mock import Mock
|
---|
| 6 |
|
---|
| 7 | from pyson.ObjectMapper import ObjectMapper
|
---|
| 8 | from unitpy.GeneralTests import GeneralTests
|
---|
| 9 |
|
---|
| 10 | from geniusweb.actions.Action import Action
|
---|
| 11 | from geniusweb.actions.PartyId import PartyId
|
---|
| 12 | from geniusweb.progress.Progress import Progress
|
---|
| 13 | from geniusweb.progress.ProgressTime import ProgressTime
|
---|
| 14 | from geniusweb.protocol.ProtocolException import ProtocolException
|
---|
| 15 | from geniusweb.protocol.session.TeamInfo import TeamInfo
|
---|
| 16 | from geniusweb.protocol.session.mopac.MOPACSettings import MOPACSettings
|
---|
| 17 | from geniusweb.protocol.session.mopac.MOPACState import MOPACState
|
---|
| 18 | from geniusweb.protocol.session.mopac.PartyStates import PartyStates
|
---|
| 19 | from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
|
---|
| 20 | from geniusweb.protocol.session.mopac.phase.Phase import PHASE_MAXTIME, Phase, \
|
---|
| 21 | PHASE_MINTIME
|
---|
| 22 | from geniusweb.references.Parameters import Parameters
|
---|
| 23 | from geniusweb.references.PartyWithParameters import PartyWithParameters
|
---|
| 24 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
| 25 | from geniusweb.references.ProfileRef import ProfileRef
|
---|
| 26 | from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
|
---|
| 27 |
|
---|
| 28 |
|
---|
| 29 | class MOPACStateTest (unittest.TestCase, GeneralTests[MOPACState]):
|
---|
| 30 | maxDiff=None
|
---|
| 31 |
|
---|
| 32 | NOW = datetime.fromtimestamp(1001/1000.)
|
---|
| 33 |
|
---|
| 34 | jackson = ObjectMapper()
|
---|
| 35 |
|
---|
| 36 | settings = Mock(MOPACSettings)
|
---|
| 37 |
|
---|
| 38 | state = MOPACState(None,[],None, settings, {})
|
---|
| 39 |
|
---|
| 40 | PARTY1 = PartyId("party1");
|
---|
| 41 | PARTY2 = PartyId("party2")
|
---|
| 42 | PARTY3 = PartyId("party3")
|
---|
| 43 |
|
---|
| 44 |
|
---|
| 45 | # copy from MopacSettingsTest. We need settings here but don't want to mock
|
---|
| 46 | # this large structure.
|
---|
| 47 | mopacsettingstr = "{\"MOPACSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}},{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}}";
|
---|
| 48 | # create real objects for the GeneralTests and for serialization tests
|
---|
| 49 | progress1 = ProgressTime(100, NOW)
|
---|
| 50 | progress2 = ProgressTime(200, NOW)
|
---|
| 51 |
|
---|
| 52 |
|
---|
| 53 | serialized = "{\"MOPACState\":{\"phase\":{\"OfferPhase\":{\"partyStates\":{\"powers\":{},\"notYetActed\":[],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{}},\"deadline\":100,\"evaluator\":{\"LargestAgreement\":{}}}},\"actions\":[],\"progress\":{\"ProgressTime\":{\"duration\":100,\"start\":1001}},\"settings\":{\"MOPACSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}},{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}},\"partyprofiles\":{}}}"
|
---|
| 54 |
|
---|
| 55 | def setUp(self):
|
---|
| 56 | self.partyparams1 = Mock(PartyWithParameters)
|
---|
| 57 | self.profile1 = PartyWithProfile(self.partyparams1,Mock(ProfileRef))
|
---|
| 58 | self.partyStates = PartyStates({})
|
---|
| 59 | self.phase1 = OfferPhase(self.partyStates, 100, LargestAgreement())
|
---|
| 60 | self.phase2 = OfferPhase(self.partyStates, 200, LargestAgreement())
|
---|
| 61 | self.params1 = Parameters().With("power", 2);
|
---|
| 62 | self.partyparams1.getParameters=Mock(return_value=self.params1)
|
---|
| 63 |
|
---|
| 64 | realsettings = self.jackson.parse(json.loads(self.mopacsettingstr), MOPACSettings)
|
---|
| 65 | party = Mock(TeamInfo)
|
---|
| 66 | pwithp = Mock(PartyWithParameters)
|
---|
| 67 | pwithp.getParameters=Mock(return_value= Parameters())
|
---|
| 68 | party.getParties=Mock(
|
---|
| 69 | return_value=[PartyWithProfile(pwithp, Mock(ProfileRef))])
|
---|
| 70 | party.getSize=Mock(return_value=1)
|
---|
| 71 | realsettings2 = realsettings.With(party)
|
---|
| 72 |
|
---|
| 73 | self.state1 = MOPACState(self.phase1, [], self.progress1, realsettings, {})
|
---|
| 74 | self.state1a = MOPACState(self.phase1, [], self.progress1, realsettings, {})
|
---|
| 75 | self.state2 = MOPACState(self.phase2, [], self.progress1, realsettings, {})
|
---|
| 76 | self.state3 = MOPACState(self.phase1, [Mock(Action)],
|
---|
| 77 | self.progress1, realsettings, {})
|
---|
| 78 | self.state4 = MOPACState(self.phase1, [], self.progress2,realsettings, {})
|
---|
| 79 | self.state5 = MOPACState(self.phase1, [], self.progress1,
|
---|
| 80 | realsettings2, {})
|
---|
| 81 | self.state6 = MOPACState(self.phase1, [], self.progress1,
|
---|
| 82 | realsettings,
|
---|
| 83 | {self.PARTY1: Mock(PartyWithProfile)})
|
---|
| 84 |
|
---|
| 85 |
|
---|
| 86 | def getGeneralTestData(self)-> List[List[MOPACState]] :
|
---|
| 87 | return [[self.state1, self.state1a],
|
---|
| 88 | [self.state2], [self.state3],
|
---|
| 89 | [self.state4], [self.state5],
|
---|
| 90 | [self.state6]]
|
---|
| 91 |
|
---|
| 92 | def getGeneralTestStrings(self)-> List[str]:
|
---|
| 93 | return [
|
---|
| 94 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
|
---|
| 95 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
|
---|
| 96 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
|
---|
| 97 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
|
---|
| 98 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
|
---|
| 99 | "MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*"]
|
---|
| 100 |
|
---|
| 101 | def testsmokeTest(self):
|
---|
| 102 | pass
|
---|
| 103 |
|
---|
| 104 | def testaddProfilesBeforeInit(self):
|
---|
| 105 | st = self.state.With(self.PARTY1, self.profile1)
|
---|
| 106 | self.assertTrue(self.PARTY1 in st.getPartyProfiles())
|
---|
| 107 |
|
---|
| 108 | def testInit(self):
|
---|
| 109 | # no parties were added, should throw? Go to final mode?
|
---|
| 110 | # Notice that it's possible to create settings with 0 participants,
|
---|
| 111 | # because this is needed for Tournament mechanism.
|
---|
| 112 | state1 = self.state.initPhase(ProgressTime(100,datetime.fromtimestamp(0)),
|
---|
| 113 | 1)
|
---|
| 114 | self.assertEqual(0, len(state1.getActions()))
|
---|
| 115 | self.assertEqual(0, len(state1.getAgreements().getMap()))
|
---|
| 116 | self.assertEqual(0, len(state1.getPartyProfiles()))
|
---|
| 117 | phase1 = state1.getPhase()
|
---|
| 118 | self.assertTrue(isinstance(phase1,OfferPhase))
|
---|
| 119 | offer1 = phase1
|
---|
| 120 | self.assertEqual(PartyStates({}), offer1.getPartyStates())
|
---|
| 121 |
|
---|
| 122 | def testgetAgreementsTest(self):
|
---|
| 123 | st = self.state.initPhase(ProgressTime(100, datetime.fromtimestamp(0)), 1)
|
---|
| 124 | self.assertEqual(0, len(st.getAgreements().getMap()))
|
---|
| 125 |
|
---|
| 126 | def testDeserialize(self):
|
---|
| 127 | obj = self.jackson.parse(json.loads(self.serialized), MOPACState)
|
---|
| 128 | print(obj)
|
---|
| 129 | self.assertEqual(self.state1, obj)
|
---|
| 130 |
|
---|
| 131 | def testSerialize(self):
|
---|
| 132 | jsonobj = self.jackson.toJson(self.state1)
|
---|
| 133 | print(jsonobj)
|
---|
| 134 | self.assertEqual(json.loads(self.serialized), jsonobj)
|
---|
| 135 |
|
---|
| 136 | def testNewPhasePossible(self):
|
---|
| 137 | phase = Mock(Phase)
|
---|
| 138 | actions = []
|
---|
| 139 | progress = Mock(Progress)
|
---|
| 140 | progress.getTerminationTime=Mock(return_value=
|
---|
| 141 | datetime.fromtimestamp(PHASE_MAXTIME/1000.)) # plenty for new phase
|
---|
| 142 | def checkargs(*args, **kwargs):
|
---|
| 143 | if args[0]==10 + PHASE_MINTIME:
|
---|
| 144 | return False
|
---|
| 145 | raise ValueError("unexpected arg");
|
---|
| 146 |
|
---|
| 147 |
|
---|
| 148 | progress.isPastDeadline.side_effect=checkargs
|
---|
| 149 |
|
---|
| 150 | partyprofiles = {}
|
---|
| 151 | s1 = MOPACState(phase, actions, progress, self.settings,
|
---|
| 152 | partyprofiles)
|
---|
| 153 |
|
---|
| 154 | states = Mock(PartyStates)
|
---|
| 155 | phase.getPartyStates=Mock(return_value=states)
|
---|
| 156 | states.getNegotiatingParties=Mock(return_value=
|
---|
| 157 | set([self.PARTY1, self.PARTY2]))
|
---|
| 158 | self.assertTrue(s1.isNewPhasePossible(10))
|
---|
| 159 |
|
---|
| 160 | def testNewPhasePossibleOnly1Party(self):
|
---|
| 161 | phase = Mock(Phase)
|
---|
| 162 | actions = []
|
---|
| 163 | progress = Mock(Progress)
|
---|
| 164 | progress.getTerminationTime=Mock(
|
---|
| 165 | return_value=datetime.fromtimestamp(PHASE_MAXTIME/1000.))
|
---|
| 166 | # plenty for new phase
|
---|
| 167 |
|
---|
| 168 | def checkargs(*args, **kwargs):
|
---|
| 169 | if args[0]==10 + PHASE_MINTIME:
|
---|
| 170 | return False
|
---|
| 171 | raise ValueError("unexpected arg");
|
---|
| 172 |
|
---|
| 173 |
|
---|
| 174 | progress.isPastDeadline.side_effect=checkargs
|
---|
| 175 |
|
---|
| 176 | partyprofiles = {}
|
---|
| 177 | s1 = MOPACState(phase, actions, progress, self.settings,
|
---|
| 178 | partyprofiles)
|
---|
| 179 |
|
---|
| 180 | states = Mock(PartyStates)
|
---|
| 181 | phase.getPartyStates=Mock(return_value=states)
|
---|
| 182 | states.getNegotiatingParties=Mock(return_value=
|
---|
| 183 | set([self.PARTY1]))
|
---|
| 184 | self.assertFalse(s1.isNewPhasePossible(10))
|
---|
| 185 |
|
---|
| 186 | def testNewPhasePossibleNotEnoughTime(self):
|
---|
| 187 | phase = Mock(Phase)
|
---|
| 188 | actions = []
|
---|
| 189 | progress = Mock(Progress)
|
---|
| 190 | progress.getTerminationTime=Mock(
|
---|
| 191 | return_value=datetime.fromtimestamp((PHASE_MINTIME - 10)/1000.))
|
---|
| 192 | partyprofiles = {}
|
---|
| 193 | s1 = MOPACState(phase, actions, progress, self.settings,
|
---|
| 194 | partyprofiles)
|
---|
| 195 |
|
---|
| 196 | states = Mock(PartyStates)
|
---|
| 197 | phase.getPartyStates=Mock(return_value=states)
|
---|
| 198 | states.getNegotiatingParties=Mock(return_value=
|
---|
| 199 | set([self.PARTY1]))
|
---|
| 200 | self.assertFalse(s1.isNewPhasePossible(10))
|
---|
| 201 |
|
---|
| 202 | def testnextPhaseTest(self):
|
---|
| 203 | NOW = 102;
|
---|
| 204 | phase = Mock(Phase)
|
---|
| 205 | actions = []
|
---|
| 206 | progress = Mock(Progress)
|
---|
| 207 | progress.getTerminationTime=Mock(return_value=
|
---|
| 208 | datetime.fromtimestamp(PHASE_MAXTIME/1000.))
|
---|
| 209 | partyprofiles = {}
|
---|
| 210 | s1 = MOPACState(phase, actions, progress, self.settings,
|
---|
| 211 | partyprofiles)
|
---|
| 212 |
|
---|
| 213 | # PhaseB is the next phase, with remaining time
|
---|
| 214 | phaseB = Mock(Phase)
|
---|
| 215 |
|
---|
| 216 | def checkargs(*args, **kwargs):
|
---|
| 217 | if args[0]==NOW and args[1]==PHASE_MAXTIME-NOW:
|
---|
| 218 | return phaseB
|
---|
| 219 | raise ValueError("unexpected args")
|
---|
| 220 |
|
---|
| 221 | phase.next.side_effect=checkargs
|
---|
| 222 |
|
---|
| 223 | s2 = s1.nextPhase(NOW)
|
---|
| 224 | self.assertEquals(phaseB, s2.getPhase())
|
---|
| 225 |
|
---|
| 226 | def testexceptionTest(self):
|
---|
| 227 | phase = Mock(Phase)
|
---|
| 228 | actions = []
|
---|
| 229 | progress = Mock(Progress)
|
---|
| 230 |
|
---|
| 231 | partyprofiles = {}
|
---|
| 232 | s1 = MOPACState(phase, actions, progress, self.settings,
|
---|
| 233 | partyprofiles)
|
---|
| 234 |
|
---|
| 235 | exphase = Mock(Phase); # supposed phase that contains the exception
|
---|
| 236 |
|
---|
| 237 | def checkargs(*args, **kwargs):
|
---|
| 238 | if isinstance(args[0], ProtocolException):
|
---|
| 239 | return exphase
|
---|
| 240 | raise ValueError("expected ProtocolException")
|
---|
| 241 |
|
---|
| 242 | phase.WithException.side_effect=checkargs
|
---|
| 243 |
|
---|
| 244 | errstate = s1.WithException(ProtocolException("test", self.PARTY1))
|
---|
| 245 | self.assertEqual(exphase, errstate.getPhase())
|
---|
| 246 | self.assertEqual(progress, errstate.getProgress())
|
---|