package geniusweb.exampleparties.simpleshaop; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import geniusweb.actions.Accept; import geniusweb.actions.Action; import geniusweb.actions.Comparison; import geniusweb.actions.ElicitComparison; import geniusweb.actions.EndNegotiation; import geniusweb.actions.Offer; import geniusweb.actions.PartyId; import geniusweb.connection.ConnectionEnd; import geniusweb.inform.ActionDone; import geniusweb.inform.Agreements; import geniusweb.inform.Finished; import geniusweb.inform.Inform; import geniusweb.inform.Settings; import geniusweb.inform.YourTurn; import geniusweb.issuevalue.Bid; import geniusweb.issuevalue.DiscreteValue; import geniusweb.issuevalue.Value; import geniusweb.party.Capabilities; import geniusweb.profile.DefaultPartialOrdering; import geniusweb.profile.Profile; import geniusweb.progress.ProgressRounds; import geniusweb.references.Parameters; import geniusweb.references.ProfileRef; import geniusweb.references.ProtocolRef; import geniusweb.references.Reference; import tudelft.utilities.listener.DefaultListenable; import tudelft.utilities.logging.Reporter; public class AngelPartyTest { private static final String SHAOP = "SHAOP"; private static final PartyId angel = new PartyId("Angel"); private static final PartyId otherparty = new PartyId("other"); private static final String PROFILE = "src/test/resources/testprofile.json"; private static final String PROFILE2 = "src/test/resources/testprofile2.json"; private static final String PROFILE3 = "src/test/resources/testprofile3.json"; private final static ObjectMapper jackson = new ObjectMapper(); private AngelParty party; private AngelParty opp; private final TestConnection connection = new TestConnection(); private final ProtocolRef protocol = mock(ProtocolRef.class); private Integer T = 10; private Integer t = 0; private Date deadline = new Date(); // private final ProgressRounds progress = new ProgressRounds(T, t, deadline); // // This was mock(ProgressRounds.class); private final ProgressRounds progress = mock(ProgressRounds.class); private Settings settings; private Settings settings2; private Profile profile; private Profile profile2; private Profile profile3; private final Parameters parameters = new Parameters().with("elicitationcost", 0.05); @Before public void before() throws JsonParseException, JsonMappingException, IOException, URISyntaxException { party = new AngelParty(); opp = new AngelParty(); settings = new Settings(new PartyId("party1"), new ProfileRef(new URI("file:" + PROFILE3)), protocol, progress, parameters); settings2 = new Settings(new PartyId("party2"), new ProfileRef(new URI("file:" + PROFILE2)), protocol, progress, parameters); String serialized = new String(Files.readAllBytes(Paths.get(PROFILE3)), StandardCharsets.UTF_8); profile3 = jackson.readValue(serialized, Profile.class); serialized = new String(Files.readAllBytes(Paths.get(PROFILE2)), StandardCharsets.UTF_8); profile2 = jackson.readValue(serialized, Profile.class); } @Test public void smokeTest() { } @Test public void getDescriptionTest() { assertNotNull(party.getDescription()); } @Test public void getCapabilitiesTest() { Capabilities capabilities = party.getCapabilities(); assertFalse("party does not define protocols", capabilities.getBehaviours().isEmpty()); } @Test public void testInformConnection() { // Good to go party.connect(connection); // agent should not start acting just after an inform assertEquals(0, connection.getActions().size()); } @Test public void testInformSettings() { // Good to go party.connect(connection); connection.notifyListeners(settings); assertEquals(0, connection.getActions().size()); } @Test public void testInformAndConnection() { // Good to go party.connect(connection); party.notifyChange(settings); assertEquals(0, connection.getActions().size()); } @Test public void testOtherWalksAway() { // Good to go party.connect(connection); party.notifyChange(settings); party.notifyChange(new ActionDone(new EndNegotiation(otherparty))); // party should not act at this point assertEquals(0, connection.getActions().size()); } @Test // Good to go public void testAgentHasFirstTurn() { party.connect(connection); party.notifyChange(settings); party.notifyChange(new YourTurn()); assertEquals(1, connection.getActions().size()); assertTrue(connection.getActions().get(0) instanceof Offer); } @Ignore // This method for testing acceptance is from the simple shaop agent, it is not // applicable to angel. @Test public void testAgentElicitsComparison() { party.connect(connection); party.notifyChange(settings); Bid bid = makeBid("3", "3"); // not yet in profile party.notifyChange(new ActionDone(new Offer(otherparty, bid))); party.notifyChange(new YourTurn()); assertEquals(1, connection.getActions().size()); assertTrue(connection.getActions().get(0) instanceof ElicitComparison); } @Ignore // This method for testing acceptance is from the simple shaop agent, it is not // applicable to angel. @Test public void testAgentAccepts() { // to make agent accept, the offered bid must score >0.9 // we would need to mock a lot t make that happen // as we need to place >10 comparable bids for that. party.connect(connection); party.notifyChange(settings); Bid bid = makeBid("1", "1");// best possible party.notifyChange(new ActionDone(new Offer(otherparty, bid))); party.notifyChange(new YourTurn()); assertEquals(1, connection.getActions().size()); assertTrue(connection.getActions().get(0) instanceof Accept); } @Test public void testAgentLogsFinal() { // Good to go // this log output is optional, this is to show how to check log Reporter reporter = mock(Reporter.class); party = new AngelParty(reporter); party.connect(connection); party.notifyChange(settings); party.notifyChange(new Finished(new Agreements())); verify(reporter).log(eq(Level.INFO), eq("Final ourcome:Finished[Agreements{}]")); } @Test public void testAgentsUpdatesProgress() { // Good to go party.connect(connection); party.notifyChange(settings); party.notifyChange(new ActionDone(new Offer(null, mock(Bid.class)))); party.notifyChange(new YourTurn()); verify(progress).advance(); } @Test public void testGetCapabilities() { // Good to go assertTrue(party.getCapabilities().getBehaviours().contains(SHAOP)); } private Bid makeBid(String val1, String val2) { Map map = new HashMap<>(); map.put("iss1", new DiscreteValue(val1)); map.put("iss2", new DiscreteValue(val2)); return new Bid(map); } private Bid getWorstBid() { Map map = new HashMap<>(); map.put("iss1", new DiscreteValue("4")); map.put("iss2", new DiscreteValue("4")); return new Bid(map); } // ***********************TESTING NEW THINGS********************************* @Test public void testMultiRounds() { // System.out.println("\n\n\n\n\n"); // System.out.println("***********BEGIN NEGOTIATION**********"); party.connect(connection); opp.connect(connection); party.notifyChange(settings); opp.notifyChange(settings2); opp.notifyChange(new YourTurn()); AngelParty current; for (int t = 0; t < 21; t++) { int numActions = connection.getActions().size(); // System.out.println("\n***turn="+t+" numActions="+numActions+"***"); Action a = connection.getActions().get(numActions - 1); if (a instanceof Accept) { Finished fin = new Finished( new Agreements(((Accept) a).getBid(), new HashSet<>(Arrays.asList(angel, otherparty)))); party.notifyChange(fin); opp.notifyChange(fin); break; } if ((t % 2 == 0)) { party.notifyChange(new ActionDone(a)); party.notifyChange(new YourTurn()); numActions = connection.getActions().size(); Action acted = connection.getActions().get(numActions - 1); while (acted instanceof ElicitComparison) { Bid bid = ((ElicitComparison) acted).getBid(); List options = ((ElicitComparison) acted).getOptions(); List better = new LinkedList(); List worse = new LinkedList(); DefaultPartialOrdering prof = (DefaultPartialOrdering) profile3; for (Bid cbid : options) { if (prof.isPreferredOrEqual(cbid, bid)) { better.add(cbid); } else { worse.add(cbid); } } party.notifyChange(new ActionDone(new Comparison(angel, bid, better, worse))); numActions = connection.getActions().size(); acted = connection.getActions().get(numActions - 1); } } else { opp.notifyChange(new ActionDone(a)); opp.notifyChange(new YourTurn()); numActions = connection.getActions().size(); Action acted = connection.getActions().get(numActions - 1); while (acted instanceof ElicitComparison) { Bid bid = ((ElicitComparison) acted).getBid(); List options = ((ElicitComparison) acted).getOptions(); List better = new LinkedList(); List worse = new LinkedList(); DefaultPartialOrdering prof = (DefaultPartialOrdering) profile2; for (Bid cbid : options) { if (prof.isPreferredOrEqual(cbid, bid)) { better.add(cbid); } else { worse.add(cbid); } } opp.notifyChange(new ActionDone(new Comparison(otherparty, bid, better, worse))); numActions = connection.getActions().size(); acted = connection.getActions().get(numActions - 1); } } } // System.out.println("***********END NEGOTIATION**********"); // System.out.println("\n\n\n\n\n"); } } /** * A "real" connection object, because the party is going to subscribe etc, and * without a real connection we would have to do a lot of mocks that would make * the test very hard to read. * */ class TestConnection extends DefaultListenable implements ConnectionEnd { private List actions = new LinkedList<>(); @Override public void send(Action action) throws IOException { actions.add(action); } @Override public Reference getReference() { return null; } @Override public URI getRemoteURI() { return null; } @Override public void close() { } @Override public Error getError() { return null; } public List getActions() { return actions; } }