/* * Copyright: Almende B.V. (2014), Rotterdam, The Netherlands * License: The Apache Software License, Version 2.0 */ package com.almende.eve.test; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import junit.framework.TestCase; import org.joda.time.DateTime; import org.joda.time.Duration; import org.junit.Test; import com.almende.eve.agent.AgentBuilder; import com.almende.eve.agent.AgentConfig; import com.almende.eve.agent.ExampleAgent; import com.almende.eve.agent.TestScaleAgent; import com.almende.eve.protocol.jsonrpc.formats.JSONRequest; import com.almende.eve.protocol.jsonrpc.formats.Params; import com.almende.eve.state.file.FileStateConfig; import com.almende.util.TypeUtil; import com.almende.util.callback.AsyncCallback; /** * The Class TestScale. */ public class TestScale extends TestCase { private static final Logger LOG = Logger.getLogger(TestScale.class .getName()); /** * Test Scale. * * @throws IOException * Signals that an I/O exception has occurred. * @throws URISyntaxException * the URI syntax exception * @throws InterruptedException * the interrupted exception */ @Test public void testScale() throws IOException, URISyntaxException, InterruptedException { AgentConfig config = AgentConfig.create(); FileStateConfig filestateconfig = FileStateConfig.create(); filestateconfig.setPath(".scaleTest"); config.setState(filestateconfig); TestScaleAgent top = new TestScaleAgent("top", config, null, new ArrayList<Integer>()); List<Integer> left = new ArrayList<Integer>(); left.add(20); left.add(10); List<Integer> right = new ArrayList<Integer>(); right.add(3); right.add(3); right.add(3); right.add(30); final long start = System.currentTimeMillis(); LOG.warning("Starting!" + start); new TestScaleAgent("left", config, top.getUrls().get(0), left); TestScaleAgent rightAgent = new TestScaleAgent("right", config, top .getUrls().get(0), right); final long created = System.currentTimeMillis(); LOG.warning("Created!" + created + "(" + (created - start) + " ms)"); List<URI> leafs = rightAgent.getAllLeafs(); assertEquals(3 * 270, leafs.size()); final long end = System.currentTimeMillis(); LOG.warning("Done!" + end + "(" + (end - created) + " ms)"); Thread.sleep(50000); } private void runTest(final int duration, final int parallel, final String test) { final Thread[] threads = new Thread[parallel]; final Long[] reports = new Long[parallel]; final String[] strings = new String[parallel]; final TypeUtil<String> stringType = new TypeUtil<String>() {}; final ExampleAgent[] agents = new ExampleAgent[parallel*2]; for (int i = 0; i< parallel; i++){ agents[i] = genAgent(); agents[parallel+i] = genAgent(); } final Boolean[] stop = new Boolean[] { false }; for (int i = 0; i < parallel; i++) { final int j = i; reports[i] = -1L; threads[i] = new Thread(new Runnable() { @Override public void run() { final DateTime start = DateTime.now(); long counter = 0; String res = ""; URI sender = agents[0].getUrls().get(0); switch (test) { case "direct": while (!stop[0]) { res = agents[0] .helloWorld("round:" + counter++); } break; case "rpcdirect": while(!stop[0]){ final Params params = new Params("message", "round:" + counter++); agents[0].receive(new JSONRequest("helloWorld",params), sender, null); } break; case "sync": final URI peer = agents[1].getUrls().get(0); while (!stop[0]) { final Params params = new Params("message", "round:" + counter++); try { res = agents[0].pubSendSync(peer, "helloWorld", params, stringType); } catch (IOException e) { LOG.log(Level.WARNING, "failed to communicate", e); } } break; case "async": case "multi": final long[] cnt = new long[] { 0L }; final String[] ress = new String[] { res }; int senderId = 0; int receiverId = 1; if ("multi".equals(test)){ senderId = j; receiverId = parallel+j; } final ExampleAgent agent = agents[senderId]; final URI peeruri = agents[receiverId].getUrls().get(0); final AsyncCallback<String> callback = new AsyncCallback<String>( stringType) { @Override public void onSuccess(final String result) { if (!stop[0]) { ress[0] = result; final Params params = new Params( "message", "round:" + cnt[0]++); try { agent.pubSend(peeruri, "helloWorld", params, this); } catch (IOException e) { LOG.log(Level.WARNING, "failed to communicate", e); } } else { final DateTime finish = DateTime.now(); final Duration duration = new Duration( start, finish); reports[j] = (cnt[0] * 1000 / duration .getMillis()); strings[j] = ress[0]; } } @Override public void onFailure(Exception exception) { LOG.log(Level.WARNING, "failed to communicate", exception); } }; callback.onSuccess("init"); return; } final DateTime finish = DateTime.now(); final Duration duration = new Duration(start, finish); reports[j] = (counter * 1000 / duration.getMillis()); strings[j] = res; }; }); } for (int i = 0; i < parallel; i++) { threads[i].start(); } try { Thread.sleep(duration); } catch (InterruptedException e) {} stop[0] = true; try { Thread.sleep(1000); } catch (InterruptedException e) {} long total = 0; int count = 0; for (int i = 0; i < parallel; i++) { if (reports[i] > 0) { total += reports[i]; count++; } } LOG.warning("Total score:" + count + " treads reported:" + (total / count) + " call/s"); } private int count = 0; private ExampleAgent genAgent() { AgentConfig config = AgentConfig.create(); config.setId(new Integer(count++).toString()); config.setClassName(ExampleAgent.class.getName()); ExampleAgent agent = (ExampleAgent) new AgentBuilder().withConfig( config).build(); return agent; } /** * Test rpc scale. */ @Test public void testRpcScale() { int runTime = 50000; boolean runDirect = false; LOG.warning("Runtime test:" + runTime + " ms"); if (runDirect) { LOG.warning("Direct:"); runTest(runTime, 8, "direct"); } LOG.warning("RPC direct:"); runTest(runTime, 4, "rpcdirect"); // LOG.warning("RPC Sync:"); // runTest(runTime, 8, "sync"); // // LOG.warning("RPC Async:"); // runTest(runTime, 8, "async"); // LOG.warning("RPC Multi-agent:"); // runTest(runTime, 4, "multi"); } }