Browse Source

add some tests

Bastien Sevajol 6 years ago
parent
commit
a40912f7ba
3 changed files with 120 additions and 31 deletions
  1. 35 6
      synergine2/cycle.py
  2. 3 3
      synergine2/simulation.py
  3. 82 22
      tests/test_simulation.py

+ 35 - 6
synergine2/cycle.py View File

254
         self.logger.info('Subjects computing: {} subjects to compute'.format(str(len(subjects))))
254
         self.logger.info('Subjects computing: {} subjects to compute'.format(str(len(subjects))))
255
 
255
 
256
         for subject in subjects:
256
         for subject in subjects:
257
-            mechanisms = subject.mechanisms.values()
257
+            subject_behaviours = self.get_active_subject_behaviors(subject)
258
+            if not subject_behaviours:
259
+                break
258
 
260
 
261
+            mechanisms = self.get_mechanisms_from_behaviors(subject_behaviours, subject)
259
             if mechanisms:
262
             if mechanisms:
260
                 self.logger.info('Subject {}: {} mechanisms'.format(
263
                 self.logger.info('Subject {}: {} mechanisms'.format(
261
                     str(subject.id),
264
                     str(subject.id),
291
                         str(mechanisms_data),
294
                         str(mechanisms_data),
292
                     ))
295
                     ))
293
 
296
 
294
-            subject_behaviours = subject.behaviours
295
-            if not subject_behaviours:
296
-                break
297
-
298
             self.logger.info('Subject {}: have {} behaviours'.format(
297
             self.logger.info('Subject {}: have {} behaviours'.format(
299
                 str(subject.id),
298
                 str(subject.id),
300
                 str(len(subject_behaviours)),
299
                 str(len(subject_behaviours)),
301
             ))
300
             ))
302
 
301
 
