-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #727 from lf-lang/cpp-tests-missing
Port more C tests to Cpp
- Loading branch information
Showing
18 changed files
with
745 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Tests the is_present variable for actions in cpp | ||
target Cpp; | ||
|
||
main reactor ActionIsPresent(offset:time(1 nsec), period:time(500 msec)) { | ||
logical action a; | ||
state success:bool(false); | ||
state zero:time(0 nsec); | ||
reaction(startup, a) -> a {= | ||
if (!a.is_present()) { | ||
if (offset == zero) { | ||
std::cout << "Hello World!" << '\n'; | ||
success = true; | ||
} else { | ||
a.schedule(offset); | ||
} | ||
} else { | ||
std::cout << "Hello World 2!" << '\n'; | ||
success = true; | ||
} | ||
=} | ||
reaction(shutdown) {= | ||
if (!success) { | ||
std::cerr << "Failed to print 'Hello World!'" << '\n'; | ||
exit(1); | ||
} | ||
=} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// This test checks that the downstream reaction is not invoked more | ||
// than once at a logical time. | ||
target Cpp { | ||
logging: LOG, | ||
timeout: 1 sec, | ||
build-type: Debug | ||
} | ||
|
||
reactor Source { | ||
output out:int; | ||
state count:int(1); | ||
timer t(0, 100 msec); | ||
reaction(t) -> out {= | ||
count++; | ||
out.set(count); | ||
=} | ||
} | ||
|
||
reactor Sieve { | ||
private preamble {= | ||
#include "reactor-cpp/logging.hh" | ||
=} | ||
input in:int; | ||
output out:bool; | ||
state primes:std::vector<int>; | ||
reaction(startup) {= | ||
// There are 1229 primes between 1 and 10,000. | ||
// Primes 1 and 2 are not on the list. | ||
primes.push_back(3); | ||
=} | ||
reaction(in) -> out {= | ||
// Reject out of bounds inputs | ||
if(*in.get() <= 0 || *in.get() > 10000) { | ||
reactor::log::Warn() << "Sieve: Input value out of range: " << *in.get(); | ||
} | ||
// Primes 1 and 2 are not on the list. | ||
if (*in.get() == 1 || *in.get() == 2) { | ||
out.set(true); | ||
return; | ||
} | ||
// If the input is greater than the last found prime, then | ||
// we have to expand the list of primes before checking to | ||
// see whether this is prime. | ||
int candidate = primes.back(); | ||
reactor::log::Info() << "Sieve: Checking prime: " << candidate; | ||
while (*in.get() > primes.back()) { | ||
candidate += 2; | ||
bool prime = true; | ||
for (auto i : primes) { | ||
if(candidate % i == 0) { | ||
// Candidate is not prime. Break and add 2 by starting the loop again | ||
prime = false; | ||
break; | ||
} | ||
} | ||
// If the candidate is not divisible by any prime in the list, it is prime | ||
if (prime) { | ||
primes.push_back(candidate); | ||
reactor::log::Info() << "Sieve: Found prime: " << candidate; | ||
} | ||
} | ||
|
||
// We are now assured that the input is less than or | ||
// equal to the last prime on the list. | ||
// See whether the input is an already found prime. | ||
// Search the primes from the end, where they are sparser. | ||
for (auto i = primes.rbegin(); i != primes.rend(); ++i) { | ||
if(*i == *in.get()) { | ||
out.set(true); | ||
return; | ||
} | ||
} | ||
=} | ||
} | ||
|
||
reactor Destination { | ||
input ok:bool; | ||
input in:int; | ||
state last_invoked:{=reactor::TimePoint=}; | ||
reaction(ok, in) {= | ||
if (ok.is_present() && in.is_present()) { | ||
reactor::log::Info() << "Destination: Input " << *in.get() << " is a prime at logical time ( " | ||
<< get_elapsed_logical_time() << " )"; | ||
} | ||
if( get_logical_time() <= last_invoked) { | ||
reactor::log::Error() << "Invoked at logical time (" << get_logical_time() << ") " | ||
<< "but previously invoked at logical time (" << get_elapsed_logical_time() << ")"; | ||
} | ||
|
||
last_invoked = get_logical_time(); | ||
=} | ||
} | ||
main reactor { | ||
source = new Source(); | ||
sieve = new Sieve(); | ||
destination = new Destination(); | ||
source.out -> sieve.in; | ||
sieve.out -> destination.ok; | ||
source.out -> destination.in; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// This tests send data through a contained reactor | ||
target Cpp; | ||
reactor Gain { | ||
input gainin:int; | ||
output y:int; | ||
reaction(gainin) -> y {= | ||
reactor::log::Info() << "Gain received " << *gainin.get(); | ||
y.set(*gainin.get()*2); | ||
=} | ||
} | ||
reactor Wrapper { | ||
input x:int; | ||
output y:int; | ||
gain = new Gain(); | ||
x -> gain.gainin; | ||
gain.y -> y; | ||
} | ||
main reactor CompositionGain { | ||
wrapper = new Wrapper(); | ||
reaction(startup) -> wrapper.x {= | ||
wrapper.x.set(42); | ||
=} | ||
reaction(wrapper.y) {= | ||
reactor::log::Info() << "Received " << *wrapper.y.get(); | ||
if (*wrapper.y.get() != 42*2) { | ||
reactor::log::Error() << "Received value should have been " << 42 * 2; | ||
exit(2); | ||
} | ||
=} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// This illustrates a very strange bug that showed up | ||
// and has now been fixed. This test ensures it does | ||
// not reappear. | ||
// At logical time zero, the two Print reactors used to be | ||
// fired twice each at the same logical time. | ||
// They should only be fired once. | ||
// This behavior was oddly eliminated by either of the following | ||
// actions, neither of which should affect this behavior: | ||
// * Removing the startup reaction in Print. | ||
// * Sending only position, not velocity from Ball. | ||
// (copied from the c version of the test) | ||
|
||
target Cpp{ | ||
timeout: 5 sec, | ||
fast: true | ||
} | ||
reactor Ball { | ||
output position:int; | ||
output velocity:int; | ||
state p:int(200); | ||
timer trigger(0, 1 sec); | ||
reaction(trigger) -> position, velocity {= | ||
position.set(p); | ||
velocity.set(-1); | ||
p -= 1; | ||
=} | ||
} | ||
reactor Print { | ||
input velocity:int; | ||
input position:int; | ||
state previous:int(-1); | ||
reaction (startup) {= | ||
reactor::log::Info() << "####### Print startup"; | ||
=} | ||
reaction (position, velocity) {= | ||
if (position.is_present()) { | ||
reactor::log::Info() << "Position: " << *position.get(); | ||
} | ||
if (*position.get() == previous) { | ||
reactor::log::Error() << "Multiple firings at the same logical time!"; | ||
exit(1); | ||
} | ||
=} | ||
|
||
} | ||
main reactor DoubleInvocation { | ||
b1 = new Ball(); | ||
p = new Print(); | ||
plot = new Print(); | ||
b1.position -> p.position; | ||
b1.velocity -> p.velocity; | ||
b1.position -> plot.position; | ||
b1.velocity -> plot.velocity; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Test the case where two upstream reactors | ||
* pass messages to a downstream reactor on two | ||
* different ports. One message carries | ||
* a microstep delay relative to the other. | ||
* | ||
* @author Maiko Brants | ||
*/ | ||
target Cpp { | ||
timeout: 900 msec, | ||
fast: true | ||
}; | ||
|
||
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 {= | ||
act.schedule( count); | ||
count++; | ||
=} | ||
|
||
reaction(act) -> out {= | ||
out.set(act.get()); | ||
=} | ||
} | ||
|
||
reactor Print { | ||
input in:int; | ||
input in2:int; | ||
reaction(in, in2) {= | ||
if(in.is_present()){ | ||
reactor::log::Info() << "At tag (" << get_elapsed_logical_time() << ", " << environment()->logical_time().micro_step() | ||
<< "), received in = " << *in.get(); | ||
} else if (in2.is_present()){ | ||
reactor::log::Info() << "At tag (" << get_elapsed_logical_time() << ", " << environment()->logical_time().micro_step() | ||
<< "), received in2 = " << *in2.get(); | ||
} | ||
|
||
|
||
if ( in.is_present() && in2.is_present()) { | ||
reactor::log::Error() << "ERROR: invalid logical simultaneity."; | ||
exit(1); | ||
} | ||
=} | ||
|
||
reaction(shutdown) {= | ||
reactor::log::Info() << "SUCCESS: messages were at least one microstep apart."; | ||
=} | ||
} | ||
|
||
main reactor DoublePort { | ||
c = new Count(); | ||
cm = new CountMicrostep(); | ||
p = new Print(); | ||
c.c -> p.in; | ||
cm.out -> p.in2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* | ||
* @author Maiko Brants TU Dresden | ||
* | ||
* This tests the ability to import a reactor definition | ||
* that itself imports a reactor definition. | ||
* | ||
* modeled after the C version of this test | ||
**/ | ||
target Cpp; | ||
import ImportedComposition from "lib/ImportedComposition.lf"; | ||
|
||
main reactor ImportComposition { | ||
public preamble {= | ||
#include "reactor-cpp/logging.hh" | ||
=} | ||
|
||
imp_comp = new ImportedComposition(); | ||
state received:bool(false); | ||
reaction(startup) -> imp_comp.x {= | ||
imp_comp.x.set(42); | ||
=} | ||
reaction(imp_comp.y) {= | ||
auto receive_time = get_elapsed_logical_time(); | ||
reactor::log::Info() << "Received " << *imp_comp.y.get() << " at time " << receive_time; | ||
received = true; | ||
if(receive_time != 55ms) { | ||
reactor::log::Error() << "ERROR: Received time should have been: 55,000,000."; | ||
exit(1); | ||
} | ||
if(*imp_comp.y.get() != 42*2*2) { | ||
reactor::log::Error() << "ERROR: Received value should have been: " << 42*2*2 << "."; | ||
exit(2); | ||
} | ||
=} | ||
reaction(shutdown) {= | ||
if(!received){ | ||
reactor::log::Error() << "ERROR: Nothing received."; | ||
exit(3); | ||
} | ||
=} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* | ||
* @author Maiko Brants TU Dresden | ||
* | ||
* This tests the ability to import a reactor definition | ||
* that itself imports a reactor definition. | ||
* | ||
* modeled after the C version of this test | ||
**/ | ||
target Cpp; | ||
import Imported as X from "lib/Imported.lf" | ||
import Imported as Y from "lib/Imported.lf" | ||
import ImportedAgain as Z from "lib/ImportedAgain.lf" | ||
main reactor { | ||
timer t; | ||
a = new X(); | ||
b = new Y(); | ||
c = new Z(); | ||
|
||
reaction(t) -> a.x {= | ||
a.x.set(42); | ||
=} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* | ||
* @author Maiko Brants TU Dresden | ||
* | ||
* Test that parameter values pass down a deep hierarchy. | ||
* | ||
* modeled after the C version of this test | ||
**/ | ||
target Cpp; | ||
reactor Deep(p:int(0)) { | ||
reaction(startup) {= | ||
if(p != 42) { | ||
reactor::log::Error() << "Parameter value is: " << p << ". Should have been 42."; | ||
exit(1); | ||
} else { | ||
reactor::log::Info() << "Success."; | ||
} | ||
=} | ||
} | ||
reactor Intermediate(p:int(10)) { | ||
a = new Deep(p = p); | ||
} | ||
reactor Another(p:int(20)) { | ||
a = new Intermediate(p = p); | ||
} | ||
main reactor ParameterHierarchy { | ||
a = new Intermediate(p = 42); | ||
} |
Oops, something went wrong.