Skip to content

JUnit

If you want to write tests with the simulator in Java directly, you can use JUnit and the extensions we provide.

  • montiarc.rte.tests.JSimTest: This class annotation can be used to hook the tests into the simulation log output.
  • montiarc.rte.msg.MessageFactory: The message factory allows you to quickly create messages that can be sent and received by ports.
  • montiarc.rte.port.PortObserver: A special port that stores all messages it receives. It can be hooked up to existing ports to collect their output streams.

Info

Be aware that for the simulation to progress over a time interval, all incoming ports must have received a tick.

Messages supplied to ports are only processed once the simulation has been started. The simulation runs until no component can process any more messages. This is indefinitely for closed-loop systems.

Example Test

Given the following MontiArc model, which acts as a medium and forwards all messages:

Medium.arc
component Medium {

  port sync in boolean i;
  port sync out boolean o;

  automaton {
    initial state S;

    S -> S / {
      o = i;
    };
  }
}

An input-output test for it looks like this:

MediumTest.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import com.google.common.base.Preconditions;
import montiarc.rte.msg.Message;
import montiarc.rte.port.PortObserver;
import montiarc.rte.tests.JSimTest;
import montiarc.types.OnOff;
import org.assertj.core.api.Assertions;
import org.codehaus.commons.nullanalysis.NotNull;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.List;
import java.util.stream.Stream;

import static montiarc.rte.msg.MessageFactory.msg;
import static montiarc.rte.msg.MessageFactory.tk;

@JSimTest
class MediumTest {

  /**
   * @param input    the input stream on port i
   * @param expected the expected output stream on port o
   */
  @ParameterizedTest
  @MethodSource("io")
  void testIO(@NotNull List<Message<Boolean>> input,
              @NotNull List<Message<Boolean>> expected) {
    Preconditions.checkNotNull(input);
    Preconditions.checkNotNull(expected);

    // Given (set up component and listen to outgoing port) 
    MediumComp sut = new MediumCompBuilder().setName("sut").build();
    PortObserver<Boolean> port_o = new PortObserver<>();

    sut.port_o().connect(port_o);

    // When (inject provided messages and run simulation)
    for (Message<Boolean> msg : input) {
      sut.port_i().receive(msg);
    }

    sut.runToCompletion();

    // Then
    Assertions
      .assertThat(port_o.getObservedMessages())
      .containsExactlyElementsOf(expected);
  }

  static Stream<Arguments> io() {
    return Stream.of(
      Arguments.of(
        List.of(tk()),
        List.of(tk())
      ),
      Arguments.of(
        List.of(msg(true), tk()),
        List.of(msg(true), tk())
      ),
      Arguments.of(
        List.of(msg(false), tk()),
        List.of(msg(false), tk())
      ),
      Arguments.of(
        List.of(tk(), msg(true), tk()),
        List.of(tk(), msg(true), tk())
      ),
      Arguments.of(
        List.of(tk(), msg(false), tk()),
        List.of(tk(), msg(false), tk())
      ),
      Arguments.of(
        List.of(msg(true), tk(), msg(true), tk()),
        List.of(msg(true), tk(), msg(true), tk())
      ),
      Arguments.of(
        List.of(msg(true), tk(), msg(false), tk()),
        List.of(msg(true), tk(), msg(false), tk())
      ),
      Arguments.of(
        List.of(msg(false), tk(), msg(true), tk()),
        List.of(msg(false), tk(), msg(true), tk())
      ),
      Arguments.of(
        List.of(msg(false), tk(), msg(false), tk()),
        List.of(msg(false), tk(), msg(false), tk())
      ),
      Arguments.of(
        List.of(msg(false), tk(), msg(true), tk(), msg(true), tk()),
        List.of(msg(false), tk(), msg(true), tk(), msg(true), tk())
      ),
      Arguments.of(
        List.of(tk(), tk()),
        List.of(tk(), tk())
      ));
  }
}