303
-            for behaviour_key, behaviour in list(subject_behaviours.items()):
302
+            for behaviour in subject_behaviours:
303
+                behaviour_key = type(behaviour)
304
+
304
                 self.logger.info('Subject {}: run {} behaviour'.format(
305
                 self.logger.info('Subject {}: run {} behaviour'.format(
305
                     str(subject.id),
306
                     str(subject.id),
306
                     str(type(behaviour)),
307
                     str(type(behaviour)),
411
 
412
 
412
     def stop(self) -> None:
413
     def stop(self) -> None:
413
         self.process_manager.terminate()
414
         self.process_manager.terminate()
415
+
416
+    def get_active_subject_behaviors(
417
+        self,
418
+        subject: Subject,
419
+    ) -> typing.List[SubjectBehaviour]:
420
+        behaviours = []
421
+        for behaviour in subject.behaviours.values():
422
+            if behaviour.is_skip(self.current_cycle):
423
+                self.logger.debug('Simulation: behaviour {} skip'.format(
424
+                    str(type(behaviour)),
425
+                ))
426
+            else:
427
+                behaviours.append(behaviour)
428
+        return behaviours
429
+
430
+    def get_mechanisms_from_behaviors(
431
+        self,
432
+        subject_behaviours: typing.List[SubjectBehaviour],
433
+        subject: Subject,
434
+    ) -> typing.List[SubjectMechanism]:
435
+        # TODO BS 20180109: Not very optimized ... could be enhanced
436
+        mechanisms = set()
437
+        for subject_mechanism in subject.mechanisms.values():
438
+            for subject_behaviour in subject_behaviours:
439
+                for behaviour_mechanism_class in subject_behaviour.use:
440
+                    if isinstance(subject_mechanism, behaviour_mechanism_class):
441
+                        mechanisms.add(subject_mechanism)
442
+        return list(mechanisms)

+ 3 - 3
synergine2/simulation.py View File

158
         super().remove(value)
158
         super().remove(value)
159
         # Remove from start_collections
159
         # Remove from start_collections
160
         for collection_name in value.collections:
160
         for collection_name in value.collections:
161
-            self.simulation.collections[collection_name].remove(value)
161
+            self.simulation.collections[collection_name].remove(value.id)
162
         # Add to removed listing
162
         # Add to removed listing
163
         if self.track_changes:
163
         if self.track_changes:
164
             self.removes.append(value)
164
             self.removes.append(value)
309
         """
309
         """
310
         cycle_frequency = self.cycle_frequency
310
         cycle_frequency = self.cycle_frequency
311
         if cycle_frequency is not None:
311
         if cycle_frequency is not None:
312
-            return not bool(cycle_number % cycle_frequency)
312
+            return bool(cycle_number % cycle_frequency)
313
 
313
 
314
         seconds_frequency = self.seconds_frequency
314
         seconds_frequency = self.seconds_frequency
315
         if seconds_frequency is not None:
315
         if seconds_frequency is not None:
316
-            return time.time() - self.last_execution_time <= seconds_frequency
316
+            return float(time.time() - self.last_execution_time) <= seconds_frequency
317
 
317
 
318
         return False
318
         return False
319
 
319
 

+ 82 - 22
tests/test_simulation.py View File

153
             process_manager=do_nothing_process_manager,
153
             process_manager=do_nothing_process_manager,
154
         )
154
         )
155
 
155
 
156
-        # Cycle 0: behaviour NOT executed
156
+        # Cycle 0: behaviour IS executed
157
         cycle_manager.current_cycle = 0
157
         cycle_manager.current_cycle = 0
158
         results_by_subjects = cycle_manager._job_subjects(worker_id=0, process_count=1)
158
         results_by_subjects = cycle_manager._job_subjects(worker_id=0, process_count=1)
159
         assert results_by_subjects
159
         assert results_by_subjects
160
-        assert id(my_subject) in results_by_subjects
161
-        assert not results_by_subjects[id(my_subject)]
162
 
160
 
163
-        # Cycle 1: behaviour executed
161
+        # Cycle 1: behaviour IS NOT executed
164
         cycle_manager.current_cycle = 1
162
         cycle_manager.current_cycle = 1
165
         results_by_subjects = cycle_manager._job_subjects(worker_id=0, process_count=1)
163
         results_by_subjects = cycle_manager._job_subjects(worker_id=0, process_count=1)
166
-        assert results_by_subjects
167
-        assert id(my_subject) in results_by_subjects
168
-        assert results_by_subjects[id(my_subject)]
164
+        assert not results_by_subjects
169
 
165
 
170
     def test_subject_behaviour_seconds_frequency(
166
     def test_subject_behaviour_seconds_frequency(
171
         self,
167
         self,
199
         # Less second after: NOT executed
195
         # Less second after: NOT executed
200
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 0, 500000)):
196
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 0, 500000)):
201
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
197
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
202
-            assert data
203
-            assert id(my_subject) in data
204
-            assert not data[id(my_subject)]
198
+            assert not data
205
 
199
 
206
         # Less second after: NOT executed
200
         # Less second after: NOT executed
207
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 0, 700000)):
201
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 0, 700000)):
208
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
202
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
209
-            assert data
210
-            assert id(my_subject) in data
211
-            assert not data[id(my_subject)]
203
+            assert not data
212
 
204
 
213
-        # Less second after: NOT executed
205
+        # Less second after: IS executed
214
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 1, 500000)):
206
         with freeze_time(datetime.datetime(2000, 12, 1, 0, 0, 1, 500000)):
215
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
207
             data = cycle_manager._job_subjects(worker_id=0, process_count=1)
216
             assert data
208
             assert data
217
-            assert id(my_subject) in data
218
-            assert data[id(my_subject)]
219
 
209
 
220
     def test_simulation_behaviour_cycle_frequency(
210
     def test_simulation_behaviour_cycle_frequency(
221
         self,
211
         self,
237
             process_manager=do_nothing_process_manager,
227
             process_manager=do_nothing_process_manager,
238
         )
228
         )
239
 
229
 
240
-        # Cycle 0: behaviour NOT executed
230
+        # Cycle 0: behaviour IS executed
241
         cycle_manager.current_cycle = 0
231
         cycle_manager.current_cycle = 0
