source: src/test/java/negotiator/protocol/AlternatingMultipleOffersProtocolTest.java

Last change on this file was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 13.4 KB
RevLine 
[1]1package negotiator.protocol;
2
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertFalse;
5import static org.junit.Assert.assertNull;
6import static org.junit.Assert.assertTrue;
7import static org.mockito.Matchers.eq;
8import static org.mockito.Mockito.mock;
9import static org.mockito.Mockito.times;
10import static org.mockito.Mockito.verify;
11import static org.mockito.Mockito.when;
12
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.List;
16
17import org.junit.Before;
18import org.junit.Test;
19import org.mockito.Mockito;
20
21import genius.core.AgentID;
22import genius.core.Bid;
23import genius.core.Domain;
24import genius.core.actions.Accept;
25import genius.core.actions.Action;
26import genius.core.actions.Offer;
27import genius.core.actions.OfferForVoting;
28import genius.core.actions.Reject;
29import genius.core.parties.NegotiationParty;
30import genius.core.protocol.AlternatingMultipleOffersProtocol;
31import genius.core.session.Round;
32import genius.core.session.Session;
33import genius.core.session.Turn;
34
35public class AlternatingMultipleOffersProtocolTest {
36
37 protected AlternatingMultipleOffersProtocol protocol;
38 private static AgentID AGENTID = new AgentID("test");
39 private static Bid receivedBid = mock(Bid.class);
40
41 private static int VOTING_ROUND = 0;
42 private static int OFFER_ROUND = 1;
43 private static int VOTING_ROUND_2 = 2;
44
45 protected static Action ACCEPT = new Accept(AGENTID, receivedBid);
46 protected static Action REJECT = new Reject(AGENTID, receivedBid);
47
48 Session session = mock(Session.class);
49 protected ArrayList<NegotiationParty> parties;
50 private NegotiationParty party1;
51 private NegotiationParty party2;
52 private NegotiationParty party3;
53
54 @Before
55 public void init() {
56
57 protocol = mock(getProtocol(), Mockito.CALLS_REAL_METHODS);
58
59 parties = new ArrayList<NegotiationParty>();
60 party1 = mock(NegotiationParty.class);
61 party2 = mock(NegotiationParty.class);
62 party3 = mock(NegotiationParty.class);
63
64 parties.add(party1);
65 parties.add(party2);
66 parties.add(party3);
67
68 }
69
70 protected Class<? extends AlternatingMultipleOffersProtocol> getProtocol() {
71 return AlternatingMultipleOffersProtocol.class;
72 }
73
74 @Test
75 public void testGetRoundStructureVotingRound() {
76 when(session.getRoundNumber()).thenReturn(VOTING_ROUND_2);
77
78 Round round = protocol.getRoundStructure(parties, session);
79
80 // check that there were created for each party one turn for an offer
81 verify(protocol, times(1)).createTurn(eq(party1), eq(OfferForVoting.class));
82 verify(protocol, times(1)).createTurn(eq(party2), eq(OfferForVoting.class));
83 verify(protocol, times(1)).createTurn(eq(party3), eq(OfferForVoting.class));
84
85 // check that round contains 3 turns and that they are associated to our
86 // parties.
87 assertEquals(3, round.getTurns().size());
88 assertEquals(party1, round.getTurns().get(0).getParty());
89 assertEquals(party2, round.getTurns().get(1).getParty());
90 assertEquals(party3, round.getTurns().get(2).getParty());
91
92 }
93
94 @Test
95 public void testGetRoundStructureOfferRound() {
96 when(session.getRoundNumber()).thenReturn(OFFER_ROUND);
97
98 // the specs has poor type, that's why we have it here too.
99 Collection<Class<? extends Action>> acceptOrReject = new ArrayList<Class<? extends Action>>(2);
100 acceptOrReject.add(Accept.class);
101 acceptOrReject.add(Reject.class);
102
103 Round round = protocol.getRoundStructure(parties, session);
104
105 // check that everyone has 3 votes, one for each proposal.
106 verify(protocol, times(3)).createTurn(eq(party1), eq(acceptOrReject));
107 verify(protocol, times(3)).createTurn(eq(party2), eq(acceptOrReject));
108 verify(protocol, times(3)).createTurn(eq(party3), eq(acceptOrReject));
109
110 // check that round contains 9 turns (3 parties * 3 votes) and that they
111 // are associated correctly to our parties.
112 assertEquals(9, round.getTurns().size());
113 assertEquals(party1, round.getTurns().get(0).getParty());
114 assertEquals(party2, round.getTurns().get(1).getParty());
115 assertEquals(party3, round.getTurns().get(2).getParty());
116 assertEquals(party1, round.getTurns().get(3).getParty());
117 assertEquals(party2, round.getTurns().get(4).getParty());
118 assertEquals(party3, round.getTurns().get(5).getParty());
119 assertEquals(party1, round.getTurns().get(6).getParty());
120 assertEquals(party2, round.getTurns().get(7).getParty());
121 assertEquals(party3, round.getTurns().get(8).getParty());
122
123 }
124
125 /**
126 * Call isFinished when in round 0 (initial situation). The round should not
127 * be finished, nothing happened yet. FAILS because
128 * get(session.getRoundNumber() - 2) in the isFinished code will give
129 * indexOutOfBoundsException.
130 */
131 @Test
132 public void isFinishedTestVoting() {
133 when(session.getRoundNumber()).thenReturn(VOTING_ROUND);
134 when(session.getRounds()).thenReturn(new ArrayList<Round>());
135 assertFalse(protocol.isFinished(session, parties));
136 assertNull(protocol.getCurrentAgreement(session, parties));
137 }
138
139 /**
140 * Call isFinished when in round 1
141 */
142 @Test
143 public void isFinishedTestNonVoting() {
144 when(session.getRoundNumber()).thenReturn(OFFER_ROUND);
145 assertFalse(protocol.isFinished(session, parties));
146 assertNull(protocol.getCurrentAgreement(session, parties));
147 }
148
149 /**
150 * Call isFinished when in round OFFER_ROUND+2 which is an offer round too.
151 */
152 @Test
153 public void isFinishedTestNonVotingRound() {
154 when(session.getRoundNumber()).thenReturn(OFFER_ROUND + 2);
155 assertFalse(protocol.isFinished(session, parties));
156 }
157
158 /**
159 * call isFinished when in round 2. The round should not be finished,
160 * nothing happened yet.
161 */
162 @Test
163 public void isFinishedTestVoting2() {
164 when(session.getRoundNumber()).thenReturn(VOTING_ROUND_2);
165 Round round1 = mock(Round.class);
166 ArrayList<Turn> turns1 = new ArrayList<Turn>();
167 for (int n = 0; n < 3; n++)
168 turns1.add(mock(Turn.class));
169 when(round1.getTurns()).thenReturn(turns1);
170
171 Round round2 = mock(Round.class);
172 ArrayList<Turn> turns = new ArrayList<Turn>();
173 when(round2.getTurns()).thenReturn(turns);
174 ArrayList<Round> rounds = new ArrayList<Round>();
175 rounds.add(round2);
176 when(session.getRounds()).thenReturn(rounds);
177 when(session.getMostRecentRound()).thenReturn(round2);
178
179 assertFalse(protocol.isFinished(session, parties));
180 }
181
182 @Test
183 public void testIsFinishedWithIncompleteAcceptVotes() {
184
185 // We need at least two rounds for a finish.
186 List<Round> rounds = new ArrayList<Round>();
187
188 // 3 turns is apparently insufficient. Not clear why.
189 // but protocol.isFinished should not crash on that.
190 Offer firstoffer = offer();
191 rounds.add(mockedRound(new Action[] { firstoffer, offer(), offer() }));
192 // incomplete: only votes for bid 1.
193 Round voteRound = mockedRound(new Action[] { ACCEPT, ACCEPT, ACCEPT });
194 rounds.add(voteRound);
195
196 when(session.getMostRecentRound()).thenReturn(voteRound);
197 when(session.getRounds()).thenReturn(rounds);
198
199 // we have round 0 and 1 done
200 when(session.getRoundNumber()).thenReturn(2);
201 when(session.getRounds()).thenReturn(rounds);
202
203 assertTrue(protocol.isFinished(session, parties));
204 assertEquals(firstoffer.getBid(), protocol.getCurrentAgreement(session, parties));
205 }
206
207 @Test
208 public void testIsNotFinishedWithIncompleteVotes() {
209
210 // We need at least two rounds for a finish.
211 List<Round> rounds = new ArrayList<Round>();
212
213 // 3 turns is apparently insufficient. Not clear why.
214 // but protocol.isFinished should not crash on that.
215 rounds.add(mockedRound(new Action[] { offer(), offer(), offer() }));
216 // incomplete: only votes for bid 1.
217 Round voteRound = mockedRound(new Action[] { REJECT, ACCEPT, ACCEPT });
218 rounds.add(voteRound);
219
220 when(session.getMostRecentRound()).thenReturn(voteRound);
221 when(session.getRounds()).thenReturn(rounds);
222
223 // we have round 0 and 1 done
224 when(session.getRoundNumber()).thenReturn(2);
225 when(session.getRounds()).thenReturn(rounds);
226
227 assertFalse(protocol.isFinished(session, parties));
228 assertEquals(null, protocol.getCurrentAgreement(session, parties));
229 }
230
231 @Test
232 public void testIsFinishedWithIncompleteAcceptVotes2() {
233
234 // We need at least two rounds for a finish.
235 List<Round> rounds = new ArrayList<Round>();
236
237 Offer firstoffer = offer();
238 rounds.add(mockedRound(new Action[] { firstoffer, offer(), offer() }));
239 // incomplete: only votes for bid 1 plus 1 extra.
240 Round voteRound = mockedRound(new Action[] { ACCEPT, ACCEPT, ACCEPT, ACCEPT });
241 rounds.add(voteRound);
242
243 when(session.getMostRecentRound()).thenReturn(voteRound);
244 when(session.getRounds()).thenReturn(rounds);
245
246 // we have round 0 and 1 done
247 when(session.getRoundNumber()).thenReturn(2);
248 when(session.getRounds()).thenReturn(rounds);
249
250 assertTrue(protocol.isFinished(session, parties));
251 assertEquals(firstoffer.getBid(), protocol.getCurrentAgreement(session, parties));
252 }
253
254 @Test
255 public void testIsFinishedWithTooFewVotes() {
256
257 // We need at least two rounds for a finish.
258 List<Round> rounds = new ArrayList<Round>();
259
260 Offer firstoffer = offer();
261 rounds.add(mockedRound(new Action[] { firstoffer, offer(), offer() }));
262 // incomplete: not even enough to judge the first offer.
263 Round voteRound = mockedRound(new Action[] { ACCEPT, ACCEPT });
264 rounds.add(voteRound);
265
266 when(session.getMostRecentRound()).thenReturn(voteRound);
267 when(session.getRounds()).thenReturn(rounds);
268
269 // we have round 0 and 1 done
270 when(session.getRoundNumber()).thenReturn(2);
271 when(session.getRounds()).thenReturn(rounds);
272
273 assertFalse(protocol.isFinished(session, parties));
274 assertNull(protocol.getCurrentAgreement(session, parties));
275 }
276
277 protected Offer offer() {
278 Bid bid = new Bid(mock(Domain.class));
279 Offer offer = new Offer(AGENTID, bid);
280 return offer;
281 }
282
283 /**
284 * isFinished expects offers round, then vote round. But should bee robust
285 * for it
286 */
287 @Test(expected = IllegalArgumentException.class)
288 public void testIsFinishedWithVoteRoundsOnly() {
289
290 // We need at least two rounds for a finish.
291 List<Round> rounds = new ArrayList<Round>();
292
293 Round voteRound = mockedRound(new Action[] { ACCEPT, ACCEPT, ACCEPT });
294 rounds.add(voteRound);
295 rounds.add(voteRound);
296
297 when(session.getMostRecentRound()).thenReturn(voteRound);
298 when(session.getRounds()).thenReturn(rounds);
299
300 // we have round 0 and 1 done
301 when(session.getRoundNumber()).thenReturn(2);
302 when(session.getRounds()).thenReturn(rounds);
303
304 assertTrue(protocol.isFinished(session, null));
305 }
306
307 @Test
308 public void testIsFinishedWithCompleteAcceptVotes() {
309
310 // We need at least two rounds for a finish.
311 List<Round> rounds = new ArrayList<Round>();
312
313 // 3 turns is apparently insufficient. Not clear why.
314 // but protocol.isFinished should not crash on that.
315 Offer firstoffer = offer();
316 rounds.add(mockedRound(new Action[] { firstoffer, offer(), offer() }));
317 Round voteround = mockedRound(
318 new Action[] { ACCEPT, ACCEPT, ACCEPT, ACCEPT, ACCEPT, ACCEPT, ACCEPT, ACCEPT, ACCEPT });
319 rounds.add(voteround);
320
321 when(session.getMostRecentRound()).thenReturn(voteround);
322 when(session.getRounds()).thenReturn(rounds);
323
324 // we have round 0 and 1 done
325 when(session.getRoundNumber()).thenReturn(2);
326 when(session.getRounds()).thenReturn(rounds);
327
328 assertTrue(protocol.isFinished(session, parties));
329 assertEquals(firstoffer.getBid(), protocol.getCurrentAgreement(session, parties));
330 }
331
332 @Test
333 public void testAcceptSecondOffer() {
334
335 // We need at least two rounds for a finish.
336 List<Round> rounds = new ArrayList<Round>();
337
338 // 3 turns is apparently insufficient. Not clear why.
339 // but protocol.isFinished should not crash on that.
340 Offer acceptedoffer = offer();
341 rounds.add(mockedRound(new Action[] { offer(), acceptedoffer, offer() }));
342 Round voteround = mockedRound(
343 new Action[] { ACCEPT, ACCEPT, REJECT, ACCEPT, ACCEPT, ACCEPT, REJECT, ACCEPT, ACCEPT });
344 rounds.add(voteround);
345
346 when(session.getMostRecentRound()).thenReturn(voteround);
347 when(session.getRounds()).thenReturn(rounds);
348
349 // we have round 0 and 1 done
350 when(session.getRoundNumber()).thenReturn(2);
351 when(session.getRounds()).thenReturn(rounds);
352
353 assertTrue(protocol.isFinished(session, parties));
354 assertEquals(acceptedoffer.getBid(), protocol.getCurrentAgreement(session, parties));
355 }
356
357 @Test
358 public void testIsFinishedWithIncompleteRejectVotes() {
359
360 // We need at least two rounds for a finish.
361 List<Round> rounds = new ArrayList<Round>();
362
363 // 3 turns is apparently insufficient. Not clear why.
364 // but protocol.isFinished should not crash on that.
365 rounds.add(mockedRound(mock(Offer.class)));
366 Round voteRound = mockedRound(new Action[] { REJECT, REJECT, REJECT });
367 rounds.add(voteRound);
368
369 when(session.getMostRecentRound()).thenReturn(voteRound);
370 when(session.getRounds()).thenReturn(rounds);
371
372 // we have round 0 and 1 done
373 when(session.getRoundNumber()).thenReturn(2);
374 when(session.getRounds()).thenReturn(rounds);
375
376 assertFalse(protocol.isFinished(session, parties));
377 assertNull(protocol.getCurrentAgreement(session, parties));
378 }
379
380 /**
381 * @param action
382 * the action to return for each of the turns in the action. Must
383 * be real action , not a mock, as the protocol compares uses
384 * instanceof to test action types
385 * @return Mocked {@link Round}.
386 */
387 protected Round mockedRound(Action... actions) {
388 Round round = mock(Round.class);
389 List<Action> actionslist = new ArrayList<Action>();
390 List<Turn> turns = new ArrayList<Turn>();
391 for (int t = 0; t < actions.length; t++) {
392 Action action = actions[t];
393 Turn turn = mock(Turn.class);
394 when(turn.getAction()).thenReturn(action);
395 turns.add(turn);
396 actionslist.add(action);
397 }
398 when(round.getTurns()).thenReturn(turns);
399 when(round.getActions()).thenReturn(actionslist);
400 return round;
401 }
402
403}
Note: See TracBrowser for help on using the repository browser.