Skip to content

Commit

Permalink
Recover parts of original federated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chanijjani committed Feb 16, 2024
1 parent 023c54d commit 6c2bf0f
Show file tree
Hide file tree
Showing 52 changed files with 2,216 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/c-tests-with-rust-rti.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
platform: ${{ (inputs.all-platforms && fromJSON('["ubuntu-latest"]')) || fromJSON('["ubuntu-latest"]') }}
runs-on: ${{ matrix.platform }}
timeout-minutes: 10
timeout-minutes: 20

steps:
- name: Check out lingua-franca repository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ public void doGenerateForRustRTI(List<FederateInstance> federates, RtiConfig rti
// Launch the RTI in the foreground.
if (host.equals("localhost") || host.equals("0.0.0.0")) {
// FIXME: the paths below will not work on Windows
shCode.append(getLaunchCodeForRustRti()).append("\n");
shCode.append(getLaunchCodeForRustRti(Integer.toString(federates.size()))).append("\n");
} else {
// Start the RTI on the remote machine - Not supported yet for Rust RTI.
}
Expand All @@ -329,10 +329,7 @@ public void doGenerateForRustRTI(List<FederateInstance> federates, RtiConfig rti
for (FederateInstance federate : federates) {
var buildConfig = getBuildConfig(federate, fileConfig, messageReporter);
if (federate.isRemote) {
Path fedRelSrcGenPath =
fileConfig.getOutPath().relativize(fileConfig.getSrcGenPath()).resolve(federate.name);
if (distCode.isEmpty()) distCode.append(distHeader).append("\n");
String logFileName = String.format("log/%s_%s.log", fileConfig.name, federate.name);
if (distCode.isEmpty()) distCode.append(distHeader).append("\n");
distCode.append(getDistCode(rtiConfig.getDirectory(), federate)).append("\n");
shCode
.append(getFedRemoteLaunchCode(rtiConfig.getDirectory(), federate, federateIndex++))
Expand Down Expand Up @@ -543,7 +540,8 @@ private String getLaunchCode(String rtiLaunchCode) {
"sleep 1");
}

private String getLaunchCodeForRustRti() {
private String getLaunchCodeForRustRti(String numberOfFederates) {
String launchCodeWithoutLogging = new String("cargo run -- -i ${FEDERATION_ID} -n "+ numberOfFederates + " -c init &");
return String.join(
"\n",
"echo \"#### Launching the Rust runtime infrastructure (RTI).\"",
Expand All @@ -561,10 +559,7 @@ private String getLaunchCodeForRustRti() {
" FIRST_RUST_RTI_PATH=${FIRST_RUST_RTI_REMOTE_PATH[0]%/*}",
" cd ${FIRST_RUST_RTI_PATH}; cd ../",
"fi",
"cargo run -- -i ${FEDERATION_ID} \\",
"-n 2 \\",
"-c init \\",
"&",
launchCodeWithoutLogging,
"# Store the PID of the RTI",
"RTI=$!",
"# Wait for the RTI to boot up before",
Expand Down
46 changes: 46 additions & 0 deletions test/RustRti/src/federated/Absent.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
target C {
tracing: true,
timeout: 100 ms
}

reactor Sender {
output out1: int
output out2: int
timer t(0, 20 ms)
state c: int = 1

reaction(t) -> out1, out2 {=
if (self->c % 2 != 0) {
lf_set(out1, self->c);
} else {
lf_set(out2, self->c);
}
self->c++;
=}
}

reactor Receiver {
input in1: int
input in2: int

reaction(in1) {=
lf_print("Received %d on in1", in1->value);
if (in1->value % 2 == 0) {
lf_print_error_and_exit("********* Expected an odd integer!");
}
=}

reaction(in2) {=
lf_print("Received %d on in2", in2->value);
if (in2->value % 2 != 0) {
lf_print_error_and_exit("********* Expected an even integer!");
}
=}
}

federated reactor(d: time = 1 ms) {
s = new Sender()
r = new Receiver()
s.out1 -> r.in1
s.out2 -> r.in2
}
33 changes: 33 additions & 0 deletions test/RustRti/src/federated/BroadcastFeedback.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/** This tests an output that is broadcast back to a multiport input of a bank. */
target C {
timeout: 1 sec,
build-type: RelWithDebInfo
}

reactor SenderAndReceiver {
output out: int
input[2] in: int
state received: bool = false

reaction(startup) -> out {=
lf_set(out, 42);
=}

reaction(in) {=
if (in[0]->is_present && in[1]->is_present && in[0]->value == 42 && in[1]->value == 42) {
lf_print("SUCCESS");
self->received = true;
}
=}

reaction(shutdown) {=
if (!self->received == true) {
lf_print_error_and_exit("Failed to receive broadcast");
}
=}
}

federated reactor {
s = new[2] SenderAndReceiver()
(s.out)+ -> s.in
}
40 changes: 40 additions & 0 deletions test/RustRti/src/federated/BroadcastFeedbackWithHierarchy.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/** This tests an output that is broadcast back to a multiport input of a bank. */
target C {
timeout: 1 sec
}

reactor SenderAndReceiver {
output out: int
input[2] in: int
state received: bool = false

r = new Receiver()
in -> r.in

reaction(startup) -> out {=
lf_set(out, 42);
=}
}

reactor Receiver {
input[2] in: int
state received: bool = false

reaction(in) {=
if (in[0]->is_present && in[1]->is_present && in[0]->value == 42 && in[1]->value == 42) {
lf_print("SUCCESS");
self->received = true;
}
=}

reaction(shutdown) {=
if (!self->received == true) {
lf_print_error_and_exit("Failed to receive broadcast");
}
=}
}

federated reactor {
s = new[2] SenderAndReceiver()
(s.out)+ -> s.in
}
20 changes: 20 additions & 0 deletions test/RustRti/src/federated/ChainWithDelay.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Demonstration that monotonic NET hypothesis is invalid.
*
* @author Edward A. Lee
*/
target C {
timeout: 3 msec
}

import Count from "../lib/Count.lf"
import InternalDelay from "../lib/InternalDelay.lf"
import TestCount from "../lib/TestCount.lf"

federated reactor {
c = new Count(period = 1 msec)
i = new InternalDelay(delay = 500 usec)
t = new TestCount(num_inputs=3)
c.out -> i.in
i.out -> t.in
}
24 changes: 24 additions & 0 deletions test/RustRti/src/federated/DistributedBank.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Check bank of federates.
target C {
timeout: 1 sec,
coordination: centralized
}

reactor Node(bank_index: int = 0) {
timer t(0, 100 msec)
state count: int = 0

reaction(t) {=
lf_print("Hello world %d.", self->count++);
=}

reaction(shutdown) {=
if (self->count == 0) {
lf_print_error_and_exit("Timer reactions did not execute.");
}
=}
}

federated reactor DistributedBank {
n = new[2] Node()
}
33 changes: 33 additions & 0 deletions test/RustRti/src/federated/DistributedBankToMultiport.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Check multiport to bank connections between federates.
target C {
timeout: 3 sec
}

import Count from "../lib/Count.lf"

reactor Destination {
input[2] in: int
state count: int = 1

reaction(in) {=
for (int i = 0; i < in_width; i++) {
lf_print("Received %d.", in[i]->value);
if (self->count != in[i]->value) {
lf_print_error_and_exit("Expected %d.", self->count);
}
}
self->count++;
=}

reaction(shutdown) {=
if (self->count == 0) {
lf_print_error_and_exit("No data received.");
}
=}
}

federated reactor {
s = new[2] Count()
d = new Destination()
s.out -> d.in
}
41 changes: 41 additions & 0 deletions test/RustRti/src/federated/DistributedCount.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Test a particularly simple form of a distributed deterministic system where a federation that
* receives timestamped messages has only those messages as triggers. Therefore, no additional
* coordination of the advancement of time (HLA or Ptides) is needed.
* @author Edward A. Lee
*/
target C {
timeout: 5 sec,
coordination: centralized
}

import Count from "../lib/Count.lf"

reactor Print {
input in: int
state c: int = 1

reaction(in) {=
interval_t elapsed_time = lf_time_logical_elapsed();
lf_print("At time " PRINTF_TIME ", received %d", elapsed_time, in->value);
if (in->value != self->c) {
lf_print_error_and_exit("Expected to receive %d.", self->c);
}
if (elapsed_time != MSEC(200) + SEC(1) * (self->c - 1) ) {
lf_print_error_and_exit("Expected received time to be " PRINTF_TIME ".", MSEC(200) * self->c);
}
self->c++;
=}

reaction(shutdown) {=
if (self->c != 6) {
lf_print_error_and_exit("Expected to receive 5 items.");
}
=}
}

federated reactor DistributedCount(offset: time = 200 msec) {
c = new Count()
p = new Print()
c.out -> p.in after offset
}
52 changes: 52 additions & 0 deletions test/RustRti/src/federated/DistributedDoublePort.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Test the case for when two upstream federates send messages to a downstream federate on two
* different ports. One message should carry a microstep delay relative to the other message.
*
* @author Soroush Bateni
*/
target C {
timeout: 900 msec,
coordination: centralized
}

import Count from "../lib/Count.lf"

reactor CountMicrostep {
state count: int = 1
output out: int
logical action act: int
timer t(0, 1 sec)

reaction(t) -> act {=
lf_schedule_int(act, 0, self->count++);
=}

reaction(act) -> out {=
lf_set(out, act->value);
=}
}

reactor Print {
input in: int
input in2: int

reaction(in, in2) {=
interval_t elapsed_time = lf_time_logical_elapsed();
lf_print("At tag " PRINTF_TAG ", received in = %d and in2 = %d.", elapsed_time, lf_tag().microstep, in->value, in2->value);
if (in->is_present && in2->is_present) {
lf_print_error_and_exit("ERROR: invalid logical simultaneity.");
}
=}

reaction(shutdown) {=
lf_print("SUCCESS: messages were at least one microstep apart.");
=}
}

federated reactor DistributedDoublePort {
c = new Count()
cm = new CountMicrostep()
p = new Print()
c.out -> p.in // Indicating a 'logical' connection.
cm.out -> p.in2
}
44 changes: 44 additions & 0 deletions test/RustRti/src/federated/DistributedInterleaved.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Check multiport to bank connections between federates.
target C {
timeout: 3 sec
}

reactor Count(offset: time = 0, period: time = 1 sec) {
state count: int = 1
output[4] out: int
timer t(offset, period)

reaction(t) -> out {=
for (int i = 0; i < out_width; i++) {
lf_set(out[i], self->count++);
}
=}
}

reactor Destination {
input[2] in: int
state count: int = 0

reaction(in) {=
lf_print("Received %d.", in[0]->value);
lf_print("Received %d.", in[1]->value);
// Because the connection is interleaved, the difference between the
// two inputs should be 2, not 1.
if (in[1]->value - in[0]->value != 2) {
lf_print_error_and_exit("Expected a difference of two.");
}
self->count++;
=}

reaction(shutdown) {=
if (self->count == 0) {
lf_print_error_and_exit("No data received.");
}
=}
}

federated reactor {
s = new Count()
d = new[2] Destination()
s.out -> interleaved(d.in)
}
Loading

0 comments on commit 6c2bf0f

Please sign in to comment.