242
         data = cycle_manager._job_simulation(worker_id=0, process_count=1)
232
         data = cycle_manager._job_simulation(worker_id=0, process_count=1)
243
-        assert not data
233
+        assert data
244
 
234
 
245
-        # Cycle 1: behaviour executed
235
+        # Cycle 1: behaviour IS NOT executed
246
         cycle_manager.current_cycle = 1
236
         cycle_manager.current_cycle = 1
247
         data = cycle_manager._job_simulation(worker_id=0, process_count=1)
237
         data = cycle_manager._job_simulation(worker_id=0, process_count=1)
248
-        assert data
238
+        assert not data
249
 
239
 
250
     def test_simulation_behaviour_seconds_frequency(
240
     def test_simulation_behaviour_seconds_frequency(
251
         self,
241
         self,
468
         cycle_manager._job_simulation(worker_id=0, process_count=1)
458
         cycle_manager._job_simulation(worker_id=0, process_count=1)
469
         assert called == 0
459
         assert called == 0
470
 
460
 
471
-    def test_mechanism_not_called_if_subject_behavior_timebase_not_active_yet(self):
461
+    def test_mechanism_not_called_if_subject_behavior_cycled_not_active_yet(
462
+        self,
463
+        do_nothing_process_manager: ProcessManager,
464
+    ):
465
+        shared.reset()
466
+        called = 0
467
+        global called
468
+
469
+        class MySubjectMechanism(SubjectMechanism):
470
+            def run(self):
471
+                global called
472
+                called += 1
473
+                return {'foo': 42}
474
+
475
+        class MySubjectBehaviour1(SubjectBehaviour):
476
+            use = [MySubjectMechanism]
477
+
478
+            @property
479
+            def cycle_frequency(self):
480
+                return 2
481
+
482
+            def run(self, data):
483
+                return {'bar': data[MySubjectMechanism]['foo'] + 100}
484
+
485
+        class MySubject(Subject):
486
+            behaviours_classes = [MySubjectBehaviour1]
487
+
488
+        simulation = Simulation(config)
489
+        my_subject = MySubject(config, simulation)
490
+        subjects = Subjects(simulation=simulation)
491
+        subjects.append(my_subject)
492
+        simulation.subjects = subjects
493
+
494
+        cycle_manager = CycleManager(
495
+            config,
496
+            logger,
497
+            simulation=simulation,
498
+            process_manager=do_nothing_process_manager,
499
+        )
500
+
501
+        cycle_manager.current_cycle = 0
502
+        cycle_manager._job_subjects(worker_id=0, process_count=1)
503
+        assert called == 1
504
+
505
+        cycle_manager.current_cycle = 1
506
+        cycle_manager._job_subjects(worker_id=0, process_count=1)
507
+        assert called == 1
508
+
509
+        cycle_manager.current_cycle = 2
510
+        cycle_manager._job_subjects(worker_id=0, process_count=1)
511
+        assert called == 2
512
+
513
+        cycle_manager.current_cycle = 3
514
+        cycle_manager._job_subjects(worker_id=0, process_count=1)
515
+        assert called == 2
516
+
517
+    def test_mechanism_not_called_if_simulation_behavior_cycled_not_active_yet(
518
+        self,
519
+        do_nothing_process_manager: ProcessManager,
520
+    ):
472
         shared.reset()
521
         shared.reset()
473
 
522
 
474
         pass
523
         pass
475
 
524
 
476
-    def test_mechanism_not_called_if_simulation_behavior_timebase_not_active_yet(self):
525
+    def test_mechanism_not_called_if_subject_behavior_timebase_not_active_yet(
526
+        self,
527
+        do_nothing_process_manager: ProcessManager,
528
+    ):
529
+        shared.reset()
530
+
531
+        pass
532
+
533
+    def test_mechanism_not_called_if_simulation_behavior_timebase_not_active_yet(
534
+        self,
535
+        do_nothing_process_manager: ProcessManager,
536
+    ):
477
         shared.reset()
537
         shared.reset()
478
 
538
 
479
         pass
539
         pass