diff --git a/.gitignore b/.gitignore index e3358f5..c555e6f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ logs/* build/ resources/ temp/ +src/main/java/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index cd0c043..94be599 100644 --- a/build.gradle +++ b/build.gradle @@ -6,9 +6,19 @@ group="offernet" version="0.0.3" task wrapper(type: Wrapper) { - gradleVersion = '3.3' + gradleVersion = '4.6' } +jacocoTestReport { + reports { + xml.enabled false + csv.enabled false + html.enabled true + } +} + +test { finalizedBy jacocoTestReport } + repositories { mavenCentral() maven { url 'https://jitpack.io' } @@ -16,11 +26,12 @@ repositories { dependencies { compile 'junit:junit:4.12' - compile 'org.codehaus.groovy:groovy-all:2.4.1' + compile 'org.codehaus.groovy:groovy-all:2.4.11' compile 'com.datastax.dse:dse-java-driver-graph:1.5.1' compile 'org.apache.tinkerpop:gremlin-core:3.3.1' compile 'log4j:log4j:1.2.17' compile 'org.slf4j:slf4j-log4j12:1.7.22' compile 'com.typesafe.akka:akka-actor_2.12:2.5.11' + compile 'com.typesafe.akka:akka-actor-typed_2.12:2.5.11' testCompile 'com.typesafe.akka:akka-testkit_2.12:2.5.11' } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9a70adb..f6b961f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 932b040..bf3de21 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Thu Jan 12 11:26:58 CET 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip diff --git a/gradlew b/gradlew index 4453cce..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } diff --git a/network-backends/dse-docker/scripts/gremlin.sh b/network-backends/dse-docker/scripts/gremlin.sh new file mode 100644 index 0000000..74cfb93 --- /dev/null +++ b/network-backends/dse-docker/scripts/gremlin.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +HOST=192.168.1.6 +PORT=8182 + +/opt/dse/bin/dse gremlin-console $HOST:$PORTe diff --git a/scripts/offernet.gremlin b/network-backends/dse-docker/scripts/offernet.gremlin similarity index 100% rename from scripts/offernet.gremlin rename to network-backends/dse-docker/scripts/offernet.gremlin diff --git a/network-backends/dse-docker/scripts/start-docker.sh b/network-backends/dse-docker/scripts/start-docker.sh index c9f809c..0b83901 100644 --- a/network-backends/dse-docker/scripts/start-docker.sh +++ b/network-backends/dse-docker/scripts/start-docker.sh @@ -1,7 +1,14 @@ #!/bin/sh # deleting all containers (not very efficient, but needed in order to run a container with the same name) +docker stop $(docker ps -a -q) docker ps -q -a | xargs docker rm # start dse-server with graph enabled -docker run -e DS_LICENSE=accept --name my-dse -d store/datastax/dse-server:5.1.6 -g +docker run -e DS_LICENSE=accept -e LISTEN_ADDRESS=127.0.0.1 -e START_RPC=true --name dse -d -p 8182:8182 -p 9042:9042 store/datastax/dse-server:5.1.6 -g + +# start dse-studio (not needed for tests) +docker run -e DS_LICENSE=accept --name dse-studio -d -p 9091:9091 --link dse datastax/dse-studio + +# start dse-opscenter +# docker run -e DS_LICENSE=accept --name opscenter -d -p 8888:8888 datastax/dse-opscenter diff --git a/scripts/compileGroovy.sh b/scripts/compileGroovy.sh index 22b8448..5f281a4 100755 --- a/scripts/compileGroovy.sh +++ b/scripts/compileGroovy.sh @@ -1,8 +1,8 @@ #!/bin/bash -if [ ! -d src/java ]; then mkdir -p src/java; else rm -r src/java/*; fi; -cp src/groovy/* src/java/ -cd src/java +if [ ! -d src/main/java ]; then mkdir -p src/main/java; else rm -r src/main/java/*; fi; +cp src/main/groovy/* src/main/java/ +cd src/main/java #remove all @Grab annotations from the file -- cannot be run by java #sed -i '/@Grab/d' *.groovy @@ -10,5 +10,5 @@ cd src/java echo $GROOVY_HOME #compile -groovyc -cp "~/.groovy/gradle/*" -encoding utf-8 *.groovy +groovyc -cp "/home/kabir/.gradle/*" -encoding utf-8 --indy *.groovy rm *.groovy diff --git a/src/main/groovy/Agent.groovy b/src/main/groovy/Agent.groovy index 5b77f27..c152c0b 100644 --- a/src/main/groovy/Agent.groovy +++ b/src/main/groovy/Agent.groovy @@ -1,5 +1,6 @@ -//@Grab(group='com.datastax.cassandra', module='dse-driver', version='1.1.1') +//@Grab(group='com.datastax.dse', module='dse-java-driver-graph', version='1.5.1') //@Grab(group='log4j', module='log4j', version='1.2.17') +//@Grab(group='com.typesafe.akka', module='akka-actor_2.12', version='2.5.11') package net.vveitas.offernet @@ -19,29 +20,22 @@ import org.apache.log4j.PropertyConfigurator import org.slf4j.Logger import org.slf4j.LoggerFactory -import akka.actor.UntypedActor; +import akka.actor.UntypedAbstractActor; import akka.actor.Props; import akka.japi.Creator; -public class Agent extends UntypedActor { +import java.util.UUID; + +public class Agent extends UntypedAbstractActor { private Vertex vertex; private DseSession session; private Logger logger; - public static Props props(DseSession session) { + static Props props(DseSession session, String agentId) { return Props.create(new Creator() { @Override public Agent create() throws Exception { - return new Agent(session); - } - }); - } - - public static Props props(Object vertexId, DseSession session) { - return Props.create(new Creator() { - @Override - public Agent create() throws Exception { - return new Agent(vertexId, session); + return new Agent(session,agentId); } }); } @@ -70,7 +64,17 @@ public class Agent extends UntypedActor { } } - public Agent(DseSession session) { + /** + * Agent constructor returning a new agent by creating a vertex in the graph + * if a vertex with the given UUID exists - connect this vertex to the newly created actor + * UUID is shared between graph identifier (agentId) and actor identifier (path) + * @param session the DSE graph session for communication with the graph + * @return Agent class instance; + * @author kabir@singularitynet.io + */ + + public Agent(DseSession session, String agentId) { + def start = System.currentTimeMillis(); def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) PropertyConfigurator.configure(config.toProperties()) @@ -80,36 +84,32 @@ public class Agent extends UntypedActor { Map params = new HashMap(); params.put("labelValue", "agent"); - - GraphResultSet rs = session.executeGraph(new SimpleGraphStatement("g.addV(label, labelValue)", params)); + params.put("agentId",agentId); + params.put("agentIdLabel","agentId") + + GraphResultSet rs = session.executeGraph(new SimpleGraphStatement( + "if (g.V().has(agentIdLabel,agentId).toList().size() == 0)\n"+ + "g.addV(label, labelValue).property(agentIdLabel,agentId)\n"+ + "else\n"+ + "g.V().has(agentIdLabel,agentId)", params)); this.vertex = rs.one().asVertex(); - logger.warn("Created a new {} with id {}", vertex.getLabel(), vertex.getId()); + logger.warn("Created a new {} with id {} and agentId {}", vertex.getLabel(), vertex.getId(), vertex.getProperty("agentId").getValue()); logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) } - public Agent(Object vertexId, DseSession session) { - def start = System.currentTimeMillis(); - def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) - PropertyConfigurator.configure(config.toProperties()) - logger = LoggerFactory.getLogger('OfferNet.class'); - - this.session= session; - - Map params = new HashMap(); - params.put("vertexId",vertexId); - - GraphResultSet rs = session.executeGraph(new SimpleGraphStatement("g.V(vertexId)", params)); - this.vertex = rs.one().asVertex(); - - logger.warn("Instantiated an {} with existing vertex id {}", vertex.getLabel(), vertex.getId()); - logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) + /** + * returns the agentId property on the vertex, which is the unique id (is also the actor name in akka system) + * need to rename into something more intuitive -- agentId + */ + private String id() { + return vertex.getProperty("agentId").getValue().asString(); } - /* - * returns an id of an Agent vertex + /** + * returns the agentId property on the vertex, which is the unique id (is also the actor name in akka system) */ - private id() { + private Object vertexId() { return vertex.getId(); } @@ -176,7 +176,7 @@ public class Agent extends UntypedActor { Map params = new HashMap(); params.put("labelValue", "work"); - params.put("agent", this.id()); + params.put("agent", this.vertexId()); params.put("edgeLabel","owns"); logger.warn("Creating new work for agent {}", params.agent) @@ -264,7 +264,7 @@ public class Agent extends UntypedActor { logger.warn("Getting all works owned by agent {}",params.agent); - SimpleGraphStatement s = new SimpleGraphStatement("g.V(agent).out(edgeLabel)",params); + SimpleGraphStatement s = new SimpleGraphStatement("g.V().has('agentId',agent).out(edgeLabel)",params); GraphResultSet rs = session.executeGraph(s); List works = rs.all().collect {it.asVertex()}; @@ -281,12 +281,13 @@ public class Agent extends UntypedActor { def start = System.currentTimeMillis(); Map params = new HashMap(); - params.put("agentLabelName", this.id()); + params.put("agentId", this.id()); + params.put("agentIdLabel", "agentId"); logger.warn("Getting all items of agent {}", this.id()) SimpleGraphStatement s = new SimpleGraphStatement( - "g.V(agentLabelName).outE('owns').inV().outE().inV().has(label,'item')", params) + "g.V().has(agentIdLabel,agentId).outE('owns').inV().outE().inV().has(label,'item')", params) GraphResultSet rs = session.executeGraph(s); List items = rs.all().collect {it.asVertex() }; @@ -334,13 +335,14 @@ public class Agent extends UntypedActor { private List itemsOfKnownAgents(Integer maxReachDistance) { def start = System.currentTimeMillis() Map params = new HashMap(); - params.put("thisAgent", this.id()); + params.put("thisAgentId", this.id()); + params.put("agentIdLabel","agentId") params.put("repeats", maxReachDistance); logger.warn("Getting a list of all connected items of agent {} with loop {}", this.id(), maxReachDistance) SimpleGraphStatement s = new SimpleGraphStatement( - "g.V(thisAgent).as('s').repeat("+ + "g.V().has(agentIdLabel,thisAgentId).as('s').repeat("+ "both('knows').has(label,'agent')).times(repeats).emit().dedup().as('t')"+ ".where('t',neq('s')).out('owns').out()",params); diff --git a/src/main/groovy/OfferNet.groovy b/src/main/groovy/OfferNet.groovy index 62dfd28..654669b 100644 --- a/src/main/groovy/OfferNet.groovy +++ b/src/main/groovy/OfferNet.groovy @@ -47,13 +47,15 @@ public class OfferNet implements AutoCloseable { def start = System.currentTimeMillis() cluster = DseCluster.builder().addContactPoint("192.168.1.6").build(); cluster.connect().executeGraph("system.graph('offernet').ifNotExists().create()"); - + cluster = DseCluster.builder() .addContactPoint("192.168.1.6") .withGraphOptions(new GraphOptions().setGraphName("offernet")) .build(); session = cluster.connect(); + session.executeGraph(new SimpleGraphStatement("schema.config().option('graph.schema_mode').set('Development')")) + logger.info("Created OfferNet instance with session {}", session); logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) @@ -140,6 +142,35 @@ public class OfferNet implements AutoCloseable { return agentIds; } + private void createAgentNetworkWithChains(String[] args){ + def numberOfAgents = args[1]; + def numberOfRandomWorks = args[2]; + def numberOfChains = args[3]; + def lenghtOfChain = args[4]; + List chains = []; + numberOfChains.times { + chains.add(Utils.createChain(lenghtOfChain)); + } + createAgentNetwork(numberOfAgents,numberOfRandomWorks,chains); + } + + private List createAgentNetwork(Integer numberOfAgents, Integer numberOfRandomWorks, ArrayList chains) { + + def start = System.currentTimeMillis(); + agentList = on.createAgentNetwork(numberOfAgents) + agentList.each {agent -> + agent.ownsWork() + } + on.addRandomWorksToAgents(numberOfRandomWorks) + chains.each {chain -> + on.addChainToNetwork(chain) + } + logger.warn("Created agentNetwork with {} agents, {} randomWorks and {} chains",numberOfAgents,numberOfRandomWorks,chains.size()) + logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) + + return agentList; + } + public addRandomWorksToAgents(int numberOfWorks) { def start=System.currentTimeMillis(); List agentIds = this.getIds('agent'); diff --git a/src/main/groovy/Simulation.groovy b/src/main/groovy/Simulation.groovy index 119782d..e8dc464 100644 --- a/src/main/groovy/Simulation.groovy +++ b/src/main/groovy/Simulation.groovy @@ -5,30 +5,26 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import com.datastax.driver.dse.graph.Vertex; +import com.datastax.driver.dse.DseSession; +import com.datastax.driver.dse.graph.GraphNode; -import akka.actor.UntypedActor; +import akka.actor.UntypedAbstractActor; import akka.actor.Props; import akka.japi.Creator; -class Simulation extends UntypedActor { +import akka.actor.ActorRef; +import java.util.UUID; + +class Simulation extends UntypedAbstractActor { OfferNet on; Logger logger; List agentList; - private static Props props(DseSession session) { - return Props.create(new Creator() { - @Override - public Simulation create() throws Exception { - return new Simulation(session); - } - }); - } - - public static Props props(Object vertexId, DseSession session) { + public static Props props() { return Props.create(new Creator() { @Override public Simulation create() throws Exception { - return new Simulation(vertexId, session); + return new Simulation(); } }); } @@ -79,52 +75,37 @@ class Simulation extends UntypedActor { - Simulations will be run by passing messages for running methods */ - private void createAgentNetworkWithChains(String[] args){ - def numberOfAgents = args[1]; - def numberOfRandomWorks = args[2]; - def numberOfChains = args[3]; - def lenghtOfChain = args[4]; - List chains = []; - numberOfChains.times { - chains.add(Utils.createChain(lenghtOfChain)); - } - createAgentNetwork(numberOfAgents,numberOfRandomWorks,chains); - } - - private List createAgentNetwork(int numberOfAgents) { - def start = System.currentTimeMillis() - List agentsList = new ArrayList() - agentsList.add(system.actorOf(Agent.props(on.session),"agent1")) - - while (agentsList.size() < numberOfAgents) { - def random = new Random(); - def i = random.nextInt(agentsList.size()) - Object agent1 = agentsList[i] - Object agent2 = system.actorOf(Agent.props(on.session),"agent1"); - agent1.tell(new Method("knowsAgent",[agent2id]),getRef()) - agentsList.add(agent2) - } - logger.info("Created a network of "+numberOfAgents+ " Agents") - logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) - return agentsList; - } + private ActorRef createAgent() { + String agentId = UUID.randomUUID().toString(); + def actorRef = getContext().actorOf(Agent.props(on.session,agentId),agentId); + return actorRef + } - private List createAgentNetwork(Integer numberOfAgents, Integer numberOfRandomWorks, ArrayList chains) { + private Vertex getAgentVertexId(ActorRef actorRef) { + return actorRef.tell(id()); + } - def start = System.currentTimeMillis(); - agentList = on.createAgentNetwork(numberOfAgents) - agentList.each {agent -> - agent.ownsWork() - } - on.addRandomWorksToAgents(numberOfRandomWorks) - chains.each {chain -> - on.addChainToNetwork(chain) - } - logger.warn("Created agentNetwork with {} agents, {} randomWorks and {} chains",numberOfAgents,numberOfRandomWorks,chains.size()) - logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) + private List createAgentNetwork(int numberOfAgents) { + def start = System.currentTimeMillis() + List agentsList = new ArrayList() + def firstAgent = Props.create(Agent.class, on.session) + + agentsList.add(system.actorOf(Agent.props(on.session),"agent1")) + + while (agentsList.size() < numberOfAgents) { + def random = new Random(); + def i = random.nextInt(agentsList.size()) + Object agent1 = agentsList[i] + Object agent2 = system.actorOf(Agent.props(on.session),"agent1"); + agent1.tell(new Method("knowsAgent",[agent2id]),getRef()) + agentsList.add(agent2) + } + logger.info("Created a network of "+numberOfAgents+ " Agents") + logger.warn("Method {} took {} seconds to complete", Utils.getCurrentMethodName(), (System.currentTimeMillis()-start)/1000) + return agentsList; + } - return agentList; - } + /* done until here */ private Integer connectIfSimilarForAllAgents(List agentList, Integer similarityThreshold, Integer maxReachDistance) { diff --git a/src/main/groovy/Utils.groovy b/src/main/groovy/Utils.groovy index 285182e..13bd496 100644 --- a/src/main/groovy/Utils.groovy +++ b/src/main/groovy/Utils.groovy @@ -13,7 +13,6 @@ import com.datastax.driver.dse.graph.Vertex import org.codehaus.groovy.runtime.StackTraceUtils - import static org.junit.Assert.* public class Utils { diff --git a/src/test/groovy/AgentTests.groovy b/src/test/groovy/AgentTests.groovy new file mode 100644 index 0000000..fe4f973 --- /dev/null +++ b/src/test/groovy/AgentTests.groovy @@ -0,0 +1,368 @@ +package net.vveitas.offernet + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; + +import java.util.UUID; + +public class AgentTests { + static private OfferNet on = new OfferNet().flushVertices(); + static private Logger logger; + static ActorSystem system = ActorSystem.create(); + + @BeforeClass + static void initLogging() { + def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) + PropertyConfigurator.configure(config.toProperties()) + logger = LoggerFactory.getLogger('Tests.class'); + } + + @Test + void idStaticTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + assertNotNull(agent1.id()) + logger.info("id of the actor via static interface is {}",agent1.id()) + } + + @Test + void idMessageTest() { + new JavaTestKit(system) {{ + def agentRef = system.actorOf(Agent.props(on.session, UUID.randomUUID().toString()),"agent1"); + agentRef.tell(new Method("id",[]),getRef()) + def agentId = receiveN(1) + assertNotNull(agentId) + logger.info("id of the actor via message is {}",agentId) + }} + } + + @Test + void connectTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work1 = agent1.ownsWork(); + def work2 = agent2.ownsWork(); + def item1 = agent1.addItemToWork("demands",work1) + def item2 = agent2.addItemToWork("demands",work1) + + def similarity = Utils.calculateSimilarity(item1,item2); + def similarityEdge = agent1.connect(item1,item2, similarity); + assertNotNull(similarityEdge); + } + + @Test + void connectAllSimilarTest() { + on.flushVertices(); + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work1 = agent1.ownsWork('1111','1110'); + def work2 = agent2.ownsWork('1100','1000'); + def start = agent1.addItemToWork("demands",work2,'0000') + + def knownItemsList = on.getVertices('item') + List similarityEdges = agent1.connectAllSimilar(start, knownItemsList,2) + assertEquals(3,similarityEdges.size()) + } + + @Test + void reciprocalDistanceLinkTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work1 = agent1.ownsWork(); + def work2 = agent2.ownsWork(); + def item1 = agent1.addItemToWork("demands",work1) + def item2 = agent2.addItemToWork("demands",work1) + + def similarity = Utils.calculateSimilarity(item1,item2); + def similarityEdge = agent1.connect(item1, item2, similarity); + assertNotNull(similarityEdge); + + def d1 =agent1.existsSimilarity(item1,item2); + assertNotNull(d1) + def d2 = agent2.existsSimilarity(item2,item1); + assertNotNull(d2) + assertEquals(d1,d2) + } + + @Test + void existsSimilarityTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work1 = agent1.ownsWork(); + def work2 = agent2.ownsWork(); + def item1 = agent1.addItemToWork("demands",work1) + def item2 = agent2.addItemToWork("demands",work1) + + def similarity = Utils.calculateSimilarity(item1,item2); + def similarityEdge = agent1.connect(item1, item2, similarity); + assertNotNull(similarityEdge); + + def d2 = agent2.existsSimilarity(item1,item2); + assertNotNull(d2) + + } + + @Test + void connectIfSimilarTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work1 = agent1.ownsWork(); + def work2 = agent2.ownsWork(); + def item1 = agent1.addItemToWork("demands",work1) + def item2 = agent2.addItemToWork("demands",work1) + + def similarity = Utils.calculateSimilarity(item1,item2); + def connectedEdge = agent1.connectIfSimilar(item1, item2, similarity-1); + assertNotNull(connectedEdge); + assertEquals(similarity,Utils.edgePropertyValueAsInteger(connectedEdge,'value')) + + def item3 = agent1.addItemToWork("offers",work1) + def item4 = agent2.addItemToWork("offers",work1) + + similarity = Utils.calculateSimilarity(item3,item4); + + connectedEdge = agent2.connectIfSimilar(item3, item4, similarity+1); + assertNull(connectedEdge); + } + + @Test + void itemsOfKnownAgentsTest() { + def agent1 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent3 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def agent4 = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + + agent1.knowsAgent(agent2.vertex.getId()); + agent2.knowsAgent(agent3.vertex.getId()); + agent3.knowsAgent(agent4.vertex.getId()); + + def work1 = agent1.ownsWork(); + agent2.ownsWork() + agent3.ownsWork() + agent4.ownsWork() + + List items = agent1.itemsOfKnownAgents(2) + assertNotNull(items) + assertEquals(4,items.size()) + items.each{ item -> + assertEquals('item',item.getLabel()) + } + } + + @Test + void createAgentNewVertexTest() { + String agentId = UUID.randomUUID().toString(); + def agent1 = TestActorRef.create(system, Agent.props(on.session,agentId)).underlyingActor(); + assertNotNull(agent1); + def agentIdFromVertex = agent1.id() + logger.info("Original agent id {} is of type {}",agentId, agentId.getClass().getSimpleName()) + logger.info("Agent id extracted from vertex {} is of type {}",agentIdFromVertex, agentIdFromVertex.getClass().getSimpleName()) + assertEquals(agentId,agentIdFromVertex) + } + + @Test + void createAgentExistingVertexTest() { + String agentId = UUID.randomUUID().toString(); + def agent1ref = TestActorRef.create(system, Agent.props(on.session,agentId)) + def agent1 = agent1ref.underlyingActor(); + assertNotNull(agent1); + assertEquals(agentId,agent1.id()); + agent1ref.stop() + + def agent2 = TestActorRef.create(system, Agent.props(on.session,agentId)).underlyingActor(); + assertNotNull(agent2); + assertEquals(agentId,agent2.id()); + + String agent3Id = UUID.randomUUID().toString(); + def agent3ref = TestActorRef.create(system, Agent.props(on.session,agent3Id)) + def agent3 = agent3ref.underlyingActor(); + assertNotNull(agent3); + assertNotEquals(agentId,agent3.id()); + + } + + @Test + void agentKnowsAgentTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent1 = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + assertNotNull(agent1); + String agent2Id = UUID.randomUUID().toString(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, agent2Id)).underlyingActor(); + assertNotNull(agent2); + def edge = agent1.knowsAgent(agent2.vertex.getId()); + assertNotNull(edge); + } + + @Test + void agentKnowsAgentViaMessageTest() { + new JavaTestKit(system) {{ + String agent1Id = UUID.randomUUID().toString(); + def agent1Ref = system.actorOf(Agent.props(on.session, agent1Id)); + assertNotNull(agent1Ref); + String agent2Id = UUID.randomUUID().toString(); + def agent2Ref = system.actorOf(Agent.props(on.session, agent2Id)); + assertNotNull(agent2Ref); + agent2Ref.tell(new Method("vertexId",[]),getRef()) + def agent2id = receiveN(1) + agent1Ref.tell(new Method("knowsAgent",[agent2id]),getRef()) + def edge = receiveN(1) + assertNotNull(edge); + }} + } + + @Test + void agentOwnsNewWorkTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent1 = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + assertNotNull(agent1); + + def work = agent1.ownsWork(); + assertNotNull(work); + } + + @Test + void agentOwnsKnownWorkTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent1 = TestActorRef.create(system, Agent.props(on.session,agent1Id)).underlyingActor(); + assertNotNull(agent1); + + def work = agent1.ownsWork("00011","00001") + assertNotNull(work); + + def demand = agent1.getWorksItems(work,"demands")[0]; + assertNotNull(demand) + def offer = agent1.getWorksItems(work,"offers")[0]; + assertNotNull(offer) + + assertEquals("00011",demand.getProperty("value").getValue().asString()) + assertEquals("00001",offer.getProperty("value").getValue().asString()) + } + + @Test + void allItemsTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + assertNotNull(agent); + + def work = agent.ownsWork(); + assertNotNull(work); + + agent.addItemToWork("demands",work); + agent.addItemToWork("offers",work); + + assertEquals(4,agent.allItems().size()) + } + + @Test + void searchAndConnectTest() { + on.flushVertices("agent"); + String agent1Id = UUID.randomUUID().toString(); + def agent1 = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + agent1.ownsWork('111110','000000'); + String agent2Id = UUID.randomUUID().toString(); + def agent2 = TestActorRef.create(system, Agent.props(on.session, agent2Id)).underlyingActor(); + agent2.ownsWork('111100','110000'); + String agent3Id = UUID.randomUUID().toString(); + def agent3 = TestActorRef.create(system, Agent.props(on.session, agent3Id)).underlyingActor(); + agent3.ownsWork('100000','111100'); + String agent4Id = UUID.randomUUID().toString(); + def agent4 = TestActorRef.create(system, Agent.props(on.session, agent4Id)).underlyingActor(); + agent4.ownsWork('111110','000000'); + + agent1.knowsAgent(agent2.vertex.getId()); + agent2.knowsAgent(agent3.vertex.getId()); + agent3.knowsAgent(agent4.vertex.getId()); + + /* + The resulting graph has 4 agents, 4 works, 8 items and 6 reciprocal connections (12 links in total) + */ + assertEquals(3,agent1.searchAndConnect(5,2)) // this traverses part of the graph + assertEquals(3,agent1.searchAndConnect(4,3)) // traverses the whole graph, and finds the rest of connections with similarity gte(4) + } + + @Test + void getWorksTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + def work1 = agent.ownsWork(); + def work2 = agent.ownsWork(); + def work3 = agent.ownsWork(); + + List worksVertexList = agent.getWorks(); + assertEquals(3,worksVertexList.size()); + assertTrue(worksVertexList.contains(work1)); + assertTrue(worksVertexList.contains(work2)); + assertTrue(worksVertexList.contains(work3)); + + } + + @Test + void addNewOfferTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + def work = agent.ownsWork() + def offer = agent.addItemToWork("offers",work) + assertNotNull(offer); + } + + @Test + void addKnownOfferTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + def work = agent.ownsWork() + def offer = agent.addItemToWork("offers",work,"00000") + assertEquals("00000",offer.getProperty("value").getValue().asString()); + } + + @Test + void addNewDemandTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + def work = agent.ownsWork() + def offer = agent.addItemToWork("demands",work) + assertNotNull(offer); + } + + @Test + void addKnownDemandTest() { + String agent1Id = UUID.randomUUID().toString(); + def agent = TestActorRef.create(system, Agent.props(on.session, agent1Id)).underlyingActor(); + def work = agent.ownsWork() + def offer = agent.addItemToWork("demands",work,"00011") + assertEquals("00011",offer.getProperty("value").getValue().asString()); + } + + @Test + void getWorkItemsTest() { + def agent = TestActorRef.create(system, Agent.props(on.session, UUID.randomUUID().toString())).underlyingActor(); + def work = agent.ownsWork(); + def item1 = agent.addItemToWork("demands",work); + def item2 = agent.addItemToWork("demands",work); + + def demands = agent.getWorksItems(work,"demands"); + assertEquals(3,demands.size()); // tree because one is created by default in Work constructor + + def offers = agent.getWorksItems(work,"offers"); + assertEquals(1,offers.size()); + + } + +} diff --git a/src/test/groovy/MethodTests.groovy b/src/test/groovy/MethodTests.groovy new file mode 100644 index 0000000..c8bd125 --- /dev/null +++ b/src/test/groovy/MethodTests.groovy @@ -0,0 +1,42 @@ +package net.vveitas.offernet + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; + +public class MethodTests { + static private OfferNet on = new OfferNet().flushVertices(); + static private Logger logger; + static ActorSystem system = ActorSystem.create(); + + @BeforeClass + static void initLogging() { + def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) + PropertyConfigurator.configure(config.toProperties()) + logger = LoggerFactory.getLogger('Tests.class'); + } + + @Test + void sendMethod() { + def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); + } + +} \ No newline at end of file diff --git a/src/test/groovy/OfferNetTests.groovy b/src/test/groovy/OfferNetTests.groovy new file mode 100644 index 0000000..797f97c --- /dev/null +++ b/src/test/groovy/OfferNetTests.groovy @@ -0,0 +1,159 @@ +package net.vveitas.offernet + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; + +public class OfferNetTests { + static private OfferNet on = new OfferNet().flushVertices(); + static private Logger logger; + static ActorSystem system = ActorSystem.create(); + + @BeforeClass + static void initLogging() { + def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) + PropertyConfigurator.configure(config.toProperties()) + logger = LoggerFactory.getLogger('Tests.class'); + } + + @Test + void createOfferNetworkTest() { + def on1 = new OfferNet() + assertNotNull(on1); + assertFalse(on1.session.isClosed()); + assertFalse(on1.cluster.isClosed()); + } + + @Test + void closeOfferNetworkTest() { + def on1 = new OfferNet() + assertNotNull(on1); + on1.close(); + assertTrue(on1.session.isClosed()); + assertTrue(on1.cluster.isClosed()); + } + + @Test + void flushAgentsTest() { + def on1 = new OfferNet() + assertNotNull(on1); + TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); + TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); + assertNotEquals(0,on1.getIds('agent').size()) + on1.flushVertices("agent"); + assertEquals(0,on1.getIds('agent').size()) + } + + @Test + void flushVerticesTest() { + def on1 = new OfferNet(); + assertNotNull(on1); + def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); + def work = agent.ownsWork(); + def item1 = agent.addItemToWork("offers",work); + def item2 = agent.addItemToWork("demands",work); + assertNotEquals(0,on1.getIds('agent').size()) + assertNotEquals(0,on1.getIds('work').size()) + assertNotEquals(0,on1.getIds('item').size()) + on1.flushVertices(); + assertEquals(0,on1.getIds('agent').size()) + assertEquals(0,on1.getIds('work').size()) + assertEquals(0,on1.getIds('item').size()) + } + + @Test + void getIdsTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + sim.on.flushVertices('agent'); + sim.createAgentNetwork(10) + def agentIds = sim.on.getIds('agent'); + assertNotNull(agentIds); + assertEquals(10,agentIds.size()); + } + + @Test + void addRandomWorksToAgentsTest() { + def on1 = new OfferNet() + on1.flushVertices(); + + on1.createAgentNetwork(10) + on1.addRandomWorksToAgents(10) + assertEquals(20,on.getIds("item").size()); // creates two items (demand and offer) when creating a random work; + } + + @Test + void allWorkItemEdgesTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + + def chains = [Utils.createChain(4)] + logger.info("Created chains: {}",chains) + + sim.createAgentNetwork(4,0,chains); + + def demandEdges = on.allWorkItemEdges("demands"); + def offerEdges = on.allWorkItemEdges("offers") + + logger.info("demandEdges {} of class {}",demandEdges,demandEdges.getClass()) + + assertEquals(7,demandEdges.size()) + assertEquals(7,offerEdges.size()) + } + + @Test + void connectMatchingPairsTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + def chainLength = 4 + + def chains = [Utils.createChain(chainLength)] + logger.info("Created chains: {}",chains) + + sim.createAgentNetwork(chainLength,0,chains); + + def demandEdges = on.allWorkItemEdges("demands"); + def offerEdges = on.allWorkItemEdges("offers") + + logger.info("demandEdges {} of class {}",demandEdges,demandEdges.getClass()) + + def matchingOfferDemandPairs = Utils.getMatchingOfferDemandPairs(offerEdges,demandEdges) + logger.warn("Offer-Demand pairs found: {}",matchingOfferDemandPairs) + + def connectedPairsCount = sim.on.connectMatchingPairs(matchingOfferDemandPairs); + assertEquals((chainLength - 2).toInteger(),connectedPairsCount) + } + + @Test + void createAgentTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + def agent = sim.on.createAgent(); + assertNotNull(agent); + } + + @Test + void createEdgeTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + def agent1 = sim.on.createAgent(); + assertNotNull(agent1) + def agent2 = sim.on.createAgent(); + assertNotNull(agent2) + def edge = sim.on.knowsAgent(agent1,agent2); + assertNotNull(edge) + } +} \ No newline at end of file diff --git a/src/test/groovy/ParametersTests.groovy b/src/test/groovy/ParametersTests.groovy new file mode 100644 index 0000000..394e2e5 --- /dev/null +++ b/src/test/groovy/ParametersTests.groovy @@ -0,0 +1,42 @@ +package net.vveitas.offernet + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; + +public class ParametersTests { + static private OfferNet on = new OfferNet().flushVertices(); + static private Logger logger; + static ActorSystem system = ActorSystem.create(); + + @BeforeClass + static void initLogging() { + def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) + PropertyConfigurator.configure(config.toProperties()) + logger = LoggerFactory.getLogger('Tests.class'); + } + + @Test + void parametersTest() { + assertEquals(16,Parameters.parameters.binaryStringLength); + assertEquals(8,Parameters.parameters.similarityThreshold); + } +} diff --git a/src/test/groovy/SimulationTests.groovy b/src/test/groovy/SimulationTests.groovy index b5c9771..43cb2b6 100644 --- a/src/test/groovy/SimulationTests.groovy +++ b/src/test/groovy/SimulationTests.groovy @@ -5,6 +5,7 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; import org.junit.Test; import org.junit.Ignore; @@ -29,8 +30,15 @@ import org.slf4j.LoggerFactory import java.text.SimpleDateFormat; -public class SimulationTests { +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; +public class SimulationTests { + static ActorSystem system = ActorSystem.create(); static private Logger logger; @BeforeClass @@ -40,6 +48,28 @@ public class SimulationTests { logger = LoggerFactory.getLogger('OfferNet.class'); } + @Test + void createSimulationTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + assertThat(sim, instanceOf(Simulation.class)) + } + + @Test + void createAgentTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + def agent1 = sim.createAgent(); + assertThat(agent1, instanceOf(ActorRef.class)); + } + + @Test + void createAgentNetworkTest() { + def sim = TestActorRef.create(system, Simulation.props()).underlyingActor(); + int size + def agentList = sim.createAgentNetwork(size) + assertThat(agentList.size(), size) + + } + //@Ignore // for now -- takes too much time @Test void cycleSearchTest() { diff --git a/src/test/groovy/Tests.groovy b/src/test/groovy/Tests.groovy deleted file mode 100644 index f3c75cf..0000000 --- a/src/test/groovy/Tests.groovy +++ /dev/null @@ -1,497 +0,0 @@ -package net.vveitas.offernet - -import org.apache.log4j.PropertyConfigurator -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import static org.junit.Assert.* - -import org.junit.Test; -import org.junit.BeforeClass; -import org.junit.AfterClass; - -import org.apache.log4j.PropertyConfigurator -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import akka.actor.Props -import akka.actor.ActorSystem; -import akka.actor.ActorRef; - -import akka.testkit.TestActorRef -import akka.testkit.JavaTestKit; - -public class Tests { - static private OfferNet on = new OfferNet().flushVertices(); - static private Logger logger; - static ActorSystem system = ActorSystem.create(); - - @BeforeClass - static void initLogging() { - def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) - PropertyConfigurator.configure(config.toProperties()) - logger = LoggerFactory.getLogger('Tests.class'); - } - - /* - * Agent.groovy - */ - - @Test - void connectTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent1.ownsWork(); - def work2 = agent2.ownsWork(); - def item1 = agent1.addItemToWork("demands",work1) - def item2 = agent2.addItemToWork("demands",work1) - - def similarity = Utils.calculateSimilarity(item1,item2); - def similarityEdge = agent1.connect(item1,item2, similarity); - assertNotNull(similarityEdge); - } - - @Test - void connectAllSimilarTest() { - on.flushVertices(); - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent1.ownsWork('1111','1110'); - def work2 = agent2.ownsWork('1100','1000'); - def start = agent1.addItemToWork("demands",work2,'0000') - - def knownItemsList = on.getVertices('item') - List similarityEdges = agent1.connectAllSimilar(start, knownItemsList,2) - assertEquals(3,similarityEdges.size()) - } - - @Test - void reciprocalDistanceLinkTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent1.ownsWork(); - def work2 = agent2.ownsWork(); - def item1 = agent1.addItemToWork("demands",work1) - def item2 = agent2.addItemToWork("demands",work1) - - def similarity = Utils.calculateSimilarity(item1,item2); - def similarityEdge = agent1.connect(item1, item2, similarity); - assertNotNull(similarityEdge); - - def d1 =agent1.existsSimilarity(item1,item2); - assertNotNull(d1) - def d2 = agent2.existsSimilarity(item2,item1); - assertNotNull(d2) - assertEquals(d1,d2) - } - - @Test - void existsSimilarityTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent1.ownsWork(); - def work2 = agent2.ownsWork(); - def item1 = agent1.addItemToWork("demands",work1) - def item2 = agent2.addItemToWork("demands",work1) - - def similarity = Utils.calculateSimilarity(item1,item2); - def similarityEdge = agent1.connect(item1, item2, similarity); - assertNotNull(similarityEdge); - - def d2 = agent2.existsSimilarity(item1,item2); - assertNotNull(d2) - - } - - @Test - void connectIfSimilarTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent1.ownsWork(); - def work2 = agent2.ownsWork(); - def item1 = agent1.addItemToWork("demands",work1) - def item2 = agent2.addItemToWork("demands",work1) - - def similarity = Utils.calculateSimilarity(item1,item2); - def connectedEdge = agent1.connectIfSimilar(item1, item2, similarity-1); - assertNotNull(connectedEdge); - assertEquals(similarity,Utils.edgePropertyValueAsInteger(connectedEdge,'value')) - - def item3 = agent1.addItemToWork("offers",work1) - def item4 = agent2.addItemToWork("offers",work1) - - similarity = Utils.calculateSimilarity(item3,item4); - - connectedEdge = agent2.connectIfSimilar(item3, item4, similarity+1); - assertNull(connectedEdge); - } - - @Test - void itemsOfKnownAgentsTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent3 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def agent4 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - - agent1.knowsAgent(agent2.vertex.getId()); - agent2.knowsAgent(agent3.vertex.getId()); - agent3.knowsAgent(agent4.vertex.getId()); - - def work1 = agent1.ownsWork(); - agent2.ownsWork() - agent3.ownsWork() - agent4.ownsWork() - - List items = agent1.itemsOfKnownAgents(2) - assertNotNull(items) - assertEquals(4,items.size()) - items.each{ item -> - assertEquals('item',item.getLabel()) - } - - } - - - @Test - void createAgentNewVertexTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent1); - } - - @Test - void createAgentExistingVertexTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent1); - def id1 = agent1.id(); - - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent2); - assertEquals(id1,agent2.id()); - } - - - @Test - void agentKnowsAgentTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent1); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent2); - def edge = agent1.knowsAgent(agent2.vertex,getId()); - assertNotNull(edge); - } - - @Test - void agentKnowsAgentViaMessageTest() { - new JavaTestKit(system) {{ - def agent1Ref = system.actorOf(Agent.props(on.session),"agent1"); - assertNotNull(agent1Ref); - def agent2Ref = system.actorOf(Agent.props(on.session),"agent2"); - assertNotNull(agent2Ref); - agent2Ref.tell(new Method("id",[]),getRef()) - def agent2id = receiveN(1) - agent1Ref.tell(new Method("knowsAgent",[agent2id]),getRef()) - def edge = receiveN(1) - assertNotNull(edge); - }} - } - - @Test - void agentOwnsNewWorkTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent1); - - def work = agent1.ownsWork(); - assertNotNull(work); - } - - @Test - void agentOwnsKnownWorkTest() { - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent1); - - def work = agent1.ownsWork("00011","00001") - assertNotNull(work); - - def demand = agent1.getWorksItems(work,"demands")[0]; - assertNotNull(demand) - def offer = agent1.getWorksItems(work,"offers")[0]; - assertNotNull(offer) - - assertEquals("00011",demand.getProperty("value").getValue().asString()) - assertEquals("00001",offer.getProperty("value").getValue().asString()) - } - - @Test - void allItemsTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotNull(agent); - - def work = agent.ownsWork(); - assertNotNull(work); - - agent.addItemToWork("demands",work); - agent.addItemToWork("offers",work); - - assertEquals(4,agent.allItems().size()) - } - - @Test - void searchAndConnectTest() { - on.flushVertices("agent"); - def agent1 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - agent1.ownsWork('111110','000000'); - def agent2 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - agent2.ownsWork('111100','110000'); - def agent3 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - agent3.ownsWork('100000','111100'); - def agent4 = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - agent4.ownsWork('111110','000000'); - - agent1.knowsAgent(agent2.vertex.getId()); - agent2.knowsAgent(agent3.vertex.getId()); - agent3.knowsAgent(agent4.vertex.getId()); - - /* - The resulting graph has 4 agents, 4 works, 8 items and 6 reciprocal connections (12 links in total) - */ - assertEquals(3,agent1.searchAndConnect(5,2)) // this traverses part of the graph - assertEquals(3,agent1.searchAndConnect(4,3)) // traverses the whole graph, and finds the rest of connections with similarity gte(4) - - } - - @Test - void getWorksTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work1 = agent.ownsWork(); - def work2 = agent.ownsWork(); - def work3 = agent.ownsWork(); - - List worksVertexList = agent.getWorks(); - assertEquals(3,worksVertexList.size()); - assertTrue(worksVertexList.contains(work1)); - assertTrue(worksVertexList.contains(work2)); - assertTrue(worksVertexList.contains(work3)); - - } - - @Test - void addNewOfferTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork() - def offer = agent.addItemToWork("offers",work) - assertNotNull(offer); - } - - @Test - void addKnownOfferTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork() - def offer = agent.addItemToWork("offers",work,"00000") - assertEquals("00000",offer.getProperty("value").getValue().asString()); - } - - @Test - void addNewDemandTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork() - def offer = agent.addItemToWork("demands",work) - assertNotNull(offer); - } - - @Test - void addKnownDemandTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork() - def offer = agent.addItemToWork("demands",work,"00011") - assertEquals("00011",offer.getProperty("value").getValue().asString()); - } - - @Test - void getWorkItemsTest() { - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork(); - def item1 = agent.addItemToWork("demands",work); - def item2 = agent.addItemToWork("demands",work); - - def demands = agent.getWorksItems(work,"demands"); - assertEquals(3,demands.size()); // tree because one is created by default in Work constructor - - def offers = agent.getWorksItems(work,"offers"); - assertEquals(1,offers.size()); - - } - - /* - * OfferNet.class - */ - - @Test - void createOfferNetworkTest() { - def on1 = new OfferNet() - assertNotNull(on1); - assertFalse(on1.session.isClosed()); - assertFalse(on1.cluster.isClosed()); - } - - @Test - void closeOfferNetworkTest() { - def on1 = new OfferNet() - assertNotNull(on1); - on1.close(); - assertTrue(on1.session.isClosed()); - assertTrue(on1.cluster.isClosed()); - } - - @Test - void flushAgentsTest() { - def on1 = new OfferNet() - assertNotNull(on1); - TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - assertNotEquals(0,on1.getIds('agent').size()) - on1.flushVertices("agent"); - assertEquals(0,on1.getIds('agent').size()) - } - - @Test - void flushVerticesTest() { - def on1 = new OfferNet(); - assertNotNull(on1); - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork(); - def item1 = agent.addItemToWork("offers",work); - def item2 = agent.addItemToWork("demands",work); - assertNotEquals(0,on1.getIds('agent').size()) - assertNotEquals(0,on1.getIds('work').size()) - assertNotEquals(0,on1.getIds('item').size()) - on1.flushVertices(); - assertEquals(0,on1.getIds('agent').size()) - assertEquals(0,on1.getIds('work').size()) - assertEquals(0,on1.getIds('item').size()) - } - - @Test - void getIdsTest() { - def on1 = new OfferNet() - on1.flushVertices('agent'); - on1.createAgentNetwork(10) - def agentIds = on1.getIds('agent'); - assertNotNull(agentIds); - assertEquals(10,agentIds.size()); - } - - - @Test - void addRandomWorksToAgentsTest() { - def on1 = new OfferNet() - on1.flushVertices(); - - on1.createAgentNetwork(10) - on1.addRandomWorksToAgents(10) - assertEquals(20,on.getIds("item").size()); // creates two items (demand and offer) when creating a random work; - } - - @Test - void allWorkItemEdgesTest() { - def sim = new Simulation(); - - def chains = [Utils.createChain(4)] - logger.info("Created chains: {}",chains) - - sim.createAgentNetwork(4,0,chains); - - def demandEdges = on.allWorkItemEdges("demands"); - def offerEdges = on.allWorkItemEdges("offers") - - logger.info("demandEdges {} of class {}",demandEdges,demandEdges.getClass()) - - assertEquals(7,demandEdges.size()) - assertEquals(7,offerEdges.size()) - } - - @Test - void connectMatchingPairsTest() { - def sim = new Simulation(); - def chainLength = 4 - - def chains = [Utils.createChain(chainLength)] - logger.info("Created chains: {}",chains) - - sim.createAgentNetwork(chainLength,0,chains); - - def demandEdges = on.allWorkItemEdges("demands"); - def offerEdges = on.allWorkItemEdges("offers") - - logger.info("demandEdges {} of class {}",demandEdges,demandEdges.getClass()) - - def matchingOfferDemandPairs = Utils.getMatchingOfferDemandPairs(offerEdges,demandEdges) - logger.warn("Offer-Demand pairs found: {}",matchingOfferDemandPairs) - - def connectedPairsCount = sim.on.connectMatchingPairs(matchingOfferDemandPairs); - assertEquals((chainLength - 2).toInteger(),connectedPairsCount) - } - - @Test - void createAgentTest() { - def sim = new Simulation(); - def agent = sim.on.createAgent(); - assertNotNull(agent); - } - - @Test - void createEdgeTest() { - def sim = new Simulation(); - def agent1 = sim.on.createAgent(); - assertNotNull(agent1) - def agent2 = sim.on.createAgent(); - assertNotNull(agent2) - def edge = sim.on.knowsAgent(agent1,agent2); - assertNotNull(edge) - } - - /* - * Utils.class - */ - - @Test - void generateBinaryStringTest() { - String string = Utils.generateBinaryString(Parameters.parameters.binaryStringLength); - assertEquals(16,string.length()); - assertTrue(string.toSet().sort().join() == '01' | string.toSet().sort().join() == '10'); - } - - @Test - void createChainTest() { - List chain = Utils.createChain(5) - assertEquals(5,chain.size()); - } - - @Test - void calculateSimilarityTest() { - String value1 = "000000" - String value2 = "000111" - def d1 = Utils.veitasSimilarity(value1,value2); - assertNotNull(d1) - def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); - def work = agent.ownsWork(value1,value2); - def item1 = agent.getWorksItems(work,"demands")[0] - def item2 = agent.getWorksItems(work,"offers")[0] - assertNotNull(item1) - assertNotNull(item2) - def d2 = Utils.calculateSimilarity(item1,item2); - assertNotNull(d2) - assertEquals(d1,d2); - assertEquals(3,d1); - } - - /* - * Parameters.class - */ - - @Test - void parametersTest() { - assertEquals(16,Parameters.parameters.binaryStringLength); - assertEquals(8,Parameters.parameters.similarityThreshold); - } - -} diff --git a/src/test/groovy/UtilsTests.groovy b/src/test/groovy/UtilsTests.groovy new file mode 100644 index 0000000..47fcd1f --- /dev/null +++ b/src/test/groovy/UtilsTests.groovy @@ -0,0 +1,68 @@ +package net.vveitas.offernet + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.Assert.* +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; +import org.junit.BeforeClass; +import org.junit.AfterClass; + +import org.apache.log4j.PropertyConfigurator +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import akka.actor.Props +import akka.actor.ActorSystem; +import akka.actor.ActorRef; + +import akka.testkit.TestActorRef +import akka.testkit.JavaTestKit; + +public class UtilsTests { + static private OfferNet on = new OfferNet().flushVertices(); + static private Logger logger; + static ActorSystem system = ActorSystem.create(); + + @BeforeClass + static void initLogging() { + def config = new ConfigSlurper().parse(new File('configs/log4j-properties.groovy').toURL()) + PropertyConfigurator.configure(config.toProperties()) + logger = LoggerFactory.getLogger('Tests.class'); + } + + @Test + void generateBinaryStringTest() { + String string = Utils.generateBinaryString(Parameters.parameters.binaryStringLength); + assertEquals(16,string.length()); + assertTrue(string.toSet().sort().join() == '01' | string.toSet().sort().join() == '10'); + } + + @Test + void createChainTest() { + List chain = Utils.createChain(5) + assertEquals(5,chain.size()); + } + + @Test + void calculateSimilarityTest() { + String value1 = "000000" + String value2 = "000111" + def d1 = Utils.veitasSimilarity(value1,value2); + assertNotNull(d1) + def agent = TestActorRef.create(system, Agent.props(on.session)).underlyingActor(); + def work = agent.ownsWork(value1,value2); + def item1 = agent.getWorksItems(work,"demands")[0] + def item2 = agent.getWorksItems(work,"offers")[0] + assertNotNull(item1) + assertNotNull(item2) + def d2 = Utils.calculateSimilarity(item1,item2); + assertNotNull(d2) + assertEquals(d1,d2); + assertEquals(3,d1); + } + +} \ No newline at end of file