diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 64a4f56c03ca376a41c8375bc46d4041baa96e02..4989fda9ed75ff08ae1e20e92038258397b4f527 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,7 +21,7 @@ test: image: openjdk:8 stage: test script: - - ./gradlew test + - ./gradlew allTests artifacts: reports: junit: ros2rag.tests/build/test-results/test/TEST-*.xml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..d27fb4030353056cd7745ff9f57d6a913389ccee --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:bionic + +ENV DEBIAN_FRONTEND noninteractive +ENV HOME /home/user +RUN useradd --create-home --home-dir $HOME user \ + && chmod -R u+rwx $HOME \ + && chown -R user:user $HOME + +RUN apt-get update -y \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends openjdk-8-jdk \ + && apt-get clean + +COPY --chown=user:user . /ros2rag/ + +USER user +WORKDIR /ros2rag + +RUN ./gradlew --no-daemon installDist + +ENTRYPOINT /bin/bash -c "./ros2rag.starter/build/install/ros2rag.starter/bin/ros2rag.starter ./ros2rag.starter/src/main/resources/config.json" + diff --git a/ros2rag.base/src/main/jastadd/backend/Generation.jadd b/ros2rag.base/src/main/jastadd/backend/Generation.jadd index 81e2dabe41761ef3e1b3058adb2809be90f6ac1d..abce6a07b80fb96313de4760511c5339e9da92a0 100644 --- a/ros2rag.base/src/main/jastadd/backend/Generation.jadd +++ b/ros2rag.base/src/main/jastadd/backend/Generation.jadd @@ -141,16 +141,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"); } diff --git a/ros2rag.base/src/main/jastadd/backend/Mappings.jrag b/ros2rag.base/src/main/jastadd/backend/Mappings.jrag index 7add42fa7e3d3f7c71cb35b5a34c8c5d05b83628..fd40385d9e8879dd188362f6a0acd802652f511e 100644 --- a/ros2rag.base/src/main/jastadd/backend/Mappings.jrag +++ b/ros2rag.base/src/main/jastadd/backend/Mappings.jrag @@ -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(); diff --git a/ros2rag.base/src/main/resources/MqttUpdater.jadd b/ros2rag.base/src/main/resources/MqttUpdater.jadd index 394735cc78595ad0ebe15b5ab1fa6e73ef435b13..df1dc10054722b249c10637781bc896eebdaf37f 100644 --- a/ros2rag.base/src/main/resources/MqttUpdater.jadd +++ b/ros2rag.base/src/main/resources/MqttUpdater.jadd @@ -231,8 +231,16 @@ public class MqttUpdater { } public void publish(String topic, byte[] bytes) { + publish(topic, bytes, false); + } + + public void publish(String topic, byte[] bytes, boolean retain) { + publish(topic, bytes, this.qos, retain); + } + + public void publish(String topic, byte[] bytes, org.fusesource.mqtt.client.QoS qos, boolean retain) { connection.getDispatchQueue().execute(() -> { - connection.publish(topic, bytes, qos, false, new org.fusesource.mqtt.client.Callback<Void>() { + connection.publish(topic, bytes, qos, retain, new org.fusesource.mqtt.client.Callback<Void>() { @Override public void onSuccess(Void value) { logger.debug("Published some bytes to {}", topic); diff --git a/ros2rag.receiverstub/src/main/java/de/tudresden/inf/st/ros2rag/receiverstub/Main.java b/ros2rag.receiverstub/src/main/java/de/tudresden/inf/st/ros2rag/receiverstub/Main.java index 8c80b172671bc2b6eed937cca1cad99cf61d920e..f954120848dad5a83d498f91c6c33bdceb32969f 100644 --- a/ros2rag.receiverstub/src/main/java/de/tudresden/inf/st/ros2rag/receiverstub/Main.java +++ b/ros2rag.receiverstub/src/main/java/de/tudresden/inf/st/ros2rag/receiverstub/Main.java @@ -7,6 +7,7 @@ import config.Robotconfig.RobotConfig; import de.tudresden.inf.st.ros2rag.starter.ast.MqttUpdater; import de.tudresden.inf.st.ros2rag.starter.data.DataConfiguration; import de.tudresden.inf.st.ros2rag.starter.data.DataJoint; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import panda.Linkstate.PandaLinkState; @@ -19,6 +20,7 @@ import java.util.concurrent.TimeUnit; public class Main { private static final Logger logger = LogManager.getLogger(Main.class); + private String topicPattern; public static void main(String[] args) throws Exception { Main main = new Main(); @@ -32,6 +34,7 @@ public class Main { private void run(DataConfiguration config) throws IOException, InterruptedException { final CountDownLatch finish = new CountDownLatch(1); + int topicMaxLength = 0; MqttUpdater receiver = new MqttUpdater("receiver stub"); receiver.setHost(config.mqttHost); receiver.waitUntilReady(2, TimeUnit.SECONDS); @@ -39,7 +42,9 @@ public class Main { receiver.newConnection(config.dataConfigTopic, this::printDataConfig); for (DataJoint joint : config.joints) { receiver.newConnection(joint.topic, this::printPandaLinkState); + topicMaxLength = Math.max(topicMaxLength, joint.topic.length()); } + this.topicPattern = "%" + topicMaxLength + "s"; receiver.newConnection("components", bytes -> { String message = new String(bytes); @@ -70,8 +75,10 @@ public class Main { PandaLinkState.Orientation tmpOrientation = pls.getOrient(); PandaLinkState.TwistLinear tmpTwistLinear = pls.getTl(); PandaLinkState.TwistAngular tmpTwistAngular = pls.getTa(); - logger.info("{}: pos({},{},{}), orient({},{},{},{})," + - " twist-linear({},{},{}), twist-angular({},{},{})", + // panda::panda_link0: pos(-3.0621333E-8,-1.5197388E-8,3.3411725E-5), orient(0.0,0.0,0.0,0.0), twist-linear(0.0,0.0,0.0), twist-angular(0.0,0.0,0.0) + + logger.printf(Level.INFO,topicPattern + ": pos(% .5f,% .5f,% .5f), ori(%.1f,%.1f,%.1f,%.1f)," + + " twL(%.1f,%.1f,%.1f), twA(%.1f,%.1f,%.1f)", pls.getName(), tmpPosition.getPositionX(), tmpPosition.getPositionY(), diff --git a/ros2rag.receiverstub/src/main/resources/log4j2.xml b/ros2rag.receiverstub/src/main/resources/log4j2.xml index 679a7bb0c6171f5366d8283c0a451598fdca17db..ed3f9b7288951b7e2aaa1b25130158cd95d2ed97 100644 --- a/ros2rag.receiverstub/src/main/resources/log4j2.xml +++ b/ros2rag.receiverstub/src/main/resources/log4j2.xml @@ -6,7 +6,7 @@ </Console> </Appenders> <Loggers> - <Root level="debug"> + <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> diff --git a/ros2rag.senderstub/src/main/java/de/tudresden/inf/st/ros2rag/senderstub/Main.java b/ros2rag.senderstub/src/main/java/de/tudresden/inf/st/ros2rag/senderstub/Main.java index a2678369be1cdecdc24132e4002b281bdb725e1a..3ae4b473b96411ac632bdbacc4fa0682ed1d7640 100644 --- a/ros2rag.senderstub/src/main/java/de/tudresden/inf/st/ros2rag/senderstub/Main.java +++ b/ros2rag.senderstub/src/main/java/de/tudresden/inf/st/ros2rag/senderstub/Main.java @@ -7,34 +7,21 @@ import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) throws Exception { - final String topic; - final byte[] message; - - if (args.length < 1) { - topic = "robot/joint1"; - } else { - topic = args[0]; - } - - if (args.length < 2) { - Linkstate.PandaLinkState pls = Linkstate.PandaLinkState.newBuilder() - .setName("Joint1") - .setPos(Linkstate.PandaLinkState.Position.newBuilder() - .setPositionX(0.5f) - .setPositionY(0.5f) - .setPositionZ(0.5f) - .build()) - .setOrient(Linkstate.PandaLinkState.Orientation.newBuilder() - .setOrientationX(0) - .setOrientationY(0) - .setOrientationZ(0) - .setOrientationW(0) - .build()) - .build(); - message = pls.toByteArray(); - } else { - message = args[1].getBytes(); + // assume 4 arguments + if (args.length < 4) { + System.err.println("Sends a new position, expected arguments: topic x y z"); + return; } + final String topic = args[0]; + Linkstate.PandaLinkState pls = Linkstate.PandaLinkState.newBuilder() + .setName(args[0]) + .setPos(Linkstate.PandaLinkState.Position.newBuilder() + .setPositionX(Float.parseFloat(args[1])) + .setPositionY(Float.parseFloat(args[2])) + .setPositionZ(Float.parseFloat(args[3])) + .build()) + .build(); + final byte[] message = pls.toByteArray(); MqttUpdater sender = new MqttUpdater("sender stub").dontSendWelcomeMessage(); sender.setHost("localhost", 1883); diff --git a/ros2rag.starter/src/main/jastadd/Computation.jrag b/ros2rag.starter/src/main/jastadd/Computation.jrag index 09c151228c5c3b4811566bc0172e1e83247f648f..bddac5a4db5245259f19cfb72c86b9533fbf3fa7 100644 --- a/ros2rag.starter/src/main/jastadd/Computation.jrag +++ b/ros2rag.starter/src/main/jastadd/Computation.jrag @@ -1,5 +1,6 @@ aspect Computation { syn boolean RobotArm.isInSafetyZone() { + System.out.println("isInSafetyZone()"); for (Joint joint : getJointList()) { if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) { return true; @@ -10,15 +11,10 @@ aspect Computation { cache ZoneModel.isInSafetyZone(IntPosition pos); syn boolean ZoneModel.isInSafetyZone(IntPosition pos) { + System.out.println("isInSafetyZone(" + pos + ")"); for (Zone sz : getSafetyZoneList()) { for (Coordinate coordinate : sz.getCoordinateList()) { - IntPosition inside = coordinate.getPosition(); - if (inside.getX() <= pos.getX() && - inside.getY() <= pos.getY() && - inside.getZ() <= pos.getZ() && - pos.getX() <= inside.getX() + getSize().getX() && - pos.getY() <= inside.getY() + getSize().getY() && - pos.getZ() <= inside.getZ() + getSize().getZ()) { + if (coordinate.getPosition().equals(pos)) { return true; } } diff --git a/ros2rag.starter/src/main/jastadd/Definitions.ros2rag b/ros2rag.starter/src/main/jastadd/Definitions.ros2rag index da9ce33855f7e8cb4a17bf27fa930b407e84b066..60e7d1923a9a0a735bc4c8c3718ddd1c8e5b7ed7 100644 --- a/ros2rag.starter/src/main/jastadd/Definitions.ros2rag +++ b/ros2rag.starter/src/main/jastadd/Definitions.ros2rag @@ -10,20 +10,23 @@ RobotArm.AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ; // --- mapping definitions --- ParseLinkState maps byte[] bytes to panda.Linkstate.PandaLinkState {: +// System.out.println("ParseLinkState"); return panda.Linkstate.PandaLinkState.parseFrom(bytes); :} SerializeRobotConfig maps config.Robotconfig.RobotConfig rc to byte[] {: +// System.out.println("SerializeRobotConfig"); return rc.toByteArray(); :} LinkStateToIntPosition maps panda.Linkstate.PandaLinkState pls to IntPosition {: +// System.out.println("LinkStateToIntPosition"); 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) (Math.round(p.getPositionX() * 2)), (int) (Math.round(p.getPositionY() * 2)), (int) (Math.round(p.getPositionZ() * 2 + 0.5))); :} CreateSpeedMessage maps double speed to config.Robotconfig.RobotConfig {: +// System.out.println("CreateSpeedMessage"); return config.Robotconfig.RobotConfig.newBuilder() .setSpeed(speed) .setLoopTrajectory(true) diff --git a/ros2rag.starter/src/main/jastadd/RobotModel.relast b/ros2rag.starter/src/main/jastadd/RobotModel.relast index ea347d0ec303a8d3555cd0118d403b53664ffe33..415d3e5e25b8d03fa1d53bc6f95c05ad5e1987d8 100644 --- a/ros2rag.starter/src/main/jastadd/RobotModel.relast +++ b/ros2rag.starter/src/main/jastadd/RobotModel.relast @@ -1,6 +1,6 @@ Model ::= RobotArm ZoneModel ; -ZoneModel ::= <Size:IntPosition> SafetyZone:Zone* ; +ZoneModel ::= SafetyZone:Zone* ; Zone ::= Coordinate* ; diff --git a/ros2rag.starter/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java b/ros2rag.starter/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java index 45d7f7f73ec414f8c3e9bfb6f3e2ccd13132188d..66a48f60b39cb7c5d48af9993eeca7159dc92e51 100644 --- a/ros2rag.starter/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java +++ b/ros2rag.starter/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java @@ -28,9 +28,8 @@ public class StarterMain { File configFile = new File(args[0]); final int[][] safetyZoneCoordinates = { - {0, 0, 0}, - {-1, 0, 0}, - {1, 0, 0} + {1, 1, 0}, + {-1, -1, 1} }; // --- No configuration below this line --- @@ -43,7 +42,6 @@ public class StarterMain { model.MqttSetHost(config.mqttHost); ZoneModel zoneModel = new ZoneModel(); - zoneModel.setSize(makePosition(1, 1, 1)); Zone safetyZone = new Zone(); for (int[] coordinate : safetyZoneCoordinates) { @@ -103,9 +101,9 @@ public class StarterMain { .setEnableOrientation(false) .setEnableTwistAngular(false) .setEnableTwistLinear(false) - .setPublishRate(1000) + .setPublishRate(100) .build(); - mainHandler.publish(dataConfigTopic, dataConfig.toByteArray()); + mainHandler.publish(dataConfigTopic, dataConfig.toByteArray(), true); } private void logStatus(String prefix, RobotArm robotArm) { diff --git a/ros2rag.starter/src/main/resources/config.json b/ros2rag.starter/src/main/resources/config.json index af5e2b9835bd31e60418d97a8162f0c2fdb82215..ad12193a6c0da29e9e8ac097e615038933b1c92f 100644 --- a/ros2rag.starter/src/main/resources/config.json +++ b/ros2rag.starter/src/main/resources/config.json @@ -1,15 +1,15 @@ { "joints": [ - {"name": "Joint0", "topic": "panda_link_0"}, - {"name": "Joint1", "topic": "panda_link_1"}, - {"name": "Joint2", "topic": "panda_link_2"}, - {"name": "Joint3", "topic": "panda_link_3"}, - {"name": "Joint4", "topic": "panda_link_4"}, - {"name": "Joint5", "topic": "panda_link_5"}, - {"name": "Joint6", "topic": "panda_link_6"}, - {"name": "EndEffector", "topic": "panda_link_7", "isEndEffector": true}, - {"name": "LeftFinger", "topic": "panda_link_8"}, - {"name": "RightFinger", "topic": "panda_link_9"} + {"name": "Joint0", "topic": "panda::panda_link0"}, + {"name": "Joint1", "topic": "panda::panda_link1"}, + {"name": "Joint2", "topic": "panda::panda_link2"}, + {"name": "Joint3", "topic": "panda::panda_link3"}, + {"name": "Joint4", "topic": "panda::panda_link4"}, + {"name": "Joint5", "topic": "panda::panda_link5"}, + {"name": "Joint6", "topic": "panda::panda_link6"}, + {"name": "EndEffector", "topic": "panda::panda_link7", "isEndEffector": true}, + {"name": "LeftFinger", "topic": "panda::panda_leftfinger"}, + {"name": "RightFinger", "topic": "panda::panda_rightfinger"} ], "robotConfigTopic": "robotconfig", "dataConfigTopic": "dataconfig" diff --git a/ros2rag.tests/build.gradle b/ros2rag.tests/build.gradle index 20906aa9cb5f938b5bc3f15c7b3d51a1135462f3..568f441a595ac78644f2d216c850ab92ef8660d9 100644 --- a/ros2rag.tests/build.gradle +++ b/ros2rag.tests/build.gradle @@ -30,11 +30,22 @@ dependencies { } test { - useJUnitPlatform() + useJUnitPlatform { + excludeTags 'mqtt' + } maxHeapSize = '1G' } +task allTests(type: Test, dependsOn: testClasses) { + description = 'Run every test' + group = 'verification' + + useJUnitPlatform { + includeTags 'mqtt' + } +} + relastTest { compilerLocation = '../libs/relast.jar' } @@ -82,7 +93,7 @@ task compileExampleTest(type: RelastTest) { 'src/test/02-after-ros2rag/example/ROS2RAG.jadd' } -test.dependsOn compileExampleTest +testClasses.dependsOn compileExampleTest compileExampleTest.dependsOn preprocessExampleTest // --- Test: default-only-read --- @@ -112,7 +123,7 @@ task compileDefaultOnlyReadTest(type: RelastTest) { 'src/test/02-after-ros2rag/defaultOnlyRead/ROS2RAG.jadd' } -test.dependsOn compileDefaultOnlyReadTest +testClasses.dependsOn compileDefaultOnlyReadTest compileDefaultOnlyReadTest.dependsOn preprocessDefaultOnlyReadTest // --- Test: default-only-write --- @@ -143,7 +154,7 @@ task compileDefaultOnlyWriteTest(type: RelastTest) { 'src/test/02-after-ros2rag/defaultOnlyWrite/ROS2RAG.jadd' } -test.dependsOn compileDefaultOnlyWriteTest +testClasses.dependsOn compileDefaultOnlyWriteTest compileDefaultOnlyWriteTest.dependsOn preprocessDefaultOnlyWriteTest // --- Test: read1write2 --- @@ -174,7 +185,7 @@ task compileRead1Write2Test(type: RelastTest) { 'src/test/02-after-ros2rag/read1write2/ROS2RAG.jadd' } -test.dependsOn compileRead1Write2Test +testClasses.dependsOn compileRead1Write2Test compileRead1Write2Test.dependsOn preprocessRead1Write2Test // --- Test: read2write1 --- @@ -205,7 +216,7 @@ task compileRead2Write1Test(type: RelastTest) { 'src/test/02-after-ros2rag/read2write1/ROS2RAG.jadd' } -test.dependsOn compileRead2Write1Test +testClasses.dependsOn compileRead2Write1Test compileRead2Write1Test.dependsOn preprocessRead2Write1Test clean { diff --git a/ros2rag.tests/src/test/01-input/example/Test.jadd b/ros2rag.tests/src/test/01-input/example/Test.jadd index 53f41b6b1d5f7c181d0e4ea06a34ab8240eb82d1..c355f57814c9def67657a148a5a28061e2569d28 100644 --- a/ros2rag.tests/src/test/01-input/example/Test.jadd +++ b/ros2rag.tests/src/test/01-input/example/Test.jadd @@ -1,4 +1,16 @@ aspect GrammarTypes { + public class TestCounter { + public static TestCounter INSTANCE = new TestCounter(); + public int numberParseLinkState = 0; + public int numberSerializeRobotConfig = 0; + public int numberLinkStateToIntPosition = 0; + public int numberCreateSpeedMessage = 0; + public int numberInSafetyZone = 0; + public static void reset() { + TestCounter.INSTANCE = new TestCounter(); + } + } + public class IntPosition { private final int x, y, z; @@ -53,6 +65,7 @@ aspect GrammarTypes { eq RobotArm.getEndEffector().containingRobotArm() = this; syn boolean RobotArm.isInSafetyZone() { + TestCounter.INSTANCE.numberInSafetyZone += 1; for (Joint joint : getJointList()) { if (model().getZoneModel().isInSafetyZone(joint.getCurrentPosition())) { return true; diff --git a/ros2rag.tests/src/test/01-input/example/Test.relast b/ros2rag.tests/src/test/01-input/example/Test.relast index c6b346d5df0db5b333141202a800b5951643eef2..ea347d0ec303a8d3555cd0118d403b53664ffe33 100644 --- a/ros2rag.tests/src/test/01-input/example/Test.relast +++ b/ros2rag.tests/src/test/01-input/example/Test.relast @@ -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> ; diff --git a/ros2rag.tests/src/test/01-input/example/Test.ros2rag b/ros2rag.tests/src/test/01-input/example/Test.ros2rag index 9168da25b6d98b26784ef67b64c515be6cecf76c..5c929386c01052f3e9cfc2bcd81fe45482ea8446 100644 --- a/ros2rag.tests/src/test/01-input/example/Test.ros2rag +++ b/ros2rag.tests/src/test/01-input/example/Test.ros2rag @@ -5,24 +5,26 @@ 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 {: + TestCounter.INSTANCE.numberParseLinkState += 1; return panda.Linkstate.PandaLinkState.parseFrom(bytes); :} SerializeRobotConfig maps config.Robotconfig.RobotConfig rc to byte[] {: + TestCounter.INSTANCE.numberSerializeRobotConfig += 1; return rc.toByteArray(); :} LinkStateToIntPosition maps panda.Linkstate.PandaLinkState pls to IntPosition {: + TestCounter.INSTANCE.numberLinkStateToIntPosition += 1; 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 {: + TestCounter.INSTANCE.numberCreateSpeedMessage += 1; return config.Robotconfig.RobotConfig.newBuilder() .setSpeed(speed) .build(); diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/AbstractMqttTest.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/AbstractMqttTest.java index 3ca2c2dd10db9c7314e86582a02c3d705af2c2f4..6c07780f93ed5f01598bb995c337df765b9256d0 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/AbstractMqttTest.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/AbstractMqttTest.java @@ -2,6 +2,7 @@ package org.jastadd.ros2rag.tests; import defaultOnlyRead.ast.MqttUpdater; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -11,6 +12,7 @@ import java.util.concurrent.TimeUnit; * * @author rschoene - Initial contribution */ +@Tag("mqtt") public abstract class AbstractMqttTest { static boolean checkDone = false; static Boolean checkResult; diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyReadTest.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyReadTest.java index 3594cfd1a946ba42f65def205aa821354dba50e2..c82e9ca1e1642dbf9589760a03f8d2164a5ff424 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyReadTest.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyReadTest.java @@ -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()); diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyWriteTest.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyWriteTest.java index df4a22f5835df09a407595392a4969e7af9ee6f2..a48228e0ad13555016cb86b5de87fe00fcf88fdb 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyWriteTest.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/DefaultOnlyWriteTest.java @@ -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"); } diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/ExampleTest.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/ExampleTest.java index c22861e996826eaf720a33fe9e0c02f7b110978e..98d8e8b58aa5015babe0d3e20c3c948c9aa55c7c 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/ExampleTest.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/ExampleTest.java @@ -4,11 +4,11 @@ import com.google.protobuf.InvalidProtocolBufferException; import config.Robotconfig.RobotConfig; import example.ast.*; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; 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 +22,24 @@ 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; + + @BeforeEach + public void resetTestCounter() { + TestCounter.reset(); + } @AfterEach public void closeConnections() { - if (receiver != null) { - receiver.close(); + if (handler != null) { + handler.close(); } if (model != null) { model.MqttCloseConnections(); @@ -44,49 +52,194 @@ public class ExampleTest extends AbstractMqttTest { } @Test - public void communicate() throws IOException, InterruptedException { + public void communicateSendInitialValue() throws IOException, InterruptedException { createModel(); - List<RobotConfig> receivedConfigs = new ArrayList<>(); - - createListener(receivedConfigs); + setupReceiverAndConnect(true); - 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(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); - // now change the position of the joint out of the safety zone - joint1.setCurrentPosition(makePosition(2, 2, 2)); + // change position of the first joint out of the safety zone, second still in + sendData(TOPIC_JOINT1, 0.2f, 0.2f, 0.2f); - // and wait for MQTT to send/receive messages - TimeUnit.SECONDS.sleep(2); + // still in safety zone, so no update should have been sent + TestUtils.waitForMqtt(); + assertEquals(makePosition(2, 2, 2), joint1.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); - // 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); + // 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); - RobotConfig actualUpdatedConfig = receivedConfigs.get(1); - assertEquals(robotArm.speedHigh(), actualUpdatedConfig.getSpeed(), TestUtils.DELTA); + TestUtils.waitForMqtt(); + assertEquals(makePosition(3, 4, 5), joint2.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), joint2.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), joint2.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); } - 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 -> { + @Test + public void communicateOnlyUpdatedValue() throws IOException, InterruptedException { + createModel(); + setupReceiverAndConnect(false); + + // 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), joint1.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), joint2.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), joint2.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), joint2.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, 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 +248,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; + } } diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read1Write2Test.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read1Write2Test.java index 9c151da32e5ca12c1dea1ec4e23e4c3168ca4910..e57c78a4c3c0a7f4ba9b8fc90e31b8b072f27e97 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read1Write2Test.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read1Write2Test.java @@ -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")); } diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java index 6c2b37b83629b245add25fd35659b7ce0ea0185a..ef741400d6bb86edffe804ef2414361f64046761 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java @@ -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); } diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/TestUtils.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/TestUtils.java index d0c03c9221023005f7896abf681f6627609ebed5..05db73e8790a25dd9d730ea637e8be500d568d5f 100644 --- a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/TestUtils.java +++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/TestUtils.java @@ -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); + } }