From 94c87fcc4a12e31cfa2828e826081768ab9cd3d2 Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Fri, 27 Sep 2024 15:58:52 -0700 Subject: [PATCH 1/3] Fix bugs in Simulator error handling and end of simulation --- lib/src/simulator.dart | 23 +++++++- test/simulator_test.dart | 110 +++++++++++++++++++++++++++++++++------ 2 files changed, 114 insertions(+), 19 deletions(-) diff --git a/lib/src/simulator.dart b/lib/src/simulator.dart index 64476c903..53443b93f 100644 --- a/lib/src/simulator.dart +++ b/lib/src/simulator.dart @@ -385,11 +385,22 @@ abstract class Simulator { _simExceptions.isEmpty && !_simulationEndRequested && (_maxSimTime < 0 || _currentTimestamp < _maxSimTime)) { - await tick(); + try { + await tick(); + } catch (__, _) { + // trigger the end of simulation if an error occurred + _simulationEndedCompleter.complete(); + + rethrow; + } } for (final err in _simExceptions) { logger.severe(err.exception.toString(), err.exception, err.stackTrace); + + // trigger the end of simulation if an error occurred + _simulationEndedCompleter.complete(); + throw err.exception; } @@ -399,7 +410,15 @@ abstract class Simulator { while (_endOfSimulationActions.isNotEmpty) { final endOfSimAction = _endOfSimulationActions.removeFirst(); - await endOfSimAction(); + + try { + await endOfSimAction(); + } catch (_) { + // trigger the end of simulation if an error occurred + _simulationEndedCompleter.complete(); + + rethrow; + } } _simulationEndedCompleter.complete(); diff --git a/test/simulator_test.dart b/test/simulator_test.dart index f6ef041c4..e993fe205 100644 --- a/test/simulator_test.dart +++ b/test/simulator_test.dart @@ -81,25 +81,101 @@ void main() { await Simulator.run(); }); - test('simulator end of action waits before ending', () async { - var endOfSimActionExecuted = false; - Simulator.registerAction(100, () => true); - Simulator.registerEndOfSimulationAction( - () => endOfSimActionExecuted = true); - unawaited(Simulator.simulationEnded - .then((value) => expect(endOfSimActionExecuted, isTrue))); - await Simulator.run(); - }); + group('simulator end of', () { + test('action waits before ending', () async { + var endOfSimActionExecuted = false; + Simulator.registerAction(100, () => true); + Simulator.registerEndOfSimulationAction( + () => endOfSimActionExecuted = true); + unawaited(Simulator.simulationEnded + .then((value) => expect(endOfSimActionExecuted, isTrue))); + await Simulator.run(); + }); - test('simulator end of action waits async before ending', () async { - var endOfSimActionExecuted = false; - Simulator.registerAction(100, () => true); - Simulator.registerEndOfSimulationAction(() async { - await Future.delayed(const Duration(microseconds: 10)); - endOfSimActionExecuted = true; + test('action waits async before ending', () async { + var endOfSimActionExecuted = false; + Simulator.registerAction(100, () => true); + Simulator.registerEndOfSimulationAction(() async { + await Future.delayed(const Duration(microseconds: 10)); + endOfSimActionExecuted = true; + }); + await Simulator.run(); + expect(endOfSimActionExecuted, isTrue); }); - await Simulator.run(); - expect(endOfSimActionExecuted, isTrue); + + test('action throws', () async { + var endOfSimActionExecuted = false; + var errorThrown = false; + + Simulator.registerAction(100, () => true); + Simulator.registerEndOfSimulationAction(() { + endOfSimActionExecuted = true; + throw Exception('End of sim action failed'); + }); + + // the Future will hang if we don't properly trigger the completion + unawaited(Simulator.run().onError((_, __) { + errorThrown = true; + })); + await Simulator.simulationEnded; + + expect(endOfSimActionExecuted, isTrue); + expect(errorThrown, isTrue); + }); + + test('action async throws', () async { + var endOfSimActionExecuted = false; + var errorThrown = false; + + Simulator.registerAction(100, () => true); + Simulator.registerEndOfSimulationAction(() async { + await Future.delayed(const Duration(microseconds: 10)); + endOfSimActionExecuted = true; + throw Exception('End of sim action failed'); + }); + + // the Future will hang if we don't properly trigger the completion + unawaited(Simulator.run().onError((_, __) { + errorThrown = true; + })); + await Simulator.simulationEnded; + + expect(endOfSimActionExecuted, isTrue); + expect(errorThrown, isTrue); + }); + }); + + test('registered action exception in simulator ends simulation', () async { + var errorThrown = false; + + Simulator.registerAction(100, () => throw Exception('failed action')); + Simulator.registerAction(200, () => true); + + unawaited(Simulator.run().onError((_, __) { + errorThrown = true; + })); + + await Simulator.simulationEnded; + + expect(errorThrown, isTrue); + }); + + test('simulator thrown exception ends simulation', () async { + var errorThrown = false; + + Simulator.registerAction( + 100, + () => Simulator.throwException( + Exception('simulator thrown exception'), StackTrace.current)); + Simulator.registerAction(200, () => true); + + unawaited(Simulator.run().onError((_, __) { + errorThrown = true; + })); + + await Simulator.simulationEnded; + + expect(errorThrown, isTrue); }); test('simulator end simulation waits for simulation to end', () async { From 4319237fcc3d6fec4cae7d92c3ea451d5fc1032c Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Mon, 30 Sep 2024 08:40:30 -0700 Subject: [PATCH 2/3] fix _ var names --- lib/src/simulator.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/simulator.dart b/lib/src/simulator.dart index 53443b93f..1fd72a809 100644 --- a/lib/src/simulator.dart +++ b/lib/src/simulator.dart @@ -387,7 +387,7 @@ abstract class Simulator { (_maxSimTime < 0 || _currentTimestamp < _maxSimTime)) { try { await tick(); - } catch (__, _) { + } catch (_, __) { // trigger the end of simulation if an error occurred _simulationEndedCompleter.complete(); From d61291b991c6c2fad473774a4c8e1a7f609348a4 Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Mon, 16 Dec 2024 15:59:50 -0800 Subject: [PATCH 3/3] increase js heap size --- tool/gh_actions/run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/gh_actions/run_tests.sh b/tool/gh_actions/run_tests.sh index d426240f3..160352cd2 100755 --- a/tool/gh_actions/run_tests.sh +++ b/tool/gh_actions/run_tests.sh @@ -14,5 +14,5 @@ set -euo pipefail dart test # run tests in JS (increase heap size also) -export NODE_OPTIONS="--max-old-space-size=6144" +export NODE_OPTIONS="--max-old-space-size=8192" dart test --platform node \ No newline at end of file