Skip to content
Snippets Groups Projects
Commit 221fa66e authored by René Schöne's avatar René Schöne
Browse files

WIP: Working on bugfixes for attributes

- compare params for list NTAs when indexed
- simplify observer add
- add Gradle task to run using parameters.txt (line-separated parameters, with #-comments)
parent 130bc9d1
No related branches found
No related tags found
1 merge request!32Resolve "Allow collection and circular attributes as endpoint targets"
Pipeline #13816 failed
This commit is part of merge request !32. Comments created here will be created in the context of that merge request.
......@@ -3,3 +3,4 @@ src/gen-res/
src/gen/
out/
*.class
/parameters.txt
......@@ -187,6 +187,15 @@ ext {
}
application.mainClassName = "${mainClassName}"
task runParameters(type: JavaExec) {
group 'application'
description 'Run using parameters.txt (line-separated with comments)'
classpath sourceSets.main.runtimeClasspath
main = "org.jastadd.ragconnect.compiler.Compiler"
args new File('ragconnect.base/parameters.txt').text.strip().split("\n").dropWhile { it.startsWith("#") }
standardInput = System.in
}
jar {
manifest.attributes "Main-Class": "${mainClassName}"
}
......
......@@ -521,14 +521,14 @@ aspect MustacheSendDefinition {
java.util.List<SendIncrementalObserverEntry> result = new java.util.ArrayList<>();
// "{{getterMethodName}}{{#IndexBasedListAccess}}_int{{/IndexBasedListAccess}}"
result.add(SendIncrementalObserverEntry.of(getterMethodName() + (getIndexBasedListAccess() ? "_int" : ""),
getIndexBasedListAccess(), "index"));
getIndexBasedListAccess(), getIndexBasedListAccess() ? "index" : "null"));
if (indexBasedAccessAndTargetIsNTA()) {
// "{{getterMethodName}}List"
result.add(SendIncrementalObserverEntry.of(getterMethodName() + "List", false, "index"));
}
if (targetIsAttribute()) {
// "{{parentTypeName}}_{{getterMethodName}}{{#IndexBasedListAccess}}_int{{/IndexBasedListAccess}}"
result.add(SendIncrementalObserverEntry.of(parentTypeName() + "_" + getterMethodName() + (getIndexBasedListAccess() ? "_int" : ""), getIndexBasedListAccess(), "index"));
result.add(SendIncrementalObserverEntry.of(parentTypeName() + "_" + getterMethodName() + (getIndexBasedListAccess() ? "_int" : ""), getIndexBasedListAccess(), getIndexBasedListAccess() ? "index" : "null"));
}
return result;
}
......@@ -611,10 +611,10 @@ containingEndpointDefinition().getIndexBasedListAccess());
syn String EndpointDefinition.typeName() = type().getName();
syn String MEndpointDefinition.typeName() = getEndpointDefinition().typeName();
static SendIncrementalObserverEntry SendIncrementalObserverEntry.of(String attributeString, boolean useParams, Object params) {
static SendIncrementalObserverEntry SendIncrementalObserverEntry.of(String attributeString, boolean compareParams, Object params) {
return new SendIncrementalObserverEntry()
.setParams(useParams ? params : null)
.setCompareParams(useParams)
.setParams(params)
.setCompareParams(compareParams)
.setAttributeString(attributeString);
}
}
......
......@@ -163,36 +163,17 @@ aspect RagConnectObserver {
node.trace().setReceiver(this);
}
void add(RagConnectToken connectToken, ASTNode node, Runnable attributeCall, String... attributeStrings) {
internal_add(connectToken, node, attributeStrings, false, null, attributeCall);
}
void add(RagConnectToken connectToken, ASTNode node, Object params, Runnable attributeCall, String... attributeStrings) {
internal_add(connectToken, node, attributeStrings, true, params, attributeCall);
}
private void internal_add(RagConnectToken connectToken, ASTNode node, String[] attributeStrings,
boolean compareParams, Object params, Runnable attributeCall) {
if (attributeStrings.length == 0) {
{{logWarn}}("No attribute string given to observe for {{log_}}!", connectToken.uri);
}
for (String attributeString : attributeStrings) {
internal_add(connectToken, node, attributeString, compareParams, params, attributeCall);
}
}
private void internal_add(RagConnectToken connectToken, ASTNode node, String attributeString,
boolean compareParams, Object params, Runnable attributeCall) {
void add(RagConnectToken connectToken, ASTNode node, boolean compareParams, Object params,
Runnable attributeCall, String attributeString) {
{{#configLoggingEnabledForIncremental}}
{{logDebug}}("** observer add: {{log_}} on {{log_}}{{log_}}",
node, attributeString, (compareParams ? " (parameterized)" : ""));
{{/configLoggingEnabledForIncremental}}
// either add to an existing entry (with same node, attribute) or create new entry
//TODO check case, where runnable differs (and baseMembersEqual returns true). need list of runnables, and map<connectToken, runnable> to remove them!
// either add to an existing entry (with same node, attribute, params) or create new entry
boolean needNewEntry = true;
for (RagConnectObserverEntry entry : observedNodes) {
if (entry.baseMembersEqualTo(node, attributeString, true, params)) {
entry.connectList.add(connectToken);
{{logError}}("baseMembersEqualTo node: {{log_}} atrStr: {{log_}} compare: {{log_}} params: {{log_}}", node, attributeString, compareParams, params);
needNewEntry = false;
break;
}
......
......@@ -68,7 +68,8 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
{{observerInstanceSingletonMethodName}}().add(
connectToken,
this,
{{#CompareParams}}{{Params}},{{/CompareParams}}
{{CompareParams}},
{{Params}},
() -> {
if (this.{{updateMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}})) {
this.{{writeMethodName}}({{#IndexBasedListAccess}}index{{/IndexBasedListAccess}});
......
......@@ -3,12 +3,10 @@ package org.jastadd.ragconnect.tests;
import indexedSendInc.ast.*;
import org.assertj.core.api.Assertions;
import org.assertj.core.groups.Tuple;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.StringJoiner;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
......@@ -25,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* @author rschoene - Initial contribution
*/
@Tag("Incremental")
@Tag("New")
public class IndexedSendTest extends AbstractMqttTest {
private static final String TOPIC_A_MANY_NORMAL_WILDCARD = "a-many/#";
......@@ -100,27 +97,37 @@ public class IndexedSendTest extends AbstractMqttTest {
assertTrue(receiverRoot.connectManyAWithSuffix(mqttUri(TOPIC_A_MANY_SUFFIX_WILDCARD)));
// connect send, and wait to receive (if writeCurrentValue is set)
assertTrue(connectNTAsInstead ?
senderRoot.connectA(mqttUri(TOPIC_A_MANY_NORMAL_0), 0, isWriteCurrentValue()) :
senderRoot.connectMultipleA(mqttUri(TOPIC_A_MANY_NORMAL_0), 0, isWriteCurrentValue()));
assertConnectAOrMultipleA(TOPIC_A_MANY_NORMAL_0, 0);
waitForValue(receiverRoot::getNumManyA, 1);
assertTrue(connectNTAsInstead ?
senderRoot.connectA(mqttUri(TOPIC_A_MANY_NORMAL_1), 1, isWriteCurrentValue()) :
senderRoot.connectMultipleA(mqttUri(TOPIC_A_MANY_NORMAL_1), 1, isWriteCurrentValue()));
assertConnectAOrMultipleA(TOPIC_A_MANY_NORMAL_1, 1);
waitForValue(receiverRoot::getNumManyA, 2);
assertTrue(connectNTAsInstead ?
senderRoot.connectComputedA(mqttUri(TOPIC_A_MANY_SUFFIX_0), 0, isWriteCurrentValue()) :
senderRoot.connectMultipleAWithSuffix(mqttUri(TOPIC_A_MANY_SUFFIX_0), 0, isWriteCurrentValue()));
assertConnectComputedAOrMultipleAWithSuffix(TOPIC_A_MANY_SUFFIX_0, 0);
waitForValue(receiverRoot::getNumManyAWithSuffix, 1);
assertTrue(connectNTAsInstead ?
senderRoot.connectComputedA(mqttUri(TOPIC_A_MANY_SUFFIX_1), 1, isWriteCurrentValue()) :
senderRoot.connectMultipleAWithSuffix(mqttUri(TOPIC_A_MANY_SUFFIX_1), 1, isWriteCurrentValue()));
assertConnectComputedAOrMultipleAWithSuffix(TOPIC_A_MANY_SUFFIX_1, 1);
waitForValue(receiverRoot::getNumManyAWithSuffix, 2);
}
private void assertConnectAOrMultipleA(String topic, int index) throws IOException {
assertTrue(connectNTAsInstead ?
senderRoot.connectA(mqttUri(topic), index, isWriteCurrentValue()) :
senderRoot.connectMultipleA(mqttUri(topic), index, isWriteCurrentValue()));
}
private void assertConnectComputedAOrMultipleAWithSuffix(String topic, int index) throws IOException {
assertTrue(connectNTAsInstead ?
senderRoot.connectComputedA(mqttUri(topic), index, isWriteCurrentValue()) :
senderRoot.connectMultipleAWithSuffix(mqttUri(topic), index, isWriteCurrentValue()));
}
private void assertDisconnectComputedAOrMultipleAWithSuffix(String topic) throws IOException {
assertTrue(connectNTAsInstead ?
senderRoot.disconnectComputedA(mqttUri(topic)) :
senderRoot.disconnectMultipleAWithSuffix(mqttUri(topic)));
}
private void checkList(String name, Tuple expected, Supplier<JastAddList<A>> actual) {
Assertions.assertThat(actual.get()).extracting("Value")
.as(name)
......@@ -199,13 +206,10 @@ public class IndexedSendTest extends AbstractMqttTest {
.put(CHECK_MANY_A, manyAtIndex1 != null ? tuple("changedValue", manyAtIndex1) : tuple("changedValue"))
.check();
if (!connectNTAsInstead) { return; } // TODO remove after testing NTAs is complete
// setting same value must not change data, and must not trigger a new sent message
listA0.setValue("changedValue");
checker.check();
logger.error(prettyPrint(senderRoot.getAList()));
listA1.setValue("");
checker.incNumberOfValues().put(CHECK_MANY_A, tuple("changedValue", "")).check();
......@@ -216,26 +220,39 @@ public class IndexedSendTest extends AbstractMqttTest {
.check();
// adding a new element does not automatically send it
A listA3InSuffix = createA("out");
senderRoot.addMultipleAWithSuffix(listA3InSuffix);
A listA2InSuffix = createA("out");
senderRoot.addMultipleAWithSuffix(listA2InSuffix);
checker.check();
// only after connecting it, the element gets sent
assertTrue(senderRoot.connectMultipleAWithSuffix(mqttUri(TOPIC_A_MANY_SUFFIX_2), 2, true));
// only after connecting it, the element gets sent (for SendInitialValue case)
assertConnectComputedAOrMultipleAWithSuffix(TOPIC_A_MANY_SUFFIX_2, 2);
if (isWriteCurrentValue()) {
checker.incNumberOfValues()
.put(CHECK_WITH_SUFFIX, suffixAtIndex0 != null ? tuple(suffixAtIndex0, "repost", "outpost") : tuple("repost", "outpost"))
.check();
.put(CHECK_WITH_SUFFIX, suffixAtIndex0 != null ? tuple(suffixAtIndex0, "repost", "outpost") : tuple("repost", "outpost"));
}
checker.check();
// after successful disconnect, no messages will be sent
assertTrue(senderRoot.disconnectMultipleAWithSuffix(mqttUri(TOPIC_A_MANY_SUFFIX_0)));
// changing the value of the newly added element will send it
listA2InSuffix.setValue("goal");
checker.incNumberOfValues()
.put(CHECK_WITH_SUFFIX, suffixAtIndex0 != null ? tuple(suffixAtIndex0, "repost", "goalpost") : tuple("repost", "goalpost"));
checker.check();
// after successful disconnect for index 0, no messages will be sent
assertDisconnectComputedAOrMultipleAWithSuffix(TOPIC_A_MANY_SUFFIX_0);
listA0InSuffix.setValue("willBeIgnored");
checker.check();
}
private String prettyPrint(JastAddList<A> aList) {
StringJoiner sj = new StringJoiner(", ", "[", "]");
aList.forEach(a -> sj.add(a.getValue() + "(" + a.getInner().getInnerValue() + ")"));
return sj.toString();
// for index 1 (not disconnected), messages will be sent still
listA1InSuffix.setValue("sign");
checker.incNumberOfValues()
.put(CHECK_WITH_SUFFIX, suffixAtIndex0 != null ? tuple(suffixAtIndex0, "signpost", "goalpost") : tuple("signpost", "goalpost"))
.check();
// after successful disconnect for index 1, no messages will be sent anymore
assertDisconnectComputedAOrMultipleAWithSuffix(TOPIC_A_MANY_SUFFIX_1);
listA1InSuffix.setValue("willBeIgnored");
checker.check();
}
@Override
......
......@@ -27,9 +27,7 @@ import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static java.util.Collections.addAll;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.util.Lists.newArrayList;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
......@@ -99,6 +97,12 @@ public class TestUtils {
return outPath;
}
public static <T> String prettyPrint(Iterable<T> aList, Function<T, String> elementPrinter) {
StringJoiner sj = new StringJoiner(", ", "[", "]");
aList.forEach(element -> sj.add(elementPrinter.apply(element)));
return sj.toString();
}
public static void assertLinesMatch(String directory, String expectedName, String out) throws IOException {
Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX)
.resolve(directory)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment