Snej69420 5 mesi fa
parent
commit
951e252ae2

+ 59 - 0
test/DEVS/runtests.py

@@ -0,0 +1,59 @@
+from pypdevs.simulator import Simulator
+from pypdevs.DEVS import CoupledDEVS
+from CSVTracer import CSVTracer
+from MockNode import MockNode
+
+
+def run_test(test_name, duration, setup_func):
+    top = CoupledDEVS("top")
+    setup_func(top)
+
+    sim = Simulator(top)
+    sim.setRealTime(False)
+    sim.setTerminationTime(duration)
+
+    csv_filename = f"../traces/expected_{test_name}.csv"
+    sim.setCustomTracer("CSVTracer", "CSVTracer", [csv_filename])
+
+    sim.simulate()
+    print(f"✅ Generated trace for: {test_name}")
+
+
+# ==========================================
+# 1. Phantom Event Purging
+# ==========================================
+def setup_phantom(top):
+    sender = top.addSubModel(MockNode("sender", out_ports=["out"], ta=1.0, cycles=5, make_out=True))
+    rec = top.addSubModel(MockNode("rec", in_ports=["in"], ta=4.0))
+    top.connectPorts(sender.p_out["out"], rec.p_in["in"])
+
+
+# ==========================================
+# 2. Immediate Transition Output Forwarding
+# ==========================================
+def setup_forwarding(top):
+    sender = top.addSubModel(MockNode("sender", out_ports=["out"], ta=1.0, make_out=True))
+    fwd = top.addSubModel(MockNode("fwd", in_ports=["in"], out_ports=["out"], forward=True))
+    rec = top.addSubModel(MockNode("rec", in_ports=["in"]))
+
+    top.connectPorts(sender.p_out["out"], fwd.p_in["in"])
+    top.connectPorts(fwd.p_out["out"], rec.p_in["in"])
+
+
+# ==========================================
+# 3. Confluent Transition Execution
+# ==========================================
+def setup_confluent(top):
+    sender = top.addSubModel(MockNode("sender", out_ports=["out"], ta=2.0, cycles=3, make_out=True))
+    rec = top.addSubModel(MockNode("rec", in_ports=["in"], ta=2.0, cycles=3))
+
+    top.connectPorts(sender.p_out["out"], rec.p_in["in"])
+
+
+# ==========================================
+# EXECUTION
+# ==========================================
+if __name__ == '__main__':
+    run_test("phantom_event", 11.0, setup_phantom)
+    run_test("forwarding", 5.0, setup_forwarding)
+    run_test("confluent", 5.0, setup_confluent)

+ 7 - 0
test/traces/ComplexBag.csv

@@ -0,0 +1,7 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sA,INIT,2.000000,none,none,Cycles: 1
+0.000000,top.sB,INIT,2.000000,none,none,Cycles: 1
+0.000000,top.rec,INIT,inf,none,none,Cycles: 1
+2.000000,top.sA,INTERNAL,inf,none,out:[42],Cycles: 0
+2.000000,top.rec,EXTERNAL,inf,in_A:[42] | in_B:[42],none,Cycles: 1
+2.000000,top.sB,INTERNAL,inf,none,out:[42],Cycles: 0

+ 5 - 0
test/traces/Confluent.csv

@@ -0,0 +1,5 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sender,INIT,2.000000,none,none,Cycles: 1
+0.000000,top.receiver,INIT,2.000000,none,none,Cycles: 1
+2.000000,top.sender,INTERNAL,inf,none,out:[42],Cycles: 0
+2.000000,top.receiver,CONFLUENT,inf,in:[42],none,Cycles: 0

+ 27 - 0
test/traces/CyclicCoupling.csv

@@ -0,0 +1,27 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.NodeA,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.NodeB,INIT,inf,none,none,Cycles: 1
+1.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+1.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+2.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+2.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+3.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+3.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+4.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+4.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+5.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+5.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+6.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+6.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+7.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+7.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+8.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+8.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+9.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+9.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+10.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+10.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+11.000000,top.NodeA,INTERNAL,inf,none,out:[1],Cycles: 1
+11.000000,top.NodeB,EXTERNAL,1.000000,in:[1],none,Cycles: 1
+12.000000,top.NodeB,INTERNAL,inf,none,out:[1],Cycles: 1
+12.000000,top.NodeA,EXTERNAL,1.000000,in:[1],none,Cycles: 1

+ 5 - 0
test/traces/ElapsedTimeInterruption.csv

@@ -0,0 +1,5 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sender,INIT,1.500000,none,none,Cycles: 1
+0.000000,top.receiver,INIT,5.000000,none,none,Cycles: 1
+1.500000,top.sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.500000,top.receiver,EXTERNAL,5.000000,in:[42],none,Cycles: 1

+ 6 - 0
test/traces/ElapsedTimeReset1.csv

