diff options
author | Martin <marcin.j.chrzanowski@gmail.com> | 2019-12-30 13:18:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-30 13:18:04 +0100 |
commit | 75d494c5b14093efbf38d5def9d67e26fd99c253 (patch) | |
tree | 9a322a93a6786002a7324a1e17e7da6c0d493eb4 | |
parent | 7f03e1ddbd73831499d63eee1075b0b1226fa173 (diff) | |
parent | c6f148b33422f0d1660a4289f413193011736475 (diff) |
Merge pull request #78 from m-chrzan/qurnik
Run queries with Qurnik
10 files changed, 403 insertions, 36 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java new file mode 100644 index 0000000..0161a37 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java @@ -0,0 +1,25 @@ +package pl.edu.mimuw.cloudatlas.agent.messages; + +import pl.edu.mimuw.cloudatlas.agent.modules.Module; +import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType; + +public abstract class QurnikMessage extends AgentMessage { + public enum Type { + RUN_QUERIES + } + + private Type type; + + public QurnikMessage(String messageId, long timestamp, Type type) { + super(messageId, ModuleType.QUERY, timestamp); + this.type = type; + } + + public Type getType() { + return type; + } + + public void callMe(Module module) throws InterruptedException, Module.InvalidMessageType { + module.handleTyped(this); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java new file mode 100644 index 0000000..35f7819 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java @@ -0,0 +1,9 @@ +package pl.edu.mimuw.cloudatlas.agent.messages; + +import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType; + +public class RunQueriesMessage extends QurnikMessage { + public RunQueriesMessage(String messageId, long timestamp) { + super(messageId, timestamp, Type.RUN_QUERIES); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java index d0bf083..ba5e1d1 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java @@ -3,6 +3,7 @@ package pl.edu.mimuw.cloudatlas.agent.modules; import pl.edu.mimuw.cloudatlas.agent.Executor; import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage; import pl.edu.mimuw.cloudatlas.agent.messages.TimerSchedulerMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.QurnikMessage; import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage; import pl.edu.mimuw.cloudatlas.agent.messages.RMIMessage; import pl.edu.mimuw.cloudatlas.agent.messages.StanikMessage; @@ -32,6 +33,10 @@ public abstract class Module { throw new InvalidMessageType("Got a TimerSchedulerMessage in module " + moduleType.toString()); } + public void handleTyped(QurnikMessage message) throws InterruptedException, InvalidMessageType { + throw new InvalidMessageType("Got a QurnikMessage in module " + moduleType.toString()); + } + public void handleTyped(RMIMessage message) throws InterruptedException, InvalidMessageType { throw new InvalidMessageType("Got an RMIMessage in module " + moduleType.toString()); } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java new file mode 100644 index 0000000..9b7268a --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java @@ -0,0 +1,105 @@ +package pl.edu.mimuw.cloudatlas.agent.modules; + +import java.util.List; +import java.util.LinkedList; +import java.util.Map.Entry; + +import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.QurnikMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.RunQueriesMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.StateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage; +import pl.edu.mimuw.cloudatlas.interpreter.Interpreter; +import pl.edu.mimuw.cloudatlas.interpreter.InterpreterException; +import pl.edu.mimuw.cloudatlas.interpreter.QueryResult; +import pl.edu.mimuw.cloudatlas.model.Attribute; +import pl.edu.mimuw.cloudatlas.model.AttributesMap; +import pl.edu.mimuw.cloudatlas.model.AttributesUtil; +import pl.edu.mimuw.cloudatlas.model.PathName; +import pl.edu.mimuw.cloudatlas.model.TypePrimitive; +import pl.edu.mimuw.cloudatlas.model.Value; +import pl.edu.mimuw.cloudatlas.model.ValueQuery; +import pl.edu.mimuw.cloudatlas.model.ValueString; +import pl.edu.mimuw.cloudatlas.model.ValueTime; +import pl.edu.mimuw.cloudatlas.model.ValueUtils; +import pl.edu.mimuw.cloudatlas.model.ZMI; + +public class Qurnik extends Module { + public Qurnik() { + super(ModuleType.QUERY); + } + + @Override + public void handleTyped(QurnikMessage message) throws InterruptedException, InvalidMessageType { + switch (message.getType()) { + case RUN_QUERIES: + handleRunQueries((RunQueriesMessage) message); + break; + default: + throw new InvalidMessageType("This type of message cannot be handled by Qurnik"); + } + } + + @Override + public void handleTyped(ResponseMessage message) throws InterruptedException, InvalidMessageType { + switch (message.getType()) { + case STATE: + runQueriesOnState((StateMessage) message); + break; + default: + throw new InvalidMessageType("This type of message cannot be handled by Qurnik"); + } + } + + private void handleRunQueries(RunQueriesMessage message) throws InterruptedException { + GetStateMessage getStateMessage = new GetStateMessage("", 0, ModuleType.QUERY, 0); + sendMessage(getStateMessage); + } + + private void runQueriesOnState(StateMessage message) throws InterruptedException { + List<ValueQuery> queries = new LinkedList(); + for (Entry<ValueQuery, ValueTime> timestampedQuery : message.getQueries().values()) { + queries.add(timestampedQuery.getKey()); + } + executeAllQueries(message.getZMI(), queries, PathName.ROOT); + } + + private void executeAllQueries(ZMI zmi, List<ValueQuery> queries, PathName currentPath) throws InterruptedException { + if(!zmi.getSons().isEmpty()) { + for(ZMI son : zmi.getSons()) { + Value sonName = son.getAttributes().getOrNull("name"); + if (ValueUtils.valueNonNullOfType(sonName, TypePrimitive.STRING)) { + String sonNameString = ((ValueString) sonName).getValue(); + executeAllQueries(son, queries, currentPath.levelDown(sonNameString)); + } else { + System.out.println("ERROR: zone without a name attribute found while executing queries"); + } + } + + Interpreter interpreter = new Interpreter(zmi); + AttributesMap newAttributes = new AttributesMap(); + for (ValueQuery query : queries) { + try { + List<QueryResult> result = interpreter.interpretProgram(query.getQuery()); + for(QueryResult r : result) { + newAttributes.addOrChange(r.getName(), r.getValue()); + } + } catch(InterpreterException exception) { + System.out.println("ERROR: thrown while running interpreter: " + exception.getMessage()); + } + } + + if (!currentPath.toString().equals("/")) { + newAttributes.add("name", new ValueString(currentPath.getSingletonName())); + } + long currentTime = System.currentTimeMillis(); + newAttributes.add("timestamp", new ValueTime(currentTime)); + + AttributesUtil.transferAttributes(newAttributes, zmi.getAttributes()); + + UpdateAttributesMessage message = new UpdateAttributesMessage("", currentTime, currentPath.toString(), newAttributes); + sendMessage(message); + } + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java index e8721b3..4694219 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java @@ -12,6 +12,7 @@ import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage; import pl.edu.mimuw.cloudatlas.agent.messages.UpdateQueriesMessage; import pl.edu.mimuw.cloudatlas.model.Attribute; import pl.edu.mimuw.cloudatlas.model.AttributesMap; +import pl.edu.mimuw.cloudatlas.model.AttributesUtil; import pl.edu.mimuw.cloudatlas.model.PathName; import pl.edu.mimuw.cloudatlas.model.Type; import pl.edu.mimuw.cloudatlas.model.TypePrimitive; @@ -67,7 +68,7 @@ public class Stanik extends Module { ZMI zone = hierarchy.findDescendant(message.getPathName()); AttributesMap attributes = zone.getAttributes(); if (valueLower(attributes.get("timestamp"), message.getAttributes().get("timestamp"))) { - transferAttributes(message.getAttributes(), attributes); + AttributesUtil.transferAttributes(message.getAttributes(), attributes); } else { System.out.println("DEBUG: not applying update with older attributes"); } @@ -127,21 +128,6 @@ public class Stanik extends Module { return value != null && !value.isNull() && value.getType().isCompatible(type); } - private void transferAttributes(AttributesMap fromAttributes, AttributesMap toAttributes) { - Iterator<Entry<Attribute, Value>> iterator = toAttributes.iterator(); - while (iterator.hasNext()) { - Entry<Attribute, Value> entry = iterator.next(); - Attribute attribute = entry.getKey(); - Value newValue = fromAttributes.getOrNull(attribute); - if (newValue == null) { - iterator.remove(); - } - } - for (Entry<Attribute, Value> entry : fromAttributes) { - toAttributes.addOrChange(entry.getKey(), entry.getValue()); - } - } - private void addMissingZones(PathName path) { try { if (!hierarchy.descendantExists(path)) { diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesUtil.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesUtil.java new file mode 100644 index 0000000..cd2ae91 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesUtil.java @@ -0,0 +1,21 @@ +package pl.edu.mimuw.cloudatlas.model; + +import java.util.Iterator; +import java.util.Map.Entry; + +public class AttributesUtil { + public static void transferAttributes(AttributesMap fromAttributes, AttributesMap toAttributes) { + Iterator<Entry<Attribute, Value>> iterator = toAttributes.iterator(); + while (iterator.hasNext()) { + Entry<Attribute, Value> entry = iterator.next(); + Attribute attribute = entry.getKey(); + Value newValue = fromAttributes.getOrNull(attribute); + if (newValue == null) { + iterator.remove(); + } + } + for (Entry<Attribute, Value> entry : fromAttributes) { + toAttributes.addOrChange(entry.getKey(), entry.getValue()); + } + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java new file mode 100644 index 0000000..01a45b5 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java @@ -0,0 +1,7 @@ +package pl.edu.mimuw.cloudatlas.model; + +public class ValueUtils { + public static boolean valueNonNullOfType(Value value, Type type) { + return value != null && !value.isNull() && value.getType().isCompatible(type); + } +} diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/QurnikTest.java b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/QurnikTest.java new file mode 100644 index 0000000..0c10092 --- /dev/null +++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/QurnikTest.java @@ -0,0 +1,203 @@ +package pl.edu.mimuw.cloudatlas.agent.modules; + +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.RunQueriesMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.StanikMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.StateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage; +import pl.edu.mimuw.cloudatlas.agent.MockExecutor; +import pl.edu.mimuw.cloudatlas.model.Attribute; +import pl.edu.mimuw.cloudatlas.model.AttributesMap; +import pl.edu.mimuw.cloudatlas.model.TestUtil; +import pl.edu.mimuw.cloudatlas.model.ValueInt; +import pl.edu.mimuw.cloudatlas.model.ValueQuery; +import pl.edu.mimuw.cloudatlas.model.ValueString; +import pl.edu.mimuw.cloudatlas.model.ValueTime; +import pl.edu.mimuw.cloudatlas.model.ZMI; + +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +public class QurnikTest { + private Qurnik qurnik; + private MockExecutor executor; + + @Before + public void setupLocals() { + qurnik = new Qurnik(); + executor = new MockExecutor(qurnik); + } + + @Test + public void runQueriesRequestsState() throws Exception { + RunQueriesMessage message = new RunQueriesMessage("", 0); + qurnik.handleTyped(message); + AgentMessage receivedMessage = (AgentMessage) executor.messagesToPass.take(); + assertEquals(ModuleType.STATE, receivedMessage.getDestinationModule()); + StanikMessage stanikMessage = (StanikMessage) receivedMessage; + assertEquals(StanikMessage.Type.GET_STATE, stanikMessage.getType()); + GetStateMessage getStateMessage = (GetStateMessage) stanikMessage; + assertEquals(ModuleType.QUERY, getStateMessage.getRequestingModule()); + } + + @Test + public void simpleQuery() throws Exception { + ZMI root = new ZMI(); + ZMI son = new ZMI(root); + root.addSon(son); + AttributesMap sonAttributes = new AttributesMap(); + sonAttributes.add("name", new ValueString("son")); + Map<Attribute, Entry<ValueQuery, ValueTime>> queries = new HashMap(); + queries.put( + new Attribute("&query"), + new SimpleImmutableEntry( + new ValueQuery("SELECT 1 AS one"), + new ValueTime(0l) + ) + ); + StateMessage message = new StateMessage("", ModuleType.QUERY, 0, 0, root, queries); + long timeBefore = System.currentTimeMillis(); + qurnik.handleTyped(message); + long timeAfter = System.currentTimeMillis(); + + assertEquals(1, executor.messagesToPass.size()); + AgentMessage receivedMessage = (AgentMessage) executor.messagesToPass.take(); + assertEquals(ModuleType.STATE, receivedMessage.getDestinationModule()); + StanikMessage stanikMessage = (StanikMessage) receivedMessage; + assertEquals(StanikMessage.Type.UPDATE_ATTRIBUTES, stanikMessage.getType()); + UpdateAttributesMessage updateAttributesMessage = (UpdateAttributesMessage) stanikMessage; + assertEquals("/", updateAttributesMessage.getPathName()); + AttributesMap updatedAttributes = updateAttributesMessage.getAttributes(); + assertEquals(2, TestUtil.iterableSize(updatedAttributes)); + assertEquals(new ValueInt(1l), updatedAttributes.getOrNull("one")); + long timestamp = ((ValueTime) updatedAttributes.getOrNull("timestamp")).getValue(); + assertTrue(timeBefore <= timestamp); + assertTrue(timestamp <= timeAfter); + } + + private ZMI setupSampleHierarchy() { + ZMI root = new ZMI(); + + ZMI uw = new ZMI(root); + root.addSon(uw); + ZMI pw = new ZMI(root); + root.addSon(pw); + + ZMI uw1 = new ZMI(uw); + uw.addSon(uw1); + ZMI uw2 = new ZMI(uw); + uw.addSon(uw2); + + AttributesMap uwAttributes = uw.getAttributes(); + uwAttributes.add("name", new ValueString("uw")); + + AttributesMap pwAttributes = pw.getAttributes(); + pwAttributes.add("name", new ValueString("pw")); + pwAttributes.add("x", new ValueInt(42l)); + pwAttributes.add("y", new ValueInt(250l)); + pwAttributes.add("z", new ValueInt(5l)); + + AttributesMap uw1Attributes = uw1.getAttributes(); + uw1Attributes.add("name", new ValueString("uw1")); + uw1Attributes.add("x", new ValueInt(12l)); + uw1Attributes.add("y", new ValueInt(100l)); + uw1Attributes.add("a", new ValueInt(123l)); + + AttributesMap uw2Attributes = uw2.getAttributes(); + uw2Attributes.add("name", new ValueString("uw2")); + uw2Attributes.add("x", new ValueInt(13l)); + uw2Attributes.add("a", new ValueInt(134l)); + uw2Attributes.add("b", new ValueInt(777l)); + + return root; + } + + public Map<Attribute, Entry<ValueQuery, ValueTime>> setupSampleQueries() throws Exception { + Map<Attribute, Entry<ValueQuery, ValueTime>> queries = new HashMap(); + + queries.put( + new Attribute("&query1"), + new SimpleImmutableEntry( + new ValueQuery("SELECT sum(x) AS x"), + new ValueTime(0l) + ) + ); + queries.put( + new Attribute("&query2"), + new SimpleImmutableEntry( + new ValueQuery("SELECT min(y) AS y"), + new ValueTime(0l) + ) + ); + queries.put( + new Attribute("&query3"), + new SimpleImmutableEntry( + new ValueQuery("SELECT max(z) AS z"), + new ValueTime(0l) + ) + ); + queries.put( + new Attribute("&query4"), + new SimpleImmutableEntry( + new ValueQuery("SELECT sum(a + 1) AS a"), + new ValueTime(0l) + ) + ); + queries.put( + new Attribute("&query5"), + new SimpleImmutableEntry( + new ValueQuery("SELECT sum(2 * b) AS b"), + new ValueTime(0l) + ) + ); + + return queries; + } + + @Test + public void multipleQueries() throws Exception { + ZMI root = setupSampleHierarchy(); + + Map<Attribute, Entry<ValueQuery, ValueTime>> queries = setupSampleQueries(); + StateMessage message = new StateMessage("", ModuleType.QUERY, 0, 0, root, queries); + long timeBefore = System.currentTimeMillis(); + qurnik.handleTyped(message); + long timeAfter = System.currentTimeMillis(); + + assertEquals(2, executor.messagesToPass.size()); + + UpdateAttributesMessage message1 = (UpdateAttributesMessage) executor.messagesToPass.take(); + assertEquals("/uw", message1.getPathName()); + AttributesMap attributes1 = message1.getAttributes(); + assertEquals(6, TestUtil.iterableSize(attributes1)); + assertEquals(new ValueString("uw"), attributes1.getOrNull("name")); + assertEquals(new ValueInt(25l), attributes1.getOrNull("x")); + assertEquals(new ValueInt(100l), attributes1.getOrNull("y")); + assertEquals(new ValueInt(259l), attributes1.getOrNull("a")); + assertEquals(new ValueInt(1554l), attributes1.getOrNull("b")); + long timestamp1 = ((ValueTime) attributes1.getOrNull("timestamp")).getValue(); + assertTrue(timeBefore <= timestamp1); + assertTrue(timestamp1 <= timeAfter); + + UpdateAttributesMessage message2 = (UpdateAttributesMessage) executor.messagesToPass.take(); + assertEquals("/", message2.getPathName()); + AttributesMap attributes2 = message2.getAttributes(); + System.out.println("got attributes " + attributes2.toString()); + assertEquals(6, TestUtil.iterableSize(attributes2)); + assertEquals(new ValueInt(67l), attributes2.getOrNull("x")); + assertEquals(new ValueInt(100l), attributes2.getOrNull("y")); + assertEquals(new ValueInt(5l), attributes2.getOrNull("z")); + assertEquals(new ValueInt(260l), attributes2.getOrNull("a")); + assertEquals(new ValueInt(3108l), attributes2.getOrNull("b")); + long timestamp2 = ((ValueTime) attributes2.getOrNull("timestamp")).getValue(); + assertTrue(timeBefore <= timestamp2); + assertTrue(timestamp2 <= timeAfter); + } +} diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java index aeaf19f..8958472 100644 --- a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java +++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java @@ -1,7 +1,5 @@ package pl.edu.mimuw.cloudatlas.agent.modules; -import java.util.Iterator; -import java.util.List; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.HashMap; import java.util.Map; @@ -16,6 +14,7 @@ import pl.edu.mimuw.cloudatlas.agent.messages.UpdateQueriesMessage; import pl.edu.mimuw.cloudatlas.agent.MockExecutor; import pl.edu.mimuw.cloudatlas.model.Attribute; import pl.edu.mimuw.cloudatlas.model.AttributesMap; +import pl.edu.mimuw.cloudatlas.model.TestUtil; import pl.edu.mimuw.cloudatlas.model.Value; import pl.edu.mimuw.cloudatlas.model.ValueInt; import pl.edu.mimuw.cloudatlas.model.ValueQuery; @@ -32,7 +31,7 @@ public class StanikTest { private MockExecutor executor; @Before - public void setupEventBus() { + public void setupLocals() { stanik = new Stanik(); executor = new MockExecutor(stanik); } @@ -50,9 +49,9 @@ public class StanikTest { ZMI zmi = stateMessage.getZMI(); assertNull(zmi.getFather()); assertTrue(zmi.getSons().isEmpty()); - assertEquals(1, iterableSize(zmi.getAttributes())); + assertEquals(1, TestUtil.iterableSize(zmi.getAttributes())); Map<Attribute, Entry<ValueQuery, ValueTime>> queries = stateMessage.getQueries(); - assertEquals(0, iterableSize(queries.keySet())); + assertEquals(0, TestUtil.iterableSize(queries.keySet())); } @Test @@ -81,7 +80,7 @@ public class StanikTest { UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/", attributes); stanik.handleTyped(message); AttributesMap actualAttributes = stanik.getHierarchy().getAttributes(); - assertEquals(3, iterableSize(actualAttributes)); + assertEquals(3, TestUtil.iterableSize(actualAttributes)); assertEquals(new ValueInt(1337l), actualAttributes.get("foo")); assertEquals(new ValueString("baz"), actualAttributes.get("bar")); assertEquals(new ValueTime("2012/12/21 04:20:00.000"), actualAttributes.getOrNull("timestamp")); @@ -97,7 +96,7 @@ public class StanikTest { UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes); stanik.handleTyped(message); AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes(); - assertEquals(4, iterableSize(actualAttributes)); + assertEquals(4, TestUtil.iterableSize(actualAttributes)); assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo")); assertEquals(new ValueString("baz"), actualAttributes.getOrNull("bar")); assertEquals(new ValueString("new"), actualAttributes.getOrNull("name")); @@ -120,7 +119,7 @@ public class StanikTest { stanik.handleTyped(newMessage); AttributesMap actualAttributes = stanik.getHierarchy().getAttributes(); - assertEquals(2, iterableSize(actualAttributes)); + assertEquals(2, TestUtil.iterableSize(actualAttributes)); assertEquals(new ValueInt(1338l), actualAttributes.getOrNull("foo")); assertEquals(new ValueTime("2012/12/21 04:20:42.000"), actualAttributes.getOrNull("timestamp")); } @@ -140,7 +139,7 @@ public class StanikTest { stanik.handleTyped(newMessage); AttributesMap actualAttributes = stanik.getHierarchy().getAttributes(); - assertEquals(2, iterableSize(actualAttributes)); + assertEquals(2, TestUtil.iterableSize(actualAttributes)); assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo")); assertEquals(new ValueTime("2012/12/21 04:20:00.000"), actualAttributes.getOrNull("timestamp")); } @@ -153,7 +152,7 @@ public class StanikTest { stanik.handleTyped(message); HashMap<Attribute, Entry<ValueQuery, ValueTime>> actualQueries = stanik.getQueries(); - assertEquals(1, iterableSize(actualQueries.keySet())); + assertEquals(1, TestUtil.iterableSize(actualQueries.keySet())); assertTrue(actualQueries.containsKey(new Attribute("&query"))); Entry<ValueQuery, ValueTime> timestampedQuery = actualQueries.get(new Attribute("&query")); assertEquals(new ValueTime(42l), timestampedQuery.getValue()); @@ -177,7 +176,7 @@ public class StanikTest { stanik.handleTyped(otherMessage); HashMap<Attribute, Entry<ValueQuery, ValueTime>> actualQueries = stanik.getQueries(); - assertEquals(4, iterableSize(actualQueries.keySet())); + assertEquals(4, TestUtil.iterableSize(actualQueries.keySet())); assertTrue(actualQueries.containsKey(new Attribute("&query1"))); assertTrue(actualQueries.containsKey(new Attribute("&query2"))); assertTrue(actualQueries.containsKey(new Attribute("&query3"))); @@ -199,13 +198,4 @@ public class StanikTest { assertEquals(new ValueTime(43l), timestampedQuery4.getValue()); assertEquals(new ValueQuery("SELECT 1000 AS foo"), timestampedQuery4.getKey()); } - - public <T> int iterableSize(Iterable<T> iterable) { - int count = 0; - for (T attribute : iterable) { - count++; - } - - return count; - } } diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/model/TestUtil.java b/src/test/java/pl/edu/mimuw/cloudatlas/model/TestUtil.java new file mode 100644 index 0000000..ed633d7 --- /dev/null +++ b/src/test/java/pl/edu/mimuw/cloudatlas/model/TestUtil.java @@ -0,0 +1,16 @@ +package pl.edu.mimuw.cloudatlas.model; + +public class TestUtil { + public static boolean valueLower(Value a, Value b) { + return ((ValueBoolean) a.isLowerThan(b)).getValue(); + } + + public static <T> int iterableSize(Iterable<T> iterable) { + int count = 0; + for (T attribute : iterable) { + count++; + } + + return count; + } +} |