Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for federated tests #1794

Merged
merged 7 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion org.lflang.tests/src/org/lflang/tests/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ private void execute(LFTest test) throws TestError {
if (!p.waitFor(MAX_EXECUTION_TIME_SECONDS, TimeUnit.SECONDS)) {
stdout.interrupt();
stderr.interrupt();
p.destroyForcibly();
p.destroy();
throw new TestError(Result.TEST_TIMEOUT);
} else {
if (stdoutException.get() != null || stderrException.get() != null) {
Expand Down
28 changes: 22 additions & 6 deletions org.lflang/src/org/lflang/TargetProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -283,10 +284,6 @@ public enum TargetProperty {
(config, value, err) -> {
config.files = ASTUtils.elementToListOfStrings(value);
},
// FIXME: This merging of lists is potentially dangerous since
// the incoming list of files can belong to a .lf file that is
// located in a different location, and keeping just filename
// strings like this without absolute paths is incorrect.
(config, value, err) -> {
config.files.addAll(ASTUtils.elementToListOfStrings(value));
}),
Expand Down Expand Up @@ -995,15 +992,34 @@ public static TargetDecl extractTargetDecl(Target target, TargetConfig config) {
*
* @param config The configuration object to update.
* @param properties AST node that holds all the target properties.
* @param relativePath The path from the main resource to the resource from which the new
* properties originate.
*/
public static void update(TargetConfig config, List<KeyValuePair> properties, ErrorReporter err) {
public static void update(
TargetConfig config, List<KeyValuePair> properties, Path relativePath, ErrorReporter err) {
properties.forEach(
property -> {
TargetProperty p = forName(property.getName());
if (p != null) {
// Mark the specified target property as set by the user
config.setByUser.add(p);
p.updater.parseIntoTargetConfig(config, property.getValue(), err);
var value = property.getValue();
if (property.getName().equals("files")) {
var array = LfFactory.eINSTANCE.createArray();
ASTUtils.elementToListOfStrings(property.getValue()).stream()
.map(relativePath::resolve) // assume all paths are relative
.map(Objects::toString)
.map(
s -> {
var element = LfFactory.eINSTANCE.createElement();
element.setLiteral(s);
return element;
})
.forEach(array.getElements()::add);
value = LfFactory.eINSTANCE.createElement();
value.setArray(array);
}
p.updater.parseIntoTargetConfig(config, value, err);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.lflang.ast.ASTUtils.convertToEmptyListIfNull;

import java.nio.file.Path;
import org.eclipse.emf.ecore.resource.Resource;
import org.lflang.ErrorReporter;
import org.lflang.TargetConfig;
Expand Down Expand Up @@ -57,11 +58,20 @@ private void mergeImportedConfig(
if (targetProperties != null) {
// Merge properties
TargetProperty.update(
this, convertToEmptyListIfNull(targetProperties.getPairs()), errorReporter);
this,
convertToEmptyListIfNull(targetProperties.getPairs()),
getRelativePath(mainResource, federateResource),
errorReporter);
}
}
}

private Path getRelativePath(Resource source, Resource target) {
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
return Path.of(source.getURI().toFileString())
.getParent()
.relativize(Path.of(target.getURI().toFileString()).getParent());
}

/** Method for the removal of things that should not appear in the target config of a federate. */
private void clearPropertiesToIgnore() {
this.setByUser.remove(TargetProperty.CLOCK_SYNC);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ public void doGenerate(List<FederateInstance> federates, RtiConfig rtiConfig) {
"do",
" wait $pid",
"done",
"echo \"All done.\"")
"echo \"All done.\"",
"EXITED_SUCCESSFULLY=true")
+ "\n");

// Create bin directory for the script.
Expand Down Expand Up @@ -281,24 +282,19 @@ private String getSetupCode() {
"# Set a trap to kill all background jobs on error or control-C",
"# Use two distinct traps so we can see which signal causes this.",
"cleanup() {",
" printf \"Killing federate %s.\\n\" ${pids[*]}",
" # The || true clause means this is not an error if kill fails.",
" kill ${pids[@]} || true",
" printf \"#### Killing RTI %s.\\n\" ${RTI}",
" kill ${RTI} || true",
" exit 1",
"}",
"cleanup_err() {",
" echo \"#### Received ERR signal on line $1. Invoking cleanup().\"",
" cleanup",
"}",
"cleanup_sigint() {",
" echo \"#### Received SIGINT signal on line $1. Invoking cleanup().\"",
" cleanup",
" if [ \"$EXITED_SUCCESSFULLY\" = true ] ; then",
" exit 0",
" else",
" printf \"Killing federate %s.\\n\" ${pids[*]}",
" # The || true clause means this is not an error if kill fails.",
" kill ${pids[@]} || true",
" printf \"#### Killing RTI %s.\\n\" ${RTI}",
" kill ${RTI} || true",
" exit 1",
" fi",
"}",
"",
"trap 'cleanup_err $LINENO' ERR",
"trap 'cleanup_sigint $LINENO' SIGINT",
"trap 'cleanup; exit' EXIT",
"",
"# Create a random 48-byte text ID for this federation.",
"# The likelihood of two federations having the same ID is 1/16,777,216 (1/2^24).",
Expand Down
4 changes: 2 additions & 2 deletions test/Python/src/docker/FilesPropertyContainerized.lf
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ preamble {=
try:
import hello
except:
lf_request_stop()
request_stop()
=}

main reactor {
preamble {=
try:
import hello
except:
lf_request_stop()
request_stop()
=}
state passed = False
timer t(1 msec)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Test for lf_request_stop() in federated execution with decentralized
* Test for request_stop() in federated execution with decentralized
* coordination.
*
* @author Soroush Bateni
Expand Down
2 changes: 1 addition & 1 deletion test/Python/src/federated/CycleDetection.lf
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ reactor UserInput {
self.sys.stderr.write("Did not receive the expected balance. Expected: 200. Got: {}.\n".format(balance.value))
self.sys.exit(1)
print("Balance: {}".format(balance.value))
lf_request_stop()
request_stop()
=}

reaction(shutdown) {= print("Test passed!") =}
Expand Down
2 changes: 1 addition & 1 deletion test/Python/src/federated/DistributedSendClass.lf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ preamble {=
reactor A {
input o

reaction(o) {= lf_request_stop() =}
reaction(o) {= request_stop() =}
}

reactor B {
Expand Down
14 changes: 7 additions & 7 deletions test/Python/src/federated/DistributedStop.lf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Test for lf_request_stop() in federated execution with centralized
* Test for request_stop() in federated execution with centralized
* coordination.
*
* @author Soroush Bateni
Expand All @@ -23,18 +23,18 @@ reactor Sender {
if lf.tag().microstep == 0:
# Instead of having a separate reaction
# for 'act' like Stop.lf, we trigger the
# same reaction to test lf_request_stop() being
# same reaction to test request_stop() being
# called multiple times
act.schedule(0)
if tag.time == USEC(1):
# Call lf_request_stop() both at (1 usec, 0) and
# Call request_stop() both at (1 usec, 0) and
# (1 usec, 1)
print("Requesting stop at ({}, {}).".format(
lf.time.logical_elapsed(),
lf.tag().microstep))
lf_request_stop()
request_stop()

_1usec1 = Tag(time=USEC(1) + get_start_time(), microstep=1)
_1usec1 = Tag(time=USEC(1) + lf.time.start(), microstep=1)
if lf.tag_compare(lf.tag(), _1usec1) == 0:
# The reaction was invoked at (1 usec, 1) as expected
self.reaction_invoked_correctly = True
Expand Down Expand Up @@ -77,12 +77,12 @@ reactor Receiver(
print("Requesting stop at ({}, {}).".format(
lf.time.logical_elapsed(),
lf.tag().microstep))
lf_request_stop()
request_stop()
# The receiver should receive a message at tag
# (1 usec, 1) and trigger this reaction
self.reaction_invoked_correctly = True

_1usec1 = Tag(time=USEC(1) + get_start_time(), microstep=1)
_1usec1 = Tag(time=USEC(1) + lf.time.start(), microstep=1)
if lf.tag_compare(lf.tag(), _1usec1) > 0:
self.reaction_invoked_correctly = False
=}
Expand Down
2 changes: 1 addition & 1 deletion test/Python/src/federated/DistributedStopDecentralized.lf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Test for lf_request_stop() in federated execution with decentralized
* Test for request_stop() in federated execution with decentralized
* coordination.
*
* @author Soroush Bateni
Expand Down
6 changes: 3 additions & 3 deletions test/Python/src/federated/DistributedStopZero.lf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Test for lf_request_stop() in federated execution with centralized
* Test for request_stop() in federated execution with centralized
* coordination at tag (0,0).
*
* @author Soroush Bateni
Expand Down Expand Up @@ -29,7 +29,7 @@ reactor Sender {
print("Requesting stop at ({}, {}).".format(
lf.time.logical_elapsed(),
lf.tag().microstep))
lf_request_stop()
request_stop()
=}

reaction(shutdown) {=
Expand Down Expand Up @@ -63,7 +63,7 @@ reactor Receiver {
print("Requesting stop at ({}, {}).".format(
tag.time,
tag.microstep))
lf_request_stop()
request_stop()
=}

reaction(shutdown) {=
Expand Down
2 changes: 1 addition & 1 deletion test/Python/src/federated/HelloDistributed.lf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ reactor Source {
reaction(startup) -> out {=
print("Sending 'Hello World!' message from source federate.");
out.set("Hello World!")
lf_request_stop()
request_stop()
=}
}

Expand Down
4 changes: 2 additions & 2 deletions test/Python/src/federated/PingPongDistributed.lf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ reactor Ping(count = 10) {
if self.pingsLeft > 0:
serve.schedule(0)
else:
lf_request_stop()
request_stop()
=}
}

Expand All @@ -53,7 +53,7 @@ reactor Pong(expected = 10) {
print("At logical time {}, Pong received {}.\n".format(lf.time.logical_elapsed(), receive.value))
send.set(receive.value)
if self.count == self.expected:
lf_request_stop()
request_stop()
=}

reaction(shutdown) {=
Expand Down
6 changes: 3 additions & 3 deletions test/Python/src/federated/StopAtShutdown.lf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Check that lf_request_stop() doesn't cause any issues at the shutdown tag.
* Check that request_stop() doesn't cause any issues at the shutdown tag.
*
* Original bug discovered by Steven Wong <[email protected]>
*
Expand All @@ -16,7 +16,7 @@ reactor A {

reaction(in_) {= print("Got it") =}

reaction(shutdown) {= lf_request_stop() =}
reaction(shutdown) {= request_stop() =}
}

reactor B {
Expand All @@ -25,7 +25,7 @@ reactor B {

reaction(t) -> out {= out.set(1) =}

reaction(shutdown) {= lf_request_stop() =}
reaction(shutdown) {= request_stop() =}
}

federated reactor {
Expand Down
2 changes: 1 addition & 1 deletion test/Python/src/include/hello.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class hello:
def __init__(self, name = "", value = 0):
self.name = name
self.value = value
self.value = value