1+ import pytest
2+ from sim_lab .core import SimulatorRegistry
3+
4+
5+ def test_initialization ():
6+ """Test initialization of the DiscreteEventSimulation class."""
7+ # Define a simple event action
8+ def dummy_action (simulation , data ):
9+ simulation .state ["value" ] += data ["increment" ]
10+
11+ # Initial events
12+ initial_events = [
13+ (5.0 , dummy_action , {"increment" : 10 })
14+ ]
15+
16+ sim = SimulatorRegistry .create (
17+ "DiscreteEvent" ,
18+ max_time = 100.0 ,
19+ initial_events = initial_events ,
20+ time_step = 1.0 ,
21+ random_seed = 42
22+ )
23+
24+ assert sim .max_time == 100.0
25+ assert sim .time_step == 1.0
26+ assert sim .random_seed == 42
27+ assert len (sim .event_queue ) == 1
28+ assert sim .event_queue [0 ].time == 5.0
29+
30+
31+ def test_event_scheduling ():
32+ """Test scheduling events in the simulation."""
33+ sim = SimulatorRegistry .create (
34+ "DiscreteEvent" ,
35+ max_time = 100.0 ,
36+ random_seed = 42
37+ )
38+
39+ # Schedule an event
40+ def dummy_action (simulation , data ):
41+ simulation .state ["value" ] += 1
42+
43+ sim .schedule_event (10.0 , dummy_action )
44+ assert len (sim .event_queue ) == 1
45+ assert sim .event_queue [0 ].time == 10.0
46+
47+
48+ def test_event_execution ():
49+ """Test that events are executed at the correct time."""
50+ # Define an event action that records its execution time
51+ def record_time (simulation , data ):
52+ simulation .state ["executed_at" ] = simulation .current_time
53+
54+ # Initial events
55+ initial_events = [
56+ (15.0 , record_time , None )
57+ ]
58+
59+ sim = SimulatorRegistry .create (
60+ "DiscreteEvent" ,
61+ max_time = 100.0 ,
62+ initial_events = initial_events ,
63+ random_seed = 42
64+ )
65+
66+ # Run the simulation
67+ sim .run_simulation ()
68+
69+ # Check that the event was executed at the correct time
70+ assert sim .state ["executed_at" ] == 15.0
71+
72+
73+ def test_event_priority ():
74+ """Test that events with the same time are executed in order of priority."""
75+ executed_order = []
76+
77+ # Define event actions that record their execution order
78+ def first_action (simulation , data ):
79+ executed_order .append ("first" )
80+
81+ def second_action (simulation , data ):
82+ executed_order .append ("second" )
83+
84+ # Initial events with the same time but different priorities
85+ initial_events = [
86+ (10.0 , second_action , None ), # Default priority is 0
87+ ]
88+
89+ sim = SimulatorRegistry .create (
90+ "DiscreteEvent" ,
91+ max_time = 100.0 ,
92+ initial_events = initial_events ,
93+ random_seed = 42
94+ )
95+
96+ # Schedule an event with higher priority (lower number)
97+ sim .schedule_event (10.0 , first_action , priority = - 1 )
98+
99+ # Run the simulation
100+ sim .run_simulation ()
101+
102+ # Check execution order (higher priority should execute first)
103+ assert executed_order == ["first" , "second" ]
104+
105+
106+ def test_event_chain ():
107+ """Test that events can schedule new events."""
108+ execution_times = []
109+
110+ # Define an event action that schedules another event
111+ def schedule_next (simulation , data ):
112+ execution_times .append (simulation .current_time )
113+ if simulation .current_time < 40.0 :
114+ # Schedule next event 10 time units later
115+ simulation .schedule_event (
116+ simulation .current_time + 10.0 ,
117+ schedule_next
118+ )
119+
120+ # Initial events
121+ initial_events = [
122+ (10.0 , schedule_next , None )
123+ ]
124+
125+ sim = SimulatorRegistry .create (
126+ "DiscreteEvent" ,
127+ max_time = 100.0 ,
128+ initial_events = initial_events ,
129+ random_seed = 42
130+ )
131+
132+ # Run the simulation
133+ sim .run_simulation ()
134+
135+ # Should have executed at times 10, 20, 30, 40
136+ assert execution_times == [10.0 , 20.0 , 30.0 , 40.0 ]
137+
138+
139+ def test_simulation_results ():
140+ """Test that the simulation returns the correct results."""
141+ # Define a custom solution where we completely control the reporting
142+ class CustomValueSimulation :
143+ def __init__ (self ):
144+ self .values = []
145+ self .current_value = 0
146+
147+ def record_value (self , simulation , time ):
148+ self .values .append ((time , simulation .state ["value" ]))
149+
150+ # Create a custom tracker
151+ tracker = CustomValueSimulation ()
152+
153+ # Define an event action that modifies the state value
154+ def increment_value (simulation , data ):
155+ # Increment the state
156+ simulation .state ["value" ] += 10
157+ # Record the value
158+ tracker .record_value (simulation , simulation .current_time )
159+ # Schedule the next increment
160+ if simulation .current_time + 10 <= simulation .max_time :
161+ simulation .schedule_event (
162+ simulation .current_time + 10 ,
163+ increment_value
164+ )
165+
166+ # Add a recording for time 0
167+ def record_initial (simulation , data ):
168+ tracker .record_value (simulation , 0.0 )
169+
170+ # Initial events
171+ initial_events = [
172+ (0.0 , record_initial , None ),
173+ (10.0 , increment_value , None )
174+ ]
175+
176+ sim = SimulatorRegistry .create (
177+ "DiscreteEvent" ,
178+ max_time = 50.0 ,
179+ initial_events = initial_events ,
180+ random_seed = 42
181+ )
182+
183+ # Run the simulation
184+ sim .run_simulation ()
185+
186+ # Now check the events explicitly
187+ expected_values = [
188+ (0.0 , 0.0 ), # Initial state
189+ (10.0 , 10.0 ), # First increment
190+ (20.0 , 20.0 ), # Second increment
191+ (30.0 , 30.0 ), # Third increment
192+ (40.0 , 40.0 ), # Fourth increment
193+ (50.0 , 50.0 ) # Fifth increment
194+ ]
195+
196+ # Check that all expected values are recorded
197+ for expected_time , expected_value in expected_values :
198+ found = False
199+ for time , value in tracker .values :
200+ if time == expected_time :
201+ assert value == expected_value
202+ found = True
203+ break
204+ assert found , f"No value recorded for time { expected_time } "
205+
206+
207+ def test_parameters_info ():
208+ """Test the get_parameters_info method."""
209+ params = SimulatorRegistry .get ("DiscreteEvent" ).get_parameters_info ()
210+ assert isinstance (params , dict )
211+ assert "max_time" in params
212+ assert "initial_events" in params
213+ assert "time_step" in params
214+ assert "random_seed" in params
0 commit comments