@@ -0,0 +1,6 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.s1,INIT,3.000000,none,none,Cycles: 1
+0.000000,top.s2,INIT,5.000000,none,none,Cycles: 1
+0.000000,top.rec,INIT,10.000000,none,none,Cycles: 1
+3.000000,top.s1,INTERNAL,inf,none,out:[42],Cycles: 0
+3.000000,top.rec,EXTERNAL,10.000000,in:[42],none,Cycles: 1

+ 8 - 0
test/traces/ElapsedTimeReset2.csv

@@ -0,0 +1,8 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.s1,INIT,3.000000,none,none,Cycles: 1
+0.000000,top.s2,INIT,5.000000,none,none,Cycles: 1
+0.000000,top.rec,INIT,10.000000,none,none,Cycles: 1
+3.000000,top.s1,INTERNAL,inf,none,out:[42],Cycles: 0
+3.000000,top.rec,EXTERNAL,10.000000,in:[42],none,Cycles: 1
+5.000000,top.s2,INTERNAL,inf,none,out:[42],Cycles: 0
+5.000000,top.rec,EXTERNAL,10.000000,in:[42],none,Cycles: 1

+ 5 - 0
test/traces/External.csv

@@ -0,0 +1,5 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sender,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.receiver,INIT,inf,none,none,Cycles: 1
+1.000000,top.sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.000000,top.receiver,EXTERNAL,inf,in:[42],none,Cycles: 1

+ 7 - 0
test/traces/FanIn.csv

@@ -0,0 +1,7 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.Sender1,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.Sender2,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.Receiver,INIT,inf,none,none,Cycles: 1
+1.000000,top.Sender1,INTERNAL,inf,none,out:[42],Cycles: 0
+1.000000,top.Receiver,EXTERNAL,inf,"in:[42, 42]",none,Cycles: 1
+1.000000,top.Sender2,INTERNAL,inf,none,out:[42],Cycles: 0

+ 7 - 0
test/traces/FanOut.csv

@@ -0,0 +1,7 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.Sender,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.Receiver1,INIT,inf,none,none,Cycles: 1
+0.000000,top.Receiver2,INIT,inf,none,none,Cycles: 1
+1.000000,top.Sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.000000,top.Receiver1,EXTERNAL,inf,in:[42],none,Cycles: 1
+1.000000,top.Receiver2,EXTERNAL,inf,in:[42],none,Cycles: 1

+ 5 - 0
test/traces/FlattenedConnection.csv

@@ -0,0 +1,5 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.child1.sender,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.child2.receiver,INIT,inf,none,none,Cycles: 1
+1.000000,top.child1.sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.000000,top.child2.receiver,EXTERNAL,inf,in:[42],none,Cycles: 1

+ 3 - 0
test/traces/Internal.csv

@@ -0,0 +1,3 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.receiver,INIT,2.000000,none,none,Cycles: 1
+2.000000,top.receiver,INTERNAL,inf,none,none,Cycles: 0

+ 6 - 0
test/traces/NearlyConfluent.csv

@@ -0,0 +1,6 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sender,INIT,1.999000,none,none,Cycles: 1
+0.000000,top.receiver,INIT,2.000000,none,none,Cycles: 1
+1.999000,top.sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.999000,top.receiver,EXTERNAL,2.000000,in:[42],none,Cycles: 1
+3.999000,top.receiver,INTERNAL,inf,none,none,Cycles: 0

+ 8 - 0
test/traces/PassThrough.csv

@@ -0,0 +1,8 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.Sender,INIT,1.000000,none,none,Cycles: 1
+0.000000,top.Forwarder,INIT,inf,none,none,Cycles: 1
+0.000000,top.Receiver,INIT,inf,none,none,Cycles: 1
+1.000000,top.Sender,INTERNAL,inf,none,out:[42],Cycles: 0
+1.000000,top.Forwarder,EXTERNAL,1.000000,in:[42],none,Cycles: 1
+2.000000,top.Forwarder,INTERNAL,inf,none,out:[42],Cycles: 1
+2.000000,top.Receiver,EXTERNAL,inf,in:[42],none,Cycles: 1

+ 5 - 0
test/traces/SimDurationBoundary.csv

@@ -0,0 +1,5 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.Ticker,INIT,1.000000,none,none,Cycles: -1
+1.000000,top.Ticker,INTERNAL,1.000000,none,none,Cycles: -1
+2.000000,top.Ticker,INTERNAL,1.000000,none,none,Cycles: -1
+3.000000,top.Ticker,INTERNAL,1.000000,none,none,Cycles: -1

+ 3 - 0
test/traces/UnconnectedPort.csv

@@ -0,0 +1,3 @@
+time,model_path,transition_type,next_ta,inputs,outputs,state
+0.000000,top.sender,INIT,1.000000,none,none,Cycles: 1
+1.000000,top.sender,INTERNAL,inf,none,out:[42],Cycles: 0