From 3d6f61cd8215acf4013e1e6a480e985c754b82e8 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Tue, 19 Jan 2021 14:07:06 +0100 Subject: [PATCH] Add tests to this repo again. --- libs/buildSrc.jar | Bin 0 -> 8942 bytes ragconnect.tests/.gitignore | 5 + ragconnect.tests/build.gradle | 338 ++++++++++++++++++ .../test/01-input/defaultOnlyRead/README.md | 3 + .../01-input/defaultOnlyRead/Test.connect | 15 + .../test/01-input/defaultOnlyRead/Test.relast | 3 + .../test/01-input/defaultOnlyWrite/README.md | 3 + .../01-input/defaultOnlyWrite/Test.connect | 51 +++ .../test/01-input/defaultOnlyWrite/Test.jadd | 49 +++ .../01-input/defaultOnlyWrite/Test.relast | 11 + .../src/test/01-input/errors/Errors.connect | 72 ++++ .../src/test/01-input/errors/Errors.expected | 0 .../src/test/01-input/errors/Errors.relast | 15 + .../src/test/01-input/errors/README.md | 25 ++ .../src/test/01-input/example/README.md | 3 + .../src/test/01-input/example/Test.connect | 31 ++ .../src/test/01-input/example/Test.jadd | 95 +++++ .../src/test/01-input/example/Test.relast | 13 + .../src/test/01-input/example/config.json | 9 + .../src/test/01-input/read1write2/README.md | 3 + .../test/01-input/read1write2/Test.connect | 18 + .../src/test/01-input/read1write2/Test.jadd | 11 + .../src/test/01-input/read1write2/Test.relast | 4 + .../test/01-input/read2write1/Test.connect | 18 + .../src/test/01-input/read2write1/Test.jadd | 11 + .../src/test/01-input/read2write1/Test.relast | 4 + .../test/01-input/tokenValueSend/README.md | 3 + .../test/01-input/tokenValueSend/Test.connect | 23 ++ .../test/01-input/tokenValueSend/Test.jadd | 4 + .../test/01-input/tokenValueSend/Test.relast | 4 + .../src/test/01-input/tutorial/README.md | 3 + .../src/test/01-input/tutorial/Test.connect | 13 + .../src/test/01-input/tutorial/Test.jadd | 7 + .../src/test/01-input/tutorial/Test.relast | 2 + .../src/test/01-input/via/Test.connect | 33 ++ .../src/test/01-input/via/Test.jadd | 8 + .../src/test/01-input/via/Test.relast | 5 + .../src/test/02-after-ragconnect/.gitignore | 2 + .../src/test/03-after-relast/.gitignore | 2 + ragconnect.tests/src/test/java-gen/.gitignore | 2 + .../ragconnect/tests/AbstractMqttTest.java | 104 ++++++ .../ragconnect/tests/DefaultOnlyReadTest.java | 138 +++++++ .../tests/DefaultOnlyWriteTest.java | 310 ++++++++++++++++ .../org/jastadd/ragconnect/tests/Errors.java | 84 +++++ .../jastadd/ragconnect/tests/ExampleTest.java | 278 ++++++++++++++ .../ragconnect/tests/Read1Write2Test.java | 241 +++++++++++++ .../ragconnect/tests/Read2Write1Test.java | 232 ++++++++++++ .../jastadd/ragconnect/tests/TestUtils.java | 73 ++++ .../ragconnect/tests/TokenValueSendTest.java | 260 ++++++++++++++ .../ragconnect/tests/TutorialTest.java | 68 ++++ .../org/jastadd/ragconnect/tests/ViaTest.java | 324 +++++++++++++++++ ragconnect.tests/src/test/proto/config.proto | 7 + .../src/test/proto/robot_state.proto | 37 ++ .../src/test/proto/trajectory.proto | 33 ++ .../src/test/resources/log4j2.xml | 16 + settings.gradle | 1 + 56 files changed, 3127 insertions(+) create mode 100644 libs/buildSrc.jar create mode 100644 ragconnect.tests/.gitignore create mode 100644 ragconnect.tests/build.gradle create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyRead/README.md create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyWrite/README.md create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/errors/Errors.connect create mode 100644 ragconnect.tests/src/test/01-input/errors/Errors.expected create mode 100644 ragconnect.tests/src/test/01-input/errors/Errors.relast create mode 100644 ragconnect.tests/src/test/01-input/errors/README.md create mode 100644 ragconnect.tests/src/test/01-input/example/README.md create mode 100644 ragconnect.tests/src/test/01-input/example/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/example/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/example/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/example/config.json create mode 100644 ragconnect.tests/src/test/01-input/read1write2/README.md create mode 100644 ragconnect.tests/src/test/01-input/read1write2/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/read1write2/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/read1write2/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/read2write1/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/read2write1/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/read2write1/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/tokenValueSend/README.md create mode 100644 ragconnect.tests/src/test/01-input/tokenValueSend/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/tokenValueSend/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/tokenValueSend/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/tutorial/README.md create mode 100644 ragconnect.tests/src/test/01-input/tutorial/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/tutorial/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/tutorial/Test.relast create mode 100644 ragconnect.tests/src/test/01-input/via/Test.connect create mode 100644 ragconnect.tests/src/test/01-input/via/Test.jadd create mode 100644 ragconnect.tests/src/test/01-input/via/Test.relast create mode 100644 ragconnect.tests/src/test/02-after-ragconnect/.gitignore create mode 100644 ragconnect.tests/src/test/03-after-relast/.gitignore create mode 100644 ragconnect.tests/src/test/java-gen/.gitignore create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TokenValueSendTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java create mode 100644 ragconnect.tests/src/test/proto/config.proto create mode 100644 ragconnect.tests/src/test/proto/robot_state.proto create mode 100644 ragconnect.tests/src/test/proto/trajectory.proto create mode 100644 ragconnect.tests/src/test/resources/log4j2.xml diff --git a/libs/buildSrc.jar b/libs/buildSrc.jar new file mode 100644 index 0000000000000000000000000000000000000000..b0ca2cbc4fc7f12022592944d7446a429d855add GIT binary patch literal 8942 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 Kz_3sr!~+0saM`W^ literal 0 HcmV?d00001 diff --git a/ragconnect.tests/.gitignore b/ragconnect.tests/.gitignore new file mode 100644 index 0000000..87b4cdd --- /dev/null +++ b/ragconnect.tests/.gitignore @@ -0,0 +1,5 @@ +build +src/gen-res/ +src/gen/ +out/ +*.class diff --git a/ragconnect.tests/build.gradle b/ragconnect.tests/build.gradle new file mode 100644 index 0000000..9af1e5b --- /dev/null +++ b/ragconnect.tests/build.gradle @@ -0,0 +1,338 @@ +buildscript { + repositories.mavenCentral() + dependencies { + classpath 'org.jastadd:jastaddgradle:1.13.3' + classpath fileTree(include: ['buildSrc.jar'], dir: '../libs') + } +} + +import org.jastadd.relast.plugin.RelastPlugin +import org.jastadd.relast.plugin.RelastTest + +plugins { + id 'java' + id 'java-library' + id 'idea' + id 'com.github.ben-manes.versions' version '0.36.0' + id 'com.google.protobuf' version "0.8.14" +} + +apply plugin: 'jastadd' +apply plugin: RelastPlugin + +group = 'de.tudresden.inf.st' + +repositories { + mavenCentral() + jcenter() +} + +dependencies { + implementation project(':ragconnect.base') + + runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0' + testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1' + + // mqtt + testImplementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15' + + // rest and client + testImplementation group: 'com.sparkjava', name: 'spark-core', version: '2.9.2' + testImplementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.2' + testImplementation group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.31' + testImplementation group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.31' + + testImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' + api group: 'com.google.protobuf', name: 'protobuf-java', version: '3.0.0' +} + +test { + useJUnitPlatform { + excludeTags 'mqtt' + } + + maxHeapSize = '1G' +} + +protobuf { + protoc { + // The artifact spec for the Protobuf Compiler + artifact = 'com.google.protobuf:protoc:3.0.0' + } +} + +task allTests(type: Test, dependsOn: testClasses) { + description = 'Run every test' + group = 'verification' + + useJUnitPlatform { + includeTags 'mqtt' + } +} + +relastTest { + //noinspection GroovyAssignabilityCheck + compilerLocation = '../libs/relast.jar' +} + +File genSrc = file("src/test/java-gen") +sourceSets.test.java.srcDir genSrc +idea.module.generatedSourceDirs += genSrc + +clean { + delete 'src/test/02-after-ragconnect/*/', 'src/test/03-after-relast/*/', 'src/test/java-gen/*/' +} + +// --- Test: Example --- +task preprocessExampleTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/example/Test.relast', + 'src/test/02-after-ragconnect/example/MqttHandler.jadd', + 'src/test/02-after-ragconnect/example/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/example', + 'src/test/01-input/example/Test.relast', + 'src/test/01-input/example/Test.connect', + '--rootNode=Model', + '--logReads', '--logWrites' +} + +task compileExampleTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/example/Test.relast', + 'src/test/02-after-ragconnect/example/RagConnect.relast' + grammarName = 'src/test/03-after-relast/example/example' + packageName = 'example.ast' + moreInputFiles 'src/test/01-input/example/Test.jadd', + 'src/test/02-after-ragconnect/example/MqttHandler.jadd', + 'src/test/02-after-ragconnect/example/RagConnect.jadd' +} + +compileTestJava.dependsOn compileExampleTest +compileExampleTest.dependsOn preprocessExampleTest + +// --- Test: default-only-read --- +task preprocessDefaultOnlyReadTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/defaultOnlyRead/Test.relast', + 'src/test/02-after-ragconnect/defaultOnlyRead/MqttHandler.jadd', + 'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/defaultOnlyRead', + 'src/test/01-input/defaultOnlyRead/Test.relast', + 'src/test/01-input/defaultOnlyRead/Test.connect', + '--rootNode=A' +} + +task compileDefaultOnlyReadTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/defaultOnlyRead/Test.relast', + 'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.relast' + grammarName = 'src/test/03-after-relast/defaultOnlyRead/defaultOnlyRead' + packageName = 'defaultOnlyRead.ast' + moreInputFiles 'src/test/02-after-ragconnect/defaultOnlyRead/MqttHandler.jadd', + 'src/test/02-after-ragconnect/defaultOnlyRead/RagConnect.jadd' +} + +compileTestJava.dependsOn compileDefaultOnlyReadTest +compileDefaultOnlyReadTest.dependsOn preprocessDefaultOnlyReadTest + +// --- Test: default-only-write --- +task preprocessDefaultOnlyWriteTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/defaultOnlyWrite/Test.relast', + 'src/test/02-after-ragconnect/defaultOnlyWrite/MqttHandler.jadd', + 'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/defaultOnlyWrite', + 'src/test/01-input/defaultOnlyWrite/Test.relast', + 'src/test/01-input/defaultOnlyWrite/Test.connect', + '--rootNode=A' +} + +task compileDefaultOnlyWriteTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/defaultOnlyWrite/Test.relast', + 'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.relast' + grammarName = 'src/test/03-after-relast/defaultOnlyWrite/defaultOnlyWrite' + packageName = 'defaultOnlyWrite.ast' + moreInputFiles 'src/test/01-input/defaultOnlyWrite/Test.jadd', + 'src/test/02-after-ragconnect/defaultOnlyWrite/MqttHandler.jadd', + 'src/test/02-after-ragconnect/defaultOnlyWrite/RagConnect.jadd' +} + +compileTestJava.dependsOn compileDefaultOnlyWriteTest +compileDefaultOnlyWriteTest.dependsOn preprocessDefaultOnlyWriteTest + +// --- Test: read1write2 --- +task preprocessRead1Write2Test(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/read1write2/Test.relast', + 'src/test/02-after-ragconnect/read1write2/MqttHandler.jadd', + 'src/test/02-after-ragconnect/read1write2/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/read1write2', + 'src/test/01-input/read1write2/Test.relast', + 'src/test/01-input/read1write2/Test.connect', + '--rootNode=A' +} + +task compileRead1Write2Test(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/read1write2/Test.relast', + 'src/test/02-after-ragconnect/read1write2/RagConnect.relast' + grammarName = 'src/test/03-after-relast/read1write2/read1write2' + packageName = 'read1write2.ast' + moreInputFiles 'src/test/01-input/read1write2/Test.jadd', + 'src/test/02-after-ragconnect/read1write2/MqttHandler.jadd', + 'src/test/02-after-ragconnect/read1write2/RagConnect.jadd' +} + +compileTestJava.dependsOn compileRead1Write2Test +compileRead1Write2Test.dependsOn preprocessRead1Write2Test + +// --- Test: read2write1 --- +task preprocessRead2Write1Test(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/read2write1/Test.relast', + 'src/test/02-after-ragconnect/read2write1/MqttHandler.jadd', + 'src/test/02-after-ragconnect/read2write1/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/read2write1', + 'src/test/01-input/read2write1/Test.relast', + 'src/test/01-input/read2write1/Test.connect', + '--rootNode=A' +} + +task compileRead2Write1Test(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/read2write1/Test.relast', + 'src/test/02-after-ragconnect/read2write1/RagConnect.relast' + grammarName = 'src/test/03-after-relast/read2write1/read2write1' + packageName = 'read2write1.ast' + moreInputFiles 'src/test/01-input/read2write1/Test.jadd', + 'src/test/02-after-ragconnect/read2write1/MqttHandler.jadd', + 'src/test/02-after-ragconnect/read2write1/RagConnect.jadd' +} + +compileTestJava.dependsOn compileRead2Write1Test +compileRead2Write1Test.dependsOn preprocessRead2Write1Test + +// --- Test: via --- +task preprocessViaTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/via/Test.relast', + 'src/test/02-after-ragconnect/via/MqttHandler.jadd', + 'src/test/02-after-ragconnect/via/RestHandler.jadd', + 'src/test/02-after-ragconnect/via/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/via', + 'src/test/01-input/via/Test.relast', + 'src/test/01-input/via/Test.connect', + '--rootNode=A', + '--protocols=mqtt,rest' +} + +task compileViaTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/via/Test.relast', + 'src/test/02-after-ragconnect/via/RagConnect.relast' + grammarName = 'src/test/03-after-relast/via/via' + packageName = 'via.ast' + moreInputFiles 'src/test/01-input/via/Test.jadd', + 'src/test/02-after-ragconnect/via/MqttHandler.jadd', + 'src/test/02-after-ragconnect/via/RestHandler.jadd', + 'src/test/02-after-ragconnect/via/RagConnect.jadd' +} + +compileTestJava.dependsOn compileViaTest +compileViaTest.dependsOn preprocessViaTest + +// --- Test: token-value-send --- +task preprocessTokenValueSendTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/tokenValueSend/Test.relast', + 'src/test/02-after-ragconnect/tokenValueSend/MqttHandler.jadd', + 'src/test/02-after-ragconnect/tokenValueSend/RestHandler.jadd', + 'src/test/02-after-ragconnect/tokenValueSend/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/tokenValueSend', + 'src/test/01-input/tokenValueSend/Test.relast', + 'src/test/01-input/tokenValueSend/Test.connect', + '--rootNode=A' +} + +task compileTokenValueSendTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/tokenValueSend/Test.relast', + 'src/test/02-after-ragconnect/tokenValueSend/RagConnect.relast' + grammarName = 'src/test/03-after-relast/tokenValueSend/tokenValueSend' + packageName = 'tokenValueSend.ast' + moreInputFiles 'src/test/01-input/tokenValueSend/Test.jadd', + 'src/test/02-after-ragconnect/tokenValueSend/MqttHandler.jadd', + 'src/test/02-after-ragconnect/tokenValueSend/RagConnect.jadd' +} + +compileTestJava.dependsOn compileTokenValueSendTest +compileTokenValueSendTest.dependsOn preprocessTokenValueSendTest + +// --- Test: tutorial --- +task preprocessTutorialTest(type: JavaExec, group: 'verification') { + doFirst { + delete 'src/test/02-after-ragconnect/tutorial/Test.relast', + 'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd', + 'src/test/02-after-ragconnect/tutorial/RagConnect.jadd' + } + + classpath = sourceSets.main.runtimeClasspath + main = 'org.jastadd.ragconnect.compiler.Compiler' + args '--o=src/test/02-after-ragconnect/tutorial', + 'src/test/01-input/tutorial/Test.relast', + 'src/test/01-input/tutorial/Test.connect', + '--rootNode=A' +} + +task compileTutorialTest(type: RelastTest) { + useJastAddNames = true + jastAddList = 'JastAddList' + relastFiles 'src/test/02-after-ragconnect/tutorial/Test.relast', + 'src/test/02-after-ragconnect/tutorial/RagConnect.relast' + grammarName = 'src/test/03-after-relast/tutorial/tutorial' + packageName = 'tutorial.ast' + moreInputFiles 'src/test/01-input/tutorial/Test.jadd', + 'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd', + 'src/test/02-after-ragconnect/tutorial/RagConnect.jadd' +} + +compileTestJava.dependsOn compileTutorialTest +compileTutorialTest.dependsOn preprocessTutorialTest diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyRead/README.md b/ragconnect.tests/src/test/01-input/defaultOnlyRead/README.md new file mode 100644 index 0000000..ee05db6 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyRead/README.md @@ -0,0 +1,3 @@ +# Default Only Read + +Idea: Use only `ReadFromMqttDefinition`, test all default mapping definitions from `byte[]` to primitive (and boxed) types diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.connect b/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.connect new file mode 100644 index 0000000..e274994 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.connect @@ -0,0 +1,15 @@ +// --- update definitions --- +receive NativeTypes.IntValue; +receive NativeTypes.ShortValue; +receive NativeTypes.LongValue; +receive NativeTypes.FloatValue; +receive NativeTypes.DoubleValue; +receive NativeTypes.CharValue; +receive NativeTypes.StringValue; + +receive BoxedTypes.IntValue; +receive BoxedTypes.ShortValue; +receive BoxedTypes.LongValue; +receive BoxedTypes.FloatValue; +receive BoxedTypes.DoubleValue; +receive BoxedTypes.CharValue; diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.relast b/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.relast new file mode 100644 index 0000000..30eba76 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyRead/Test.relast @@ -0,0 +1,3 @@ +A ::= NativeTypes* BoxedTypes* ; +NativeTypes ::= <IntValue:int> <ShortValue:short> <LongValue:long> <FloatValue:float> <DoubleValue:double> <CharValue:char> <StringValue:String> ; +BoxedTypes ::= <IntValue:Integer> <ShortValue:Short> <LongValue:Long> <FloatValue:Float> <DoubleValue:Double> <CharValue:Character> ; diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyWrite/README.md b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/README.md new file mode 100644 index 0000000..1bcc8d6 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/README.md @@ -0,0 +1,3 @@ +# Default Only Write + +Idea: Use only `WriteToMqttDefintion`, test all default mapping definitions from primitive (and boxed) types to `byte[]`. diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.connect b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.connect new file mode 100644 index 0000000..a48f49f --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.connect @@ -0,0 +1,51 @@ +// --- update definitions --- +// native types, synthesized +send NativeTypesSyn.IntValue; +send NativeTypesSyn.ShortValue; +send NativeTypesSyn.LongValue; +send NativeTypesSyn.FloatValue; +send NativeTypesSyn.DoubleValue; +send NativeTypesSyn.CharValue; +send NativeTypesSyn.StringValue; + +// boxed types, synthesized +send BoxedTypesSyn.IntValue; +send BoxedTypesSyn.ShortValue; +send BoxedTypesSyn.LongValue; +send BoxedTypesSyn.FloatValue; +send BoxedTypesSyn.DoubleValue; +send BoxedTypesSyn.CharValue; + +// --- dependency definitions --- +NativeTypesSyn.IntValue canDependOn NativeTypesSyn.DriverSyn as nativeIntDependency; +NativeTypesSyn.ShortValue canDependOn NativeTypesSyn.DriverSyn as nativeShortDependency; +NativeTypesSyn.LongValue canDependOn NativeTypesSyn.DriverSyn as nativeLongDependency; +NativeTypesSyn.FloatValue canDependOn NativeTypesSyn.DriverSyn as nativeFloatDependency; +NativeTypesSyn.DoubleValue canDependOn NativeTypesSyn.DriverSyn as nativeDoubleDependency; +NativeTypesSyn.CharValue canDependOn NativeTypesSyn.DriverSyn as nativeCharDependency; +NativeTypesSyn.StringValue canDependOn NativeTypesSyn.DriverSyn as nativeStringDependency; +BoxedTypesSyn.IntValue canDependOn BoxedTypesSyn.DriverSyn as boxedIntDependency; +BoxedTypesSyn.ShortValue canDependOn BoxedTypesSyn.DriverSyn as boxedShortDependency; +BoxedTypesSyn.LongValue canDependOn BoxedTypesSyn.DriverSyn as boxedLongDependency; +BoxedTypesSyn.FloatValue canDependOn BoxedTypesSyn.DriverSyn as boxedFloatDependency; +BoxedTypesSyn.DoubleValue canDependOn BoxedTypesSyn.DriverSyn as boxedDoubleDependency; +BoxedTypesSyn.CharValue canDependOn BoxedTypesSyn.DriverSyn as boxedCharDependency; + + +// --- inherited attributes not supported --- +//// native types, inherited +//send NativeTypesInh.IntValue; +//send NativeTypesInh.ShortValue; +//send NativeTypesInh.LongValue; +//send NativeTypesInh.FloatValue; +//send NativeTypesInh.DoubleValue; +//send NativeTypesInh.CharValue; +//send NativeTypesInh.StringValue; +// +//// boxed types, inherited +//send BoxedTypesInh.IntValue; +//send BoxedTypesInh.ShortValue; +//send BoxedTypesInh.LongValue; +//send BoxedTypesInh.FloatValue; +//send BoxedTypesInh.DoubleValue; +//send BoxedTypesInh.CharValue; diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.jadd b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.jadd new file mode 100644 index 0000000..49bbf60 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.jadd @@ -0,0 +1,49 @@ +aspect Computation { + // native types, synthesized + syn int NativeTypesSyn.getIntValue() = Integer.parseInt(getDriverSyn()); + syn short NativeTypesSyn.getShortValue() = Short.parseShort(getDriverSyn()); + syn long NativeTypesSyn.getLongValue() = Long.parseLong(getDriverSyn()); + syn float NativeTypesSyn.getFloatValue() = Float.parseFloat(getDriverSyn()); + syn double NativeTypesSyn.getDoubleValue() = Double.parseDouble(getDriverSyn()); + syn char NativeTypesSyn.getCharValue() = getDriverSyn().charAt(0); + syn String NativeTypesSyn.getStringValue() = new String(getDriverSyn()); + + // boxed types, synthesized + syn Integer BoxedTypesSyn.getIntValue() = Integer.valueOf(getDriverSyn()); + syn Short BoxedTypesSyn.getShortValue() = Short.valueOf(getDriverSyn()); + syn Long BoxedTypesSyn.getLongValue() = Long.valueOf(getDriverSyn()); + syn Float BoxedTypesSyn.getFloatValue() = Float.valueOf(getDriverSyn()); + syn Double BoxedTypesSyn.getDoubleValue() = Double.valueOf(getDriverSyn()); + syn Character BoxedTypesSyn.getCharValue() = getDriverSyn().charAt(0); + +// --- inherited attributes not supported --- +// // native types, inherited +// inh int NativeTypesInh.getIntValue(); +// eq A.getNativeTypesInh().getIntValue() = Integer.parseInt(getDriverInh()); +// inh short NativeTypesInh.getShortValue(); +// eq A.getNativeTypesInh().getShortValue() = Short.parseShort(getDriverInh()); +// inh long NativeTypesInh.getLongValue(); +// eq A.getNativeTypesInh().getLongValue() = Long.parseLong(getDriverInh()); +// inh float NativeTypesInh.getFloatValue(); +// eq A.getNativeTypesInh().getFloatValue() = Float.parseFloat(getDriverInh()); +// inh double NativeTypesInh.getDoubleValue(); +// eq A.getNativeTypesInh().getDoubleValue() = Double.parseDouble(getDriverInh()); +// inh char NativeTypesInh.getCharValue(); +// eq A.getNativeTypesInh().getCharValue() = getDriverInh().charAt(0); +// inh String NativeTypesInh.getStringValue(); +// eq A.getNativeTypesInh().getStringValue() = new String(getDriverInh()); +// +// // boxed types, inherited +// inh Integer BoxedTypesInh.getIntValue(); +// eq A.getBoxedTypesInh().getIntValue() = Integer.valueOf(getDriverInh()); +// inh Short BoxedTypesInh.getShortValue(); +// eq A.getBoxedTypesInh().getShortValue() = Short.valueOf(getDriverInh()); +// inh Long BoxedTypesInh.getLongValue(); +// eq A.getBoxedTypesInh().getLongValue() = Long.valueOf(getDriverInh()); +// inh Float BoxedTypesInh.getFloatValue(); +// eq A.getBoxedTypesInh().getFloatValue() = Float.valueOf(getDriverInh()); +// inh Double BoxedTypesInh.getDoubleValue(); +// eq A.getBoxedTypesInh().getDoubleValue() = Double.valueOf(getDriverInh()); +// inh Character BoxedTypesInh.getCharValue(); +// eq A.getBoxedTypesInh().getCharValue() = getDriverInh().charAt(0); +} diff --git a/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.relast b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.relast new file mode 100644 index 0000000..e0fd782 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/defaultOnlyWrite/Test.relast @@ -0,0 +1,11 @@ +A ::= NativeTypesSyn* BoxedTypesSyn* <DriverInh:String>; +// native types, synthesized +NativeTypesSyn ::= <DriverSyn:String> /<IntValue:int>/ /<ShortValue:short>/ /<LongValue:long>/ /<FloatValue:float>/ /<DoubleValue:double>/ /<CharValue:char>/ /<StringValue:String>/ ; +// boxed types, synthesized +BoxedTypesSyn ::= <DriverSyn:String> /<IntValue:Integer>/ /<ShortValue:Short>/ /<LongValue:Long>/ /<FloatValue:Float>/ /<DoubleValue:Double>/ /<CharValue:Character>/ ; + +// --- inherited attributes not supported --- +//// native types, inherited +//NativeTypesInh ::= /<IntValue:int>/ /<ShortValue:short>/ /<LongValue:long>/ /<FloatValue:float>/ /<DoubleValue:double>/ /<CharValue:char>/ /<StringValue:String>/ ; +//// boxed types, inherited +//BoxedTypesInh ::= /<IntValue:Integer>/ /<ShortValue:Short>/ /<LongValue:Long>/ /<FloatValue:Float>/ /<DoubleValue:Double>/ /<CharValue:Character>/ ; diff --git a/ragconnect.tests/src/test/01-input/errors/Errors.connect b/ragconnect.tests/src/test/01-input/errors/Errors.connect new file mode 100644 index 0000000..bd57822 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/errors/Errors.connect @@ -0,0 +1,72 @@ +// --- update receive definitions --- +// Error: there must not be two receive definitions for the same token +receive B.DoubledValue ; +receive B.DoubledValue using IntToInt ; + +// NOT HANDLED \\ Error: the token must be resolvable within the parent type +// NOT HANDLED \\ receive B.NonExisting ; + +// Error: the Token must not be a TokenNTA (i.e., check for !Token.getNTA()) +receive B.ErrorNTA ; + +// Error: from-type of first mapping must be byte[] or a supported primitive type +receive B.ErrorTypeOfFirstMapping using ListToList ; + +// Error: to-type of last mapping must be type of the Token +receive B.ErrorTypeOfLastMapping using StringToList ; + +// Error: types of mappings must match (modulo inheritance) +receive B.ErrorTypeMismatch using StringToList, IntToInt ; + +// --- update send definitions --- +// NOT HANDLED \\ Error: the token must be resolvable within the parent type +// NOT HANDLED \\ receive C.NonExisting ; + +// Error: Token must be a TokenNTA (i.e., check for Token.getNTA()) +send C.ErrorNotNTA ; + +// Error: from-type of first mapping must be type of Token +send C.ErrorTypeOfFirstMapping using IntToInt ; + +// Error: to-type of last mapping must be byte[] or a supported primitive type +send C.ErrorTypeOfLastMapping1 using StringToList ; +send C.ErrorTypeOfLastMapping2 ; + +// Error: types of mappings must match (modulo inheritance) +send C.ErrorTypeMismatch using StringToList, IntToInt ; + +// Error: no more than one send mapping for each TokenComponent +send C.DoubledValue ; +send C.DoubledValue using IntToInt ; + +// --- dependency definitions --- +// NOT HANDLED \\ Error: Both, source and target must be resolvable within the parent type +// NOT HANDLED \\ D.SourceNonExistingTarget canDependOn D.NonExisting as NonExistingTarget ; +// NOT HANDLED \\ D.NonExisting canDependOn D.TargetNonExistingSource as NonExistingSource ; + +// Error: There must be a send update definition for the target token +D.SourceNoWriteDef canDependOn D.TargetNoWriteDef as NoWriteDef ; + +// Error: The name of a dependency definition must not be equal to a list-node on the source +D.SourceSameAsListNode canDependOn D.TargetSameAsListNode as MyList ; +send D.TargetSameAsListNode; + +// Error: There must not be two dependency definitions with the same name +D.SourceDoubledValue canDependOn D.TargetDoubledValue as DoubledValue ; +D.SourceDoubledValue canDependOn D.TargetDoubledValue as DoubledValue ; +send D.TargetDoubledValue; + +// --- mapping definitions --- +ListToList maps java.util.List<String> list to java.util.List<String> {: + return list; +:} + +StringToList maps String s to List<String> {: + java.util.List<String> result = new java.util.ArrayList<>(); + result.add(s); + return result; +:} + +IntToInt maps int number to int {: + return number + 1; +:} diff --git a/ragconnect.tests/src/test/01-input/errors/Errors.expected b/ragconnect.tests/src/test/01-input/errors/Errors.expected new file mode 100644 index 0000000..e69de29 diff --git a/ragconnect.tests/src/test/01-input/errors/Errors.relast b/ragconnect.tests/src/test/01-input/errors/Errors.relast new file mode 100644 index 0000000..fcde7df --- /dev/null +++ b/ragconnect.tests/src/test/01-input/errors/Errors.relast @@ -0,0 +1,15 @@ +A ::= B C D ; + +// read definitions +B ::= /<ErrorNTA:String>/ <ErrorTypeOfFirstMapping:String> <ErrorTypeOfLastMapping:String> <DoubledValue:int> <ErrorTypeMismatch:String> ; + +// write definitions +C ::= <ErrorNotNTA:String> /<ErrorTypeOfFirstMapping:String>/ /<ErrorTypeOfLastMapping1:String>/ /<ErrorTypeOfLastMapping2:List<String>>/ /<ErrorTypeMismatch:String>/ /<DoubledValue:int>/ ; + +// dependency definitions +D ::= <SourceNonExistingTarget> + /<TargetNonExistingSource>/ + <SourceNoWriteDef> /<TargetNoWriteDef>/ + <SourceSameAsListNode> /<TargetSameAsListNode>/ + <SourceDoubledValue> /<TargetDoubledValue>/ + MyList:D* ; diff --git a/ragconnect.tests/src/test/01-input/errors/README.md b/ragconnect.tests/src/test/01-input/errors/README.md new file mode 100644 index 0000000..e8efed3 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/errors/README.md @@ -0,0 +1,25 @@ +Ideas for errors: + +- Read-Update + - the token must be resolvable within the parent type + - the Token must not be a TokenNTA (i.e., check for `!Token.getNTA()`) + - type of first mapping must be `byte[]` + - type of last mapping must be type of the Token + - types of mappings must match (modulo inheritance) +- Write-Update + - the token must be resolvable within the parent type + - Token must be a TokenNTA (i.e., check for `Token.getNTA()`) + - type of first mapping must be type of Token + - type of last mapping must be `byte[]` + - types of mappings must match (modulo inheritance) + - no more than one write mapping for each TokenComponent +- for all type checks, there are three cases regarding the two types to check against: + 1) both are nonterminal types, check with grammar + 2) both are known classes, check with `Class.forName()` and subclass-checking-methods + 3) otherwise issue warning, that types could not be matched +- dependency-definition + - There **must be** a write update definition for the target token + - Otherwise there are missing update and write methods used in the virtual setter + - Both, source and target must be resolvable within the parent type + - The name of a dependency definition must not be equal to a list-node on the source + - There must not be two dependency definitions with the same name diff --git a/ragconnect.tests/src/test/01-input/example/README.md b/ragconnect.tests/src/test/01-input/example/README.md new file mode 100644 index 0000000..7665b43 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/example/README.md @@ -0,0 +1,3 @@ +# Example + +Idea: Use the motivating example from our paper as a test case, including one read, one write update definition diff --git a/ragconnect.tests/src/test/01-input/example/Test.connect b/ragconnect.tests/src/test/01-input/example/Test.connect new file mode 100644 index 0000000..2a26051 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/example/Test.connect @@ -0,0 +1,31 @@ +/* Version 2020-07-15 */ +// --- update definitions --- +receive Link.CurrentPosition using ParseRobotState, RobotStateToIntPosition ; +send RobotArm.AppropriateSpeed using CreateSpeedMessage, SerializeRobotConfig ; + +// --- dependency definitions --- +RobotArm.AppropriateSpeed canDependOn Link.CurrentPosition as dependency1 ; + +// --- mapping definitions --- +ParseRobotState maps byte[] bytes to robot.RobotStateOuterClass.RobotState {: + TestCounter.INSTANCE.numberParseLinkState += 1; + return robot.RobotStateOuterClass.RobotState.parseFrom(bytes); +:} + +SerializeRobotConfig maps config.Config.RobotConfig rc to byte[] {: + TestCounter.INSTANCE.numberSerializeRobotConfig += 1; + return rc.toByteArray(); +:} + +RobotStateToIntPosition maps robot.RobotStateOuterClass.RobotState rs to IntPosition {: + TestCounter.INSTANCE.numberLinkStateToIntPosition += 1; + robot.RobotStateOuterClass.RobotState.Position p = rs.getPosition(); + return IntPosition.of((int) (Math.round(p.getX() * 10)), (int) (Math.round(p.getY() * 10)), (int) (Math.round(p.getZ() * 10))); +:} + +CreateSpeedMessage maps double speed to config.Config.RobotConfig {: + TestCounter.INSTANCE.numberCreateSpeedMessage += 1; + return config.Config.RobotConfig.newBuilder() + .setSpeed(speed) + .build(); +:} diff --git a/ragconnect.tests/src/test/01-input/example/Test.jadd b/ragconnect.tests/src/test/01-input/example/Test.jadd new file mode 100644 index 0000000..b62b9ae --- /dev/null +++ b/ragconnect.tests/src/test/01-input/example/Test.jadd @@ -0,0 +1,95 @@ +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; + + private IntPosition(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public static IntPosition of(int x, int y, int z) { + return new IntPosition(x, y, z); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IntPosition that = (IntPosition) o; + return x == that.x && + y == that.y && + z == that.z; + } + + @Override + public int hashCode() { + return java.util.Objects.hash(x, y, z); + } + + @Override + public String toString() { + return "(" + x + ", " + y + ", " + z + ")"; + } + } + + inh Model RobotArm.model(); + eq Model.getRobotArm().model() = this; + + inh RobotArm Link.containingRobotArm(); + eq RobotArm.getLink().containingRobotArm() = this; + eq RobotArm.getEndEffector().containingRobotArm() = this; + + syn boolean RobotArm.isInSafetyZone() { + TestCounter.INSTANCE.numberInSafetyZone += 1; + for (Link link : getLinkList()) { + if (model().getZoneModel().isInSafetyZone(link.getCurrentPosition())) { + return true; + } + } + return model().getZoneModel().isInSafetyZone(getEndEffector().getCurrentPosition()); + } + + cache ZoneModel.isInSafetyZone(IntPosition pos); + syn boolean ZoneModel.isInSafetyZone(IntPosition pos) { + for (Zone sz : getSafetyZoneList()) { + for (Coordinate coordinate : sz.getCoordinateList()) { + if (coordinate.getPosition().equals(pos)) { + return true; + } + } + } + return false; + } + + syn double RobotArm.speedLow() = 0.4d; + syn double RobotArm.speedHigh() = 1.0d; + + syn double RobotArm.getAppropriateSpeed() { + return isInSafetyZone() ? speedLow() : speedHigh(); + } +} diff --git a/ragconnect.tests/src/test/01-input/example/Test.relast b/ragconnect.tests/src/test/01-input/example/Test.relast new file mode 100644 index 0000000..b8d932a --- /dev/null +++ b/ragconnect.tests/src/test/01-input/example/Test.relast @@ -0,0 +1,13 @@ +Model ::= RobotArm ZoneModel ; + +ZoneModel ::= SafetyZone:Zone* ; + +Zone ::= Coordinate* ; + +RobotArm ::= Link* EndEffector /<AppropriateSpeed:double>/ ; + +Link ::= <Name:String> <CurrentPosition:IntPosition> ; + +EndEffector : Link; + +Coordinate ::= <Position:IntPosition> ; diff --git a/ragconnect.tests/src/test/01-input/example/config.json b/ragconnect.tests/src/test/01-input/example/config.json new file mode 100644 index 0000000..0284315 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/example/config.json @@ -0,0 +1,9 @@ +{ + "joints": [ + {"name": "Joint1", "topic": "robot/arm/joint1"}, + {"name": "Joint2", "topic": "robot/arm/joint2"}, + {"name": "EndEffector", "topic": "-", "isEndEffector": true} + ], + "robotConfigTopic": "robot/config", + "dataConfigTopic": "-" +} diff --git a/ragconnect.tests/src/test/01-input/read1write2/README.md b/ragconnect.tests/src/test/01-input/read1write2/README.md new file mode 100644 index 0000000..197eeb5 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read1write2/README.md @@ -0,0 +1,3 @@ +# Read one - Write two + +Idea: Define Read-Update for one terminal, add dependencies to two other terminals, which each have Write-Update defined. Test, whether code gets generated correctly and that write is trigger for each of the two terminals upon read. diff --git a/ragconnect.tests/src/test/01-input/read1write2/Test.connect b/ragconnect.tests/src/test/01-input/read1write2/Test.connect new file mode 100644 index 0000000..e826f1d --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read1write2/Test.connect @@ -0,0 +1,18 @@ +// --- update definitions --- +// OnSameNonterminal +receive OnSameNonterminal.Input; +send OnSameNonterminal.OutInteger; +send OnSameNonterminal.OutString; + +// OnDifferentNonterminal +receive OnDifferentNonterminal.Input; +send TheOther.OutInteger; +send TheOther.OutString; + +// --- dependency definitions --- +// OnSameNonterminal +OnSameNonterminal.OutInteger canDependOn OnSameNonterminal.Input as IntDependency; +OnSameNonterminal.OutString canDependOn OnSameNonterminal.Input as StringDependency; +// OnDifferentNonterminal +TheOther.OutInteger canDependOn OnDifferentNonterminal.Input as IntDependency; +TheOther.OutString canDependOn OnDifferentNonterminal.Input as StringDependency; diff --git a/ragconnect.tests/src/test/01-input/read1write2/Test.jadd b/ragconnect.tests/src/test/01-input/read1write2/Test.jadd new file mode 100644 index 0000000..490772f --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read1write2/Test.jadd @@ -0,0 +1,11 @@ +aspect Computation{ + // OnSameNonterminal + syn int OnSameNonterminal.getOutInteger() = Integer.parseInt(getInput()); + syn String OnSameNonterminal.getOutString() = "prefix" + getInput(); + + // OnDifferentNonterminal + syn int TheOther.getOutInteger() = Integer.parseInt(input()); + syn String TheOther.getOutString() = "prefix" + input(); + inh String TheOther.input(); + eq OnDifferentNonterminal.getTheOther().input() = getInput(); +} diff --git a/ragconnect.tests/src/test/01-input/read1write2/Test.relast b/ragconnect.tests/src/test/01-input/read1write2/Test.relast new file mode 100644 index 0000000..fa0b171 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read1write2/Test.relast @@ -0,0 +1,4 @@ +A ::= OnSameNonterminal OnDifferentNonterminal ; +OnSameNonterminal ::= <Input:String> /<OutInteger:int>/ /<OutString:String>/ ; +OnDifferentNonterminal ::= <Input:String> TheOther* ; +TheOther ::= /<OutInteger:int>/ /<OutString:String>/ ; diff --git a/ragconnect.tests/src/test/01-input/read2write1/Test.connect b/ragconnect.tests/src/test/01-input/read2write1/Test.connect new file mode 100644 index 0000000..4c2a9b2 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read2write1/Test.connect @@ -0,0 +1,18 @@ +// --- update definitions --- +// OnSameNonterminal +receive OnSameNonterminal.Input1; +receive OnSameNonterminal.Input2; +send OnSameNonterminal.OutInteger; + +// OnDifferentNonterminal +receive OnDifferentNonterminal.Input1; +receive OnDifferentNonterminal.Input2; +send TheOther.OutInteger; + +// --- dependency definitions --- +// OnSameNonterminal +OnSameNonterminal.OutInteger canDependOn OnSameNonterminal.Input1 as Int1Dependency; +OnSameNonterminal.OutInteger canDependOn OnSameNonterminal.Input2 as Int2Dependency; +// OnDifferentNonterminal +TheOther.OutInteger canDependOn OnDifferentNonterminal.Input1 as Int1Dependency; +TheOther.OutInteger canDependOn OnDifferentNonterminal.Input2 as Int2Dependency; diff --git a/ragconnect.tests/src/test/01-input/read2write1/Test.jadd b/ragconnect.tests/src/test/01-input/read2write1/Test.jadd new file mode 100644 index 0000000..4d31f1a --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read2write1/Test.jadd @@ -0,0 +1,11 @@ +aspect Computation{ + // OnSameNonterminal + syn int OnSameNonterminal.getOutInteger() = Integer.parseInt(getInput1() + getInput2()); + + // OnDifferentNonterminal + syn int TheOther.getOutInteger() = Integer.parseInt(input1() + input2()); + inh String TheOther.input1(); + eq OnDifferentNonterminal.getTheOther().input1() = getInput1(); + inh String TheOther.input2(); + eq OnDifferentNonterminal.getTheOther().input2() = getInput2(); +} diff --git a/ragconnect.tests/src/test/01-input/read2write1/Test.relast b/ragconnect.tests/src/test/01-input/read2write1/Test.relast new file mode 100644 index 0000000..afe0125 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/read2write1/Test.relast @@ -0,0 +1,4 @@ +A ::= OnSameNonterminal OnDifferentNonterminal ; +OnSameNonterminal ::= <Input1:String> <Input2:String> /<OutInteger:int>/ ; +OnDifferentNonterminal ::= <Input1:String> <Input2:String> TheOther* ; +TheOther ::= /<OutInteger:int>/ ; diff --git a/ragconnect.tests/src/test/01-input/tokenValueSend/README.md b/ragconnect.tests/src/test/01-input/tokenValueSend/README.md new file mode 100644 index 0000000..b2d0c3c --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tokenValueSend/README.md @@ -0,0 +1,3 @@ +# Token Value Send + +Idea: 1) Test normal token send, 2) Test combined receive and send on same token, 3) Test combined receive, send and a dependency diff --git a/ragconnect.tests/src/test/01-input/tokenValueSend/Test.connect b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.connect new file mode 100644 index 0000000..bcc26d1 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.connect @@ -0,0 +1,23 @@ +// OnlySend +send OnlySend.Value using AddPostfix ; + +// ReceiveAndSend +receive ReceiveAndSend.Value using AddPrefix ; +send ReceiveAndSend.Value using AddPostfix ; + +// ReceiveSendAndDepend +receive ReceiveSendAndDepend.Value using AddPrefix ; +send ReceiveSendAndDepend.Value using AddPostfix ; +send ReceiveSendAndDepend.OtherOutput using AddPostfix ; + +ReceiveSendAndDepend.OtherOutput canDependOn ReceiveSendAndDepend.Value as dependency1 ; + +AddPrefix maps String s to String {: + System.out.println("receive " + s); + return "Pre-" + s; +:} + +AddPostfix maps String s to String {: + System.out.println("send " + s); + return s + "-Post"; +:} diff --git a/ragconnect.tests/src/test/01-input/tokenValueSend/Test.jadd b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.jadd new file mode 100644 index 0000000..6a2f3e0 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.jadd @@ -0,0 +1,4 @@ +aspect Computation{ + // ReceiveSendAndDepend + syn String ReceiveSendAndDepend.getOtherOutput() = getValue() + "-T"; +} diff --git a/ragconnect.tests/src/test/01-input/tokenValueSend/Test.relast b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.relast new file mode 100644 index 0000000..eef6095 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tokenValueSend/Test.relast @@ -0,0 +1,4 @@ +A ::= OnlySend ReceiveAndSend ReceiveSendAndDepend ; +OnlySend ::= <Value:String> ; +ReceiveAndSend ::= <Value:String> ; +ReceiveSendAndDepend ::= <Value:String> /<OtherOutput:String>/ ; diff --git a/ragconnect.tests/src/test/01-input/tutorial/README.md b/ragconnect.tests/src/test/01-input/tutorial/README.md new file mode 100644 index 0000000..09995a9 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tutorial/README.md @@ -0,0 +1,3 @@ +# Tutorial + +Idea: Test the example from the [documentation](https://jastadd.pages.st.inf.tu-dresden.de/ragconnect/using.html) diff --git a/ragconnect.tests/src/test/01-input/tutorial/Test.connect b/ragconnect.tests/src/test/01-input/tutorial/Test.connect new file mode 100644 index 0000000..c6bdc7b --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tutorial/Test.connect @@ -0,0 +1,13 @@ +// 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 ; diff --git a/ragconnect.tests/src/test/01-input/tutorial/Test.jadd b/ragconnect.tests/src/test/01-input/tutorial/Test.jadd new file mode 100644 index 0000000..4cb9dbf --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tutorial/Test.jadd @@ -0,0 +1,7 @@ +aspect Computation { + syn String A.getOutputOnA() = "a" + getInput(); + + syn String B.getOutputOnB() = "b" + input(); + inh String B.input(); + eq A.getB().input() = getInput(); +} diff --git a/ragconnect.tests/src/test/01-input/tutorial/Test.relast b/ragconnect.tests/src/test/01-input/tutorial/Test.relast new file mode 100644 index 0000000..9009e27 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/tutorial/Test.relast @@ -0,0 +1,2 @@ +A ::= <Input:String> /<OutputOnA:String>/ B* ; +B ::= /<OutputOnB:String>/ ; diff --git a/ragconnect.tests/src/test/01-input/via/Test.connect b/ragconnect.tests/src/test/01-input/via/Test.connect new file mode 100644 index 0000000..e4d2862 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/via/Test.connect @@ -0,0 +1,33 @@ +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"; +:} diff --git a/ragconnect.tests/src/test/01-input/via/Test.jadd b/ragconnect.tests/src/test/01-input/via/Test.jadd new file mode 100644 index 0000000..9d25387 --- /dev/null +++ b/ragconnect.tests/src/test/01-input/via/Test.jadd @@ -0,0 +1,8 @@ +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" ; +} diff --git a/ragconnect.tests/src/test/01-input/via/Test.relast b/ragconnect.tests/src/test/01-input/via/Test.relast new file mode 100644 index 0000000..1e707fb --- /dev/null +++ b/ragconnect.tests/src/test/01-input/via/Test.relast @@ -0,0 +1,5 @@ +A ::= <Mqtt2MqttInput> /<Mqtt2MqttOutput>/ + <Rest2RestInput> /<Rest2RestOutput>/ + <Mqtt2RestInput> /<Mqtt2RestOutput>/ + <Rest2MqttInput> /<Rest2MqttOutput>/ + <Both2BothInput> /<Both2MqttOutput>/ /<Both2RestOutput>/; diff --git a/ragconnect.tests/src/test/02-after-ragconnect/.gitignore b/ragconnect.tests/src/test/02-after-ragconnect/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/ragconnect.tests/src/test/02-after-ragconnect/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/ragconnect.tests/src/test/03-after-relast/.gitignore b/ragconnect.tests/src/test/03-after-relast/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/ragconnect.tests/src/test/03-after-relast/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/ragconnect.tests/src/test/java-gen/.gitignore b/ragconnect.tests/src/test/java-gen/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/ragconnect.tests/src/test/java-gen/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java new file mode 100644 index 0000000..36baf2c --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java @@ -0,0 +1,104 @@ +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(); + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java new file mode 100644 index 0000000..65302cf --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java @@ -0,0 +1,138 @@ +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); + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java new file mode 100644 index 0000000..c312d4c --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java @@ -0,0 +1,310 @@ +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; + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java new file mode 100644 index 0000000..17d853f --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java @@ -0,0 +1,84 @@ +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); + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java new file mode 100644 index 0000000..c3df78d --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java @@ -0,0 +1,278 @@ +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; + } +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java new file mode 100644 index 0000000..2940aac --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java @@ -0,0 +1,241 @@ +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; + } + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java new file mode 100644 index 0000000..4790b17 --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java @@ -0,0 +1,232 @@ +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; + } + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java new file mode 100644 index 0000000..143c74e --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java @@ -0,0 +1,73 @@ +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); + } +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TokenValueSendTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TokenValueSendTest.java new file mode 100644 index 0000000..bc68f5b --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TokenValueSendTest.java @@ -0,0 +1,260 @@ +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); + } + } + +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java new file mode 100644 index 0000000..d7f3462 --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java @@ -0,0 +1,68 @@ +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 + } +} diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java new file mode 100644 index 0000000..3c17352 --- /dev/null +++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java @@ -0,0 +1,324 @@ +package org.jastadd.ragconnect.tests; + +import org.junit.jupiter.api.Tag; +import via.ast.A; +import via.ast.MqttHandler; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import static org.jastadd.ragconnect.tests.TestUtils.mqttUri; +import static org.jastadd.ragconnect.tests.TestUtils.restUri; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Test case "via". + * + * @author rschoene - Initial contribution + */ +@Tag("rest") +public class ViaTest extends AbstractMqttTest { + + private static final int REST_PORT = 9002; + + private static final String TOPIC_MQTT_2_MQTT_RECEIVE = "mqtt2mqtt/receive"; + private static final String PATH_REST_2_REST_RECEIVE = "rest2rest/receive"; + private static final String TOPIC_MQTT_2_REST_RECEIVE = "mqtt2rest/receive"; + private static final String PATH_REST_2_MQTT_RECEIVE = "rest2mqtt/receive"; + private static final String TOPIC_BOTH_MQTT_RECEIVE = "both/send"; + private static final String PATH_BOTH_REST_RECEIVE = "both/send"; + + private static final String TOPIC_MQTT_2_MQTT_SEND = "mqtt2mqtt/send"; + private static final String PATH_REST_2_REST_SEND = "rest2rest/send"; + private static final String PATH_MQTT_2_REST_SEND = "mqtt2rest/send"; + private static final String TOPIC_REST_2_MQTT_SEND = "rest2mqtt/send"; + private static final String TOPIC_BOTH_2_MQTT_SEND = "both2mqtt/send"; + private static final String PATH_BOTH_2_REST_SEND = "both2rest/send"; + + private static final String REST_SERVER_BASE_URL = "http://localhost:" + REST_PORT + "/"; + + private MqttHandler handler; + private A model; + private ReceiverData dataMqtt2Mqtt; + private ReceiverData dataRest2Mqtt; + private WebTarget dataRest2Rest; + private WebTarget dataMqtt2Rest; + private ReceiverData dataBoth2Mqtt; + private WebTarget dataBoth2Rest; + + private WebTarget senderRest2Rest; + private WebTarget senderRest2Mqtt; + private WebTarget senderBoth2Rest; + + @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, "100-M2M-ToMqtt", + "200-R2R-ToRest", + "300-M2R-ToRest", + 1, "400-R2M-ToMqtt", + 1, "500-B2M-ToMqtt", + "500-B2R-ToRest"); + + sendData("101", "201", "301", "401"); + sendDataForBoth("501", true); + + // check new value + TestUtils.waitForMqtt(); + checkData(2, "FromMqtt-101-M2M-ToMqtt", + "FromRest-201-R2R-ToRest", + "FromMqtt-301-M2R-ToRest", + 2, "FromRest-401-R2M-ToMqtt", + 2, "501-B2M-ToMqtt", + "501-B2R-ToRest"); + + // send value only for bothInput via REST + sendDataForBoth("502", false); + + // check this value + TestUtils.waitForMqtt(); + checkData(2, "FromMqtt-101-M2M-ToMqtt", + "FromRest-201-R2R-ToRest", + "FromMqtt-301-M2R-ToRest", + 2, "FromRest-401-R2M-ToMqtt", + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); + + // send same value only for bothInput via MQTT + sendDataForBoth("502", true); + + // check this value + TestUtils.waitForMqtt(); + checkData(2, "FromMqtt-101-M2M-ToMqtt", + "FromRest-201-R2R-ToRest", + "FromMqtt-301-M2R-ToRest", + 2, "FromRest-401-R2M-ToMqtt", + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); + + // send values for other things + sendData("102", "202", "302", "402"); + + // check this value + TestUtils.waitForMqtt(); + checkData(3, "FromMqtt-102-M2M-ToMqtt", + "FromRest-202-R2R-ToRest", + "FromMqtt-302-M2R-ToRest", + 3, "FromRest-402-R2M-ToMqtt", + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); + + // send same values again for other things + sendData("102", "202", "302", "402"); + + // check this value + TestUtils.waitForMqtt(); + checkData(3, "FromMqtt-102-M2M-ToMqtt", + "FromRest-202-R2R-ToRest", + "FromMqtt-302-M2R-ToRest", + 3, "FromRest-402-R2M-ToMqtt", + 3, "502-B2M-ToMqtt", + "502-B2R-ToRest"); + } + + @Override + protected void communicateOnlyUpdatedValue() throws InterruptedException { +// check initial value + TestUtils.waitForMqtt(); + checkData(0, null, + "200-R2R-ToRest", + "300-M2R-ToRest", + 0, null, + 0, null, + "500-B2R-ToRest"); + + sendData("111", "211", "311", "411"); + sendDataForBoth("511", true); + + // check new value + TestUtils.waitForMqtt(); + checkData(1, "FromMqtt-111-M2M-ToMqtt", + "FromRest-211-R2R-ToRest", + "FromMqtt-311-M2R-ToRest", + 1, "FromRest-411-R2M-ToMqtt", + 1, "511-B2M-ToMqtt", + "511-B2R-ToRest"); + + // send value only for bothInput via REST + sendDataForBoth("512", false); + + // check this value + TestUtils.waitForMqtt(); + checkData(1, "FromMqtt-111-M2M-ToMqtt", + "FromRest-211-R2R-ToRest", + "FromMqtt-311-M2R-ToRest", + 1, "FromRest-411-R2M-ToMqtt", + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); + + // send same value only for bothInput via MQTT + sendDataForBoth("512", true); + + // check this value + TestUtils.waitForMqtt(); + checkData(1, "FromMqtt-111-M2M-ToMqtt", + "FromRest-211-R2R-ToRest", + "FromMqtt-311-M2R-ToRest", + 1, "FromRest-411-R2M-ToMqtt", + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); + + // send values for other things + sendData("112", "212", "312", "412"); + + // check this value + TestUtils.waitForMqtt(); + checkData(2, "FromMqtt-112-M2M-ToMqtt", + "FromRest-212-R2R-ToRest", + "FromMqtt-312-M2R-ToRest", + 2, "FromRest-412-R2M-ToMqtt", + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); + + // send same values again for other things + sendData("112", "212", "312", "412"); + + // check this value + TestUtils.waitForMqtt(); + checkData(2, "FromMqtt-112-M2M-ToMqtt", + "FromRest-212-R2R-ToRest", + "FromMqtt-312-M2R-ToRest", + 2, "FromRest-412-R2M-ToMqtt", + 2, "512-B2M-ToMqtt", + "512-B2R-ToRest"); + } + + private void sendData(String inputMqtt2Mqtt, String inputRest2Rest, String inputMqtt2Rest, String inputRest2Mqtt) { + handler.publish(TOPIC_MQTT_2_MQTT_RECEIVE, inputMqtt2Mqtt.getBytes()); + senderRest2Rest.request().put(Entity.entity(inputRest2Rest, MediaType.TEXT_PLAIN_TYPE)); + handler.publish(TOPIC_MQTT_2_REST_RECEIVE, inputMqtt2Rest.getBytes()); + senderRest2Mqtt.request().put(Entity.entity(inputRest2Mqtt, MediaType.TEXT_PLAIN_TYPE)); + } + + private void sendDataForBoth(String input, boolean useMqtt) { + if (useMqtt) { + handler.publish(TOPIC_BOTH_MQTT_RECEIVE, input.getBytes()); + } else { + senderBoth2Rest.request().put(Entity.entity(input, MediaType.TEXT_PLAIN_TYPE)); + } + } + + private void checkData(int numberOfMqtt2MqttValues, String mqtt2MqttValue, String rest2RestValue, String mqtt2RestValue, int numberOfRest2MqttValues, String rest2MqttValue, int numberOfBoth2MqttValues, String both2MqttValue, String both2RestValue) { + dataMqtt2Mqtt.assertEqualData(numberOfMqtt2MqttValues, mqtt2MqttValue); + dataRest2Mqtt.assertEqualData(numberOfRest2MqttValues, rest2MqttValue); + dataBoth2Mqtt.assertEqualData(numberOfBoth2MqttValues, both2MqttValue); + assertEquals(rest2RestValue, readRest2Rest()); + assertEquals(mqtt2RestValue, readMqtt2Rest()); + assertEquals(both2RestValue, readBoth2Rest()); + } + + private String readRest2Rest() { + return dataRest2Rest.request().get().readEntity(String.class); + } + + private String readMqtt2Rest() { + return dataMqtt2Rest.request().get().readEntity(String.class); + } + + private String readBoth2Rest() { + return dataBoth2Rest.request().get().readEntity(String.class); + } + + @Override + protected void createModel() { + // Setting value for Input without dependencies does not trigger any updates + model = new A(); + model.setMqtt2MqttInput("100"); + model.setRest2RestInput("200"); + model.setMqtt2RestInput("300"); + model.setRest2MqttInput("400"); + model.setBoth2BothInput("500"); + } + + @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)); + + model.addDependencyMqtt2Mqtt(model); + model.addDependencyRest2Rest(model); + model.addDependencyMqtt2Rest(model); + model.addDependencyRest2Mqtt(model); + model.addDependencyBoth2Mqtt(model); + model.addDependencyBoth2Rest(model); + + dataMqtt2Mqtt = new ReceiverData(); + dataRest2Mqtt = new ReceiverData(); + dataBoth2Mqtt = new ReceiverData(); + + handler.newConnection(TOPIC_MQTT_2_MQTT_SEND, bytes -> { + dataMqtt2Mqtt.numberOfStringValues += 1; + dataMqtt2Mqtt.lastStringValue = new String(bytes); + }); + handler.newConnection(TOPIC_REST_2_MQTT_SEND, bytes -> { + dataRest2Mqtt.numberOfStringValues += 1; + dataRest2Mqtt.lastStringValue = new String(bytes); + }); + handler.newConnection(TOPIC_BOTH_2_MQTT_SEND, bytes -> { + dataBoth2Mqtt.numberOfStringValues += 1; + dataBoth2Mqtt.lastStringValue = new String(bytes); + }); + + Client client = ClientBuilder.newClient(); + dataRest2Rest = client.target(REST_SERVER_BASE_URL + PATH_REST_2_REST_SEND); + dataMqtt2Rest = client.target(REST_SERVER_BASE_URL + PATH_MQTT_2_REST_SEND); + dataBoth2Rest = client.target(REST_SERVER_BASE_URL + PATH_BOTH_2_REST_SEND); + senderRest2Rest = client.target(REST_SERVER_BASE_URL + PATH_REST_2_REST_RECEIVE); + senderRest2Mqtt = client.target(REST_SERVER_BASE_URL + PATH_REST_2_MQTT_RECEIVE); + senderBoth2Rest = client.target(REST_SERVER_BASE_URL + PATH_BOTH_REST_RECEIVE); + + model.connectMqtt2MqttInput(mqttUri(TOPIC_MQTT_2_MQTT_RECEIVE)); + model.connectMqtt2MqttOutput(mqttUri(TOPIC_MQTT_2_MQTT_SEND), writeCurrentValue); + model.connectMqtt2RestInput(mqttUri(TOPIC_MQTT_2_REST_RECEIVE)); + model.connectMqtt2RestOutput(restUri(PATH_MQTT_2_REST_SEND, REST_PORT), writeCurrentValue); + model.connectRest2MqttInput(restUri(PATH_REST_2_MQTT_RECEIVE, REST_PORT)); + model.connectRest2MqttOutput(mqttUri(TOPIC_REST_2_MQTT_SEND), writeCurrentValue); + model.connectRest2RestInput(restUri(PATH_REST_2_REST_RECEIVE, REST_PORT)); + model.connectRest2RestOutput(restUri(PATH_REST_2_REST_SEND, REST_PORT), writeCurrentValue); + model.connectBoth2BothInput(mqttUri(TOPIC_BOTH_MQTT_RECEIVE)); + model.connectBoth2BothInput(restUri(PATH_BOTH_REST_RECEIVE, REST_PORT)); + model.connectBoth2MqttOutput(mqttUri(TOPIC_BOTH_2_MQTT_SEND), writeCurrentValue); + model.connectBoth2RestOutput(restUri(PATH_BOTH_2_REST_SEND, REST_PORT), writeCurrentValue); + } + + private static class ReceiverData { + String lastStringValue; + int numberOfStringValues = 0; + + public void assertEqualData(int expectedNumberOfValues, String expectedLastValue) { + assertEquals(expectedNumberOfValues, this.numberOfStringValues); + assertEquals(expectedLastValue, this.lastStringValue); + } + } +} diff --git a/ragconnect.tests/src/test/proto/config.proto b/ragconnect.tests/src/test/proto/config.proto new file mode 100644 index 0000000..38cb5d0 --- /dev/null +++ b/ragconnect.tests/src/test/proto/config.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package config; + +message RobotConfig { + double speed = 1; +} \ No newline at end of file diff --git a/ragconnect.tests/src/test/proto/robot_state.proto b/ragconnect.tests/src/test/proto/robot_state.proto new file mode 100644 index 0000000..6630631 --- /dev/null +++ b/ragconnect.tests/src/test/proto/robot_state.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package robot; + +message RobotState { + + message Position { + double x = 1; + double y = 2; + double z = 3; + } + + message Orientation { + double x = 1; + double y = 2; + double z = 3; + double w = 4; + } + + message LinearTwist { + double x = 1; + double y = 2; + double z = 3; + } + + message AngularTwist { + double x = 1; + double y = 2; + double z = 3; + } + + string name = 1; + Position position = 2; + Orientation orientation = 3; + LinearTwist linear_twist = 4; + AngularTwist angular_twist = 5; +} \ No newline at end of file diff --git a/ragconnect.tests/src/test/proto/trajectory.proto b/ragconnect.tests/src/test/proto/trajectory.proto new file mode 100644 index 0000000..4a7f375 --- /dev/null +++ b/ragconnect.tests/src/test/proto/trajectory.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package plan; + +message Trajectory { + + message Position { + double x = 1; + double y = 2; + double z = 3; + } + + message Orientation { + double x = 1; + double y = 2; + double z = 3; + double w = 4; + } + + enum PlanningMode { + FLUID = 0; + CARTESIAN = 1; + } + + message Pose { + Position position = 1; + Orientation orientation = 2; + PlanningMode mode = 3; + } + + repeated Pose pose = 1; + bool loop = 2; +} diff --git a/ragconnect.tests/src/test/resources/log4j2.xml b/ragconnect.tests/src/test/resources/log4j2.xml new file mode 100644 index 0000000..4c0d454 --- /dev/null +++ b/ragconnect.tests/src/test/resources/log4j2.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="INFO"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + <Loggers> + <Root level="debug"> + <AppenderRef ref="Console"/> + </Root> + <Logger name="org.eclipse.jetty" level="info" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + </Loggers> +</Configuration> diff --git a/settings.gradle b/settings.gradle index 63cc07e..e776987 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,3 +2,4 @@ rootProject.name = 'ragconnect' include 'relast-preprocessor' include 'ragconnect.base' +include 'ragconnect.tests' -- GitLab