Skip to content
Snippets Groups Projects
Commit 39f1effb authored by Sebastian Ebert's avatar Sebastian Ebert
Browse files

merged upstream master in fork-master

parents 38c4a6a2 24062cab
Branches
No related tags found
1 merge request!11Merge/dev to fork master merge
Showing
with 1865 additions and 0 deletions
# Tutorial
Idea: Test the example from the [documentation](https://jastadd.pages.st.inf.tu-dresden.de/ragconnect/using.html)
// endpoint definitions
receive A.Input ;
send A.OutputOnA ;
send B.OutputOnB using Transformation ;
// mapping definitions
Transformation maps String s to String {:
return s + "postfix";
:}
// dependency definitions
A.OutputOnA canDependOn A.Input as dependencyA ;
B.OutputOnB canDependOn A.Input as dependencyB ;
aspect Computation {
syn String A.getOutputOnA() = "a" + getInput();
syn String B.getOutputOnB() = "b" + input();
inh String B.input();
eq A.getB().input() = getInput();
}
A ::= <Input:String> /<OutputOnA:String>/ B* ;
B ::= /<OutputOnB:String>/ ;
receive A.Mqtt2MqttInput using MarkMqttInput ;
receive A.Rest2RestInput using MarkRestInput ;
receive A.Mqtt2RestInput using MarkMqttInput ;
receive A.Rest2MqttInput using MarkRestInput ;
receive A.Both2BothInput ;
send A.Mqtt2MqttOutput using MarkMqttOutput ;
send A.Rest2RestOutput using MarkRestOutput ;
send A.Mqtt2RestOutput using MarkRestOutput ;
send A.Rest2MqttOutput using MarkMqttOutput ;
send A.Both2RestOutput using MarkRestOutput ;
send A.Both2MqttOutput using MarkMqttOutput ;
A.Mqtt2MqttOutput canDependOn A.Mqtt2MqttInput as dependencyMqtt2Mqtt ;
A.Rest2RestOutput canDependOn A.Rest2RestInput as dependencyRest2Rest ;
A.Mqtt2RestOutput canDependOn A.Mqtt2RestInput as dependencyMqtt2Rest ;
A.Rest2MqttOutput canDependOn A.Rest2MqttInput as dependencyRest2Mqtt ;
A.Both2RestOutput canDependOn A.Both2BothInput as dependencyBoth2Rest ;
A.Both2MqttOutput canDependOn A.Both2BothInput as dependencyBoth2Mqtt ;
MarkMqttInput maps String s to String {:
return "FromMqtt-" + s;
:}
MarkRestInput maps String s to String {:
return "FromRest-" + s;
:}
MarkMqttOutput maps String s to String {:
return s + "-ToMqtt";
:}
MarkRestOutput maps String s to String {:
return s + "-ToRest";
:}
aspect Computation {
syn lazy String A.getMqtt2MqttOutput() = getMqtt2MqttInput() + "-M2M" ;
syn lazy String A.getRest2RestOutput() = getRest2RestInput() + "-R2R" ;
syn lazy String A.getMqtt2RestOutput() = getMqtt2RestInput() + "-M2R" ;
syn lazy String A.getRest2MqttOutput() = getRest2MqttInput() + "-R2M" ;
syn lazy String A.getBoth2MqttOutput() = getBoth2BothInput() + "-B2M" ;
syn lazy String A.getBoth2RestOutput() = getBoth2BothInput() + "-B2R" ;
}
A ::= <Mqtt2MqttInput> /<Mqtt2MqttOutput>/
<Rest2RestInput> /<Rest2RestOutput>/
<Mqtt2RestInput> /<Mqtt2RestOutput>/
<Rest2MqttInput> /<Rest2MqttOutput>/
<Both2BothInput> /<Both2MqttOutput>/ /<Both2RestOutput>/;
*
!.gitignore
*
!.gitignore
*
!.gitignore
package org.jastadd.ragconnect.tests;
import defaultOnlyRead.ast.MqttHandler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* Base class for tests ensuring running mqtt broker.
*
* @author rschoene - Initial contribution
*/
@Tag("mqtt")
public abstract class AbstractMqttTest {
static boolean checkDone = false;
static Boolean checkResult;
@BeforeAll
public static void checkMqttConnection() {
if (!checkDone) {
checkDone = true;
try {
checkResult = new MqttHandler()
.dontSendWelcomeMessage()
.setHost(TestUtils.getMqttHost())
.waitUntilReady(2, TimeUnit.SECONDS);
} catch (IOException e) {
checkResult = false;
}
}
if (!checkResult) {
throw new IllegalStateException("Mqtt Broker not ready!");
}
}
@Test
public final void buildModel() {
createModel();
}
@Tag("mqtt")
@Test
public final void testCommunicateSendInitialValue() throws IOException, InterruptedException {
createModel();
setupReceiverAndConnect(true);
communicateSendInitialValue();
}
protected abstract void communicateSendInitialValue() throws InterruptedException;
@Tag("mqtt")
@Test
public final void testCommunicateOnlyUpdatedValue() throws IOException, InterruptedException {
createModel();
setupReceiverAndConnect(false);
communicateOnlyUpdatedValue();
}
protected abstract void communicateOnlyUpdatedValue() throws InterruptedException;
protected abstract void createModel();
/**
* Begin with this snippet
* <pre>
* model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
*
* handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
* assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
* </pre>
*
* And then add dependencies, initialise receiver, add connections to those receivers,
* and finally call generated connect* methods on model elements.
* @param writeCurrentValue
*/
protected abstract void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException;
@AfterEach
public void alwaysCloseConnections() {
closeConnections();
}
/**
* Write the following snippet (using your correct handler and model):
* <pre>
* if (handler != null) {
* handler.close();
* }
* if (model != null) {
* model.ragconnectCloseConnections();
* }
* </pre>
*/
protected abstract void closeConnections();
}
package org.jastadd.ragconnect.tests;
import defaultOnlyRead.ast.A;
import defaultOnlyRead.ast.BoxedTypes;
import defaultOnlyRead.ast.MqttHandler;
import defaultOnlyRead.ast.NativeTypes;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "defaultOnlyRead".
*
* @author rschoene - Initial contribution
*/
public class DefaultOnlyReadTest extends AbstractMqttTest {
private static final String TOPIC_NATIVE_INT = "native/int";
private static final String TOPIC_NATIVE_SHORT = "native/short";
private static final String TOPIC_NATIVE_LONG = "native/long";
private static final String TOPIC_NATIVE_FLOAT = "native/float";
private static final String TOPIC_NATIVE_DOUBLE = "native/double";
private static final String TOPIC_NATIVE_CHAR = "native/char";
private static final String TOPIC_NATIVE_STRING = "native/string";
private static final String TOPIC_BOXED_INTEGER = "boxed/Integer";
private static final String TOPIC_BOXED_SHORT = "boxed/Short";
private static final String TOPIC_BOXED_LONG = "boxed/Long";
private static final String TOPIC_BOXED_FLOAT = "boxed/Float";
private static final String TOPIC_BOXED_DOUBLE = "boxed/Double";
private static final String TOPIC_BOXED_CHARACTER = "boxed/Character";
private A model;
private NativeTypes integers;
private NativeTypes floats;
private NativeTypes chars;
private BoxedTypes allBoxed;
private MqttHandler sender;
@Override
public void closeConnections() {
if (sender != null) {
sender.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
integers.connectIntValue(mqttUri(TOPIC_NATIVE_INT));
integers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT));
integers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG));
floats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT));
floats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE));
chars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR));
chars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING));
allBoxed.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER));
allBoxed.connectShortValue(mqttUri(TOPIC_BOXED_SHORT));
allBoxed.connectLongValue(mqttUri(TOPIC_BOXED_LONG));
allBoxed.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT));
allBoxed.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE));
allBoxed.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER));
sender = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(sender.waitUntilReady(2, TimeUnit.SECONDS));
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
final int expectedIntValue = 1;
final short expectedShortValue = 2;
final long expectedLongValue = 3L;
final float expectedFloatValue = 4.1f;
final double expectedDoubleValue = 5.2;
final char expectedCharValue = 'c';
final String expectedStringValue = "6.3";
sender.publish(TOPIC_NATIVE_INT, ByteBuffer.allocate(4).putInt(expectedIntValue).array());
sender.publish(TOPIC_NATIVE_SHORT, ByteBuffer.allocate(2).putShort(expectedShortValue).array());
sender.publish(TOPIC_NATIVE_LONG, ByteBuffer.allocate(8).putLong(expectedLongValue).array());
sender.publish(TOPIC_NATIVE_FLOAT, ByteBuffer.allocate(4).putFloat(expectedFloatValue).array());
sender.publish(TOPIC_NATIVE_DOUBLE, ByteBuffer.allocate(8).putDouble(expectedDoubleValue).array());
sender.publish(TOPIC_NATIVE_CHAR, ByteBuffer.allocate(2).putChar(expectedCharValue).array());
sender.publish(TOPIC_NATIVE_STRING, expectedStringValue.getBytes());
sender.publish(TOPIC_BOXED_INTEGER, ByteBuffer.allocate(4).putInt(expectedIntValue).array());
sender.publish(TOPIC_BOXED_SHORT, ByteBuffer.allocate(2).putShort(expectedShortValue).array());
sender.publish(TOPIC_BOXED_LONG, ByteBuffer.allocate(8).putLong(expectedLongValue).array());
sender.publish(TOPIC_BOXED_FLOAT, ByteBuffer.allocate(4).putFloat(expectedFloatValue).array());
sender.publish(TOPIC_BOXED_DOUBLE, ByteBuffer.allocate(8).putDouble(expectedDoubleValue).array());
sender.publish(TOPIC_BOXED_CHARACTER, ByteBuffer.allocate(2).putChar(expectedCharValue).array());
TestUtils.waitForMqtt();
assertEquals(expectedIntValue, integers.getIntValue());
assertEquals(expectedShortValue, integers.getShortValue());
assertEquals(expectedLongValue, integers.getLongValue());
assertEquals(expectedFloatValue, floats.getFloatValue(), TestUtils.DELTA);
assertEquals(expectedDoubleValue, floats.getDoubleValue(), TestUtils.DELTA);
assertEquals(expectedCharValue, chars.getCharValue());
assertEquals(expectedStringValue, chars.getStringValue());
assertEquals(expectedIntValue, allBoxed.getIntValue().intValue());
assertEquals(expectedShortValue, allBoxed.getShortValue().shortValue());
assertEquals(expectedLongValue, allBoxed.getLongValue().longValue());
assertEquals(expectedFloatValue, allBoxed.getFloatValue(), TestUtils.DELTA);
assertEquals(expectedDoubleValue, allBoxed.getDoubleValue(), TestUtils.DELTA);
assertEquals(expectedCharValue, allBoxed.getCharValue().charValue());
}
@Override
protected void communicateSendInitialValue() {
// empty
}
@Override
protected void createModel() {
model = new A();
integers = new NativeTypes();
model.addNativeTypes(integers);
floats = new NativeTypes();
model.addNativeTypes(floats);
chars = new NativeTypes();
model.addNativeTypes(chars);
allBoxed = new BoxedTypes();
model.addBoxedTypes(allBoxed);
}
}
package org.jastadd.ragconnect.tests;
import defaultOnlyWrite.ast.A;
import defaultOnlyWrite.ast.BoxedTypesSyn;
import defaultOnlyWrite.ast.MqttHandler;
import defaultOnlyWrite.ast.NativeTypesSyn;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.*;
/**
* Test case "defaultOnlyRead".
*
* @author rschoene - Initial contribution
*/
public class DefaultOnlyWriteTest extends AbstractMqttTest {
private static final String TOPIC_NATIVE_INT = "native/int";
private static final String TOPIC_NATIVE_SHORT = "native/short";
private static final String TOPIC_NATIVE_LONG = "native/long";
private static final String TOPIC_NATIVE_FLOAT = "native/float";
private static final String TOPIC_NATIVE_DOUBLE = "native/double";
private static final String TOPIC_NATIVE_CHAR = "native/char";
private static final String TOPIC_NATIVE_STRING = "native/string";
private static final String TOPIC_BOXED_INTEGER = "boxed/Integer";
private static final String TOPIC_BOXED_SHORT = "boxed/Short";
private static final String TOPIC_BOXED_LONG = "boxed/Long";
private static final String TOPIC_BOXED_FLOAT = "boxed/Float";
private static final String TOPIC_BOXED_DOUBLE = "boxed/Double";
private static final String TOPIC_BOXED_CHARACTER = "boxed/Character";
private A model;
private NativeTypesSyn nativeIntegers;
private NativeTypesSyn nativeFloats;
private NativeTypesSyn nativeChars;
private BoxedTypesSyn boxedIntegers;
private BoxedTypesSyn boxedFloats;
private BoxedTypesSyn boxedChars;
private MqttHandler receiver;
private ReceiverData data;
@Override
public void closeConnections() {
if (receiver != null) {
receiver.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(1, 1, 1.1, 'a', "ab");
// set new value
setData("2", "2.2", "cd");
// check new value
TestUtils.waitForMqtt();
checkData(2, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TestUtils.waitForMqtt();
checkData(3, 3, 3.2, 'e', "ee");
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// check initial value (will be default values)
TestUtils.waitForMqtt();
checkData(0, null, null, null, null);
// set new value
setData("2", "2.2", "cd");
// check new value
TestUtils.waitForMqtt();
checkData(1, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TestUtils.waitForMqtt();
checkData(2, 3, 3.2, 'e', "ee");
}
@Override
protected void createModel() {
model = new A();
nativeIntegers = new NativeTypesSyn();
nativeFloats = new NativeTypesSyn();
nativeChars = new NativeTypesSyn();
model.addNativeTypesSyn(nativeIntegers);
model.addNativeTypesSyn(nativeFloats);
model.addNativeTypesSyn(nativeChars);
boxedIntegers = new BoxedTypesSyn();
boxedFloats = new BoxedTypesSyn();
boxedChars = new BoxedTypesSyn();
model.addBoxedTypesSyn(boxedIntegers);
model.addBoxedTypesSyn(boxedFloats);
model.addBoxedTypesSyn(boxedChars);
setData("1", "1.1", "ab");
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
receiver = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(receiver.waitUntilReady(2, TimeUnit.SECONDS));
nativeIntegers.addNativeIntDependency(nativeIntegers);
nativeIntegers.addNativeShortDependency(nativeIntegers);
nativeIntegers.addNativeLongDependency(nativeIntegers);
nativeFloats.addNativeFloatDependency(nativeFloats);
nativeFloats.addNativeDoubleDependency(nativeFloats);
nativeChars.addNativeCharDependency(nativeChars);
nativeChars.addNativeStringDependency(nativeChars);
boxedIntegers.addBoxedIntDependency(boxedIntegers);
boxedIntegers.addBoxedShortDependency(boxedIntegers);
boxedIntegers.addBoxedLongDependency(boxedIntegers);
boxedFloats.addBoxedFloatDependency(boxedFloats);
boxedFloats.addBoxedDoubleDependency(boxedFloats);
boxedChars.addBoxedCharDependency(boxedChars);
data = new ReceiverData();
receiver.newConnection(TOPIC_NATIVE_INT, bytes -> {
data.numberOfNativeIntValues += 1;
data.lastNativeIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
receiver.newConnection(TOPIC_NATIVE_SHORT, bytes -> {
data.numberOfNativeShortValues += 1;
data.lastNativeShortValue = java.nio.ByteBuffer.wrap(bytes).getShort();
});
receiver.newConnection(TOPIC_NATIVE_LONG, bytes -> {
data.numberOfNativeLongValues += 1;
data.lastNativeLongValue = java.nio.ByteBuffer.wrap(bytes).getLong();
});
receiver.newConnection(TOPIC_NATIVE_FLOAT, bytes -> {
data.numberOfNativeFloatValues += 1;
data.lastNativeFloatValue = java.nio.ByteBuffer.wrap(bytes).getFloat();
});
receiver.newConnection(TOPIC_NATIVE_DOUBLE, bytes -> {
data.numberOfNativeDoubleValues += 1;
data.lastNativeDoubleValue = java.nio.ByteBuffer.wrap(bytes).getDouble();
});
receiver.newConnection(TOPIC_NATIVE_CHAR, bytes -> {
data.numberOfNativeCharValues += 1;
data.lastNativeCharValue = java.nio.ByteBuffer.wrap(bytes).getChar();
});
receiver.newConnection(TOPIC_NATIVE_STRING, bytes -> {
data.numberOfNativeStringValues += 1;
data.lastNativeStringValue = new String(bytes);
});
receiver.newConnection(TOPIC_BOXED_INTEGER, bytes -> {
data.numberOfBoxedIntValues += 1;
data.lastBoxedIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
receiver.newConnection(TOPIC_BOXED_SHORT, bytes -> {
data.numberOfBoxedShortValues += 1;
data.lastBoxedShortValue = java.nio.ByteBuffer.wrap(bytes).getShort();
});
receiver.newConnection(TOPIC_BOXED_LONG, bytes -> {
data.numberOfBoxedLongValues += 1;
data.lastBoxedLongValue = java.nio.ByteBuffer.wrap(bytes).getLong();
});
receiver.newConnection(TOPIC_BOXED_FLOAT, bytes -> {
data.numberOfBoxedFloatValues += 1;
data.lastBoxedFloatValue = java.nio.ByteBuffer.wrap(bytes).getFloat();
});
receiver.newConnection(TOPIC_BOXED_DOUBLE, bytes -> {
data.numberOfBoxedDoubleValues += 1;
data.lastBoxedDoubleValue = java.nio.ByteBuffer.wrap(bytes).getDouble();
});
receiver.newConnection(TOPIC_BOXED_CHARACTER, bytes -> {
data.numberOfBoxedCharValues += 1;
data.lastBoxedCharValue = java.nio.ByteBuffer.wrap(bytes).getChar();
});
nativeIntegers.connectIntValue(mqttUri(TOPIC_NATIVE_INT), writeCurrentValue);
nativeIntegers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT), writeCurrentValue);
nativeIntegers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG), writeCurrentValue);
nativeFloats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT), writeCurrentValue);
nativeFloats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE), writeCurrentValue);
nativeChars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR), writeCurrentValue);
nativeChars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING), writeCurrentValue);
boxedIntegers.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER), writeCurrentValue);
boxedIntegers.connectShortValue(mqttUri(TOPIC_BOXED_SHORT), writeCurrentValue);
boxedIntegers.connectLongValue(mqttUri(TOPIC_BOXED_LONG), writeCurrentValue);
boxedFloats.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT), writeCurrentValue);
boxedFloats.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE), writeCurrentValue);
boxedChars.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER), writeCurrentValue);
}
private void setData(String integerDriver, String floatDriver, String stringDriver) {
nativeIntegers.setDriverSyn(integerDriver);
nativeFloats.setDriverSyn(floatDriver);
nativeChars.setDriverSyn(stringDriver);
boxedIntegers.setDriverSyn(integerDriver);
boxedFloats.setDriverSyn(floatDriver);
boxedChars.setDriverSyn(stringDriver);
}
private void checkData(int expectedNumberOfValues,
Integer expectedInt, Double expectedDouble,
Character expectedChar, String expectedString) {
assertEquals(expectedNumberOfValues, data.numberOfNativeIntValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeShortValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeLongValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeFloatValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeDoubleValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeCharValues);
assertEquals(expectedNumberOfValues, data.numberOfNativeStringValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedIntValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedShortValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedLongValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedFloatValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedDoubleValues);
assertEquals(expectedNumberOfValues, data.numberOfBoxedCharValues);
if (expectedInt != null) {
assertEquals(expectedInt.intValue(), data.lastNativeIntValue);
assertEquals(expectedInt.shortValue(), data.lastNativeShortValue);
assertEquals(expectedInt.longValue(), data.lastNativeLongValue);
assertEquals(expectedInt.intValue(), data.lastBoxedIntValue.intValue());
assertEquals(expectedInt.shortValue(), data.lastBoxedShortValue.shortValue());
assertEquals(expectedInt.longValue(), data.lastBoxedLongValue.longValue());
} else {
assertEquals(0, data.lastNativeIntValue);
assertEquals(0, data.lastNativeShortValue);
assertEquals(0, data.lastNativeLongValue);
assertNull(data.lastBoxedIntValue);
assertNull(data.lastBoxedShortValue);
assertNull(data.lastBoxedLongValue);
}
if (expectedDouble != null) {
assertEquals(expectedDouble.floatValue(), data.lastNativeFloatValue, TestUtils.DELTA);
assertEquals(expectedDouble, data.lastNativeDoubleValue, TestUtils.DELTA);
assertEquals(expectedDouble.floatValue(), data.lastBoxedFloatValue, TestUtils.DELTA);
assertEquals(expectedDouble, data.lastBoxedDoubleValue, TestUtils.DELTA);
} else {
assertEquals(0f, data.lastNativeFloatValue, TestUtils.DELTA);
assertEquals(0d, data.lastNativeDoubleValue, TestUtils.DELTA);
assertNull(data.lastBoxedFloatValue);
assertNull(data.lastBoxedDoubleValue);
}
if (expectedChar != null) {
assertEquals(expectedChar.charValue(), data.lastNativeCharValue);
assertEquals(expectedChar, data.lastBoxedCharValue);
} else {
assertEquals('\0', data.lastNativeCharValue);
assertNull(data.lastBoxedCharValue);
}
assertEquals(expectedString, data.lastNativeStringValue);
}
private static class ReceiverData {
int lastNativeIntValue;
int numberOfNativeIntValues = 0;
short lastNativeShortValue;
int numberOfNativeShortValues = 0;
long lastNativeLongValue;
int numberOfNativeLongValues = 0;
float lastNativeFloatValue;
int numberOfNativeFloatValues = 0;
double lastNativeDoubleValue;
int numberOfNativeDoubleValues = 0;
char lastNativeCharValue;
int numberOfNativeCharValues = 0;
String lastNativeStringValue;
int numberOfNativeStringValues = 0;
Integer lastBoxedIntValue;
int numberOfBoxedIntValues = 0;
Short lastBoxedShortValue;
int numberOfBoxedShortValues = 0;
Long lastBoxedLongValue;
int numberOfBoxedLongValues = 0;
Float lastBoxedFloatValue;
int numberOfBoxedFloatValues = 0;
Double lastBoxedDoubleValue;
int numberOfBoxedDoubleValues = 0;
Character lastBoxedCharValue;
int numberOfBoxedCharValues = 0;
}
}
package org.jastadd.ragconnect.tests;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jastadd.ragconnect.compiler.Compiler;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.jastadd.ragconnect.tests.TestUtils.exec;
import static org.jastadd.ragconnect.tests.TestUtils.readFile;
import static org.junit.jupiter.api.Assertions.assertTrue;
class Errors {
private static final Logger logger = LogManager.getLogger(Errors.class);
private static final String FILENAME_PATTERN = "$FILENAME";
private static final String INPUT_DIRECTORY = "./src/test/01-input/errors/";
private static final String OUTPUT_DIRECTORY = "./src/test/02-after-ragconnect/errors/";
@BeforeAll
public static void createOutputDirectory() {
File outputDirectory = new File(OUTPUT_DIRECTORY);
assertTrue((outputDirectory.exists() && outputDirectory.isDirectory()) || outputDirectory.mkdir());
}
@Test
void testStandardErrors() throws IOException {
test("Errors", "A");
}
@SuppressWarnings("SameParameterValue")
private void test(String name, String rootNode) throws IOException {
String grammarFile = INPUT_DIRECTORY + name + ".relast";
String ragconnectFile = INPUT_DIRECTORY + name + ".connect";
String outFile = OUTPUT_DIRECTORY + name + ".out";
String expectedFile = INPUT_DIRECTORY + name + ".expected";
try {
logger.debug("user.dir: {}", System.getProperty("user.dir"));
String[] args = {
"--o=" + OUTPUT_DIRECTORY,
grammarFile,
ragconnectFile,
"--rootNode=" + rootNode,
"--verbose"
};
int returnValue = exec(Compiler.class, args, new File(outFile));
Assertions.assertEquals(1, returnValue, "RagConnect did not return with value 1");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
String out = readFile(outFile, Charset.defaultCharset());
String expected = readFile(expectedFile, Charset.defaultCharset());
// if (inFiles.size() == 1) {
expected = expected.replace(FILENAME_PATTERN, name);
// } else {
// for (int i = 0; i < inFiles.size(); i++) {
// expected = expected.replace(FILENAME_PATTERN + (i + 1), inFiles.get(i));
// }
// }
List<String> outList = Arrays.asList(out.split("\n"));
Collections.sort(outList);
List<String> expectedList = Arrays.stream(expected.split("\n"))
.sorted()
.filter(s -> !s.isEmpty() && !s.startsWith("//"))
.collect(Collectors.toList());
// FIXME errors not handled correctly at the moment
// Assertions.assertLinesMatch(expectedList, outList);
logger.info("ragconnect for " + name + " returned:\n{}", out);
}
}
package org.jastadd.ragconnect.tests;
import com.google.protobuf.InvalidProtocolBufferException;
import config.Config.RobotConfig;
import example.ast.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import robot.RobotStateOuterClass.RobotState;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.*;
/**
* Test case "example".
*
* @author rschoene - Initial contribution
*/
public class ExampleTest extends AbstractMqttTest {
private static final String TOPIC_CONFIG = "robot/config";
private static final String TOPIC_JOINT1 = "robot/arm/joint1";
private static final String TOPIC_JOINT2 = "robot/arm/joint2";
private Model model;
private RobotArm robotArm;
private Link link1;
private Link link2;
private MqttHandler handler;
private ReceiverData data;
@BeforeEach
public void resetTestCounter() {
TestCounter.reset();
}
@Override
public void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// joint is currently within the safety zone, so speed should be low
TestUtils.waitForMqtt();
assertEquals(0, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(0, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(1, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(1, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(1, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedLow(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// change position of the first joint out of the safety zone, second still in
sendData(TOPIC_JOINT1, 0.2f, 0.2f, 0.2f);
// still in safety zone, so no update should have been sent
TestUtils.waitForMqtt();
assertEquals(makePosition(2, 2, 2), link1.getCurrentPosition());
assertEquals(1, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(1, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(2, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(2, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(2, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedLow(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// change position of second joint also out of the safety zone, now speed must be high
sendData(TOPIC_JOINT2, 0.3f, 0.4f, 0.5f);
TestUtils.waitForMqtt();
assertEquals(makePosition(3, 4, 5), link2.getCurrentPosition());
assertEquals(2, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(2, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(3, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(3, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(3, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(2, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedHigh(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// change position of second joint, no change after mapping
sendData(TOPIC_JOINT2, 0.33f, 0.42f, 0.51f);
TestUtils.waitForMqtt();
assertEquals(makePosition(3, 4, 5), link2.getCurrentPosition());
assertEquals(3, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(3, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(3, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(3, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(3, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(2, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
// change position of second joint, still out of the safety zone, no update should be sent
sendData(TOPIC_JOINT2, 1.3f, 2.4f, 3.5f);
TestUtils.waitForMqtt();
assertEquals(makePosition(13, 24, 35), link2.getCurrentPosition());
assertEquals(4, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(4, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(4, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(4, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(4, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(2, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// no value should have been sent
TestUtils.waitForMqtt();
assertEquals(0, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(0, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(1, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(1, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(1, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(0, data.numberOfConfigs);
// change position of the first joint out of the safety zone, second still in
sendData(TOPIC_JOINT1, 0.2f, 0.2f, 0.2f);
// still in safety zone, hence, no value should have been sent
TestUtils.waitForMqtt();
assertEquals(makePosition(2, 2, 2), link1.getCurrentPosition());
assertEquals(1, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(1, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(2, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(2, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(2, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(0, data.numberOfConfigs);
// change position of second joint also out of the safety zone, now speed must be high
sendData(TOPIC_JOINT2, 0.3f, 0.4f, 0.5f);
TestUtils.waitForMqtt();
assertEquals(makePosition(3, 4, 5), link2.getCurrentPosition());
assertEquals(2, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(2, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(3, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(3, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(3, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedHigh(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// change position of second joint, no change after mapping
sendData(TOPIC_JOINT2, 0.33f, 0.42f, 0.51f);
TestUtils.waitForMqtt();
assertEquals(makePosition(3, 4, 5), link2.getCurrentPosition());
assertEquals(3, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(3, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(3, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(3, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(3, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
// change position of second joint, still out of the safety zone, no update should be sent
sendData(TOPIC_JOINT2, 1.3f, 2.4f, 3.5f);
TestUtils.waitForMqtt();
assertEquals(makePosition(13, 24, 35), link2.getCurrentPosition());
assertEquals(4, TestCounter.INSTANCE.numberParseLinkState);
assertEquals(4, TestCounter.INSTANCE.numberLinkStateToIntPosition);
assertEquals(4, TestCounter.INSTANCE.numberInSafetyZone);
assertEquals(4, TestCounter.INSTANCE.numberCreateSpeedMessage);
assertEquals(4, TestCounter.INSTANCE.numberSerializeRobotConfig);
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
}
@Test
public void testFailedConversion() throws IOException {
createModel();
setupReceiverAndConnect(false);
handler.publish(TOPIC_JOINT1, "not-a-pandaLinkState".getBytes());
assertEquals(0, data.numberOfConfigs);
assertTrue(data.failedLastConversion);
}
private void sendData(String topic, float x, float y, float z) {
handler.publish(topic, RobotState.newBuilder()
.setPosition(RobotState.Position.newBuilder().setX(x).setY(y).setZ(z).build())
.build()
.toByteArray()
);
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
// add dependencies
robotArm.addDependency1(link1);
robotArm.addDependency1(link2);
robotArm.addDependency1(robotArm.getEndEffector());
data = new ReceiverData();
handler.newConnection(TOPIC_CONFIG, bytes -> {
data.numberOfConfigs += 1;
try {
data.lastConfig = RobotConfig.parseFrom(bytes);
data.failedLastConversion = false;
} catch (InvalidProtocolBufferException e) {
data.failedLastConversion = true;
}
});
robotArm.connectAppropriateSpeed(mqttUri(TOPIC_CONFIG), writeCurrentValue);
link1.connectCurrentPosition(mqttUri(TOPIC_JOINT1));
link2.connectCurrentPosition(mqttUri(TOPIC_JOINT2));
}
@Override
protected void createModel() {
model = new Model();
ZoneModel zoneModel = new ZoneModel();
IntPosition firstPosition = makePosition(0, 0, 0);
IntPosition secondPosition = makePosition(-1, 0, 0);
IntPosition thirdPosition = makePosition(1, 0, 0);
Zone safetyZone = new Zone();
safetyZone.addCoordinate(new Coordinate(firstPosition));
safetyZone.addCoordinate(new Coordinate(secondPosition));
safetyZone.addCoordinate(new Coordinate(thirdPosition));
zoneModel.addSafetyZone(safetyZone);
model.setZoneModel(zoneModel);
robotArm = new RobotArm();
link1 = new Link();
link1.setName("joint1");
link1.setCurrentPosition(firstPosition);
link2 = new Link();
link2.setName("joint2");
link2.setCurrentPosition(secondPosition);
EndEffector endEffector = new EndEffector();
endEffector.setName("gripper");
endEffector.setCurrentPosition(makePosition(2, 2, 3));
robotArm.addLink(link1);
robotArm.addLink(link2);
robotArm.setEndEffector(endEffector);
model.setRobotArm(robotArm);
}
private static IntPosition makePosition(int x, int y, int z) {
return IntPosition.of(x, y, z);
}
private static class ReceiverData {
RobotConfig lastConfig;
boolean failedLastConversion = true;
int numberOfConfigs = 0;
}
}
package org.jastadd.ragconnect.tests;
import read1write2.ast.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "read-1-write-2".
*
* @author rschoene - Initial contribution
*/
public class Read1Write2Test extends AbstractMqttTest {
private static final String TOPIC_SAME_READ = "same/read";
private static final String TOPIC_SAME_WRITE_INT = "same/write/int";
private static final String TOPIC_SAME_WRITE_STRING = "same/write/string";
private static final String TOPIC_DIFFERENT_READ = "different/read";
private static final String TOPIC_DIFFERENT_WRITE1_INT = "different/write1/int";
private static final String TOPIC_DIFFERENT_WRITE1_STRING = "different/write1/string";
private static final String TOPIC_DIFFERENT_WRITE2_INT = "different/write2/int";
private static final String TOPIC_DIFFERENT_WRITE2_STRING = "different/write2/string";
private static final String INITIAL_VALUE = "-1";
private MqttHandler handler;
private A model;
private OnSameNonterminal onSameNonterminal;
private OnDifferentNonterminal onDifferentNonterminal;
private TheOther other1;
private TheOther other2;
private ReceiverData dataSame;
private ReceiverData dataOther1;
private ReceiverData dataOther2;
@Override
public void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(1, Integer.parseInt(INITIAL_VALUE), prefixed(INITIAL_VALUE), 1, Integer.parseInt(INITIAL_VALUE), prefixed(INITIAL_VALUE));
// set new value
sendData("2", "3");
// check new value
TestUtils.waitForMqtt();
checkData(2, 2, prefixed("2"), 2, 3, prefixed("3"));
// set new value
sendData("4", "4");
// check new value
TestUtils.waitForMqtt();
checkData(3, 4, prefixed("4"), 3, 4, prefixed("4"));
// set new value only for same
setDataOnlySame("77");
// check new value
TestUtils.waitForMqtt();
checkData(4, 77, prefixed("77"), 3, 4, prefixed("4"));
}
private String prefixed(String s) {
return "prefix" + s;
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(0, null, null, 0, null, null);
// set new value
sendData("2", "3");
// check new value
TestUtils.waitForMqtt();
checkData(1, 2, prefixed("2"), 1, 3, prefixed("3"));
// set new value
sendData("4", "4");
// check new value
TestUtils.waitForMqtt();
checkData(2, 4, prefixed("4"), 2, 4, prefixed("4"));
// set new value only for same
setDataOnlySame("77");
// check new value
TestUtils.waitForMqtt();
checkData(3, 77, prefixed("77"), 2, 4, prefixed("4"));
}
@Override
protected void createModel() {
// Setting value for Input without dependencies does not trigger any updates
model = new A();
onSameNonterminal = new OnSameNonterminal();
model.setOnSameNonterminal(onSameNonterminal);
onSameNonterminal.setInput(INITIAL_VALUE);
onDifferentNonterminal = new OnDifferentNonterminal();
other1 = new TheOther();
other2 = new TheOther();
onDifferentNonterminal.addTheOther(other1);
onDifferentNonterminal.addTheOther(other2);
model.setOnDifferentNonterminal(onDifferentNonterminal);
onDifferentNonterminal.setInput(INITIAL_VALUE);
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
onSameNonterminal.addIntDependency(onSameNonterminal);
onSameNonterminal.addStringDependency(onSameNonterminal);
other1.addIntDependency(onDifferentNonterminal);
other1.addStringDependency(onDifferentNonterminal);
other2.addIntDependency(onDifferentNonterminal);
other2.addStringDependency(onDifferentNonterminal);
dataSame = new Read1Write2Test.ReceiverData();
dataOther1 = new Read1Write2Test.ReceiverData();
dataOther2 = new Read1Write2Test.ReceiverData();
handler.newConnection(TOPIC_SAME_WRITE_INT, bytes -> {
dataSame.numberOfIntValues += 1;
dataSame.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
handler.newConnection(TOPIC_SAME_WRITE_STRING, bytes -> {
dataSame.numberOfStringValues += 1;
dataSame.lastStringValue = new String(bytes);
});
handler.newConnection(TOPIC_DIFFERENT_WRITE1_INT, bytes -> {
dataOther1.numberOfIntValues += 1;
dataOther1.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
handler.newConnection(TOPIC_DIFFERENT_WRITE1_STRING, bytes -> {
dataOther1.numberOfStringValues += 1;
dataOther1.lastStringValue = new String(bytes);
});
handler.newConnection(TOPIC_DIFFERENT_WRITE2_INT, bytes -> {
dataOther2.numberOfIntValues += 1;
dataOther2.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
handler.newConnection(TOPIC_DIFFERENT_WRITE2_STRING, bytes -> {
dataOther2.numberOfStringValues += 1;
dataOther2.lastStringValue = new String(bytes);
});
onSameNonterminal.connectInput(mqttUri(TOPIC_SAME_READ));
onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue);
onSameNonterminal.connectOutString(mqttUri(TOPIC_SAME_WRITE_STRING), writeCurrentValue);
onDifferentNonterminal.connectInput(mqttUri(TOPIC_DIFFERENT_READ));
other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue);
other1.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE1_STRING), writeCurrentValue);
other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue);
other2.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE2_STRING), writeCurrentValue);
}
private void sendData(String inputSame, String inputDifferent) {
handler.publish(TOPIC_SAME_READ, inputSame.getBytes());
handler.publish(TOPIC_DIFFERENT_READ, inputDifferent.getBytes());
}
private void setDataOnlySame(String inputSame) {
handler.publish(TOPIC_SAME_READ, inputSame.getBytes());
}
private void checkData(int numberOfSameValues, Integer lastSameIntValue, String lastSameStringValue,
int numberOfDifferentValues, Integer lastDifferentIntValue,
String lastDifferentStringValue) {
/* the value "-2" is never used in the test, so a test will always fail comparing to this value
especially, it is not the initial value */
ReceiverData expectedDataSame = ReceiverData.of(
numberOfSameValues,
lastSameIntValue != null ? lastSameIntValue : -2,
lastSameStringValue);
compareData(expectedDataSame, dataSame);
ReceiverData expectedDataDifferent = ReceiverData.of(
numberOfDifferentValues,
lastDifferentIntValue != null ? lastDifferentIntValue : -2,
lastDifferentStringValue);
compareData(expectedDataDifferent, dataOther1);
compareData(expectedDataDifferent, dataOther2);
}
private void compareData(ReceiverData expectedData,
ReceiverData actual) {
assertEquals(expectedData.numberOfIntValues, actual.numberOfIntValues);
assertEquals(expectedData.numberOfStringValues, actual.numberOfStringValues);
if (expectedData.numberOfIntValues > 0) {
assertEquals(expectedData.lastIntValue, actual.lastIntValue);
}
if (expectedData.numberOfStringValues > 0) {
assertEquals(expectedData.lastStringValue, actual.lastStringValue);
}
}
private static class ReceiverData {
int lastIntValue;
int numberOfIntValues = 0;
String lastStringValue;
int numberOfStringValues = 0;
static ReceiverData of(int numberOfValues, int lastIntValue, String lastStringValue) {
ReceiverData result = new ReceiverData();
result.lastIntValue = lastIntValue;
result.lastStringValue = lastStringValue;
result.numberOfIntValues = numberOfValues;
result.numberOfStringValues = numberOfValues;
return result;
}
}
}
package org.jastadd.ragconnect.tests;
import read2write1.ast.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "read-1-write-2".
*
* @author rschoene - Initial contribution
*/
public class Read2Write1Test extends AbstractMqttTest {
private static final String TOPIC_SAME_READ1 = "same/read1";
private static final String TOPIC_SAME_READ2 = "same/read2";
private static final String TOPIC_SAME_WRITE_INT = "same/write/int";
private static final String TOPIC_DIFFERENT_READ1 = "different/read1";
private static final String TOPIC_DIFFERENT_READ2 = "different/read2";
private static final String TOPIC_DIFFERENT_WRITE1_INT = "different/write1/int";
private static final String TOPIC_DIFFERENT_WRITE2_INT = "different/write2/int";
private static final String INITIAL_VALUE = "0";
private MqttHandler handler;
private A model;
private OnSameNonterminal onSameNonterminal;
private OnDifferentNonterminal onDifferentNonterminal;
private TheOther other1;
private TheOther other2;
private ReceiverData dataSame;
private ReceiverData dataOther1;
private ReceiverData dataOther2;
@Override
public void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE),
1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE));
// set new value
sendData(true, "2", true, "3");
// check new value. same: 2, 0. different: 3, 0.
TestUtils.waitForMqtt();
checkData(2, 20,
2, 30);
// set new value
sendData(false, "4", false, "4");
// check new value. same: 2, 4. different: 3, 4.
TestUtils.waitForMqtt();
checkData(3, 24,
3, 34);
// set new value only for same
setDataOnlySame(true, "77");
// check new value. same: 77, 4. different: 3, 4.
TestUtils.waitForMqtt();
checkData(4, 774,
3, 34);
}
private String prefixed(String s) {
return "prefix" + s;
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(0, null,
0, null);
// set new value
sendData(true, "2", true, "3");
// check new value. same: 2, 0. different: 3, 0.
TestUtils.waitForMqtt();
checkData(1, 20,
1, 30);
// set new value
sendData(false, "4", false, "4");
// check new value. same: 2, 4. different: 3, 4.
TestUtils.waitForMqtt();
checkData(2, 24,
2, 34);
// set new value only for same
setDataOnlySame(true, "77");
// check new value. same: 77, 4. different: 3, 4.
TestUtils.waitForMqtt();
checkData(3, 774,
2, 34);
}
@Override
protected void createModel() {
// Setting value for Input without dependencies does not trigger any updates
model = new A();
onSameNonterminal = new OnSameNonterminal();
model.setOnSameNonterminal(onSameNonterminal);
onSameNonterminal.setInput1(INITIAL_VALUE);
onSameNonterminal.setInput2(INITIAL_VALUE);
onDifferentNonterminal = new OnDifferentNonterminal();
other1 = new TheOther();
other2 = new TheOther();
onDifferentNonterminal.addTheOther(other1);
onDifferentNonterminal.addTheOther(other2);
model.setOnDifferentNonterminal(onDifferentNonterminal);
onDifferentNonterminal.setInput1(INITIAL_VALUE);
onDifferentNonterminal.setInput2(INITIAL_VALUE);
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
onSameNonterminal.addInt1Dependency(onSameNonterminal);
onSameNonterminal.addInt2Dependency(onSameNonterminal);
other1.addInt1Dependency(onDifferentNonterminal);
other1.addInt2Dependency(onDifferentNonterminal);
other2.addInt1Dependency(onDifferentNonterminal);
other2.addInt2Dependency(onDifferentNonterminal);
dataSame = new Read2Write1Test.ReceiverData();
dataOther1 = new Read2Write1Test.ReceiverData();
dataOther2 = new Read2Write1Test.ReceiverData();
handler.newConnection(TOPIC_SAME_WRITE_INT, bytes -> {
dataSame.numberOfIntValues += 1;
dataSame.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
handler.newConnection(TOPIC_DIFFERENT_WRITE1_INT, bytes -> {
dataOther1.numberOfIntValues += 1;
dataOther1.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
handler.newConnection(TOPIC_DIFFERENT_WRITE2_INT, bytes -> {
dataOther2.numberOfIntValues += 1;
dataOther2.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
});
onSameNonterminal.connectInput1(mqttUri(TOPIC_SAME_READ1));
onSameNonterminal.connectInput2(mqttUri(TOPIC_SAME_READ2));
onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue);
onDifferentNonterminal.connectInput1(mqttUri(TOPIC_DIFFERENT_READ1));
onDifferentNonterminal.connectInput2(mqttUri(TOPIC_DIFFERENT_READ2));
other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue);
other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue);
}
private void sendData(boolean useSameInput1, String inputSame,
boolean useDifferentInput1, String inputDifferent) {
handler.publish(useSameInput1 ? TOPIC_SAME_READ1 : TOPIC_SAME_READ2,
inputSame.getBytes());
handler.publish(useDifferentInput1 ? TOPIC_DIFFERENT_READ1 : TOPIC_DIFFERENT_READ2,
inputDifferent.getBytes());
}
private void setDataOnlySame(boolean useSameInput1, String inputSame) {
handler.publish(useSameInput1 ? TOPIC_SAME_READ1 : TOPIC_DIFFERENT_READ2,
inputSame.getBytes());
}
private void checkData(int numberOfSameValues, Integer lastSameIntValue,
int numberOfDifferentValues, Integer lastDifferentIntValue) {
/* the value "-2" is never used in the test, so a test will always fail comparing to this value
especially, it is not the initial value */
ReceiverData expectedDataSame = ReceiverData.of(
numberOfSameValues,
lastSameIntValue != null ? lastSameIntValue : -2
);
compareData(expectedDataSame, dataSame);
ReceiverData expectedDataDifferent = ReceiverData.of(
numberOfDifferentValues,
lastDifferentIntValue != null ? lastDifferentIntValue : -2
);
compareData(expectedDataDifferent, dataOther1);
compareData(expectedDataDifferent, dataOther2);
}
private void compareData(ReceiverData expectedData,
ReceiverData actual) {
assertEquals(expectedData.numberOfIntValues, actual.numberOfIntValues);
if (expectedData.numberOfIntValues > 0) {
assertEquals(expectedData.lastIntValue, actual.lastIntValue);
}
}
private static class ReceiverData {
int lastIntValue;
int numberOfIntValues = 0;
static ReceiverData of(int numberOfValues, int lastIntValue) {
ReceiverData result = new ReceiverData();
result.lastIntValue = lastIntValue;
result.numberOfIntValues = numberOfValues;
return result;
}
}
}
package org.jastadd.ragconnect.tests;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
/**
* Utility methods for tests.
*
* @author rschoene - Initial contribution
*/
public class TestUtils {
public static final double DELTA = 0.001d;
public static String getMqttHost() {
if (System.getenv("GITLAB_CI") != null) {
// we are in the CI, so use "mqtt" as host
return "mqtt";
} {
// else assume a locally running mqtt broker
return "localhost";
}
}
public static String mqttUri(String path) {
return "mqtt://" + getMqttHost() + "/" + path;
}
public static String restUri(String path, int port) {
return "rest://localhost:" + port + "/" + path;
}
public static int getMqttDefaultPort() {
return 1883;
}
public static int exec(Class<?> klass, String[] args, File err) throws IOException,
InterruptedException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");
String className = klass.getName();
String[] newArgs = new String[args.length + 4];
newArgs[0] = javaBin;
newArgs[1] = "-cp";
newArgs[2] = classpath;
newArgs[3] = className;
System.arraycopy(args, 0, newArgs, 4, args.length);
ProcessBuilder builder = new ProcessBuilder(newArgs);
// builder.redirectOutput(err);
builder.redirectError(err);
Process process = builder.start();
process.waitFor();
return process.exitValue();
}
public static String readFile(String path, Charset encoding)
throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
static void waitForMqtt() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
}
}
package org.jastadd.ragconnect.tests;
import tokenValueSend.ast.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "tokenValueSend".
*
* @author rschoene - Initial contribution
*/
public class TokenValueSendTest extends AbstractMqttTest {
private static final String TOPIC_SEND_ONE = "one/value/out";
private static final String TOPIC_RECEIVE_TWO = "two/value/in";
private static final String TOPIC_SEND_TWO = "two/value/out";
private static final String TOPIC_RECEIVE_THREE_VALUE = "three/value/in";
private static final String TOPIC_SEND_THREE_VALUE = "three/value/out";
private static final String TOPIC_SEND_THREE_OTHER = "three/other/out";
private static final String INITIAL_VALUE = "Start";
private MqttHandler handler;
private A model;
private OnlySend one;
private ReceiveAndSend two;
private ReceiveSendAndDepend three;
private ReceiverData dataOne;
private ReceiverData dataTwo;
private ReceiverData dataThree;
private ReceiverData dataThreeOther;
@Override
public void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(1, "Start-Post",
1, "Start-Post",
1, "Start-Post",
1, "Start-T-Post");
// send new value
sendData("200", "300");
// check new value
TestUtils.waitForMqtt();
checkData(1, "Start-Post",
2, "Pre-200-Post",
2, "Pre-300-Post",
2, "Pre-300-T-Post");
// set new value
setData("101", "201", "301");
// check new value
TestUtils.waitForMqtt();
checkData(2, "101-Post",
3, "201-Post",
3, "301-Post",
3, "301-T-Post");
// send the same values (will not be sent again)
setData("101", "201", "301");
// check new value
TestUtils.waitForMqtt();
checkData(2, "101-Post",
3, "201-Post",
3, "301-Post",
3, "301-T-Post");
// send values with prefixes imitating receiving
setData("102", "Pre-202", "Pre-302");
// check new value
TestUtils.waitForMqtt();
checkData(3, "102-Post",
4, "Pre-202-Post",
4, "Pre-302-Post",
4, "Pre-302-T-Post");
// send the same values (will not be sent again, because previously prefixed)
sendData("202", "302");
// check new value
TestUtils.waitForMqtt();
checkData(3, "102-Post",
4, "Pre-202-Post",
4, "Pre-302-Post",
4, "Pre-302-T-Post");
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// check initial value
TestUtils.waitForMqtt();
checkData(0, null,
0, null,
0, null,
0, null);
// send new value
sendData("210", "310");
// check new value
TestUtils.waitForMqtt();
checkData(0, null,
1, "Pre-210-Post",
1, "Pre-310-Post",
1, "Pre-310-T-Post");
// set new value
setData("111", "211", "311");
// check new value
TestUtils.waitForMqtt();
checkData(1, "111-Post",
2, "211-Post",
2, "311-Post",
2, "311-T-Post");
// send the same values (will not be sent again)
setData("111", "211", "311");
// check new value
TestUtils.waitForMqtt();
checkData(1, "111-Post",
2, "211-Post",
2, "311-Post",
2, "311-T-Post");
// send values with prefixes imitating receiving
setData("112", "Pre-212", "Pre-312");
// check new value
TestUtils.waitForMqtt();
checkData(2, "112-Post",
3, "Pre-212-Post",
3, "Pre-312-Post",
3, "Pre-312-T-Post");
// send the same values (will not be sent again, because previously prefixed)
sendData("212", "312");
// check new value
TestUtils.waitForMqtt();
checkData(2, "112-Post",
3, "Pre-212-Post",
3, "Pre-312-Post",
3, "Pre-312-T-Post");
}
@Override
protected void createModel() {
// Setting value for Input without dependencies does not trigger any updates
model = new A();
one = new OnlySend();
one.setValue(INITIAL_VALUE);
model.setOnlySend(one);
two = new ReceiveAndSend();
two.setValue(INITIAL_VALUE);
model.setReceiveAndSend(two);
three = new ReceiveSendAndDepend();
three.setValue(INITIAL_VALUE);
model.setReceiveSendAndDepend(three);
}
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
three.addDependency1(three);
dataOne = new ReceiverData();
dataTwo = new ReceiverData();
dataThree = new ReceiverData();
dataThreeOther = new ReceiverData();
handler.newConnection(TOPIC_SEND_ONE, bytes -> {
dataOne.numberOfStringValues += 1;
dataOne.lastStringValue = new String(bytes);
});
handler.newConnection(TOPIC_SEND_TWO, bytes -> {
dataTwo.numberOfStringValues += 1;
dataTwo.lastStringValue = new String(bytes);
});
handler.newConnection(TOPIC_SEND_THREE_VALUE, bytes -> {
dataThree.numberOfStringValues += 1;
dataThree.lastStringValue = new String(bytes);
});
handler.newConnection(TOPIC_SEND_THREE_OTHER, bytes -> {
dataThreeOther.numberOfStringValues += 1;
dataThreeOther.lastStringValue = new String(bytes);
});
one.connectValue(mqttUri(TOPIC_SEND_ONE), writeCurrentValue);
two.connectValue(mqttUri(TOPIC_RECEIVE_TWO));
two.connectValue(mqttUri(TOPIC_SEND_TWO), writeCurrentValue);
three.connectValue(mqttUri(TOPIC_RECEIVE_THREE_VALUE));
three.connectValue(mqttUri(TOPIC_SEND_THREE_VALUE), writeCurrentValue);
three.connectOtherOutput(mqttUri(TOPIC_SEND_THREE_OTHER), writeCurrentValue);
}
private void sendData(String inputTwo, String inputThree) {
handler.publish(TOPIC_RECEIVE_TWO, inputTwo.getBytes());
handler.publish(TOPIC_RECEIVE_THREE_VALUE, inputThree.getBytes());
}
private void setData(String inputOne, String inputTwo, String inputThree) {
one.setValue(inputOne);
two.setValue(inputTwo);
three.setValue(inputThree);
}
private void checkData(int numberOfOneValues, String lastOneStringValue,
int numberOfTwoValues, String lastTwoStringValue,
int numberOfThreeValues, String lastThreeStringValue,
int numberOfOtherValues, String lastOtherStringValue
) {
dataOne.assertEqualData(numberOfOneValues, lastOneStringValue);
dataTwo.assertEqualData(numberOfTwoValues, lastTwoStringValue);
dataThree.assertEqualData(numberOfThreeValues, lastThreeStringValue);
dataThreeOther.assertEqualData(numberOfOtherValues, lastOtherStringValue);
}
private static class ReceiverData {
String lastStringValue;
int numberOfStringValues = 0;
public void assertEqualData(int expectedNumberOfValues, String expectedLastValue) {
assertEquals(expectedNumberOfValues, this.numberOfStringValues);
assertEquals(expectedLastValue, this.lastStringValue);
}
}
}
package org.jastadd.ragconnect.tests;
import tutorial.ast.A;
import tutorial.ast.B;
import tutorial.ast.MqttHandler;
import java.io.IOException;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
/**
* Testcase "Tutorial".
*
* @author rschoene - Initial contribution
*/
public class TutorialTest extends AbstractMqttTest {
private MqttHandler handler;
private A a;
private B b1;
private B b2;
@Override
protected void closeConnections() {
if (handler != null) {
handler.close();
}
if (a != null) {
a.ragconnectCloseConnections();
}
}
@Override
protected void createModel() {
a = new A();
// set some default value for input
a.setInput("");
b1 = new B();
b2 = new B();
a.addB(b1);
a.addB(b2);
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
// a.OutputOnA -> a.Input
a.addDependencyA(a);
// b1.OutputOnB -> a.Input
b1.addDependencyB(a);
// b2.OutputOnB -> a.Input
b2.addDependencyB(a);
a.connectInput(mqttUri("topic/for/input"));
a.connectOutputOnA(mqttUri("a/out"), true);
b1.connectOutputOnB(mqttUri("b1/out"), true);
b2.connectOutputOnB(mqttUri("b2/out"), false);
}
@Override
protected void communicateSendInitialValue() {
// empty
}
@Override
protected void communicateOnlyUpdatedValue() {
// empty
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment