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

Fixed issue #22

- Added TestUtils.waitForMqtt
parent fe3ebc47
Branches
No related tags found
No related merge requests found
Pipeline #6988 passed
Showing
with 172 additions and 85 deletions
......@@ -146,16 +146,23 @@ aspect AspectGeneration {
sb.append(ind(indent + 1)).append(preemptiveReturnStatement()).append("\n");
sb.append(ind(indent)).append("}\n");
if (!getAlwaysApply()) {
sb.append(ind(indent)).append("if (").append(preemptiveExpectedValue());
if (getToken().isPrimitiveType()) {
sb.append(" == ").append(inputVariableName);
} else if (effectiveMappings().get(effectiveMappings().size() - 1).isDefaultMappingDefinition()) {
sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")");
MappingDefinition lastMapping = effectiveMappings().get(effectiveMappings().size() - 1);
sb.append(ind(indent)).append("if (");
if (lastMapping.getToType().isArray()) {
sb.append("java.util.Arrays.equals(").append(preemptiveExpectedValue())
.append(", ").append(inputVariableName).append(")");
} else {
sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")").append(" : ")
.append(inputVariableName).append(" == null");
sb.append(preemptiveExpectedValue());
if (getToken().isPrimitiveType() && lastMapping.getToType().isPrimitiveType()) {
sb.append(" == ").append(inputVariableName);
} else if (lastMapping.isDefaultMappingDefinition()) {
sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")");
} else {
sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
.append(inputVariableName).append(")").append(" : ")
.append(inputVariableName).append(" == null");
}
}
sb.append(") { ").append(preemptiveReturnStatement()).append(" }\n");
}
......
......@@ -151,6 +151,12 @@ aspect Mappings {
default: return false;
}
}
syn boolean MappingDefinitionType.isPrimitiveType() = false;
eq JavaMappingDefinitionType.isPrimitiveType() = getType().isPrimitiveType();
// --- isArray ---
syn boolean MappingDefinitionType.isArray() = false;
eq JavaArrayMappingDefinitionType.isArray() = true;
// --- suitableDefaultMapping ---
syn DefaultMappingDefinition UpdateDefinition.suitableDefaultMapping();
......
......@@ -4,7 +4,7 @@ ZoneModel ::= <Size:IntPosition> SafetyZone:Zone* ;
Zone ::= Coordinate* ;
RobotArm ::= Joint* EndEffector <AttributeTestSource:int> /<AppropriateSpeed:double>/ ;
RobotArm ::= Joint* EndEffector /<AppropriateSpeed:double>/ ;
Joint ::= <Name:String> <CurrentPosition:IntPosition> ;
......
......@@ -5,7 +5,6 @@ write RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ;
// --- dependency definitions ---
RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ;
RobotArm.AppropriateSpeed canDependOn RobotArm.AttributeTestSource as dependency2 ;
// --- mapping definitions ---
ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {:
......@@ -18,8 +17,7 @@ SerializeRobotConfig maps config.Robotconfig.RobotConfig rc to byte[] {:
LinkStateToIntPosition maps panda.Linkstate.PandaLinkState pls to IntPosition {:
panda.Linkstate.PandaLinkState.Position p = pls.getPos();
{ int i = 0; }
return IntPosition.of((int) p.getPositionX(), (int) p.getPositionY(), (int) p.getPositionZ());
return IntPosition.of((int) (10 * p.getPositionX()), (int) (10 * p.getPositionY()), (int) (10 * p.getPositionZ()));
:}
CreateSpeedMessage maps double speed to config.Robotconfig.RobotConfig {:
......
......@@ -106,7 +106,7 @@ public class DefaultOnlyReadTest extends AbstractMqttTest {
sender.publish(TOPIC_BOXED_DOUBLE, ByteBuffer.allocate(8).putDouble(expectedDoubleValue).array());
sender.publish(TOPIC_BOXED_CHARACTER, ByteBuffer.allocate(2).putChar(expectedCharValue).array());
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
assertEquals(expectedIntValue, integers.getIntValue());
assertEquals(expectedShortValue, integers.getShortValue());
......
......@@ -67,21 +67,21 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
setupReceiverAndConnect(true);
// check initial value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 1, 1.1, 'a', "ab");
// set new value
setData("2", "2.2", "cd");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 3, 3.2, 'e', "ee");
}
......@@ -92,21 +92,21 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
setupReceiverAndConnect(false);
// check initial value (will be default values)
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(0, null, null, null, null);
// set new value
setData("2", "2.2", "cd");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 2, 2.2, 'c', "cd");
// set new value
setData("3", "3.2", "ee");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 3, 3.2, 'e', "ee");
}
......
......@@ -5,10 +5,9 @@ import config.Robotconfig.RobotConfig;
import example.ast.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import panda.Linkstate;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.*;
......@@ -22,16 +21,19 @@ 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 Joint joint1;
private MqttUpdater receiver;
private Joint joint2;
private MqttUpdater handler;
private ReceiverData data;
@AfterEach
public void closeConnections() {
if (receiver != null) {
receiver.close();
if (handler != null) {
handler.close();
}
if (model != null) {
model.MqttCloseConnections();
......@@ -44,49 +46,116 @@ public class ExampleTest extends AbstractMqttTest {
}
@Test
public void communicate() throws IOException, InterruptedException {
public void communicateSendInitialValue() throws IOException, InterruptedException {
createModel();
List<RobotConfig> receivedConfigs = new ArrayList<>();
setupReceiverAndConnect(true);
createListener(receivedConfigs);
model.MqttSetHost(TestUtils.getMqttHost());
assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
// joint is currently within the safety zone, so speed should be low
robotArm.connectAppropriateSpeed(TOPIC_CONFIG, true);
joint1.connectCurrentPosition(TOPIC_JOINT1);
TestUtils.waitForMqtt();
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), joint1.getCurrentPosition());
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), joint2.getCurrentPosition());
assertEquals(2, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedHigh(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// 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), joint2.getCurrentPosition());
assertEquals(2, data.numberOfConfigs);
}
@Test
public void communicateOnlyUpdatedValue() throws IOException, InterruptedException {
createModel();
setupReceiverAndConnect(false);
// now change the position of the joint out of the safety zone
joint1.setCurrentPosition(makePosition(2, 2, 2));
// no value should have been sent
TestUtils.waitForMqtt();
assertEquals(0, data.numberOfConfigs);
// and wait for MQTT to send/receive messages
TimeUnit.SECONDS.sleep(2);
// change position of the first joint out of the safety zone, second still in
sendData(TOPIC_JOINT1, 0.2f, 0.2f, 0.2f);
// there should be two configs received by now (the initial one, and the updated)
assertEquals(2, receivedConfigs.size());
RobotConfig actualInitialConfig = receivedConfigs.get(0);
assertEquals(robotArm.speedLow(), actualInitialConfig.getSpeed(), TestUtils.DELTA);
// still in safety zone, first update should have been sent
TestUtils.waitForMqtt();
assertEquals(makePosition(2, 2, 2), joint1.getCurrentPosition());
assertEquals(0, data.numberOfConfigs);
RobotConfig actualUpdatedConfig = receivedConfigs.get(1);
assertEquals(robotArm.speedHigh(), actualUpdatedConfig.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), joint2.getCurrentPosition());
assertEquals(1, data.numberOfConfigs);
assertFalse(data.failedLastConversion);
assertEquals(robotArm.speedHigh(), data.lastConfig.getSpeed(), TestUtils.DELTA);
// 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), joint2.getCurrentPosition());
assertEquals(1, data.numberOfConfigs);
}
private void createListener(List<RobotConfig> receivedConfigs) {
receiver = new MqttUpdater("receiver");
try {
receiver.setHost(TestUtils.getMqttHost(), TestUtils.getMqttDefaultPort());
} catch (IOException e) {
fail("Could not set host: " + e.getMessage());
}
assertTrue(receiver.waitUntilReady(2, TimeUnit.SECONDS));
receiver.newConnection(TOPIC_CONFIG, bytes -> {
private void sendData(String topic, float x, float y, float z) {
handler.publish(topic, Linkstate.PandaLinkState.newBuilder()
.setPos(Linkstate.PandaLinkState.Position.newBuilder()
.setPositionX(x)
.setPositionY(y)
.setPositionZ(z)
.build())
.build()
.toByteArray()
);
}
private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
model.MqttSetHost(TestUtils.getMqttHost());
assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
handler = new MqttUpdater().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
// add dependencies
robotArm.addDependency1(joint1);
robotArm.addDependency1(joint2);
robotArm.addDependency1(robotArm.getEndEffector());
data = new ReceiverData();
handler.newConnection(TOPIC_CONFIG, bytes -> {
data.numberOfConfigs += 1;
try {
RobotConfig config = RobotConfig.parseFrom(bytes);
receivedConfigs.add(config);
data.lastConfig = RobotConfig.parseFrom(bytes);
data.failedLastConversion = false;
} catch (InvalidProtocolBufferException e) {
fail("Received bad config: " + e.getMessage());
data.failedLastConversion = true;
}
});
robotArm.connectAppropriateSpeed(TOPIC_CONFIG, writeCurrentValue);
joint1.connectCurrentPosition(TOPIC_JOINT1);
joint2.connectCurrentPosition(TOPIC_JOINT2);
}
private void createModel() {
......@@ -95,41 +164,44 @@ public class ExampleTest extends AbstractMqttTest {
ZoneModel zoneModel = new ZoneModel();
zoneModel.setSize(makePosition(1, 1, 1));
IntPosition myPosition = makePosition(0, 0, 0);
Coordinate myCoordinate = new Coordinate(myPosition);
Coordinate leftPosition = new Coordinate(makePosition(-1, 0, 0));
Coordinate rightPosition = new Coordinate(makePosition(1, 0, 0));
IntPosition firstPosition = makePosition(0, 0, 0);
IntPosition secondPosition = makePosition(-1, 0, 0);
IntPosition thirdPosition = makePosition(1, 0, 0);
Zone safetyZone = new Zone();
safetyZone.addCoordinate(myCoordinate);
safetyZone.addCoordinate(leftPosition);
safetyZone.addCoordinate(rightPosition);
safetyZone.addCoordinate(new Coordinate(firstPosition));
safetyZone.addCoordinate(new Coordinate(secondPosition));
safetyZone.addCoordinate(new Coordinate(thirdPosition));
zoneModel.addSafetyZone(safetyZone);
model.setZoneModel(zoneModel);
robotArm = new RobotArm();
robotArm.setAttributeTestSource(1); // set initial value, no trigger
joint1 = new Joint();
joint1.setName("joint1");
joint1.setCurrentPosition(myPosition);
joint1.setCurrentPosition(firstPosition);
joint2 = new Joint();
joint2.setName("joint2");
joint2.setCurrentPosition(secondPosition);
EndEffector endEffector = new EndEffector();
endEffector.setName("gripper");
endEffector.setCurrentPosition(makePosition(2, 2, 3));
robotArm.addJoint(joint1);
robotArm.addJoint(joint2);
robotArm.setEndEffector(endEffector);
model.setRobotArm(robotArm);
// add dependencies
robotArm.addDependency1(joint1);
robotArm.addDependency1(endEffector);
robotArm.addDependency2(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;
}
}
......@@ -59,28 +59,28 @@ public class Read1Write2Test extends AbstractMqttTest {
setupReceiverAndConnect(true);
// check initial value
TimeUnit.SECONDS.sleep(2);
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
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 2, prefixed("2"), 2, 3, prefixed("3"));
// set new value
sendData("4", "4");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 4, prefixed("4"), 3, 4, prefixed("4"));
// set new value only for same
setDataOnlySame("77");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(4, 77, prefixed("77"), 3, 4, prefixed("4"));
}
......@@ -94,28 +94,28 @@ public class Read1Write2Test extends AbstractMqttTest {
setupReceiverAndConnect(false);
// check initial value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(0, null, null, 0, null, null);
// set new value
sendData("2", "3");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 2, prefixed("2"), 1, 3, prefixed("3"));
// set new value
sendData("4", "4");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 4, prefixed("4"), 2, 4, prefixed("4"));
// set new value only for same
setDataOnlySame("77");
// check new value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 77, prefixed("77"), 2, 4, prefixed("4"));
}
......
......@@ -58,7 +58,7 @@ public class Read2Write1Test extends AbstractMqttTest {
setupReceiverAndConnect(true);
// check initial value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE),
1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE));
......@@ -66,7 +66,7 @@ public class Read2Write1Test extends AbstractMqttTest {
sendData(true, "2", true, "3");
// check new value. same: 2, 0. different: 3, 0.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 20,
2, 30);
......@@ -74,7 +74,7 @@ public class Read2Write1Test extends AbstractMqttTest {
sendData(false, "4", false, "4");
// check new value. same: 2, 4. different: 3, 4.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 24,
3, 34);
......@@ -82,7 +82,7 @@ public class Read2Write1Test extends AbstractMqttTest {
setDataOnlySame(true, "77");
// check new value. same: 77, 4. different: 3, 4.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(4, 774,
3, 34);
}
......@@ -97,7 +97,7 @@ public class Read2Write1Test extends AbstractMqttTest {
setupReceiverAndConnect(false);
// check initial value
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(0, null,
0, null);
......@@ -105,7 +105,7 @@ public class Read2Write1Test extends AbstractMqttTest {
sendData(true, "2", true, "3");
// check new value. same: 2, 0. different: 3, 0.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(1, 20,
1, 30);
......@@ -113,7 +113,7 @@ public class Read2Write1Test extends AbstractMqttTest {
sendData(false, "4", false, "4");
// check new value. same: 2, 4. different: 3, 4.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(2, 24,
2, 34);
......@@ -121,7 +121,7 @@ public class Read2Write1Test extends AbstractMqttTest {
setDataOnlySame(true, "77");
// check new value. same: 77, 4. different: 3, 4.
TimeUnit.SECONDS.sleep(2);
TestUtils.waitForMqtt();
checkData(3, 774,
2, 34);
}
......
......@@ -5,6 +5,7 @@ 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.
......@@ -58,4 +59,7 @@ public class TestUtils {
return new String(encoded, encoding);
}
static void waitForMqtt() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment