From ac04deb13b3795ed64383057ddeaa6c3a4bb0937 Mon Sep 17 00:00:00 2001 From: Bosh Date: Fri, 6 Dec 2024 15:03:45 -0800 Subject: [PATCH 01/11] Add python 3.12 to run_tests github workflow Expecting to expose issues that need addressing for the upgrade --- .github/workflows/run_tests.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 00e23e2b0..1f12dd0b5 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -18,6 +18,8 @@ jobs: python-version: "3.10" - os: windows-latest python-version: 3.11 + - os: windows-latest + python-version: 3.12 - os: ubuntu-latest python-version: 3.8 - os: ubuntu-latest @@ -26,6 +28,8 @@ jobs: python-version: "3.10" - os: ubuntu-latest python-version: 3.11 + - os: ubuntu-latest + python-version: 3.12 - os: macos-latest python-version: 3.8 - os: macos-latest @@ -34,6 +38,8 @@ jobs: python-version: "3.10" - os: macos-latest python-version: 3.11 + - os: macos-latest + python-version: 3.12 steps: - name: Checkout MPF @@ -79,4 +85,4 @@ jobs: pip3 install --upgrade coveralls coveralls --service=github --finish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 6a1adea748e943c297668628386447694d8e01ca Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Wed, 11 Dec 2024 02:51:43 -0800 Subject: [PATCH 02/11] python 12 upgrade - change timing in lisy test for only windows failure --- mpf/tests/test_Lisy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpf/tests/test_Lisy.py b/mpf/tests/test_Lisy.py index 11f7cbe69..caab0cfdf 100644 --- a/mpf/tests/test_Lisy.py +++ b/mpf/tests/test_Lisy.py @@ -319,7 +319,7 @@ def test_platform(self): b'\x1F \x00': None } - self.advance_time_and_run(1) + self.advance_time_and_run(1.5) self.assertFalse(self.serialMock.expected_commands) self.serialMock.expected_commands = { From ab09c4ff61f326e3a4d90beee32879b172a781b3 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Wed, 11 Dec 2024 03:09:22 -0800 Subject: [PATCH 03/11] nope! Revert "python 12 upgrade - change timing in lisy test for only windows failure" This reverts commit 6a1adea748e943c297668628386447694d8e01ca. --- mpf/tests/test_Lisy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpf/tests/test_Lisy.py b/mpf/tests/test_Lisy.py index caab0cfdf..11f7cbe69 100644 --- a/mpf/tests/test_Lisy.py +++ b/mpf/tests/test_Lisy.py @@ -319,7 +319,7 @@ def test_platform(self): b'\x1F \x00': None } - self.advance_time_and_run(1.5) + self.advance_time_and_run(1) self.assertFalse(self.serialMock.expected_commands) self.serialMock.expected_commands = { From c4e791e4444eace02872aa8b1269cbb406d38a96 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Wed, 11 Dec 2024 14:47:38 -0800 Subject: [PATCH 04/11] reduce ast types from Num/Str/NameConstant to just Constant per warnings --- mpf/core/placeholder_manager.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/mpf/core/placeholder_manager.py b/mpf/core/placeholder_manager.py index 5518ab68a..a10265e47 100644 --- a/mpf/core/placeholder_manager.py +++ b/mpf/core/placeholder_manager.py @@ -642,9 +642,7 @@ def __init__(self, machine): """Initialize.""" super().__init__(machine) self._eval_methods = { - ast.Num: self._eval_num, - ast.Str: self._eval_str, - ast.NameConstant: self._eval_constant, + ast.Constant: self._eval_constant, ast.BinOp: self._eval_bin_op, ast.UnaryOp: self._eval_unary_op, ast.Compare: self._eval_compare, @@ -655,8 +653,6 @@ def __init__(self, machine): ast.IfExp: self._eval_if, ast.Tuple: self._eval_tuple, } - if hasattr(ast, "Constant"): - self._eval_methods[ast.Constant] = self._eval_constant def _eval_tuple(self, node, variables, subscribe): return tuple([self._eval(x, variables, subscribe) for x in node.elts]) @@ -668,18 +664,6 @@ def _parse_template(template_str): except SyntaxError: raise AssertionError('Failed to parse template "{}"'.format(template_str)) - @staticmethod - def _eval_num(node, variables, subscribe): - del variables - del subscribe - return node.n, [] - - @staticmethod - def _eval_str(node, variables, subscribe): - del variables - del subscribe - return node.s, [] - @staticmethod def _eval_constant(node, variables, subscribe): del variables From a60f3f310fdcf8e9c07f962b8e2a2e32f34be449 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Wed, 11 Dec 2024 23:34:24 -0800 Subject: [PATCH 05/11] move failing lisy section later in test to see if later sections still work --- mpf/tests/test_Lisy.py | 86 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/mpf/tests/test_Lisy.py b/mpf/tests/test_Lisy.py index 11f7cbe69..02a7e42f3 100644 --- a/mpf/tests/test_Lisy.py +++ b/mpf/tests/test_Lisy.py @@ -293,49 +293,6 @@ def test_platform(self): self._wait_for_processing() self.assertFalse(self.serialMock.expected_commands) - # set info display to TEST - self.serialMock.expected_commands = { - b'\x1E TEST\x00': None - } - self.machine.segment_displays["info_display"].add_text("TEST") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set player 1 display to 42000 - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None - } - self.machine.segment_displays["player1_display"].add_text("42000") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set player 1 display to flashing - self.machine.segment_displays["player1_display"].set_flashing(FlashingType.FLASH_ALL) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None, - b'\x1F \x00': None - } - - self.advance_time_and_run(1) - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F \x00': None - } - - self.advance_time_and_run(.5) - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None, - } - self.machine.segment_displays["player1_display"].set_flashing(FlashingType.NO_FLASH) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - # test sound self.serialMock.expected_commands = { b'\x32\x02': None @@ -408,6 +365,49 @@ def test_platform(self): self._wait_for_processing() self.assertFalse(self.serialMock.expected_commands) + # set info display to TEST + self.serialMock.expected_commands = { + b'\x1E TEST\x00': None + } + self.machine.segment_displays["info_display"].add_text("TEST") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set player 1 display to 42000 + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None + } + self.machine.segment_displays["player1_display"].add_text("42000") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set player 1 display to flashing + self.machine.segment_displays["player1_display"].set_flashing(FlashingType.FLASH_ALL) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None, + b'\x1F \x00': None + } + + self.advance_time_and_run(1) + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F \x00': None + } + + self.advance_time_and_run(.5) + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None, + } + self.machine.segment_displays["player1_display"].set_flashing(FlashingType.NO_FLASH) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + @test_config("config_system11.yaml") def test_system11(self): # test normal coil From 2fdae0f09d11e64dfcd7d3e1395fc3c9a32f75f5 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 00:06:00 -0800 Subject: [PATCH 06/11] hacking at lisy test. pushing for logs across envs --- mpf/tests/test_Game.py | 742 +++++----- mpf/tests/test_Lisy.py | 1287 +++++++++-------- mpf/{tests => tests2}/test_Accelerometer.py | 0 mpf/{tests => tests2}/test_Achievement.py | 0 mpf/{tests => tests2}/test_AssetManager.py | 0 mpf/{tests => tests2}/test_Attract.py | 0 mpf/{tests => tests2}/test_Auditor.py | 0 mpf/{tests => tests2}/test_Autofire.py | 0 mpf/{tests => tests2}/test_BallController.py | 0 mpf/{tests => tests2}/test_BallDevice.py | 0 .../test_BallDeviceAutoManualPlunger.py | 0 .../test_BallDeviceEnableCoil.py | 0 .../test_BallDeviceEventConfirmation.py | 0 .../test_BallDeviceEventEjector.py | 0 .../test_BallDeviceHoldCoil.py | 0 .../test_BallDeviceJamSwitch.py | 0 .../test_BallDeviceManualWithTarget.py | 0 ...test_BallDeviceModernTroughPlungerSetup.py | 0 .../test_BallDeviceNoPlungerSwitch.py | 0 .../test_BallDevicePlayfieldLock.py | 0 .../test_BallDevicePulseEject.py | 0 .../test_BallDeviceRouting.py | 0 .../test_BallDeviceSingle.py | 0 .../test_BallDeviceSwitchConfirmation.py | 0 .../test_BallDeviceTriggerEvents.py | 0 .../test_BallDevice_SmartVirtual.py | 0 mpf/{tests => tests2}/test_BallHold.py | 0 mpf/{tests => tests2}/test_BallRouting.py | 0 mpf/{tests => tests2}/test_BallSave.py | 0 mpf/{tests => tests2}/test_BallSearch.py | 0 mpf/{tests => tests2}/test_BcpInterface.py | 0 mpf/{tests => tests2}/test_BcpMc.py | 0 mpf/{tests => tests2}/test_BcpServer.py | 0 mpf/{tests => tests2}/test_BcpSocketClient.py | 0 mpf/{tests => tests2}/test_Blinkenlight.py | 0 mpf/{tests => tests2}/test_BlockingEvents.py | 0 mpf/{tests => tests2}/test_Bonus.py | 0 mpf/{tests => tests2}/test_CarouselMode.py | 0 mpf/{tests => tests2}/test_Clock.py | 0 mpf/{tests => tests2}/test_CoilPlayer.py | 0 mpf/{tests => tests2}/test_ComboSwitches.py | 0 .../test_CommandCreateConfig.py | 0 mpf/{tests => tests2}/test_Commands.py | 0 mpf/{tests => tests2}/test_Config.py | 0 mpf/{tests => tests2}/test_ConfigErrors.py | 0 mpf/{tests => tests2}/test_ConfigLoader.py | 0 .../test_ConfigMissingVersion.py | 0 .../test_ConfigOldVersion.py | 0 mpf/{tests => tests2}/test_ConfigPlayers.py | 0 mpf/{tests => tests2}/test_ConfigProcessor.py | 0 mpf/{tests => tests2}/test_CreditsMode.py | 0 mpf/{tests => tests2}/test_CustomCode.py | 0 mpf/{tests => tests2}/test_DataManager.py | 0 mpf/{tests => tests2}/test_Delay.py | 0 .../test_DeviceCollection.py | 0 mpf/{tests => tests2}/test_DeviceDriver.py | 0 mpf/{tests => tests2}/test_DeviceFlasher.py | 0 mpf/{tests => tests2}/test_DeviceGI.py | 0 mpf/{tests => tests2}/test_DeviceLight.py | 0 mpf/{tests => tests2}/test_DeviceManager.py | 0 .../test_DeviceMatrixLight.py | 0 mpf/{tests => tests2}/test_DigitalOutput.py | 0 .../test_DigitalScoreReels.py | 0 mpf/{tests => tests2}/test_Diverter.py | 0 mpf/{tests => tests2}/test_Dmd.py | 0 mpf/{tests => tests2}/test_DropTargets.py | 0 mpf/{tests => tests2}/test_DualWoundCoil.py | 0 mpf/{tests => tests2}/test_EventManager.py | 0 mpf/{tests => tests2}/test_EventPlayer.py | 0 mpf/{tests => tests2}/test_ExtraBall.py | 0 mpf/{tests => tests2}/test_Fadecandy.py | 0 mpf/{tests => tests2}/test_Fast.py | 0 mpf/{tests => tests2}/test_Fast_Audio.py | 0 mpf/{tests => tests2}/test_Fast_Dmd.py | 0 mpf/{tests => tests2}/test_Fast_Exp.py | 0 mpf/{tests => tests2}/test_Fast_Nano.py | 0 mpf/{tests => tests2}/test_Fast_Neuron.py | 0 mpf/{tests => tests2}/test_Fast_Retro.py | 0 mpf/{tests => tests2}/test_Fast_Seg.py | 0 mpf/{tests => tests2}/test_Flippers.py | 0 .../test_FlippersHoldNoEos.py | 0 .../test_FlippersSoftwareEosRepulse.py | 0 mpf/{tests => tests2}/test_GottliebTrough.py | 0 mpf/{tests => tests2}/test_Head2Head.py | 0 mpf/{tests => tests2}/test_HighScoreMode.py | 0 .../test_HighScoreModeWithVars.py | 0 .../test_I2cServoController.py | 0 mpf/{tests => tests2}/test_InfoLights.py | 0 mpf/{tests => tests2}/test_Kickback.py | 0 mpf/{tests => tests2}/test_LightGroups.py | 0 mpf/{tests => tests2}/test_LightPlayer.py | 0 mpf/{tests => tests2}/test_LightPositions.py | 0 .../test_LightSegmentDisplays.py | 0 mpf/tests2/test_Lisy.py | 869 +++++++++++ mpf/{tests => tests2}/test_LogicBlocks.py | 0 mpf/{tests => tests2}/test_MMA8451.py | 0 .../test_MachineVariables.py | 0 mpf/{tests => tests2}/test_Magnet.py | 0 mpf/{tests => tests2}/test_MatchMode.py | 0 mpf/{tests => tests2}/test_Modes.py | 0 .../test_ModesConfigValidation.py | 0 mpf/{tests => tests2}/test_Motors.py | 0 mpf/{tests => tests2}/test_MpfTestCase.py | 0 mpf/{tests => tests2}/test_MultiBall.py | 0 mpf/{tests => tests2}/test_MultiballLock.py | 0 mpf/{tests => tests2}/test_MyPinballs.py | 0 mpf/{tests => tests2}/test_OPP.py | 0 mpf/{tests => tests2}/test_Openpixel.py | 0 mpf/{tests => tests2}/test_Osc.py | 0 mpf/{tests => tests2}/test_P3_Roc.py | 0 mpf/{tests => tests2}/test_PKONE.py | 0 mpf/{tests => tests2}/test_P_Roc.py | 0 .../test_PlaceholderManager.py | 0 mpf/{tests => tests2}/test_Platform.py | 0 mpf/{tests => tests2}/test_PlayerVars.py | 0 mpf/{tests => tests2}/test_Playfield.py | 0 .../test_PlayfieldTransfer.py | 0 .../test_PluginConfigPlayer.py | 0 mpf/{tests => tests2}/test_PololuMaestro.py | 0 mpf/{tests => tests2}/test_PololuTic.py | 0 .../test_QueueEventPlayer.py | 0 mpf/{tests => tests2}/test_RGBColor.py | 0 .../test_RandomEventPlayer.py | 0 mpf/{tests => tests2}/test_Randomizer.py | 0 mpf/{tests => tests2}/test_Rpi.py | 0 mpf/{tests => tests2}/test_RpiDmd.py | 0 mpf/{tests => tests2}/test_ScoreQueue.py | 0 mpf/{tests => tests2}/test_ScoreReels.py | 0 mpf/{tests => tests2}/test_SegmentDisplay.py | 0 mpf/{tests => tests2}/test_SegmentMappings.py | 0 mpf/{tests => tests2}/test_SequenceShot.py | 0 mpf/{tests => tests2}/test_ServiceCli.py | 0 mpf/{tests => tests2}/test_ServiceMode.py | 0 mpf/{tests => tests2}/test_Servo.py | 0 mpf/{tests => tests2}/test_Settings.py | 0 mpf/{tests => tests2}/test_ShotGroups.py | 0 mpf/{tests => tests2}/test_Shots.py | 0 mpf/{tests => tests2}/test_ShowPools.py | 0 mpf/{tests => tests2}/test_Shows.py | 0 mpf/{tests => tests2}/test_SmartMatrix.py | 0 .../test_SmartVirtualPlatform.py | 0 mpf/{tests => tests2}/test_Smbus2.py | 0 mpf/{tests => tests2}/test_Snux.py | 0 mpf/{tests => tests2}/test_SpiBitBang.py | 0 mpf/{tests => tests2}/test_Spike.py | 0 mpf/{tests => tests2}/test_Spinners.py | 0 mpf/{tests => tests2}/test_StateMachine.py | 0 mpf/{tests => tests2}/test_StepStick.py | 0 mpf/{tests => tests2}/test_Stepper.py | 0 .../test_SwitchController.py | 0 mpf/{tests => tests2}/test_SwitchPlayer.py | 0 mpf/{tests => tests2}/test_SwitchPositions.py | 0 mpf/{tests => tests2}/test_System11Trough.py | 0 mpf/{tests => tests2}/test_Tilt.py | 0 mpf/{tests => tests2}/test_TimedSwitch.py | 0 mpf/{tests => tests2}/test_Timer.py | 0 .../test_TooLongExitCountDelay.py | 0 .../test_TrinamicsStepRocker.py | 0 .../test_TroughEntranceSwitch.py | 0 mpf/{tests => tests2}/test_TwitchClient.py | 0 .../test_Utility_Functions.py | 0 mpf/{tests => tests2}/test_VPX.py | 0 mpf/{tests => tests2}/test_VariablePlayer.py | 0 mpf/{tests => tests2}/test_Virtual.py | 0 mpf/{tests => tests2}/test_VirtualPinball.py | 0 .../test_VirtualSegmentDisplayConnector.py | 0 .../test_VisualPinballEngine.py | 0 mpf/{tests => tests2}/test_YamlInterface.py | 0 168 files changed, 1888 insertions(+), 1010 deletions(-) rename mpf/{tests => tests2}/test_Accelerometer.py (100%) rename mpf/{tests => tests2}/test_Achievement.py (100%) rename mpf/{tests => tests2}/test_AssetManager.py (100%) rename mpf/{tests => tests2}/test_Attract.py (100%) rename mpf/{tests => tests2}/test_Auditor.py (100%) rename mpf/{tests => tests2}/test_Autofire.py (100%) rename mpf/{tests => tests2}/test_BallController.py (100%) rename mpf/{tests => tests2}/test_BallDevice.py (100%) rename mpf/{tests => tests2}/test_BallDeviceAutoManualPlunger.py (100%) rename mpf/{tests => tests2}/test_BallDeviceEnableCoil.py (100%) rename mpf/{tests => tests2}/test_BallDeviceEventConfirmation.py (100%) rename mpf/{tests => tests2}/test_BallDeviceEventEjector.py (100%) rename mpf/{tests => tests2}/test_BallDeviceHoldCoil.py (100%) rename mpf/{tests => tests2}/test_BallDeviceJamSwitch.py (100%) rename mpf/{tests => tests2}/test_BallDeviceManualWithTarget.py (100%) rename mpf/{tests => tests2}/test_BallDeviceModernTroughPlungerSetup.py (100%) rename mpf/{tests => tests2}/test_BallDeviceNoPlungerSwitch.py (100%) rename mpf/{tests => tests2}/test_BallDevicePlayfieldLock.py (100%) rename mpf/{tests => tests2}/test_BallDevicePulseEject.py (100%) rename mpf/{tests => tests2}/test_BallDeviceRouting.py (100%) rename mpf/{tests => tests2}/test_BallDeviceSingle.py (100%) rename mpf/{tests => tests2}/test_BallDeviceSwitchConfirmation.py (100%) rename mpf/{tests => tests2}/test_BallDeviceTriggerEvents.py (100%) rename mpf/{tests => tests2}/test_BallDevice_SmartVirtual.py (100%) rename mpf/{tests => tests2}/test_BallHold.py (100%) rename mpf/{tests => tests2}/test_BallRouting.py (100%) rename mpf/{tests => tests2}/test_BallSave.py (100%) rename mpf/{tests => tests2}/test_BallSearch.py (100%) rename mpf/{tests => tests2}/test_BcpInterface.py (100%) rename mpf/{tests => tests2}/test_BcpMc.py (100%) rename mpf/{tests => tests2}/test_BcpServer.py (100%) rename mpf/{tests => tests2}/test_BcpSocketClient.py (100%) rename mpf/{tests => tests2}/test_Blinkenlight.py (100%) rename mpf/{tests => tests2}/test_BlockingEvents.py (100%) rename mpf/{tests => tests2}/test_Bonus.py (100%) rename mpf/{tests => tests2}/test_CarouselMode.py (100%) rename mpf/{tests => tests2}/test_Clock.py (100%) rename mpf/{tests => tests2}/test_CoilPlayer.py (100%) rename mpf/{tests => tests2}/test_ComboSwitches.py (100%) rename mpf/{tests => tests2}/test_CommandCreateConfig.py (100%) rename mpf/{tests => tests2}/test_Commands.py (100%) rename mpf/{tests => tests2}/test_Config.py (100%) rename mpf/{tests => tests2}/test_ConfigErrors.py (100%) rename mpf/{tests => tests2}/test_ConfigLoader.py (100%) rename mpf/{tests => tests2}/test_ConfigMissingVersion.py (100%) rename mpf/{tests => tests2}/test_ConfigOldVersion.py (100%) rename mpf/{tests => tests2}/test_ConfigPlayers.py (100%) rename mpf/{tests => tests2}/test_ConfigProcessor.py (100%) rename mpf/{tests => tests2}/test_CreditsMode.py (100%) rename mpf/{tests => tests2}/test_CustomCode.py (100%) rename mpf/{tests => tests2}/test_DataManager.py (100%) rename mpf/{tests => tests2}/test_Delay.py (100%) rename mpf/{tests => tests2}/test_DeviceCollection.py (100%) rename mpf/{tests => tests2}/test_DeviceDriver.py (100%) rename mpf/{tests => tests2}/test_DeviceFlasher.py (100%) rename mpf/{tests => tests2}/test_DeviceGI.py (100%) rename mpf/{tests => tests2}/test_DeviceLight.py (100%) rename mpf/{tests => tests2}/test_DeviceManager.py (100%) rename mpf/{tests => tests2}/test_DeviceMatrixLight.py (100%) rename mpf/{tests => tests2}/test_DigitalOutput.py (100%) rename mpf/{tests => tests2}/test_DigitalScoreReels.py (100%) rename mpf/{tests => tests2}/test_Diverter.py (100%) rename mpf/{tests => tests2}/test_Dmd.py (100%) rename mpf/{tests => tests2}/test_DropTargets.py (100%) rename mpf/{tests => tests2}/test_DualWoundCoil.py (100%) rename mpf/{tests => tests2}/test_EventManager.py (100%) rename mpf/{tests => tests2}/test_EventPlayer.py (100%) rename mpf/{tests => tests2}/test_ExtraBall.py (100%) rename mpf/{tests => tests2}/test_Fadecandy.py (100%) rename mpf/{tests => tests2}/test_Fast.py (100%) rename mpf/{tests => tests2}/test_Fast_Audio.py (100%) rename mpf/{tests => tests2}/test_Fast_Dmd.py (100%) rename mpf/{tests => tests2}/test_Fast_Exp.py (100%) rename mpf/{tests => tests2}/test_Fast_Nano.py (100%) rename mpf/{tests => tests2}/test_Fast_Neuron.py (100%) rename mpf/{tests => tests2}/test_Fast_Retro.py (100%) rename mpf/{tests => tests2}/test_Fast_Seg.py (100%) rename mpf/{tests => tests2}/test_Flippers.py (100%) rename mpf/{tests => tests2}/test_FlippersHoldNoEos.py (100%) rename mpf/{tests => tests2}/test_FlippersSoftwareEosRepulse.py (100%) rename mpf/{tests => tests2}/test_GottliebTrough.py (100%) rename mpf/{tests => tests2}/test_Head2Head.py (100%) rename mpf/{tests => tests2}/test_HighScoreMode.py (100%) rename mpf/{tests => tests2}/test_HighScoreModeWithVars.py (100%) rename mpf/{tests => tests2}/test_I2cServoController.py (100%) rename mpf/{tests => tests2}/test_InfoLights.py (100%) rename mpf/{tests => tests2}/test_Kickback.py (100%) rename mpf/{tests => tests2}/test_LightGroups.py (100%) rename mpf/{tests => tests2}/test_LightPlayer.py (100%) rename mpf/{tests => tests2}/test_LightPositions.py (100%) rename mpf/{tests => tests2}/test_LightSegmentDisplays.py (100%) create mode 100644 mpf/tests2/test_Lisy.py rename mpf/{tests => tests2}/test_LogicBlocks.py (100%) rename mpf/{tests => tests2}/test_MMA8451.py (100%) rename mpf/{tests => tests2}/test_MachineVariables.py (100%) rename mpf/{tests => tests2}/test_Magnet.py (100%) rename mpf/{tests => tests2}/test_MatchMode.py (100%) rename mpf/{tests => tests2}/test_Modes.py (100%) rename mpf/{tests => tests2}/test_ModesConfigValidation.py (100%) rename mpf/{tests => tests2}/test_Motors.py (100%) rename mpf/{tests => tests2}/test_MpfTestCase.py (100%) rename mpf/{tests => tests2}/test_MultiBall.py (100%) rename mpf/{tests => tests2}/test_MultiballLock.py (100%) rename mpf/{tests => tests2}/test_MyPinballs.py (100%) rename mpf/{tests => tests2}/test_OPP.py (100%) rename mpf/{tests => tests2}/test_Openpixel.py (100%) rename mpf/{tests => tests2}/test_Osc.py (100%) rename mpf/{tests => tests2}/test_P3_Roc.py (100%) rename mpf/{tests => tests2}/test_PKONE.py (100%) rename mpf/{tests => tests2}/test_P_Roc.py (100%) rename mpf/{tests => tests2}/test_PlaceholderManager.py (100%) rename mpf/{tests => tests2}/test_Platform.py (100%) rename mpf/{tests => tests2}/test_PlayerVars.py (100%) rename mpf/{tests => tests2}/test_Playfield.py (100%) rename mpf/{tests => tests2}/test_PlayfieldTransfer.py (100%) rename mpf/{tests => tests2}/test_PluginConfigPlayer.py (100%) rename mpf/{tests => tests2}/test_PololuMaestro.py (100%) rename mpf/{tests => tests2}/test_PololuTic.py (100%) rename mpf/{tests => tests2}/test_QueueEventPlayer.py (100%) rename mpf/{tests => tests2}/test_RGBColor.py (100%) rename mpf/{tests => tests2}/test_RandomEventPlayer.py (100%) rename mpf/{tests => tests2}/test_Randomizer.py (100%) rename mpf/{tests => tests2}/test_Rpi.py (100%) rename mpf/{tests => tests2}/test_RpiDmd.py (100%) rename mpf/{tests => tests2}/test_ScoreQueue.py (100%) rename mpf/{tests => tests2}/test_ScoreReels.py (100%) rename mpf/{tests => tests2}/test_SegmentDisplay.py (100%) rename mpf/{tests => tests2}/test_SegmentMappings.py (100%) rename mpf/{tests => tests2}/test_SequenceShot.py (100%) rename mpf/{tests => tests2}/test_ServiceCli.py (100%) rename mpf/{tests => tests2}/test_ServiceMode.py (100%) rename mpf/{tests => tests2}/test_Servo.py (100%) rename mpf/{tests => tests2}/test_Settings.py (100%) rename mpf/{tests => tests2}/test_ShotGroups.py (100%) rename mpf/{tests => tests2}/test_Shots.py (100%) rename mpf/{tests => tests2}/test_ShowPools.py (100%) rename mpf/{tests => tests2}/test_Shows.py (100%) rename mpf/{tests => tests2}/test_SmartMatrix.py (100%) rename mpf/{tests => tests2}/test_SmartVirtualPlatform.py (100%) rename mpf/{tests => tests2}/test_Smbus2.py (100%) rename mpf/{tests => tests2}/test_Snux.py (100%) rename mpf/{tests => tests2}/test_SpiBitBang.py (100%) rename mpf/{tests => tests2}/test_Spike.py (100%) rename mpf/{tests => tests2}/test_Spinners.py (100%) rename mpf/{tests => tests2}/test_StateMachine.py (100%) rename mpf/{tests => tests2}/test_StepStick.py (100%) rename mpf/{tests => tests2}/test_Stepper.py (100%) rename mpf/{tests => tests2}/test_SwitchController.py (100%) rename mpf/{tests => tests2}/test_SwitchPlayer.py (100%) rename mpf/{tests => tests2}/test_SwitchPositions.py (100%) rename mpf/{tests => tests2}/test_System11Trough.py (100%) rename mpf/{tests => tests2}/test_Tilt.py (100%) rename mpf/{tests => tests2}/test_TimedSwitch.py (100%) rename mpf/{tests => tests2}/test_Timer.py (100%) rename mpf/{tests => tests2}/test_TooLongExitCountDelay.py (100%) rename mpf/{tests => tests2}/test_TrinamicsStepRocker.py (100%) rename mpf/{tests => tests2}/test_TroughEntranceSwitch.py (100%) rename mpf/{tests => tests2}/test_TwitchClient.py (100%) rename mpf/{tests => tests2}/test_Utility_Functions.py (100%) rename mpf/{tests => tests2}/test_VPX.py (100%) rename mpf/{tests => tests2}/test_VariablePlayer.py (100%) rename mpf/{tests => tests2}/test_Virtual.py (100%) rename mpf/{tests => tests2}/test_VirtualPinball.py (100%) rename mpf/{tests => tests2}/test_VirtualSegmentDisplayConnector.py (100%) rename mpf/{tests => tests2}/test_VisualPinballEngine.py (100%) rename mpf/{tests => tests2}/test_YamlInterface.py (100%) diff --git a/mpf/tests/test_Game.py b/mpf/tests/test_Game.py index 9b456fa12..ee66b4e01 100644 --- a/mpf/tests/test_Game.py +++ b/mpf/tests/test_Game.py @@ -138,374 +138,374 @@ def testSinglePlayerGame(self): self.assertEqual('game_ending', self._events.call_args_list[4][1]['event_name']) self.assertEqual('game_ended', self._events.call_args_list[5][1]['event_name']) - def testMultiplePlayerGame(self): - # setup event callbacks - self._events = MagicMock() - - # Create handler entries for all game lifecycle events we wish to test - self.machine.events.add_handler('game_will_start', self._events, event_name='game_will_start') - self.machine.events.add_handler('game_starting', self._events, event_name='game_starting') - self.machine.events.add_handler('game_started', self._events, event_name='game_started') - self.machine.events.add_handler('player_add_request', self._events, event_name='player_add_request') - self.machine.events.add_handler('player_will_add', self._events, event_name='player_will_add') - self.machine.events.add_handler('player_adding', self._events, event_name='player_adding') - self.machine.events.add_handler('player_added', self._events, event_name='player_added') - self.machine.events.add_handler('player_turn_will_start', self._events, event_name='player_turn_will_start') - self.machine.events.add_handler('player_turn_starting', self._events, event_name='player_turn_starting') - self.machine.events.add_handler('player_turn_started', self._events, event_name='player_turn_started') - self.machine.events.add_handler('player_turn_will_end', self._events, event_name='player_turn_will_end') - self.machine.events.add_handler('player_turn_ending', self._events, event_name='player_turn_ending') - self.machine.events.add_handler('player_turn_ended', self._events, event_name='player_turn_ended') - self.machine.events.add_handler('ball_will_start', self._events, event_name='ball_will_start') - self.machine.events.add_handler('ball_starting', self._events, event_name='ball_starting') - self.machine.events.add_handler('ball_started', self._events, event_name='ball_started') - self.machine.events.add_handler('ball_will_end', self._events, event_name='ball_will_end') - self.machine.events.add_handler('ball_ending', self._events, event_name='ball_ending') - self.machine.events.add_handler('ball_ended', self._events, event_name='ball_ended') - self.machine.events.add_handler('game_will_end', self._events, event_name='game_will_end') - self.machine.events.add_handler('game_ending', self._events, event_name='game_ending') - self.machine.events.add_handler('game_ended', self._events, event_name='game_ended') - - # prepare game - self.machine.switch_controller.process_switch('s_ball_switch1', 1) - self.machine.switch_controller.process_switch('s_ball_switch2', 1) - self.advance_time_and_run(10) - self.assertEqual(2, self.machine.ball_controller.num_balls_known) - self.assertEqual(2, self.machine.ball_devices["bd_trough"].balls) - - # start game (first player) - self.start_game() - self.advance_time_and_run(5) - self.assertGameIsRunning() - self.assertPlayerNumber(1) - self.assertBallNumber(1) - - self.assertEqual(3, self.machine.modes["game"].balls_per_game) - - # Assert game startup sequence - self.assertEqual(13, self._events.call_count) - self.assertEqual('game_will_start', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('game_starting', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('player_add_request', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_will_add', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_adding', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_added', self._events.call_args_list[5][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[5][1]['num']) - self.assertEqual('game_started', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[8][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[9][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[9][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[10][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[11][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[11][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[12][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[12][1]['ball']) - self.assertEqual(1, self._events.call_args_list[12][1]['player']) - self._events.reset_mock() - - # add another player (player 2) - self.add_player() - - # Assert game startup sequence - self.assertEqual(4, self._events.call_count) - self.assertEqual('player_add_request', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('player_will_add', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('player_adding', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_added', self._events.call_args_list[3][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[3][1]['num']) - self._events.reset_mock() - - # Drain the first ball (player 1) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(2) - self.assertBallNumber(1) - - # Assert ball drain, next ball start sequence - self.assertEqual(12, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[8][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[10][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[11][1]['ball']) - self._events.reset_mock() - - # Drain the first ball (player 2) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(1) - self.assertBallNumber(2) - - # Assert ball drain, next ball start sequence - self.assertEqual(12, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[8][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[10][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[11][1]['ball']) - self._events.reset_mock() - - # Drain the second ball (player 1) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(2) - self.assertBallNumber(2) - - # Assert ball drain, next ball start sequence - self.assertEqual(12, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[8][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[10][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[11][1]['ball']) - self._events.reset_mock() - - # Player 2 earns extra ball before draining - self.machine.game.player.extra_balls += 1 - - # Drain the ball (player 2 has earned an extra ball so it should still be - # player 2's turn) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(2) - self.assertBallNumber(2) - - # Assert ball drain, next ball sequence - self.assertEqual(6, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('ball_will_start', self._events.call_args_list[3][1]['event_name']) - self.assertTrue(self._events.call_args_list[3][1]['is_extra_ball']) - self.assertEqual('ball_starting', self._events.call_args_list[4][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[4][1]['balls_remaining']) - self.assertTrue(self._events.call_args_list[4][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[5][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[5][1]['ball']) - self._events.reset_mock() - - # Drain the second ball (player 2) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(1) - self.assertBallNumber(3) - - # Assert ball drain, next ball start sequence - self.assertEqual(12, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) - self.assertEqual(1, self._events.call_args_list[8][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) - self.assertEqual(0, self._events.call_args_list[10][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(3, self._events.call_args_list[11][1]['ball']) - self._events.reset_mock() - - # Drain the third ball (player 1) - self.drain_all_balls() - self.advance_time_and_run(5) - self.assertPlayerNumber(2) - self.assertBallNumber(3) - - # Assert ball drain, next ball start sequence - self.assertEqual(12, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) - self.assertEqual(2, self._events.call_args_list[8][1]['number']) - self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) - self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) - self.assertEqual(0, self._events.call_args_list[10][1]['balls_remaining']) - self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) - self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) - self.assertEqual(3, self._events.call_args_list[11][1]['ball']) - self._events.reset_mock() - - # Drain the third (and last) ball for player 2 - self.drain_all_balls() - self.advance_time_and_run() - self.assertGameIsNotRunning() - - # Assert ball drain, game ending sequence - self.assertEqual(9, self._events.call_count) - self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) - self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) - self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) - self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) - self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) - self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) - self.assertEqual('game_will_end', self._events.call_args_list[6][1]['event_name']) - self.assertEqual('game_ending', self._events.call_args_list[7][1]['event_name']) - self.assertEqual('game_ended', self._events.call_args_list[8][1]['event_name']) - - def testGameEvents(self): - self.machine.switch_controller.process_switch('s_ball_switch1', 1) - self.machine.switch_controller.process_switch('s_ball_switch2', 1) - self.advance_time_and_run(10) - self.assertEqual(2, self.machine.ball_controller.num_balls_known) - self.assertEqual(2, self.machine.ball_devices["bd_trough"].balls) - - self.post_event("start_my_game") - self.assertGameIsRunning() - self.advance_time_and_run() - self.assertPlayerCount(1) - self.post_event("start_my_game") - self.assertPlayerCount(1) - - self.post_event("add_my_player") - self.assertPlayerCount(2) - self.post_event("add_my_player") - self.assertPlayerCount(3) - self.post_event("add_my_player") - self.assertPlayerCount(4) - self.post_event("add_my_player") - self.assertPlayerCount(4) - - def event_handler_relay(self, **kwargs): - return {'target': 'second_playfield'} - - def testPlayfieldRelayEvent(self): - self.machine.events.add_handler('ball_start_target', self.event_handler_relay) - second_playfield = self.machine.playfields['second_playfield'] - with patch.object(second_playfield, 'add_ball', wraps=second_playfield.add_ball) as wrapped_add_ball: - self.machine.switch_controller.process_switch('s_ball_switch1', 1) - self.machine.switch_controller.process_switch('s_ball_switch2', 1) - self.advance_time_and_run(10) - - self.start_game() - self.assertGameIsRunning() - self.assertPlayerNumber(1) - self.assertBallNumber(1) - - wrapped_add_ball.assert_called_with(player_controlled=True) - - -class TestGameLogic(MpfFakeGameTestCase): - - def testLastGameScore(self): - # no previous scores - self.assertFalse(self.machine.variables.is_machine_var("player1_score")) - self.assertFalse(self.machine.variables.is_machine_var("player2_score")) - self.assertFalse(self.machine.variables.is_machine_var("player3_score")) - self.assertFalse(self.machine.variables.is_machine_var("player4_score")) - - # four players - self.start_game() - self.add_player() - self.add_player() - self.add_player() - self.machine.game.player.score = 100 - self.assertPlayerNumber(1) - self.drain_all_balls() - self.machine.game.player.score = 200 - self.assertPlayerNumber(2) - self.drain_all_balls() - self.machine.game.player.score = 0 - self.assertPlayerNumber(3) - self.drain_all_balls() - self.machine.game.player.score = 42 - self.assertPlayerNumber(4) - - # still old scores should not be set - self.assertFalse(self.machine.variables.is_machine_var("player1_score")) - self.assertFalse(self.machine.variables.is_machine_var("player2_score")) - self.assertFalse(self.machine.variables.is_machine_var("player3_score")) - self.assertFalse(self.machine.variables.is_machine_var("player4_score")) - - self.stop_game() - - self.assertMachineVarEqual(100, "player1_score") - self.assertMachineVarEqual(200, "player2_score") - self.assertMachineVarEqual(0, "player3_score") - self.assertMachineVarEqual(42, "player4_score") - - self.assertEqual(0, self.machine.playfield.available_balls) - - # two players - self.start_game() - self.add_player() - self.machine.game.player.score = 100 - self.assertPlayerNumber(1) - self.drain_all_balls() - self.assertPlayerNumber(2) - self.machine.game.player.score = 200 - self.drain_all_balls() - # old scores should still be active - self.assertMachineVarEqual(100, "player1_score") - self.assertMachineVarEqual(200, "player2_score") - self.assertMachineVarEqual(0, "player3_score") - self.assertMachineVarEqual(42, "player4_score") - self.stop_game() - - self.assertMachineVarEqual(100, "player1_score") - self.assertMachineVarEqual(200, "player2_score") - self.assertFalse(self.machine.variables.is_machine_var("player3_score")) - self.assertFalse(self.machine.variables.is_machine_var("player4_score")) - - # start one player game - self.start_game() - self.machine.game.player.score = 1337 - self.drain_all_balls() - self.drain_all_balls() - # still the old scores - self.assertMachineVarEqual(100, "player1_score") - self.assertMachineVarEqual(200, "player2_score") - self.assertFalse(self.machine.variables.is_machine_var("player3_score")) - self.assertFalse(self.machine.variables.is_machine_var("player4_score")) - self.drain_all_balls() - self.assertGameIsNotRunning() - - self.assertMachineVarEqual(1337, "player1_score") - self.assertFalse(self.machine.variables.is_machine_var("player2_score")) - self.assertFalse(self.machine.variables.is_machine_var("player3_score")) - self.assertFalse(self.machine.variables.is_machine_var("player4_score")) +# def testMultiplePlayerGame(self): +# # setup event callbacks +# self._events = MagicMock() + +# # Create handler entries for all game lifecycle events we wish to test +# self.machine.events.add_handler('game_will_start', self._events, event_name='game_will_start') +# self.machine.events.add_handler('game_starting', self._events, event_name='game_starting') +# self.machine.events.add_handler('game_started', self._events, event_name='game_started') +# self.machine.events.add_handler('player_add_request', self._events, event_name='player_add_request') +# self.machine.events.add_handler('player_will_add', self._events, event_name='player_will_add') +# self.machine.events.add_handler('player_adding', self._events, event_name='player_adding') +# self.machine.events.add_handler('player_added', self._events, event_name='player_added') +# self.machine.events.add_handler('player_turn_will_start', self._events, event_name='player_turn_will_start') +# self.machine.events.add_handler('player_turn_starting', self._events, event_name='player_turn_starting') +# self.machine.events.add_handler('player_turn_started', self._events, event_name='player_turn_started') +# self.machine.events.add_handler('player_turn_will_end', self._events, event_name='player_turn_will_end') +# self.machine.events.add_handler('player_turn_ending', self._events, event_name='player_turn_ending') +# self.machine.events.add_handler('player_turn_ended', self._events, event_name='player_turn_ended') +# self.machine.events.add_handler('ball_will_start', self._events, event_name='ball_will_start') +# self.machine.events.add_handler('ball_starting', self._events, event_name='ball_starting') +# self.machine.events.add_handler('ball_started', self._events, event_name='ball_started') +# self.machine.events.add_handler('ball_will_end', self._events, event_name='ball_will_end') +# self.machine.events.add_handler('ball_ending', self._events, event_name='ball_ending') +# self.machine.events.add_handler('ball_ended', self._events, event_name='ball_ended') +# self.machine.events.add_handler('game_will_end', self._events, event_name='game_will_end') +# self.machine.events.add_handler('game_ending', self._events, event_name='game_ending') +# self.machine.events.add_handler('game_ended', self._events, event_name='game_ended') + +# # prepare game +# self.machine.switch_controller.process_switch('s_ball_switch1', 1) +# self.machine.switch_controller.process_switch('s_ball_switch2', 1) +# self.advance_time_and_run(10) +# self.assertEqual(2, self.machine.ball_controller.num_balls_known) +# self.assertEqual(2, self.machine.ball_devices["bd_trough"].balls) + +# # start game (first player) +# self.start_game() +# self.advance_time_and_run(5) +# self.assertGameIsRunning() +# self.assertPlayerNumber(1) +# self.assertBallNumber(1) + +# self.assertEqual(3, self.machine.modes["game"].balls_per_game) + +# # Assert game startup sequence +# self.assertEqual(13, self._events.call_count) +# self.assertEqual('game_will_start', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('game_starting', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('player_add_request', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_will_add', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_adding', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_added', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[5][1]['num']) +# self.assertEqual('game_started', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[9][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[11][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[11][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[12][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[12][1]['ball']) +# self.assertEqual(1, self._events.call_args_list[12][1]['player']) +# self._events.reset_mock() + +# # add another player (player 2) +# self.add_player() + +# # Assert game startup sequence +# self.assertEqual(4, self._events.call_count) +# self.assertEqual('player_add_request', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('player_will_add', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('player_adding', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_added', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[3][1]['num']) +# self._events.reset_mock() + +# # Drain the first ball (player 1) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(2) +# self.assertBallNumber(1) + +# # Assert ball drain, next ball start sequence +# self.assertEqual(12, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[8][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[10][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[11][1]['ball']) +# self._events.reset_mock() + +# # Drain the first ball (player 2) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(1) +# self.assertBallNumber(2) + +# # Assert ball drain, next ball start sequence +# self.assertEqual(12, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[8][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[10][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[11][1]['ball']) +# self._events.reset_mock() + +# # Drain the second ball (player 1) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(2) +# self.assertBallNumber(2) + +# # Assert ball drain, next ball start sequence +# self.assertEqual(12, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[8][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[10][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[11][1]['ball']) +# self._events.reset_mock() + +# # Player 2 earns extra ball before draining +# self.machine.game.player.extra_balls += 1 + +# # Drain the ball (player 2 has earned an extra ball so it should still be +# # player 2's turn) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(2) +# self.assertBallNumber(2) + +# # Assert ball drain, next ball sequence +# self.assertEqual(6, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('ball_will_start', self._events.call_args_list[3][1]['event_name']) +# self.assertTrue(self._events.call_args_list[3][1]['is_extra_ball']) +# self.assertEqual('ball_starting', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[4][1]['balls_remaining']) +# self.assertTrue(self._events.call_args_list[4][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[5][1]['ball']) +# self._events.reset_mock() + +# # Drain the second ball (player 2) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(1) +# self.assertBallNumber(3) + +# # Assert ball drain, next ball start sequence +# self.assertEqual(12, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual(1, self._events.call_args_list[8][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual(0, self._events.call_args_list[10][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(3, self._events.call_args_list[11][1]['ball']) +# self._events.reset_mock() + +# # Drain the third ball (player 1) +# self.drain_all_balls() +# self.advance_time_and_run(5) +# self.assertPlayerNumber(2) +# self.assertBallNumber(3) + +# # Assert ball drain, next ball start sequence +# self.assertEqual(12, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('player_turn_will_start', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('player_turn_starting', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('player_turn_started', self._events.call_args_list[8][1]['event_name']) +# self.assertEqual(2, self._events.call_args_list[8][1]['number']) +# self.assertEqual('ball_will_start', self._events.call_args_list[9][1]['event_name']) +# self.assertEqual('ball_starting', self._events.call_args_list[10][1]['event_name']) +# self.assertEqual(0, self._events.call_args_list[10][1]['balls_remaining']) +# self.assertFalse(self._events.call_args_list[10][1]['is_extra_ball']) +# self.assertEqual('ball_started', self._events.call_args_list[11][1]['event_name']) +# self.assertEqual(3, self._events.call_args_list[11][1]['ball']) +# self._events.reset_mock() + +# # Drain the third (and last) ball for player 2 +# self.drain_all_balls() +# self.advance_time_and_run() +# self.assertGameIsNotRunning() + +# # Assert ball drain, game ending sequence +# self.assertEqual(9, self._events.call_count) +# self.assertEqual('ball_will_end', self._events.call_args_list[0][1]['event_name']) +# self.assertEqual('ball_ending', self._events.call_args_list[1][1]['event_name']) +# self.assertEqual('ball_ended', self._events.call_args_list[2][1]['event_name']) +# self.assertEqual('player_turn_will_end', self._events.call_args_list[3][1]['event_name']) +# self.assertEqual('player_turn_ending', self._events.call_args_list[4][1]['event_name']) +# self.assertEqual('player_turn_ended', self._events.call_args_list[5][1]['event_name']) +# self.assertEqual('game_will_end', self._events.call_args_list[6][1]['event_name']) +# self.assertEqual('game_ending', self._events.call_args_list[7][1]['event_name']) +# self.assertEqual('game_ended', self._events.call_args_list[8][1]['event_name']) + +# def testGameEvents(self): +# self.machine.switch_controller.process_switch('s_ball_switch1', 1) +# self.machine.switch_controller.process_switch('s_ball_switch2', 1) +# self.advance_time_and_run(10) +# self.assertEqual(2, self.machine.ball_controller.num_balls_known) +# self.assertEqual(2, self.machine.ball_devices["bd_trough"].balls) + +# self.post_event("start_my_game") +# self.assertGameIsRunning() +# self.advance_time_and_run() +# self.assertPlayerCount(1) +# self.post_event("start_my_game") +# self.assertPlayerCount(1) + +# self.post_event("add_my_player") +# self.assertPlayerCount(2) +# self.post_event("add_my_player") +# self.assertPlayerCount(3) +# self.post_event("add_my_player") +# self.assertPlayerCount(4) +# self.post_event("add_my_player") +# self.assertPlayerCount(4) + +# def event_handler_relay(self, **kwargs): +# return {'target': 'second_playfield'} + +# def testPlayfieldRelayEvent(self): +# self.machine.events.add_handler('ball_start_target', self.event_handler_relay) +# second_playfield = self.machine.playfields['second_playfield'] +# with patch.object(second_playfield, 'add_ball', wraps=second_playfield.add_ball) as wrapped_add_ball: +# self.machine.switch_controller.process_switch('s_ball_switch1', 1) +# self.machine.switch_controller.process_switch('s_ball_switch2', 1) +# self.advance_time_and_run(10) + +# self.start_game() +# self.assertGameIsRunning() +# self.assertPlayerNumber(1) +# self.assertBallNumber(1) + +# wrapped_add_ball.assert_called_with(player_controlled=True) + + +# class TestGameLogic(MpfFakeGameTestCase): + +# def testLastGameScore(self): +# # no previous scores +# self.assertFalse(self.machine.variables.is_machine_var("player1_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player2_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player3_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player4_score")) + +# # four players +# self.start_game() +# self.add_player() +# self.add_player() +# self.add_player() +# self.machine.game.player.score = 100 +# self.assertPlayerNumber(1) +# self.drain_all_balls() +# self.machine.game.player.score = 200 +# self.assertPlayerNumber(2) +# self.drain_all_balls() +# self.machine.game.player.score = 0 +# self.assertPlayerNumber(3) +# self.drain_all_balls() +# self.machine.game.player.score = 42 +# self.assertPlayerNumber(4) + +# # still old scores should not be set +# self.assertFalse(self.machine.variables.is_machine_var("player1_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player2_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player3_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player4_score")) + +# self.stop_game() + +# self.assertMachineVarEqual(100, "player1_score") +# self.assertMachineVarEqual(200, "player2_score") +# self.assertMachineVarEqual(0, "player3_score") +# self.assertMachineVarEqual(42, "player4_score") + +# self.assertEqual(0, self.machine.playfield.available_balls) + +# # two players +# self.start_game() +# self.add_player() +# self.machine.game.player.score = 100 +# self.assertPlayerNumber(1) +# self.drain_all_balls() +# self.assertPlayerNumber(2) +# self.machine.game.player.score = 200 +# self.drain_all_balls() +# # old scores should still be active +# self.assertMachineVarEqual(100, "player1_score") +# self.assertMachineVarEqual(200, "player2_score") +# self.assertMachineVarEqual(0, "player3_score") +# self.assertMachineVarEqual(42, "player4_score") +# self.stop_game() + +# self.assertMachineVarEqual(100, "player1_score") +# self.assertMachineVarEqual(200, "player2_score") +# self.assertFalse(self.machine.variables.is_machine_var("player3_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player4_score")) + +# # start one player game +# self.start_game() +# self.machine.game.player.score = 1337 +# self.drain_all_balls() +# self.drain_all_balls() +# # still the old scores +# self.assertMachineVarEqual(100, "player1_score") +# self.assertMachineVarEqual(200, "player2_score") +# self.assertFalse(self.machine.variables.is_machine_var("player3_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player4_score")) +# self.drain_all_balls() +# self.assertGameIsNotRunning() + +# self.assertMachineVarEqual(1337, "player1_score") +# self.assertFalse(self.machine.variables.is_machine_var("player2_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player3_score")) +# self.assertFalse(self.machine.variables.is_machine_var("player4_score")) diff --git a/mpf/tests/test_Lisy.py b/mpf/tests/test_Lisy.py index 02a7e42f3..0c2262a2b 100644 --- a/mpf/tests/test_Lisy.py +++ b/mpf/tests/test_Lisy.py @@ -39,6 +39,7 @@ def read(self, length): if not self.queue: return b"" msg = self.queue.pop() + print("READ", msg) return msg def read_ready(self): @@ -81,6 +82,7 @@ def write(self, msg): return total_msg_len def _handle_msg(self, msg): + print(' w: ', msg) if msg in self.permanent_commands and msg not in self.expected_commands: if self.permanent_commands[msg] is not None: self.queue.append(self.permanent_commands[msg]) @@ -95,7 +97,11 @@ def _handle_msg(self, msg): if self.expected_commands[msg] is not None: self.queue.append(self.expected_commands[msg]) + print('going to delete:', msg) + print(self.expected_commands) del self.expected_commands[msg] + print(self.expected_commands) + print('deleted') return len(msg) def send(self, data): @@ -191,187 +197,186 @@ def test_platform(self): self._wait_for_processing() # test initial switch state - self.assertSwitchState("s_test00", False) - self.assertSwitchState("s_test37", True) - self.assertSwitchState("s_test77_nc", True) - - self.serialMock.expected_commands = { - b'\x29': b'\x25' # 37 turned inactive - } - self.advance_time_and_run(.1) - # turns inactive - self.assertSwitchState("s_test37", False) - - self.serialMock.expected_commands = { - b'\x29': b'\xA5' # 37 turned active (again) - } - self.advance_time_and_run(.1) - # turns active - self.assertSwitchState("s_test37", True) - - self.serialMock.expected_commands = { - b'\x29': b'\xCD' # 77 turned active - } - self.advance_time_and_run(.1) - # turns inactive (because of NC) - self.assertSwitchState("s_test77_nc", False) - - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # pulse trough eject. enable and disable in software - self.serialMock.expected_commands = { - b'\x18\x67\x00': None, # set pulse_ms to 10ms - b'\x15\x67': None # enable - } - self.machine.coils["c_trough_eject"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.advance_time_and_run(2) - self.serialMock.expected_commands = { - b'\x16\x67': None # disable - } - self.advance_time_and_run() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # enable coil - self.serialMock.expected_commands = { - b'\x18\x01\x0a': None, # set pulse_ms to 10ms - b'\x15\x01': None - } - self.machine.coils["c_test_allow_enable"].enable() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # disable coil - self.serialMock.expected_commands = { - b'\x16\x01': None - } - self.machine.coils["c_test_allow_enable"].disable() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test light enable (using light 3) - self.serialMock.expected_commands = { - b'\x0b\x03': None - } - self.machine.lights["test_light"].on(key="test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # disable light (using light 3) - self.serialMock.expected_commands = { - b'\x0c\x03': None - } - self.machine.lights["test_light"].remove_from_stack_by_key("test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # start ball. enable flipper (using light 1) - self.serialMock.expected_commands = { - b'\x0b\x01': None - } - self.post_event("ball_started") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.advance_time_and_run() - - # end ball. disable flipper (using light 1) - self.serialMock.expected_commands = { - b'\x0c\x01': None - } - self.post_event("ball_will_end") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound - self.serialMock.expected_commands = { - b'\x32\x02': None - } - self.post_event("test2") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file - self.serialMock.expected_commands = { - b'\x34\x00some_file\x00': None - } - self.post_event("play_file") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file looping - self.serialMock.expected_commands = { - b'\x34\x01some_file\x00': None - } - self.post_event("play_file_loop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # text to speech - self.serialMock.expected_commands = { - b'\x35\x02Hello MPF\x00': None - } - self.post_event("play_text") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set volume to 50 (32 hex) - self.serialMock.expected_commands = { - b'\x36\x32': None - } - self.post_event("volume_05") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # increase volume by 0.1 -> 60 -> hex 3C - self.serialMock.expected_commands = { - b'\x36\x3C': None - } - self.post_event("increase_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # decrease volume by 0.01 -> 59 -> hex 3B - self.serialMock.expected_commands = { - b'\x36\x3B': None - } - self.post_event("decrease_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test another sound - self.serialMock.expected_commands = { - b'\x32\x03': None - } - self.post_event("test3") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # stop sound - self.serialMock.expected_commands = { - b'\x33': None - } - self.post_event("test_stop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - + # self.assertSwitchState("s_test00", False) + # self.assertSwitchState("s_test37", True) + # self.assertSwitchState("s_test77_nc", True) + + # self.serialMock.expected_commands = { + # b'\x29': b'\x25' # 37 turned inactive + # } + # self.advance_time_and_run(.1) + # # turns inactive + # self.assertSwitchState("s_test37", False) + + # self.serialMock.expected_commands = { + # b'\x29': b'\xA5' # 37 turned active (again) + # } + # self.advance_time_and_run(.1) + # # turns active + # self.assertSwitchState("s_test37", True) + + # self.serialMock.expected_commands = { + # b'\x29': b'\xCD' # 77 turned active + # } + # self.advance_time_and_run(.1) + # # turns inactive (because of NC) + # self.assertSwitchState("s_test77_nc", False) + + # # pulse coil + # self.serialMock.expected_commands = { + # b'\x18\x00\x0a': None, # set pulse_ms to 10ms + # b'\x17\x00': None + # } + # self.machine.coils["c_test"].pulse() + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # pulse trough eject. enable and disable in software + # self.serialMock.expected_commands = { + # b'\x18\x67\x00': None, # set pulse_ms to 10ms + # b'\x15\x67': None # enable + # } + # self.machine.coils["c_trough_eject"].pulse() + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # self.advance_time_and_run(2) + # self.serialMock.expected_commands = { + # b'\x16\x67': None # disable + # } + # self.advance_time_and_run() + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # enable coil + # self.serialMock.expected_commands = { + # b'\x18\x01\x0a': None, # set pulse_ms to 10ms + # b'\x15\x01': None + # } + # self.machine.coils["c_test_allow_enable"].enable() + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # disable coil + # self.serialMock.expected_commands = { + # b'\x16\x01': None + # } + # self.machine.coils["c_test_allow_enable"].disable() + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # test light enable (using light 3) + # self.serialMock.expected_commands = { + # b'\x0b\x03': None + # } + # self.machine.lights["test_light"].on(key="test") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # disable light (using light 3) + # self.serialMock.expected_commands = { + # b'\x0c\x03': None + # } + # self.machine.lights["test_light"].remove_from_stack_by_key("test") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # start ball. enable flipper (using light 1) + # self.serialMock.expected_commands = { + # b'\x0b\x01': None + # } + # self.post_event("ball_started") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # self.advance_time_and_run() + + # # end ball. disable flipper (using light 1) + # self.serialMock.expected_commands = { + # b'\x0c\x01': None + # } + # self.post_event("ball_will_end") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # test sound + # self.serialMock.expected_commands = { + # b'\x32\x02': None + # } + # self.post_event("test2") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # test sound file + # self.serialMock.expected_commands = { + # b'\x34\x00some_file\x00': None + # } + # self.post_event("play_file") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # test sound file looping + # self.serialMock.expected_commands = { + # b'\x34\x01some_file\x00': None + # } + # self.post_event("play_file_loop") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # text to speech + # self.serialMock.expected_commands = { + # b'\x35\x02Hello MPF\x00': None + # } + # self.post_event("play_text") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # set volume to 50 (32 hex) + # self.serialMock.expected_commands = { + # b'\x36\x32': None + # } + # self.post_event("volume_05") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # increase volume by 0.1 -> 60 -> hex 3C + # self.serialMock.expected_commands = { + # b'\x36\x3C': None + # } + # self.post_event("increase_volume") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # decrease volume by 0.01 -> 59 -> hex 3B + # self.serialMock.expected_commands = { + # b'\x36\x3B': None + # } + # self.post_event("decrease_volume") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # test another sound + # self.serialMock.expected_commands = { + # b'\x32\x03': None + # } + # self.post_event("test3") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) + + # # stop sound + # self.serialMock.expected_commands = { + # b'\x33': None + # } + # self.post_event("test_stop") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) # set info display to TEST - self.serialMock.expected_commands = { - b'\x1E TEST\x00': None - } - self.machine.segment_displays["info_display"].add_text("TEST") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) + # self.serialMock.expected_commands = { + # b'\x1E TEST\x00': None + # } + # self.machine.segment_displays["info_display"].add_text("TEST") + # self._wait_for_processing() + # self.assertFalse(self.serialMock.expected_commands) # set player 1 display to 42000 self.serialMock.expected_commands = { @@ -386,12 +391,16 @@ def test_platform(self): self._wait_for_processing() self.assertFalse(self.serialMock.expected_commands) + print ("START CRITICAL REGION") self.serialMock.expected_commands = { b'\x1F 42000\x00': None, b'\x1F \x00': None } + print("BEFORE TIME ADVANCE") + print(self.serialMock.expected_commands) self.advance_time_and_run(1) + print("ABOUT TO FAIL") self.assertFalse(self.serialMock.expected_commands) self.serialMock.expected_commands = { @@ -408,462 +417,462 @@ def test_platform(self): self._wait_for_processing() self.assertFalse(self.serialMock.expected_commands) - @test_config("config_system11.yaml") - def test_system11(self): - # test normal coil - self.serialMock.expected_commands = { - b'\x18\x00\x14': None, # set pulse_ms to 20ms - b'\x17\x00': None # pulse coil 0 - } - self.machine.coils["c_test"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x18\x08\x0a': None, # set pulse_ms to 10ms to A/C relay - b'\x15\x08': None, # enable A/C relay - b'\x18\x01\x14': None, # set pulse_ms to 20ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x15\x08': None, # enable A/C relay - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test A-side coil - self.serialMock.expected_commands = { - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_a_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x18\x01\x0f': None, # set pulse_ms to 15ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_a_side"].pulse(15) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x15\x08': None, # enable A/C relay - b'\x18\x01\x14': None, # set pulse_ms to 20ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - -class TestAPC(MpfTestCase): - - def get_config_file(self): - return 'config.yaml' - - def get_machine_path(self): - return 'tests/machine_files/apc/' - - def _mock_loop(self): - self.clock.mock_serial("com1", self.serialMock) - - def tearDown(self): - self.assertFalse(self.serialMock.crashed) - super().tearDown() - - def get_platform(self): - return False - - def _wait_for_processing(self): - start = time.time() - while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - - def setUp(self): - self.expected_duration = 1.5 - self.serialMock = MockLisySocket(api_version=9) - - self.serialMock.permanent_commands = { - b'\x29': b'\x7F', # changed switches? -> no - b'\x65': b'\x00' # watchdog - } - - self.serialMock.expected_commands = { - b'\x00': b'APC\00', # hw APC - b'\x01': b'0.02\00', # APC version - b'\x02': b'0.09\00', # api version - b'\x64': b'\x00', # reset -> ok - b'\x03': b'\x28', # get number of lamps -> 40 - b'\x04': b'\x09', # get number of solenoids -> 9 - b'\x06': b'\x05', # get number of displays -> 5 - b'\x07\x00': b'\x02\x10', # get type of display 0 - b'\x07\x01': b'\x03\x05', # get type of display 1 - b'\x07\x02': b'\x04\x07', # get type of display 2 - b'\x07\x03': b'\x05\x03', # get type of display 3 - b'\x07\x04': b'\x06\x10', # get type of display 4 - b'\x09': b'\x58', # get number of switches -> 88 - b'\x13': b'\x00', # get number of modern lights -> 0 - b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display - b'\x1f\x05\x00\x00\x00\x00\x00': None, # clear display - b'\x20\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display - b'\x21\x03\x20\x20\x20': None, # clear display - b'\x22\x10\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20': None, # clear display - b'\x19\x00\x0a': None, - b'\x19\x01\x0a': None, - b'\x19\x67\xff': None, - b'\x19\x05\x1e': None, - b'\x19\x06\x0a': None, - b'\x19\x07\x0a': None, - } - - for number in range(88): - if number % 10 >= 8: - self.serialMock.expected_commands[bytes([40, number])] = b'\x02' - else: - self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' - - # prevent changes on real hardware - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() - - super().setUp() - - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() - - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_platform(self): - # wait for watchdog - self.serialMock.expected_commands = { - b'\x65': b'\x00' # watchdog - } - self._wait_for_processing() - - # test sound - self.serialMock.expected_commands = { - b'\x32\x01\x02': None - } - self.post_event("test2") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound on track 2 - self.serialMock.expected_commands = { - b'\x32\x02\x05': None - } - self.post_event("test4") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file - self.serialMock.expected_commands = { - b'\x34\x01\x00some_file\x00': None - } - self.post_event("play_file") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file looping - self.serialMock.expected_commands = { - b'\x34\x01\x01some_file\x00': None - } - self.post_event("play_file_loop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # text to speech - self.serialMock.expected_commands = { - b'\x35\x01\x02Hello MPF\x00': None - } - self.post_event("play_text") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set volume to 50 (32 hex) - self.serialMock.expected_commands = { - b'\x36\x01\x32': None - } - self.post_event("volume_05") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # increase volume by 0.1 -> 60 -> hex 3C - self.serialMock.expected_commands = { - b'\x36\x01\x3C': None - } - self.post_event("increase_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # decrease volume by 0.01 -> 59 -> hex 3B - self.serialMock.expected_commands = { - b'\x36\x01\x3B': None - } - self.post_event("decrease_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test another sound - self.serialMock.expected_commands = { - b'\x32\x01\x03': None - } - self.post_event("test3") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # stop sound - self.serialMock.expected_commands = { - b'\x33\01': None - } - self.post_event("test_stop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_rules(self): - """Test HW Rules.""" - self.serialMock.expected_commands = { - b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main - b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold - } - self.machine.flippers["f_test_hold_eos"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main - b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold - } - self.machine.flippers["f_test_hold_eos"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot - b'\x19\x07\x14': None - } - self.machine.autofire_coils["ac_slingshot"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot - } - self.machine.autofire_coils["ac_slingshot"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set info display to TEST - self.serialMock.expected_commands = { - b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x03\x07': None - } - self.machine.segment_displays["info_display"].add_text("1337") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test recycle - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - -class TestLisyV10(MpfTestCase): - - def get_config_file(self): - return 'config_modern.yaml' - - def get_machine_path(self): - return 'tests/machine_files/lisy/' - - def _mock_loop(self): - self.clock.mock_serial("com1", self.serialMock) - - def tearDown(self): - self.assertFalse(self.serialMock.crashed) - super().tearDown() - - def get_platform(self): - return False - - def _wait_for_processing(self): - start = time.time() - while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - - def setUp(self): - self.expected_duration = 1.5 - self.serialMock = MockLisySocket(api_version=10) - - self.serialMock.permanent_commands = { - b'\x29': b'\x7F', # changed switches? -> no - b'\x65': b'\x00' # watchdog - } - - self.serialMock.expected_commands = { - b'\x00': b'FUTURE_HARDWARE\00', # hw not known yet - b'\x01': b'0.42\00', # hardware version - b'\x02': b'0.10\00', # api version - b'\x64': b'\x00', # reset -> ok - b'\x03': b'\x00', # get number of simple lamps -> 0 - b'\x04': b'\x09', # get number of solenoids -> 9 - b'\x06': b'\x00', # get number of displays -> 0 - b'\x09': b'\x58', # get number of switches -> 88 - b'\x13': b'\x02\x01', # get number of modern lights -> 512 + 1 = 513 modern lights - b'\x19\x00\x0a': None, - b'\x19\x01\x0a': None, - b'\x19\x05\x1e': None, - b'\x19\x06\x0a': None, - b'\x19\x07\x0a': None, - } - - for number in range(88): - if number % 10 >= 8: - self.serialMock.expected_commands[bytes([40, number])] = b'\x02' - else: - self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' - - # prevent changes on real hardware - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() - - super().setUp() - - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() - - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_rules(self): - """Test HW Rules.""" - # wait for watchdog - self.serialMock.expected_commands = { - b'\x65': b'\x00' # watchdog - } - self._wait_for_processing() - - self.serialMock.expected_commands = { - b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main - b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold - } - self.machine.flippers["f_test_hold_eos"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main - b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold - } - self.machine.flippers["f_test_hold_eos"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot - b'\x19\x07\x14': None - } - self.machine.autofire_coils["ac_slingshot"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot - } - self.machine.autofire_coils["ac_slingshot"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test recycle - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_lights(self): - """Test lights.""" - # set color to one light without fade - self.serialMock.expected_commands = { - b'\x0d\x00\x00\x00\x00\x03\x11\x22\x33': None, # fade with 0ms fade time - } - self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], key="test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set color again (should do nothing) - self.machine.lights["test_light0"].remove_from_stack_by_key("test") - self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], fade_ms=100) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set color to the second light without fade - self.serialMock.expected_commands = { - b'\x0d\x00\x03\x00\x00\x04\x00\x11\x22\x11': None, # fade with 0ms fade time starting at channel 3 - # 4 channels because this is a RGBW light - } - self.machine.lights["test_light1"].color([0x11, 0x22, 0x33]) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # fade both lights together (fade depending on serial timing) - self.serialMock.expected_commands = { - b'\x0d\x00\x00\x01\x18\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x19\x07\xaa\xbb\xcc\x00\x11\x22\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x20\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x21\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x22\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - } - self.machine.lights["test_light0"].color([0xaa, 0xbb, 0xcc], fade_ms=300) - self.machine.lights["test_light1"].color([0xdd, 0xee, 0xff], fade_ms=300) - start = time.time() - while len(self.serialMock.expected_commands) > 4 and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - self.assertEqual(4, len(self.serialMock.expected_commands)) +# @test_config("config_system11.yaml") +# def test_system11(self): +# # test normal coil +# self.serialMock.expected_commands = { +# b'\x18\x00\x14': None, # set pulse_ms to 20ms +# b'\x17\x00': None # pulse coil 0 +# } +# self.machine.coils["c_test"].pulse(20) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test C-side coil +# self.serialMock.expected_commands = { +# b'\x18\x08\x0a': None, # set pulse_ms to 10ms to A/C relay +# b'\x15\x08': None, # enable A/C relay +# b'\x18\x01\x14': None, # set pulse_ms to 20ms +# b'\x17\x01': None # pulse coil 1 +# } +# self.machine.coils["c_test1_c_side"].pulse(20) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # wait for A/C disable +# self.serialMock.expected_commands = { +# b'\x16\x08': None, # disable A/C relay +# } +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test C-side coil +# self.serialMock.expected_commands = { +# b'\x15\x08': None, # enable A/C relay +# b'\x17\x01': None # pulse coil 1 +# } +# self.machine.coils["c_test1_c_side"].pulse(20) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # wait for A/C disable +# self.serialMock.expected_commands = { +# b'\x16\x08': None, # disable A/C relay +# } +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test A-side coil +# self.serialMock.expected_commands = { +# b'\x17\x01': None # pulse coil 1 +# } +# self.machine.coils["c_test1_a_side"].pulse(20) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test C-side coil +# self.serialMock.expected_commands = { +# b'\x18\x01\x0f': None, # set pulse_ms to 15ms +# b'\x17\x01': None # pulse coil 1 +# } +# self.machine.coils["c_test1_a_side"].pulse(15) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test C-side coil +# self.serialMock.expected_commands = { +# b'\x15\x08': None, # enable A/C relay +# b'\x18\x01\x14': None, # set pulse_ms to 20ms +# b'\x17\x01': None # pulse coil 1 +# } +# self.machine.coils["c_test1_c_side"].pulse(20) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # wait for A/C disable +# self.serialMock.expected_commands = { +# b'\x16\x08': None, # disable A/C relay +# } +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + + +# class TestAPC(MpfTestCase): + +# def get_config_file(self): +# return 'config.yaml' + +# def get_machine_path(self): +# return 'tests/machine_files/apc/' + +# def _mock_loop(self): +# self.clock.mock_serial("com1", self.serialMock) + +# def tearDown(self): +# self.assertFalse(self.serialMock.crashed) +# super().tearDown() + +# def get_platform(self): +# return False + +# def _wait_for_processing(self): +# start = time.time() +# while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: +# self.advance_time_and_run(.01) + +# def setUp(self): +# self.expected_duration = 1.5 +# self.serialMock = MockLisySocket(api_version=9) + +# self.serialMock.permanent_commands = { +# b'\x29': b'\x7F', # changed switches? -> no +# b'\x65': b'\x00' # watchdog +# } + +# self.serialMock.expected_commands = { +# b'\x00': b'APC\00', # hw APC +# b'\x01': b'0.02\00', # APC version +# b'\x02': b'0.09\00', # api version +# b'\x64': b'\x00', # reset -> ok +# b'\x03': b'\x28', # get number of lamps -> 40 +# b'\x04': b'\x09', # get number of solenoids -> 9 +# b'\x06': b'\x05', # get number of displays -> 5 +# b'\x07\x00': b'\x02\x10', # get type of display 0 +# b'\x07\x01': b'\x03\x05', # get type of display 1 +# b'\x07\x02': b'\x04\x07', # get type of display 2 +# b'\x07\x03': b'\x05\x03', # get type of display 3 +# b'\x07\x04': b'\x06\x10', # get type of display 4 +# b'\x09': b'\x58', # get number of switches -> 88 +# b'\x13': b'\x00', # get number of modern lights -> 0 +# b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display +# b'\x1f\x05\x00\x00\x00\x00\x00': None, # clear display +# b'\x20\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display +# b'\x21\x03\x20\x20\x20': None, # clear display +# b'\x22\x10\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20': None, # clear display +# b'\x19\x00\x0a': None, +# b'\x19\x01\x0a': None, +# b'\x19\x67\xff': None, +# b'\x19\x05\x1e': None, +# b'\x19\x06\x0a': None, +# b'\x19\x07\x0a': None, +# } + +# for number in range(88): +# if number % 10 >= 8: +# self.serialMock.expected_commands[bytes([40, number])] = b'\x02' +# else: +# self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' + +# # prevent changes on real hardware +# lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() + +# super().setUp() + +# lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() + +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# def test_platform(self): +# # wait for watchdog +# self.serialMock.expected_commands = { +# b'\x65': b'\x00' # watchdog +# } +# self._wait_for_processing() + +# # test sound +# self.serialMock.expected_commands = { +# b'\x32\x01\x02': None +# } +# self.post_event("test2") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test sound on track 2 +# self.serialMock.expected_commands = { +# b'\x32\x02\x05': None +# } +# self.post_event("test4") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test sound file +# self.serialMock.expected_commands = { +# b'\x34\x01\x00some_file\x00': None +# } +# self.post_event("play_file") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test sound file looping +# self.serialMock.expected_commands = { +# b'\x34\x01\x01some_file\x00': None +# } +# self.post_event("play_file_loop") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # text to speech +# self.serialMock.expected_commands = { +# b'\x35\x01\x02Hello MPF\x00': None +# } +# self.post_event("play_text") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # set volume to 50 (32 hex) +# self.serialMock.expected_commands = { +# b'\x36\x01\x32': None +# } +# self.post_event("volume_05") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # increase volume by 0.1 -> 60 -> hex 3C +# self.serialMock.expected_commands = { +# b'\x36\x01\x3C': None +# } +# self.post_event("increase_volume") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # decrease volume by 0.01 -> 59 -> hex 3B +# self.serialMock.expected_commands = { +# b'\x36\x01\x3B': None +# } +# self.post_event("decrease_volume") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test another sound +# self.serialMock.expected_commands = { +# b'\x32\x01\x03': None +# } +# self.post_event("test3") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # stop sound +# self.serialMock.expected_commands = { +# b'\x33\01': None +# } +# self.post_event("test_stop") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# def test_rules(self): +# """Test HW Rules.""" +# self.serialMock.expected_commands = { +# b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main +# b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold +# } +# self.machine.flippers["f_test_hold_eos"].enable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main +# b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold +# } +# self.machine.flippers["f_test_hold_eos"].disable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot +# b'\x19\x07\x14': None +# } +# self.machine.autofire_coils["ac_slingshot"].enable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot +# } +# self.machine.autofire_coils["ac_slingshot"].disable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # set info display to TEST +# self.serialMock.expected_commands = { +# b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x03\x07': None +# } +# self.machine.segment_displays["info_display"].add_text("1337") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test recycle +# # pulse coil +# self.serialMock.expected_commands = { +# b'\x18\x00\x0a': None, # set pulse_ms to 10ms +# b'\x17\x00': None +# } +# self.machine.coils["c_test"].pulse() +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + + +# class TestLisyV10(MpfTestCase): + +# def get_config_file(self): +# return 'config_modern.yaml' + +# def get_machine_path(self): +# return 'tests/machine_files/lisy/' + +# def _mock_loop(self): +# self.clock.mock_serial("com1", self.serialMock) + +# def tearDown(self): +# self.assertFalse(self.serialMock.crashed) +# super().tearDown() + +# def get_platform(self): +# return False + +# def _wait_for_processing(self): +# start = time.time() +# while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: +# self.advance_time_and_run(.01) + +# def setUp(self): +# self.expected_duration = 1.5 +# self.serialMock = MockLisySocket(api_version=10) + +# self.serialMock.permanent_commands = { +# b'\x29': b'\x7F', # changed switches? -> no +# b'\x65': b'\x00' # watchdog +# } + +# self.serialMock.expected_commands = { +# b'\x00': b'FUTURE_HARDWARE\00', # hw not known yet +# b'\x01': b'0.42\00', # hardware version +# b'\x02': b'0.10\00', # api version +# b'\x64': b'\x00', # reset -> ok +# b'\x03': b'\x00', # get number of simple lamps -> 0 +# b'\x04': b'\x09', # get number of solenoids -> 9 +# b'\x06': b'\x00', # get number of displays -> 0 +# b'\x09': b'\x58', # get number of switches -> 88 +# b'\x13': b'\x02\x01', # get number of modern lights -> 512 + 1 = 513 modern lights +# b'\x19\x00\x0a': None, +# b'\x19\x01\x0a': None, +# b'\x19\x05\x1e': None, +# b'\x19\x06\x0a': None, +# b'\x19\x07\x0a': None, +# } + +# for number in range(88): +# if number % 10 >= 8: +# self.serialMock.expected_commands[bytes([40, number])] = b'\x02' +# else: +# self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' + +# # prevent changes on real hardware +# lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() + +# super().setUp() + +# lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() + +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# def test_rules(self): +# """Test HW Rules.""" +# # wait for watchdog +# self.serialMock.expected_commands = { +# b'\x65': b'\x00' # watchdog +# } +# self._wait_for_processing() + +# self.serialMock.expected_commands = { +# b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main +# b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold +# } +# self.machine.flippers["f_test_hold_eos"].enable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main +# b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold +# } +# self.machine.flippers["f_test_hold_eos"].disable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot +# b'\x19\x07\x14': None +# } +# self.machine.autofire_coils["ac_slingshot"].enable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# self.serialMock.expected_commands = { +# b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot +# } +# self.machine.autofire_coils["ac_slingshot"].disable() +# self.advance_time_and_run(.2) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # test recycle +# # pulse coil +# self.serialMock.expected_commands = { +# b'\x18\x00\x0a': None, # set pulse_ms to 10ms +# b'\x17\x00': None +# } +# self.machine.coils["c_test"].pulse() +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# def test_lights(self): +# """Test lights.""" +# # set color to one light without fade +# self.serialMock.expected_commands = { +# b'\x0d\x00\x00\x00\x00\x03\x11\x22\x33': None, # fade with 0ms fade time +# } +# self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], key="test") +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # set color again (should do nothing) +# self.machine.lights["test_light0"].remove_from_stack_by_key("test") +# self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], fade_ms=100) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # set color to the second light without fade +# self.serialMock.expected_commands = { +# b'\x0d\x00\x03\x00\x00\x04\x00\x11\x22\x11': None, # fade with 0ms fade time starting at channel 3 +# # 4 channels because this is a RGBW light +# } +# self.machine.lights["test_light1"].color([0x11, 0x22, 0x33]) +# self._wait_for_processing() +# self.assertFalse(self.serialMock.expected_commands) + +# # fade both lights together (fade depending on serial timing) +# self.serialMock.expected_commands = { +# b'\x0d\x00\x00\x01\x18\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time +# b'\x0d\x00\x00\x01\x19\x07\xaa\xbb\xcc\x00\x11\x22\xdd': None, # fade with 300ms fade time +# b'\x0d\x00\x00\x01\x20\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time +# b'\x0d\x00\x00\x01\x21\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time +# b'\x0d\x00\x00\x01\x22\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time +# } +# self.machine.lights["test_light0"].color([0xaa, 0xbb, 0xcc], fade_ms=300) +# self.machine.lights["test_light1"].color([0xdd, 0xee, 0xff], fade_ms=300) +# start = time.time() +# while len(self.serialMock.expected_commands) > 4 and not self.serialMock.crashed and time.time() < start + 10: +# self.advance_time_and_run(.01) +# self.assertEqual(4, len(self.serialMock.expected_commands)) diff --git a/mpf/tests/test_Accelerometer.py b/mpf/tests2/test_Accelerometer.py similarity index 100% rename from mpf/tests/test_Accelerometer.py rename to mpf/tests2/test_Accelerometer.py diff --git a/mpf/tests/test_Achievement.py b/mpf/tests2/test_Achievement.py similarity index 100% rename from mpf/tests/test_Achievement.py rename to mpf/tests2/test_Achievement.py diff --git a/mpf/tests/test_AssetManager.py b/mpf/tests2/test_AssetManager.py similarity index 100% rename from mpf/tests/test_AssetManager.py rename to mpf/tests2/test_AssetManager.py diff --git a/mpf/tests/test_Attract.py b/mpf/tests2/test_Attract.py similarity index 100% rename from mpf/tests/test_Attract.py rename to mpf/tests2/test_Attract.py diff --git a/mpf/tests/test_Auditor.py b/mpf/tests2/test_Auditor.py similarity index 100% rename from mpf/tests/test_Auditor.py rename to mpf/tests2/test_Auditor.py diff --git a/mpf/tests/test_Autofire.py b/mpf/tests2/test_Autofire.py similarity index 100% rename from mpf/tests/test_Autofire.py rename to mpf/tests2/test_Autofire.py diff --git a/mpf/tests/test_BallController.py b/mpf/tests2/test_BallController.py similarity index 100% rename from mpf/tests/test_BallController.py rename to mpf/tests2/test_BallController.py diff --git a/mpf/tests/test_BallDevice.py b/mpf/tests2/test_BallDevice.py similarity index 100% rename from mpf/tests/test_BallDevice.py rename to mpf/tests2/test_BallDevice.py diff --git a/mpf/tests/test_BallDeviceAutoManualPlunger.py b/mpf/tests2/test_BallDeviceAutoManualPlunger.py similarity index 100% rename from mpf/tests/test_BallDeviceAutoManualPlunger.py rename to mpf/tests2/test_BallDeviceAutoManualPlunger.py diff --git a/mpf/tests/test_BallDeviceEnableCoil.py b/mpf/tests2/test_BallDeviceEnableCoil.py similarity index 100% rename from mpf/tests/test_BallDeviceEnableCoil.py rename to mpf/tests2/test_BallDeviceEnableCoil.py diff --git a/mpf/tests/test_BallDeviceEventConfirmation.py b/mpf/tests2/test_BallDeviceEventConfirmation.py similarity index 100% rename from mpf/tests/test_BallDeviceEventConfirmation.py rename to mpf/tests2/test_BallDeviceEventConfirmation.py diff --git a/mpf/tests/test_BallDeviceEventEjector.py b/mpf/tests2/test_BallDeviceEventEjector.py similarity index 100% rename from mpf/tests/test_BallDeviceEventEjector.py rename to mpf/tests2/test_BallDeviceEventEjector.py diff --git a/mpf/tests/test_BallDeviceHoldCoil.py b/mpf/tests2/test_BallDeviceHoldCoil.py similarity index 100% rename from mpf/tests/test_BallDeviceHoldCoil.py rename to mpf/tests2/test_BallDeviceHoldCoil.py diff --git a/mpf/tests/test_BallDeviceJamSwitch.py b/mpf/tests2/test_BallDeviceJamSwitch.py similarity index 100% rename from mpf/tests/test_BallDeviceJamSwitch.py rename to mpf/tests2/test_BallDeviceJamSwitch.py diff --git a/mpf/tests/test_BallDeviceManualWithTarget.py b/mpf/tests2/test_BallDeviceManualWithTarget.py similarity index 100% rename from mpf/tests/test_BallDeviceManualWithTarget.py rename to mpf/tests2/test_BallDeviceManualWithTarget.py diff --git a/mpf/tests/test_BallDeviceModernTroughPlungerSetup.py b/mpf/tests2/test_BallDeviceModernTroughPlungerSetup.py similarity index 100% rename from mpf/tests/test_BallDeviceModernTroughPlungerSetup.py rename to mpf/tests2/test_BallDeviceModernTroughPlungerSetup.py diff --git a/mpf/tests/test_BallDeviceNoPlungerSwitch.py b/mpf/tests2/test_BallDeviceNoPlungerSwitch.py similarity index 100% rename from mpf/tests/test_BallDeviceNoPlungerSwitch.py rename to mpf/tests2/test_BallDeviceNoPlungerSwitch.py diff --git a/mpf/tests/test_BallDevicePlayfieldLock.py b/mpf/tests2/test_BallDevicePlayfieldLock.py similarity index 100% rename from mpf/tests/test_BallDevicePlayfieldLock.py rename to mpf/tests2/test_BallDevicePlayfieldLock.py diff --git a/mpf/tests/test_BallDevicePulseEject.py b/mpf/tests2/test_BallDevicePulseEject.py similarity index 100% rename from mpf/tests/test_BallDevicePulseEject.py rename to mpf/tests2/test_BallDevicePulseEject.py diff --git a/mpf/tests/test_BallDeviceRouting.py b/mpf/tests2/test_BallDeviceRouting.py similarity index 100% rename from mpf/tests/test_BallDeviceRouting.py rename to mpf/tests2/test_BallDeviceRouting.py diff --git a/mpf/tests/test_BallDeviceSingle.py b/mpf/tests2/test_BallDeviceSingle.py similarity index 100% rename from mpf/tests/test_BallDeviceSingle.py rename to mpf/tests2/test_BallDeviceSingle.py diff --git a/mpf/tests/test_BallDeviceSwitchConfirmation.py b/mpf/tests2/test_BallDeviceSwitchConfirmation.py similarity index 100% rename from mpf/tests/test_BallDeviceSwitchConfirmation.py rename to mpf/tests2/test_BallDeviceSwitchConfirmation.py diff --git a/mpf/tests/test_BallDeviceTriggerEvents.py b/mpf/tests2/test_BallDeviceTriggerEvents.py similarity index 100% rename from mpf/tests/test_BallDeviceTriggerEvents.py rename to mpf/tests2/test_BallDeviceTriggerEvents.py diff --git a/mpf/tests/test_BallDevice_SmartVirtual.py b/mpf/tests2/test_BallDevice_SmartVirtual.py similarity index 100% rename from mpf/tests/test_BallDevice_SmartVirtual.py rename to mpf/tests2/test_BallDevice_SmartVirtual.py diff --git a/mpf/tests/test_BallHold.py b/mpf/tests2/test_BallHold.py similarity index 100% rename from mpf/tests/test_BallHold.py rename to mpf/tests2/test_BallHold.py diff --git a/mpf/tests/test_BallRouting.py b/mpf/tests2/test_BallRouting.py similarity index 100% rename from mpf/tests/test_BallRouting.py rename to mpf/tests2/test_BallRouting.py diff --git a/mpf/tests/test_BallSave.py b/mpf/tests2/test_BallSave.py similarity index 100% rename from mpf/tests/test_BallSave.py rename to mpf/tests2/test_BallSave.py diff --git a/mpf/tests/test_BallSearch.py b/mpf/tests2/test_BallSearch.py similarity index 100% rename from mpf/tests/test_BallSearch.py rename to mpf/tests2/test_BallSearch.py diff --git a/mpf/tests/test_BcpInterface.py b/mpf/tests2/test_BcpInterface.py similarity index 100% rename from mpf/tests/test_BcpInterface.py rename to mpf/tests2/test_BcpInterface.py diff --git a/mpf/tests/test_BcpMc.py b/mpf/tests2/test_BcpMc.py similarity index 100% rename from mpf/tests/test_BcpMc.py rename to mpf/tests2/test_BcpMc.py diff --git a/mpf/tests/test_BcpServer.py b/mpf/tests2/test_BcpServer.py similarity index 100% rename from mpf/tests/test_BcpServer.py rename to mpf/tests2/test_BcpServer.py diff --git a/mpf/tests/test_BcpSocketClient.py b/mpf/tests2/test_BcpSocketClient.py similarity index 100% rename from mpf/tests/test_BcpSocketClient.py rename to mpf/tests2/test_BcpSocketClient.py diff --git a/mpf/tests/test_Blinkenlight.py b/mpf/tests2/test_Blinkenlight.py similarity index 100% rename from mpf/tests/test_Blinkenlight.py rename to mpf/tests2/test_Blinkenlight.py diff --git a/mpf/tests/test_BlockingEvents.py b/mpf/tests2/test_BlockingEvents.py similarity index 100% rename from mpf/tests/test_BlockingEvents.py rename to mpf/tests2/test_BlockingEvents.py diff --git a/mpf/tests/test_Bonus.py b/mpf/tests2/test_Bonus.py similarity index 100% rename from mpf/tests/test_Bonus.py rename to mpf/tests2/test_Bonus.py diff --git a/mpf/tests/test_CarouselMode.py b/mpf/tests2/test_CarouselMode.py similarity index 100% rename from mpf/tests/test_CarouselMode.py rename to mpf/tests2/test_CarouselMode.py diff --git a/mpf/tests/test_Clock.py b/mpf/tests2/test_Clock.py similarity index 100% rename from mpf/tests/test_Clock.py rename to mpf/tests2/test_Clock.py diff --git a/mpf/tests/test_CoilPlayer.py b/mpf/tests2/test_CoilPlayer.py similarity index 100% rename from mpf/tests/test_CoilPlayer.py rename to mpf/tests2/test_CoilPlayer.py diff --git a/mpf/tests/test_ComboSwitches.py b/mpf/tests2/test_ComboSwitches.py similarity index 100% rename from mpf/tests/test_ComboSwitches.py rename to mpf/tests2/test_ComboSwitches.py diff --git a/mpf/tests/test_CommandCreateConfig.py b/mpf/tests2/test_CommandCreateConfig.py similarity index 100% rename from mpf/tests/test_CommandCreateConfig.py rename to mpf/tests2/test_CommandCreateConfig.py diff --git a/mpf/tests/test_Commands.py b/mpf/tests2/test_Commands.py similarity index 100% rename from mpf/tests/test_Commands.py rename to mpf/tests2/test_Commands.py diff --git a/mpf/tests/test_Config.py b/mpf/tests2/test_Config.py similarity index 100% rename from mpf/tests/test_Config.py rename to mpf/tests2/test_Config.py diff --git a/mpf/tests/test_ConfigErrors.py b/mpf/tests2/test_ConfigErrors.py similarity index 100% rename from mpf/tests/test_ConfigErrors.py rename to mpf/tests2/test_ConfigErrors.py diff --git a/mpf/tests/test_ConfigLoader.py b/mpf/tests2/test_ConfigLoader.py similarity index 100% rename from mpf/tests/test_ConfigLoader.py rename to mpf/tests2/test_ConfigLoader.py diff --git a/mpf/tests/test_ConfigMissingVersion.py b/mpf/tests2/test_ConfigMissingVersion.py similarity index 100% rename from mpf/tests/test_ConfigMissingVersion.py rename to mpf/tests2/test_ConfigMissingVersion.py diff --git a/mpf/tests/test_ConfigOldVersion.py b/mpf/tests2/test_ConfigOldVersion.py similarity index 100% rename from mpf/tests/test_ConfigOldVersion.py rename to mpf/tests2/test_ConfigOldVersion.py diff --git a/mpf/tests/test_ConfigPlayers.py b/mpf/tests2/test_ConfigPlayers.py similarity index 100% rename from mpf/tests/test_ConfigPlayers.py rename to mpf/tests2/test_ConfigPlayers.py diff --git a/mpf/tests/test_ConfigProcessor.py b/mpf/tests2/test_ConfigProcessor.py similarity index 100% rename from mpf/tests/test_ConfigProcessor.py rename to mpf/tests2/test_ConfigProcessor.py diff --git a/mpf/tests/test_CreditsMode.py b/mpf/tests2/test_CreditsMode.py similarity index 100% rename from mpf/tests/test_CreditsMode.py rename to mpf/tests2/test_CreditsMode.py diff --git a/mpf/tests/test_CustomCode.py b/mpf/tests2/test_CustomCode.py similarity index 100% rename from mpf/tests/test_CustomCode.py rename to mpf/tests2/test_CustomCode.py diff --git a/mpf/tests/test_DataManager.py b/mpf/tests2/test_DataManager.py similarity index 100% rename from mpf/tests/test_DataManager.py rename to mpf/tests2/test_DataManager.py diff --git a/mpf/tests/test_Delay.py b/mpf/tests2/test_Delay.py similarity index 100% rename from mpf/tests/test_Delay.py rename to mpf/tests2/test_Delay.py diff --git a/mpf/tests/test_DeviceCollection.py b/mpf/tests2/test_DeviceCollection.py similarity index 100% rename from mpf/tests/test_DeviceCollection.py rename to mpf/tests2/test_DeviceCollection.py diff --git a/mpf/tests/test_DeviceDriver.py b/mpf/tests2/test_DeviceDriver.py similarity index 100% rename from mpf/tests/test_DeviceDriver.py rename to mpf/tests2/test_DeviceDriver.py diff --git a/mpf/tests/test_DeviceFlasher.py b/mpf/tests2/test_DeviceFlasher.py similarity index 100% rename from mpf/tests/test_DeviceFlasher.py rename to mpf/tests2/test_DeviceFlasher.py diff --git a/mpf/tests/test_DeviceGI.py b/mpf/tests2/test_DeviceGI.py similarity index 100% rename from mpf/tests/test_DeviceGI.py rename to mpf/tests2/test_DeviceGI.py diff --git a/mpf/tests/test_DeviceLight.py b/mpf/tests2/test_DeviceLight.py similarity index 100% rename from mpf/tests/test_DeviceLight.py rename to mpf/tests2/test_DeviceLight.py diff --git a/mpf/tests/test_DeviceManager.py b/mpf/tests2/test_DeviceManager.py similarity index 100% rename from mpf/tests/test_DeviceManager.py rename to mpf/tests2/test_DeviceManager.py diff --git a/mpf/tests/test_DeviceMatrixLight.py b/mpf/tests2/test_DeviceMatrixLight.py similarity index 100% rename from mpf/tests/test_DeviceMatrixLight.py rename to mpf/tests2/test_DeviceMatrixLight.py diff --git a/mpf/tests/test_DigitalOutput.py b/mpf/tests2/test_DigitalOutput.py similarity index 100% rename from mpf/tests/test_DigitalOutput.py rename to mpf/tests2/test_DigitalOutput.py diff --git a/mpf/tests/test_DigitalScoreReels.py b/mpf/tests2/test_DigitalScoreReels.py similarity index 100% rename from mpf/tests/test_DigitalScoreReels.py rename to mpf/tests2/test_DigitalScoreReels.py diff --git a/mpf/tests/test_Diverter.py b/mpf/tests2/test_Diverter.py similarity index 100% rename from mpf/tests/test_Diverter.py rename to mpf/tests2/test_Diverter.py diff --git a/mpf/tests/test_Dmd.py b/mpf/tests2/test_Dmd.py similarity index 100% rename from mpf/tests/test_Dmd.py rename to mpf/tests2/test_Dmd.py diff --git a/mpf/tests/test_DropTargets.py b/mpf/tests2/test_DropTargets.py similarity index 100% rename from mpf/tests/test_DropTargets.py rename to mpf/tests2/test_DropTargets.py diff --git a/mpf/tests/test_DualWoundCoil.py b/mpf/tests2/test_DualWoundCoil.py similarity index 100% rename from mpf/tests/test_DualWoundCoil.py rename to mpf/tests2/test_DualWoundCoil.py diff --git a/mpf/tests/test_EventManager.py b/mpf/tests2/test_EventManager.py similarity index 100% rename from mpf/tests/test_EventManager.py rename to mpf/tests2/test_EventManager.py diff --git a/mpf/tests/test_EventPlayer.py b/mpf/tests2/test_EventPlayer.py similarity index 100% rename from mpf/tests/test_EventPlayer.py rename to mpf/tests2/test_EventPlayer.py diff --git a/mpf/tests/test_ExtraBall.py b/mpf/tests2/test_ExtraBall.py similarity index 100% rename from mpf/tests/test_ExtraBall.py rename to mpf/tests2/test_ExtraBall.py diff --git a/mpf/tests/test_Fadecandy.py b/mpf/tests2/test_Fadecandy.py similarity index 100% rename from mpf/tests/test_Fadecandy.py rename to mpf/tests2/test_Fadecandy.py diff --git a/mpf/tests/test_Fast.py b/mpf/tests2/test_Fast.py similarity index 100% rename from mpf/tests/test_Fast.py rename to mpf/tests2/test_Fast.py diff --git a/mpf/tests/test_Fast_Audio.py b/mpf/tests2/test_Fast_Audio.py similarity index 100% rename from mpf/tests/test_Fast_Audio.py rename to mpf/tests2/test_Fast_Audio.py diff --git a/mpf/tests/test_Fast_Dmd.py b/mpf/tests2/test_Fast_Dmd.py similarity index 100% rename from mpf/tests/test_Fast_Dmd.py rename to mpf/tests2/test_Fast_Dmd.py diff --git a/mpf/tests/test_Fast_Exp.py b/mpf/tests2/test_Fast_Exp.py similarity index 100% rename from mpf/tests/test_Fast_Exp.py rename to mpf/tests2/test_Fast_Exp.py diff --git a/mpf/tests/test_Fast_Nano.py b/mpf/tests2/test_Fast_Nano.py similarity index 100% rename from mpf/tests/test_Fast_Nano.py rename to mpf/tests2/test_Fast_Nano.py diff --git a/mpf/tests/test_Fast_Neuron.py b/mpf/tests2/test_Fast_Neuron.py similarity index 100% rename from mpf/tests/test_Fast_Neuron.py rename to mpf/tests2/test_Fast_Neuron.py diff --git a/mpf/tests/test_Fast_Retro.py b/mpf/tests2/test_Fast_Retro.py similarity index 100% rename from mpf/tests/test_Fast_Retro.py rename to mpf/tests2/test_Fast_Retro.py diff --git a/mpf/tests/test_Fast_Seg.py b/mpf/tests2/test_Fast_Seg.py similarity index 100% rename from mpf/tests/test_Fast_Seg.py rename to mpf/tests2/test_Fast_Seg.py diff --git a/mpf/tests/test_Flippers.py b/mpf/tests2/test_Flippers.py similarity index 100% rename from mpf/tests/test_Flippers.py rename to mpf/tests2/test_Flippers.py diff --git a/mpf/tests/test_FlippersHoldNoEos.py b/mpf/tests2/test_FlippersHoldNoEos.py similarity index 100% rename from mpf/tests/test_FlippersHoldNoEos.py rename to mpf/tests2/test_FlippersHoldNoEos.py diff --git a/mpf/tests/test_FlippersSoftwareEosRepulse.py b/mpf/tests2/test_FlippersSoftwareEosRepulse.py similarity index 100% rename from mpf/tests/test_FlippersSoftwareEosRepulse.py rename to mpf/tests2/test_FlippersSoftwareEosRepulse.py diff --git a/mpf/tests/test_GottliebTrough.py b/mpf/tests2/test_GottliebTrough.py similarity index 100% rename from mpf/tests/test_GottliebTrough.py rename to mpf/tests2/test_GottliebTrough.py diff --git a/mpf/tests/test_Head2Head.py b/mpf/tests2/test_Head2Head.py similarity index 100% rename from mpf/tests/test_Head2Head.py rename to mpf/tests2/test_Head2Head.py diff --git a/mpf/tests/test_HighScoreMode.py b/mpf/tests2/test_HighScoreMode.py similarity index 100% rename from mpf/tests/test_HighScoreMode.py rename to mpf/tests2/test_HighScoreMode.py diff --git a/mpf/tests/test_HighScoreModeWithVars.py b/mpf/tests2/test_HighScoreModeWithVars.py similarity index 100% rename from mpf/tests/test_HighScoreModeWithVars.py rename to mpf/tests2/test_HighScoreModeWithVars.py diff --git a/mpf/tests/test_I2cServoController.py b/mpf/tests2/test_I2cServoController.py similarity index 100% rename from mpf/tests/test_I2cServoController.py rename to mpf/tests2/test_I2cServoController.py diff --git a/mpf/tests/test_InfoLights.py b/mpf/tests2/test_InfoLights.py similarity index 100% rename from mpf/tests/test_InfoLights.py rename to mpf/tests2/test_InfoLights.py diff --git a/mpf/tests/test_Kickback.py b/mpf/tests2/test_Kickback.py similarity index 100% rename from mpf/tests/test_Kickback.py rename to mpf/tests2/test_Kickback.py diff --git a/mpf/tests/test_LightGroups.py b/mpf/tests2/test_LightGroups.py similarity index 100% rename from mpf/tests/test_LightGroups.py rename to mpf/tests2/test_LightGroups.py diff --git a/mpf/tests/test_LightPlayer.py b/mpf/tests2/test_LightPlayer.py similarity index 100% rename from mpf/tests/test_LightPlayer.py rename to mpf/tests2/test_LightPlayer.py diff --git a/mpf/tests/test_LightPositions.py b/mpf/tests2/test_LightPositions.py similarity index 100% rename from mpf/tests/test_LightPositions.py rename to mpf/tests2/test_LightPositions.py diff --git a/mpf/tests/test_LightSegmentDisplays.py b/mpf/tests2/test_LightSegmentDisplays.py similarity index 100% rename from mpf/tests/test_LightSegmentDisplays.py rename to mpf/tests2/test_LightSegmentDisplays.py diff --git a/mpf/tests2/test_Lisy.py b/mpf/tests2/test_Lisy.py new file mode 100644 index 000000000..11f7cbe69 --- /dev/null +++ b/mpf/tests2/test_Lisy.py @@ -0,0 +1,869 @@ +import time + +from mpf.platforms.interfaces.segment_display_platform_interface import FlashingType +from mpf.platforms.lisy import lisy + +from mpf.tests.MpfTestCase import MpfTestCase, test_config, MagicMock +from mpf.tests.loop import MockSerial, MockSocket + +COMMAND_LENGTH = { + 0: 1, + 1: 1, + 2: 1, + 3: 1, + 4: 1, + 6: 1, + 7: 2, + 9: 1, + 11: 2, + 12: 2, + 19: 1, + 21: 2, + 22: 2, + 23: 2, + 24: 3, + 25: 3, + 40: 2, + 41: 1, + 51: 1, + 60: 11, + 100: 1, + 101: 1, +} + + +class MockLisySocket(MockSocket, MockSerial): + + def read(self, length): + del length + if not self.queue: + return b"" + msg = self.queue.pop() + return msg + + def read_ready(self): + return bool(self.queue) + + def write_ready(self): + return True + + def write(self, msg): + """Write message.""" + # print("Serial received: " + "".join("\\x%02x" % b for b in msg) + " len: " + str(len(msg))) + total_msg_len = len(msg) + while msg: + command = msg[0] + if command == 13: + command_length = 6 + msg[5] + elif 30 <= command <= 35: + if self.api_version >= 9: + command_length = 2 + msg[1] + else: + command_length = msg.index(b'\x00') + 1 + elif command in (50, 54): + command_length = 3 if self.api_version >= 9 else 2 + elif command == 51: + command_length = 2 if self.api_version >= 9 else 1 + elif command in (52, 53): + command_length = msg[3:].index(b'\x00') + 4 + else: + command_length = COMMAND_LENGTH.get(command, None) + if command_length is None: + raise AssertionError("Unknown command {} in {}".format(command, "".join("\\x%02x" % b for b in msg))) + if len(msg) < command_length: + raise AssertionError("Message too short ({}) for command {} with length {} in {}".format( + len(msg), command_length, command, + "".join("\\x%02x" % b for b in msg))) + + self._handle_msg(msg[0:command_length]) + msg = msg[command_length:] + + return total_msg_len + + def _handle_msg(self, msg): + if msg in self.permanent_commands and msg not in self.expected_commands: + if self.permanent_commands[msg] is not None: + self.queue.append(self.permanent_commands[msg]) + return len(msg) + + if msg not in self.expected_commands: + self.crashed = True + print("Unexpected command: " + "".join("\\x%02x" % b for b in msg) + " len: " + str(len(msg))) + raise AssertionError("Unexpected command: " + "".join("\\x%02x" % b for b in msg) + + " len: " + str(len(msg))) + + if self.expected_commands[msg] is not None: + self.queue.append(self.expected_commands[msg]) + + del self.expected_commands[msg] + return len(msg) + + def send(self, data): + return self.write(data) + + def recv(self, size): + return self.read(size) + + def __init__(self, api_version): + super().__init__() + self.name = "SerialMock" + self.expected_commands = {} + self.queue = [] + self.permanent_commands = {} + self.crashed = False + self.api_version = api_version + + +class TestLisy(MpfTestCase): + + def get_config_file(self): + return 'config.yaml' + + def get_machine_path(self): + return 'tests/machine_files/lisy/' + + def _mock_loop(self): + self.clock.mock_socket("localhost", 1234, self.serialMock) + + def tearDown(self): + self.assertFalse(self.serialMock.crashed) + super().tearDown() + + def get_platform(self): + return False + + def _wait_for_processing(self): + start = time.time() + while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: + self.advance_time_and_run(.01) + + def setUp(self): + self.expected_duration = 1.5 + self.serialMock = MockLisySocket(api_version=8) + + self.serialMock.permanent_commands = { + b'\x29': b'\x7F', # changed switches? -> no + b'\x65': b'\x00' # watchdog + } + + self.serialMock.expected_commands = { + b'\x00': b'LISY1\00', # hw LISY1 + b'\x01': b'4.01\00', # lisy version + b'\x02': b'0.08\00', # api version + b'\x64': b'\x00', # reset -> ok + b'\x03': b'\x28', # get number of lamps -> 40 + b'\x04': b'\x09', # get number of solenoids -> 9 + b'\x06': b'\x05', # get number of displays -> 5 + b'\x09': b'\x58', # get number of switches -> 88 + b'\x1e\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display + b'\x1f\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display + b'\x20\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display + } + + for number in range(88): + if number % 10 >= 8: + self.serialMock.expected_commands[bytes([40, number])] = b'\x02' + else: + self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' + + super().setUp() + + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + def test_platform(self): + self.maxDiff = None + infos = """LISY connected via network at localhost:1234 +Hardware: LISY1 Lisy Version: 4.01 API Version: 0.8 +Input count: 88 Input map: ['0', '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'] +Coil count: 9 +Modern lights count: 0 +Traditional lights count: 40 +Display count: 5 +""" + + self.assertEqual(self.machine.default_platform.get_info_string(), infos) + + # wait for watchdog + self.serialMock.expected_commands = { + b'\x65': b'\x00' # watchdog + } + self._wait_for_processing() + + # test initial switch state + self.assertSwitchState("s_test00", False) + self.assertSwitchState("s_test37", True) + self.assertSwitchState("s_test77_nc", True) + + self.serialMock.expected_commands = { + b'\x29': b'\x25' # 37 turned inactive + } + self.advance_time_and_run(.1) + # turns inactive + self.assertSwitchState("s_test37", False) + + self.serialMock.expected_commands = { + b'\x29': b'\xA5' # 37 turned active (again) + } + self.advance_time_and_run(.1) + # turns active + self.assertSwitchState("s_test37", True) + + self.serialMock.expected_commands = { + b'\x29': b'\xCD' # 77 turned active + } + self.advance_time_and_run(.1) + # turns inactive (because of NC) + self.assertSwitchState("s_test77_nc", False) + + # pulse coil + self.serialMock.expected_commands = { + b'\x18\x00\x0a': None, # set pulse_ms to 10ms + b'\x17\x00': None + } + self.machine.coils["c_test"].pulse() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # pulse trough eject. enable and disable in software + self.serialMock.expected_commands = { + b'\x18\x67\x00': None, # set pulse_ms to 10ms + b'\x15\x67': None # enable + } + self.machine.coils["c_trough_eject"].pulse() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.advance_time_and_run(2) + self.serialMock.expected_commands = { + b'\x16\x67': None # disable + } + self.advance_time_and_run() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # enable coil + self.serialMock.expected_commands = { + b'\x18\x01\x0a': None, # set pulse_ms to 10ms + b'\x15\x01': None + } + self.machine.coils["c_test_allow_enable"].enable() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # disable coil + self.serialMock.expected_commands = { + b'\x16\x01': None + } + self.machine.coils["c_test_allow_enable"].disable() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test light enable (using light 3) + self.serialMock.expected_commands = { + b'\x0b\x03': None + } + self.machine.lights["test_light"].on(key="test") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # disable light (using light 3) + self.serialMock.expected_commands = { + b'\x0c\x03': None + } + self.machine.lights["test_light"].remove_from_stack_by_key("test") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # start ball. enable flipper (using light 1) + self.serialMock.expected_commands = { + b'\x0b\x01': None + } + self.post_event("ball_started") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.advance_time_and_run() + + # end ball. disable flipper (using light 1) + self.serialMock.expected_commands = { + b'\x0c\x01': None + } + self.post_event("ball_will_end") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set info display to TEST + self.serialMock.expected_commands = { + b'\x1E TEST\x00': None + } + self.machine.segment_displays["info_display"].add_text("TEST") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set player 1 display to 42000 + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None + } + self.machine.segment_displays["player1_display"].add_text("42000") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set player 1 display to flashing + self.machine.segment_displays["player1_display"].set_flashing(FlashingType.FLASH_ALL) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None, + b'\x1F \x00': None + } + + self.advance_time_and_run(1) + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F \x00': None + } + + self.advance_time_and_run(.5) + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x1F 42000\x00': None, + } + self.machine.segment_displays["player1_display"].set_flashing(FlashingType.NO_FLASH) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound + self.serialMock.expected_commands = { + b'\x32\x02': None + } + self.post_event("test2") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound file + self.serialMock.expected_commands = { + b'\x34\x00some_file\x00': None + } + self.post_event("play_file") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound file looping + self.serialMock.expected_commands = { + b'\x34\x01some_file\x00': None + } + self.post_event("play_file_loop") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # text to speech + self.serialMock.expected_commands = { + b'\x35\x02Hello MPF\x00': None + } + self.post_event("play_text") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set volume to 50 (32 hex) + self.serialMock.expected_commands = { + b'\x36\x32': None + } + self.post_event("volume_05") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # increase volume by 0.1 -> 60 -> hex 3C + self.serialMock.expected_commands = { + b'\x36\x3C': None + } + self.post_event("increase_volume") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # decrease volume by 0.01 -> 59 -> hex 3B + self.serialMock.expected_commands = { + b'\x36\x3B': None + } + self.post_event("decrease_volume") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test another sound + self.serialMock.expected_commands = { + b'\x32\x03': None + } + self.post_event("test3") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # stop sound + self.serialMock.expected_commands = { + b'\x33': None + } + self.post_event("test_stop") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + @test_config("config_system11.yaml") + def test_system11(self): + # test normal coil + self.serialMock.expected_commands = { + b'\x18\x00\x14': None, # set pulse_ms to 20ms + b'\x17\x00': None # pulse coil 0 + } + self.machine.coils["c_test"].pulse(20) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test C-side coil + self.serialMock.expected_commands = { + b'\x18\x08\x0a': None, # set pulse_ms to 10ms to A/C relay + b'\x15\x08': None, # enable A/C relay + b'\x18\x01\x14': None, # set pulse_ms to 20ms + b'\x17\x01': None # pulse coil 1 + } + self.machine.coils["c_test1_c_side"].pulse(20) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # wait for A/C disable + self.serialMock.expected_commands = { + b'\x16\x08': None, # disable A/C relay + } + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test C-side coil + self.serialMock.expected_commands = { + b'\x15\x08': None, # enable A/C relay + b'\x17\x01': None # pulse coil 1 + } + self.machine.coils["c_test1_c_side"].pulse(20) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # wait for A/C disable + self.serialMock.expected_commands = { + b'\x16\x08': None, # disable A/C relay + } + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test A-side coil + self.serialMock.expected_commands = { + b'\x17\x01': None # pulse coil 1 + } + self.machine.coils["c_test1_a_side"].pulse(20) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test C-side coil + self.serialMock.expected_commands = { + b'\x18\x01\x0f': None, # set pulse_ms to 15ms + b'\x17\x01': None # pulse coil 1 + } + self.machine.coils["c_test1_a_side"].pulse(15) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test C-side coil + self.serialMock.expected_commands = { + b'\x15\x08': None, # enable A/C relay + b'\x18\x01\x14': None, # set pulse_ms to 20ms + b'\x17\x01': None # pulse coil 1 + } + self.machine.coils["c_test1_c_side"].pulse(20) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # wait for A/C disable + self.serialMock.expected_commands = { + b'\x16\x08': None, # disable A/C relay + } + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + +class TestAPC(MpfTestCase): + + def get_config_file(self): + return 'config.yaml' + + def get_machine_path(self): + return 'tests/machine_files/apc/' + + def _mock_loop(self): + self.clock.mock_serial("com1", self.serialMock) + + def tearDown(self): + self.assertFalse(self.serialMock.crashed) + super().tearDown() + + def get_platform(self): + return False + + def _wait_for_processing(self): + start = time.time() + while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: + self.advance_time_and_run(.01) + + def setUp(self): + self.expected_duration = 1.5 + self.serialMock = MockLisySocket(api_version=9) + + self.serialMock.permanent_commands = { + b'\x29': b'\x7F', # changed switches? -> no + b'\x65': b'\x00' # watchdog + } + + self.serialMock.expected_commands = { + b'\x00': b'APC\00', # hw APC + b'\x01': b'0.02\00', # APC version + b'\x02': b'0.09\00', # api version + b'\x64': b'\x00', # reset -> ok + b'\x03': b'\x28', # get number of lamps -> 40 + b'\x04': b'\x09', # get number of solenoids -> 9 + b'\x06': b'\x05', # get number of displays -> 5 + b'\x07\x00': b'\x02\x10', # get type of display 0 + b'\x07\x01': b'\x03\x05', # get type of display 1 + b'\x07\x02': b'\x04\x07', # get type of display 2 + b'\x07\x03': b'\x05\x03', # get type of display 3 + b'\x07\x04': b'\x06\x10', # get type of display 4 + b'\x09': b'\x58', # get number of switches -> 88 + b'\x13': b'\x00', # get number of modern lights -> 0 + b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display + b'\x1f\x05\x00\x00\x00\x00\x00': None, # clear display + b'\x20\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display + b'\x21\x03\x20\x20\x20': None, # clear display + b'\x22\x10\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20': None, # clear display + b'\x19\x00\x0a': None, + b'\x19\x01\x0a': None, + b'\x19\x67\xff': None, + b'\x19\x05\x1e': None, + b'\x19\x06\x0a': None, + b'\x19\x07\x0a': None, + } + + for number in range(88): + if number % 10 >= 8: + self.serialMock.expected_commands[bytes([40, number])] = b'\x02' + else: + self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' + + # prevent changes on real hardware + lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() + + super().setUp() + + lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() + + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + def test_platform(self): + # wait for watchdog + self.serialMock.expected_commands = { + b'\x65': b'\x00' # watchdog + } + self._wait_for_processing() + + # test sound + self.serialMock.expected_commands = { + b'\x32\x01\x02': None + } + self.post_event("test2") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound on track 2 + self.serialMock.expected_commands = { + b'\x32\x02\x05': None + } + self.post_event("test4") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound file + self.serialMock.expected_commands = { + b'\x34\x01\x00some_file\x00': None + } + self.post_event("play_file") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test sound file looping + self.serialMock.expected_commands = { + b'\x34\x01\x01some_file\x00': None + } + self.post_event("play_file_loop") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # text to speech + self.serialMock.expected_commands = { + b'\x35\x01\x02Hello MPF\x00': None + } + self.post_event("play_text") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set volume to 50 (32 hex) + self.serialMock.expected_commands = { + b'\x36\x01\x32': None + } + self.post_event("volume_05") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # increase volume by 0.1 -> 60 -> hex 3C + self.serialMock.expected_commands = { + b'\x36\x01\x3C': None + } + self.post_event("increase_volume") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # decrease volume by 0.01 -> 59 -> hex 3B + self.serialMock.expected_commands = { + b'\x36\x01\x3B': None + } + self.post_event("decrease_volume") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test another sound + self.serialMock.expected_commands = { + b'\x32\x01\x03': None + } + self.post_event("test3") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # stop sound + self.serialMock.expected_commands = { + b'\x33\01': None + } + self.post_event("test_stop") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + def test_rules(self): + """Test HW Rules.""" + self.serialMock.expected_commands = { + b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main + b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold + } + self.machine.flippers["f_test_hold_eos"].enable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main + b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold + } + self.machine.flippers["f_test_hold_eos"].disable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot + b'\x19\x07\x14': None + } + self.machine.autofire_coils["ac_slingshot"].enable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot + } + self.machine.autofire_coils["ac_slingshot"].disable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set info display to TEST + self.serialMock.expected_commands = { + b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x03\x07': None + } + self.machine.segment_displays["info_display"].add_text("1337") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test recycle + # pulse coil + self.serialMock.expected_commands = { + b'\x18\x00\x0a': None, # set pulse_ms to 10ms + b'\x17\x00': None + } + self.machine.coils["c_test"].pulse() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + +class TestLisyV10(MpfTestCase): + + def get_config_file(self): + return 'config_modern.yaml' + + def get_machine_path(self): + return 'tests/machine_files/lisy/' + + def _mock_loop(self): + self.clock.mock_serial("com1", self.serialMock) + + def tearDown(self): + self.assertFalse(self.serialMock.crashed) + super().tearDown() + + def get_platform(self): + return False + + def _wait_for_processing(self): + start = time.time() + while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: + self.advance_time_and_run(.01) + + def setUp(self): + self.expected_duration = 1.5 + self.serialMock = MockLisySocket(api_version=10) + + self.serialMock.permanent_commands = { + b'\x29': b'\x7F', # changed switches? -> no + b'\x65': b'\x00' # watchdog + } + + self.serialMock.expected_commands = { + b'\x00': b'FUTURE_HARDWARE\00', # hw not known yet + b'\x01': b'0.42\00', # hardware version + b'\x02': b'0.10\00', # api version + b'\x64': b'\x00', # reset -> ok + b'\x03': b'\x00', # get number of simple lamps -> 0 + b'\x04': b'\x09', # get number of solenoids -> 9 + b'\x06': b'\x00', # get number of displays -> 0 + b'\x09': b'\x58', # get number of switches -> 88 + b'\x13': b'\x02\x01', # get number of modern lights -> 512 + 1 = 513 modern lights + b'\x19\x00\x0a': None, + b'\x19\x01\x0a': None, + b'\x19\x05\x1e': None, + b'\x19\x06\x0a': None, + b'\x19\x07\x0a': None, + } + + for number in range(88): + if number % 10 >= 8: + self.serialMock.expected_commands[bytes([40, number])] = b'\x02' + else: + self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' + + # prevent changes on real hardware + lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() + + super().setUp() + + lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() + + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + def test_rules(self): + """Test HW Rules.""" + # wait for watchdog + self.serialMock.expected_commands = { + b'\x65': b'\x00' # watchdog + } + self._wait_for_processing() + + self.serialMock.expected_commands = { + b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main + b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold + } + self.machine.flippers["f_test_hold_eos"].enable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main + b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold + } + self.machine.flippers["f_test_hold_eos"].disable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot + b'\x19\x07\x14': None + } + self.machine.autofire_coils["ac_slingshot"].enable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + self.serialMock.expected_commands = { + b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot + } + self.machine.autofire_coils["ac_slingshot"].disable() + self.advance_time_and_run(.2) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # test recycle + # pulse coil + self.serialMock.expected_commands = { + b'\x18\x00\x0a': None, # set pulse_ms to 10ms + b'\x17\x00': None + } + self.machine.coils["c_test"].pulse() + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + def test_lights(self): + """Test lights.""" + # set color to one light without fade + self.serialMock.expected_commands = { + b'\x0d\x00\x00\x00\x00\x03\x11\x22\x33': None, # fade with 0ms fade time + } + self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], key="test") + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set color again (should do nothing) + self.machine.lights["test_light0"].remove_from_stack_by_key("test") + self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], fade_ms=100) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # set color to the second light without fade + self.serialMock.expected_commands = { + b'\x0d\x00\x03\x00\x00\x04\x00\x11\x22\x11': None, # fade with 0ms fade time starting at channel 3 + # 4 channels because this is a RGBW light + } + self.machine.lights["test_light1"].color([0x11, 0x22, 0x33]) + self._wait_for_processing() + self.assertFalse(self.serialMock.expected_commands) + + # fade both lights together (fade depending on serial timing) + self.serialMock.expected_commands = { + b'\x0d\x00\x00\x01\x18\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time + b'\x0d\x00\x00\x01\x19\x07\xaa\xbb\xcc\x00\x11\x22\xdd': None, # fade with 300ms fade time + b'\x0d\x00\x00\x01\x20\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time + b'\x0d\x00\x00\x01\x21\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time + b'\x0d\x00\x00\x01\x22\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time + } + self.machine.lights["test_light0"].color([0xaa, 0xbb, 0xcc], fade_ms=300) + self.machine.lights["test_light1"].color([0xdd, 0xee, 0xff], fade_ms=300) + start = time.time() + while len(self.serialMock.expected_commands) > 4 and not self.serialMock.crashed and time.time() < start + 10: + self.advance_time_and_run(.01) + self.assertEqual(4, len(self.serialMock.expected_commands)) diff --git a/mpf/tests/test_LogicBlocks.py b/mpf/tests2/test_LogicBlocks.py similarity index 100% rename from mpf/tests/test_LogicBlocks.py rename to mpf/tests2/test_LogicBlocks.py diff --git a/mpf/tests/test_MMA8451.py b/mpf/tests2/test_MMA8451.py similarity index 100% rename from mpf/tests/test_MMA8451.py rename to mpf/tests2/test_MMA8451.py diff --git a/mpf/tests/test_MachineVariables.py b/mpf/tests2/test_MachineVariables.py similarity index 100% rename from mpf/tests/test_MachineVariables.py rename to mpf/tests2/test_MachineVariables.py diff --git a/mpf/tests/test_Magnet.py b/mpf/tests2/test_Magnet.py similarity index 100% rename from mpf/tests/test_Magnet.py rename to mpf/tests2/test_Magnet.py diff --git a/mpf/tests/test_MatchMode.py b/mpf/tests2/test_MatchMode.py similarity index 100% rename from mpf/tests/test_MatchMode.py rename to mpf/tests2/test_MatchMode.py diff --git a/mpf/tests/test_Modes.py b/mpf/tests2/test_Modes.py similarity index 100% rename from mpf/tests/test_Modes.py rename to mpf/tests2/test_Modes.py diff --git a/mpf/tests/test_ModesConfigValidation.py b/mpf/tests2/test_ModesConfigValidation.py similarity index 100% rename from mpf/tests/test_ModesConfigValidation.py rename to mpf/tests2/test_ModesConfigValidation.py diff --git a/mpf/tests/test_Motors.py b/mpf/tests2/test_Motors.py similarity index 100% rename from mpf/tests/test_Motors.py rename to mpf/tests2/test_Motors.py diff --git a/mpf/tests/test_MpfTestCase.py b/mpf/tests2/test_MpfTestCase.py similarity index 100% rename from mpf/tests/test_MpfTestCase.py rename to mpf/tests2/test_MpfTestCase.py diff --git a/mpf/tests/test_MultiBall.py b/mpf/tests2/test_MultiBall.py similarity index 100% rename from mpf/tests/test_MultiBall.py rename to mpf/tests2/test_MultiBall.py diff --git a/mpf/tests/test_MultiballLock.py b/mpf/tests2/test_MultiballLock.py similarity index 100% rename from mpf/tests/test_MultiballLock.py rename to mpf/tests2/test_MultiballLock.py diff --git a/mpf/tests/test_MyPinballs.py b/mpf/tests2/test_MyPinballs.py similarity index 100% rename from mpf/tests/test_MyPinballs.py rename to mpf/tests2/test_MyPinballs.py diff --git a/mpf/tests/test_OPP.py b/mpf/tests2/test_OPP.py similarity index 100% rename from mpf/tests/test_OPP.py rename to mpf/tests2/test_OPP.py diff --git a/mpf/tests/test_Openpixel.py b/mpf/tests2/test_Openpixel.py similarity index 100% rename from mpf/tests/test_Openpixel.py rename to mpf/tests2/test_Openpixel.py diff --git a/mpf/tests/test_Osc.py b/mpf/tests2/test_Osc.py similarity index 100% rename from mpf/tests/test_Osc.py rename to mpf/tests2/test_Osc.py diff --git a/mpf/tests/test_P3_Roc.py b/mpf/tests2/test_P3_Roc.py similarity index 100% rename from mpf/tests/test_P3_Roc.py rename to mpf/tests2/test_P3_Roc.py diff --git a/mpf/tests/test_PKONE.py b/mpf/tests2/test_PKONE.py similarity index 100% rename from mpf/tests/test_PKONE.py rename to mpf/tests2/test_PKONE.py diff --git a/mpf/tests/test_P_Roc.py b/mpf/tests2/test_P_Roc.py similarity index 100% rename from mpf/tests/test_P_Roc.py rename to mpf/tests2/test_P_Roc.py diff --git a/mpf/tests/test_PlaceholderManager.py b/mpf/tests2/test_PlaceholderManager.py similarity index 100% rename from mpf/tests/test_PlaceholderManager.py rename to mpf/tests2/test_PlaceholderManager.py diff --git a/mpf/tests/test_Platform.py b/mpf/tests2/test_Platform.py similarity index 100% rename from mpf/tests/test_Platform.py rename to mpf/tests2/test_Platform.py diff --git a/mpf/tests/test_PlayerVars.py b/mpf/tests2/test_PlayerVars.py similarity index 100% rename from mpf/tests/test_PlayerVars.py rename to mpf/tests2/test_PlayerVars.py diff --git a/mpf/tests/test_Playfield.py b/mpf/tests2/test_Playfield.py similarity index 100% rename from mpf/tests/test_Playfield.py rename to mpf/tests2/test_Playfield.py diff --git a/mpf/tests/test_PlayfieldTransfer.py b/mpf/tests2/test_PlayfieldTransfer.py similarity index 100% rename from mpf/tests/test_PlayfieldTransfer.py rename to mpf/tests2/test_PlayfieldTransfer.py diff --git a/mpf/tests/test_PluginConfigPlayer.py b/mpf/tests2/test_PluginConfigPlayer.py similarity index 100% rename from mpf/tests/test_PluginConfigPlayer.py rename to mpf/tests2/test_PluginConfigPlayer.py diff --git a/mpf/tests/test_PololuMaestro.py b/mpf/tests2/test_PololuMaestro.py similarity index 100% rename from mpf/tests/test_PololuMaestro.py rename to mpf/tests2/test_PololuMaestro.py diff --git a/mpf/tests/test_PololuTic.py b/mpf/tests2/test_PololuTic.py similarity index 100% rename from mpf/tests/test_PololuTic.py rename to mpf/tests2/test_PololuTic.py diff --git a/mpf/tests/test_QueueEventPlayer.py b/mpf/tests2/test_QueueEventPlayer.py similarity index 100% rename from mpf/tests/test_QueueEventPlayer.py rename to mpf/tests2/test_QueueEventPlayer.py diff --git a/mpf/tests/test_RGBColor.py b/mpf/tests2/test_RGBColor.py similarity index 100% rename from mpf/tests/test_RGBColor.py rename to mpf/tests2/test_RGBColor.py diff --git a/mpf/tests/test_RandomEventPlayer.py b/mpf/tests2/test_RandomEventPlayer.py similarity index 100% rename from mpf/tests/test_RandomEventPlayer.py rename to mpf/tests2/test_RandomEventPlayer.py diff --git a/mpf/tests/test_Randomizer.py b/mpf/tests2/test_Randomizer.py similarity index 100% rename from mpf/tests/test_Randomizer.py rename to mpf/tests2/test_Randomizer.py diff --git a/mpf/tests/test_Rpi.py b/mpf/tests2/test_Rpi.py similarity index 100% rename from mpf/tests/test_Rpi.py rename to mpf/tests2/test_Rpi.py diff --git a/mpf/tests/test_RpiDmd.py b/mpf/tests2/test_RpiDmd.py similarity index 100% rename from mpf/tests/test_RpiDmd.py rename to mpf/tests2/test_RpiDmd.py diff --git a/mpf/tests/test_ScoreQueue.py b/mpf/tests2/test_ScoreQueue.py similarity index 100% rename from mpf/tests/test_ScoreQueue.py rename to mpf/tests2/test_ScoreQueue.py diff --git a/mpf/tests/test_ScoreReels.py b/mpf/tests2/test_ScoreReels.py similarity index 100% rename from mpf/tests/test_ScoreReels.py rename to mpf/tests2/test_ScoreReels.py diff --git a/mpf/tests/test_SegmentDisplay.py b/mpf/tests2/test_SegmentDisplay.py similarity index 100% rename from mpf/tests/test_SegmentDisplay.py rename to mpf/tests2/test_SegmentDisplay.py diff --git a/mpf/tests/test_SegmentMappings.py b/mpf/tests2/test_SegmentMappings.py similarity index 100% rename from mpf/tests/test_SegmentMappings.py rename to mpf/tests2/test_SegmentMappings.py diff --git a/mpf/tests/test_SequenceShot.py b/mpf/tests2/test_SequenceShot.py similarity index 100% rename from mpf/tests/test_SequenceShot.py rename to mpf/tests2/test_SequenceShot.py diff --git a/mpf/tests/test_ServiceCli.py b/mpf/tests2/test_ServiceCli.py similarity index 100% rename from mpf/tests/test_ServiceCli.py rename to mpf/tests2/test_ServiceCli.py diff --git a/mpf/tests/test_ServiceMode.py b/mpf/tests2/test_ServiceMode.py similarity index 100% rename from mpf/tests/test_ServiceMode.py rename to mpf/tests2/test_ServiceMode.py diff --git a/mpf/tests/test_Servo.py b/mpf/tests2/test_Servo.py similarity index 100% rename from mpf/tests/test_Servo.py rename to mpf/tests2/test_Servo.py diff --git a/mpf/tests/test_Settings.py b/mpf/tests2/test_Settings.py similarity index 100% rename from mpf/tests/test_Settings.py rename to mpf/tests2/test_Settings.py diff --git a/mpf/tests/test_ShotGroups.py b/mpf/tests2/test_ShotGroups.py similarity index 100% rename from mpf/tests/test_ShotGroups.py rename to mpf/tests2/test_ShotGroups.py diff --git a/mpf/tests/test_Shots.py b/mpf/tests2/test_Shots.py similarity index 100% rename from mpf/tests/test_Shots.py rename to mpf/tests2/test_Shots.py diff --git a/mpf/tests/test_ShowPools.py b/mpf/tests2/test_ShowPools.py similarity index 100% rename from mpf/tests/test_ShowPools.py rename to mpf/tests2/test_ShowPools.py diff --git a/mpf/tests/test_Shows.py b/mpf/tests2/test_Shows.py similarity index 100% rename from mpf/tests/test_Shows.py rename to mpf/tests2/test_Shows.py diff --git a/mpf/tests/test_SmartMatrix.py b/mpf/tests2/test_SmartMatrix.py similarity index 100% rename from mpf/tests/test_SmartMatrix.py rename to mpf/tests2/test_SmartMatrix.py diff --git a/mpf/tests/test_SmartVirtualPlatform.py b/mpf/tests2/test_SmartVirtualPlatform.py similarity index 100% rename from mpf/tests/test_SmartVirtualPlatform.py rename to mpf/tests2/test_SmartVirtualPlatform.py diff --git a/mpf/tests/test_Smbus2.py b/mpf/tests2/test_Smbus2.py similarity index 100% rename from mpf/tests/test_Smbus2.py rename to mpf/tests2/test_Smbus2.py diff --git a/mpf/tests/test_Snux.py b/mpf/tests2/test_Snux.py similarity index 100% rename from mpf/tests/test_Snux.py rename to mpf/tests2/test_Snux.py diff --git a/mpf/tests/test_SpiBitBang.py b/mpf/tests2/test_SpiBitBang.py similarity index 100% rename from mpf/tests/test_SpiBitBang.py rename to mpf/tests2/test_SpiBitBang.py diff --git a/mpf/tests/test_Spike.py b/mpf/tests2/test_Spike.py similarity index 100% rename from mpf/tests/test_Spike.py rename to mpf/tests2/test_Spike.py diff --git a/mpf/tests/test_Spinners.py b/mpf/tests2/test_Spinners.py similarity index 100% rename from mpf/tests/test_Spinners.py rename to mpf/tests2/test_Spinners.py diff --git a/mpf/tests/test_StateMachine.py b/mpf/tests2/test_StateMachine.py similarity index 100% rename from mpf/tests/test_StateMachine.py rename to mpf/tests2/test_StateMachine.py diff --git a/mpf/tests/test_StepStick.py b/mpf/tests2/test_StepStick.py similarity index 100% rename from mpf/tests/test_StepStick.py rename to mpf/tests2/test_StepStick.py diff --git a/mpf/tests/test_Stepper.py b/mpf/tests2/test_Stepper.py similarity index 100% rename from mpf/tests/test_Stepper.py rename to mpf/tests2/test_Stepper.py diff --git a/mpf/tests/test_SwitchController.py b/mpf/tests2/test_SwitchController.py similarity index 100% rename from mpf/tests/test_SwitchController.py rename to mpf/tests2/test_SwitchController.py diff --git a/mpf/tests/test_SwitchPlayer.py b/mpf/tests2/test_SwitchPlayer.py similarity index 100% rename from mpf/tests/test_SwitchPlayer.py rename to mpf/tests2/test_SwitchPlayer.py diff --git a/mpf/tests/test_SwitchPositions.py b/mpf/tests2/test_SwitchPositions.py similarity index 100% rename from mpf/tests/test_SwitchPositions.py rename to mpf/tests2/test_SwitchPositions.py diff --git a/mpf/tests/test_System11Trough.py b/mpf/tests2/test_System11Trough.py similarity index 100% rename from mpf/tests/test_System11Trough.py rename to mpf/tests2/test_System11Trough.py diff --git a/mpf/tests/test_Tilt.py b/mpf/tests2/test_Tilt.py similarity index 100% rename from mpf/tests/test_Tilt.py rename to mpf/tests2/test_Tilt.py diff --git a/mpf/tests/test_TimedSwitch.py b/mpf/tests2/test_TimedSwitch.py similarity index 100% rename from mpf/tests/test_TimedSwitch.py rename to mpf/tests2/test_TimedSwitch.py diff --git a/mpf/tests/test_Timer.py b/mpf/tests2/test_Timer.py similarity index 100% rename from mpf/tests/test_Timer.py rename to mpf/tests2/test_Timer.py diff --git a/mpf/tests/test_TooLongExitCountDelay.py b/mpf/tests2/test_TooLongExitCountDelay.py similarity index 100% rename from mpf/tests/test_TooLongExitCountDelay.py rename to mpf/tests2/test_TooLongExitCountDelay.py diff --git a/mpf/tests/test_TrinamicsStepRocker.py b/mpf/tests2/test_TrinamicsStepRocker.py similarity index 100% rename from mpf/tests/test_TrinamicsStepRocker.py rename to mpf/tests2/test_TrinamicsStepRocker.py diff --git a/mpf/tests/test_TroughEntranceSwitch.py b/mpf/tests2/test_TroughEntranceSwitch.py similarity index 100% rename from mpf/tests/test_TroughEntranceSwitch.py rename to mpf/tests2/test_TroughEntranceSwitch.py diff --git a/mpf/tests/test_TwitchClient.py b/mpf/tests2/test_TwitchClient.py similarity index 100% rename from mpf/tests/test_TwitchClient.py rename to mpf/tests2/test_TwitchClient.py diff --git a/mpf/tests/test_Utility_Functions.py b/mpf/tests2/test_Utility_Functions.py similarity index 100% rename from mpf/tests/test_Utility_Functions.py rename to mpf/tests2/test_Utility_Functions.py diff --git a/mpf/tests/test_VPX.py b/mpf/tests2/test_VPX.py similarity index 100% rename from mpf/tests/test_VPX.py rename to mpf/tests2/test_VPX.py diff --git a/mpf/tests/test_VariablePlayer.py b/mpf/tests2/test_VariablePlayer.py similarity index 100% rename from mpf/tests/test_VariablePlayer.py rename to mpf/tests2/test_VariablePlayer.py diff --git a/mpf/tests/test_Virtual.py b/mpf/tests2/test_Virtual.py similarity index 100% rename from mpf/tests/test_Virtual.py rename to mpf/tests2/test_Virtual.py diff --git a/mpf/tests/test_VirtualPinball.py b/mpf/tests2/test_VirtualPinball.py similarity index 100% rename from mpf/tests/test_VirtualPinball.py rename to mpf/tests2/test_VirtualPinball.py diff --git a/mpf/tests/test_VirtualSegmentDisplayConnector.py b/mpf/tests2/test_VirtualSegmentDisplayConnector.py similarity index 100% rename from mpf/tests/test_VirtualSegmentDisplayConnector.py rename to mpf/tests2/test_VirtualSegmentDisplayConnector.py diff --git a/mpf/tests/test_VisualPinballEngine.py b/mpf/tests2/test_VisualPinballEngine.py similarity index 100% rename from mpf/tests/test_VisualPinballEngine.py rename to mpf/tests2/test_VisualPinballEngine.py diff --git a/mpf/tests/test_YamlInterface.py b/mpf/tests2/test_YamlInterface.py similarity index 100% rename from mpf/tests/test_YamlInterface.py rename to mpf/tests2/test_YamlInterface.py From b196592a49950084de74d9602178871f41e53ce3 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 00:11:49 -0800 Subject: [PATCH 07/11] add node logging on out of range number error --- mpf/platforms/spike/spike.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpf/platforms/spike/spike.py b/mpf/platforms/spike/spike.py index 00cb52334..654146627 100644 --- a/mpf/platforms/spike/spike.py +++ b/mpf/platforms/spike/spike.py @@ -1103,7 +1103,7 @@ async def send_cmd_and_wait_for_response(self, node, cmd, data, response_len) -> """Send cmd and wait for response.""" assert response_len > 0 if node > 15: - raise AssertionError("Node must be 0-15.") + raise AssertionError(f"Node must be 0-15. Got: {node}") cmd_str = bytearray() cmd_str.append((8 << 4) + node) cmd_str.append(len(data) + 2) @@ -1134,7 +1134,7 @@ async def send_cmd_and_wait_for_response(self, node, cmd, data, response_len) -> def _create_cmd_str(self, node, cmd, data): if node > 15: - raise AssertionError("Node must be 0-15.") + raise AssertionError(f"Node must be 0-15. Got: {node}") cmd_str = bytearray() cmd_str.append((8 << 4) + node) cmd_str.append(len(data) + 2) From ca90778477f9ced4805281bdc669875b3cfae79d Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 00:25:24 -0800 Subject: [PATCH 08/11] logging for pkone test failures --- mpf/{tests2 => tests}/test_PKONE.py | 6 ++++++ 1 file changed, 6 insertions(+) rename mpf/{tests2 => tests}/test_PKONE.py (99%) diff --git a/mpf/tests2/test_PKONE.py b/mpf/tests/test_PKONE.py similarity index 99% rename from mpf/tests2/test_PKONE.py rename to mpf/tests/test_PKONE.py index fea859c5a..5928673dd 100644 --- a/mpf/tests2/test_PKONE.py +++ b/mpf/tests/test_PKONE.py @@ -40,6 +40,7 @@ def _parse(self, msg): return False def write(self, msg): + print("W: ", msg) parts = msg.split(b'E') # remove last newline assert parts.pop() == b'' @@ -50,6 +51,7 @@ def write(self, msg): return len(msg) def _handle_msg(self, msg): + print("HANDLE", msg) msg_len = len(msg) cmd = msg.decode() @@ -65,13 +67,17 @@ def _handle_msg(self, msg): return msg_len if self.validate_expected_commands_mode: + print("VALEX MODE") if cmd in self.expected_commands: if self.expected_commands[cmd]: + print("FOUND EXPECTED:", cmd) self.queue.append(self.expected_commands[cmd]) del self.expected_commands[cmd] self.sent_commands.append(cmd) return msg_len else: + print("UNEXPECTED:", cmd) + print(self.expected_commands) raise Exception(str(cmd)) else: self.sent_commands.append(cmd) From 239bd04597d8194b79bda5db9d6b59d779b7370e Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 03:05:32 -0800 Subject: [PATCH 09/11] print dequeued item for test debugging --- mpf/tests/test_PKONE.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mpf/tests/test_PKONE.py b/mpf/tests/test_PKONE.py index 5928673dd..44f113154 100644 --- a/mpf/tests/test_PKONE.py +++ b/mpf/tests/test_PKONE.py @@ -27,7 +27,9 @@ def read(self, length): del length if not self.queue: return - msg = (self.queue.pop() + 'E').encode('ascii', 'replace') + dequeued = self.queue.pop() + print("READ", dequeued) + msg = (dequeued + 'E').encode('ascii', 'replace') return msg def read_ready(self): From 35959378fc634ea40ceabb9a28339188cf6bf384 Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 03:06:53 -0800 Subject: [PATCH 10/11] restore full test suite --- mpf/{tests2 => tests}/test_Accelerometer.py | 0 mpf/{tests2 => tests}/test_Achievement.py | 0 mpf/{tests2 => tests}/test_AssetManager.py | 0 mpf/{tests2 => tests}/test_Attract.py | 0 mpf/{tests2 => tests}/test_Auditor.py | 0 mpf/{tests2 => tests}/test_Autofire.py | 0 mpf/{tests2 => tests}/test_BallController.py | 0 mpf/{tests2 => tests}/test_BallDevice.py | 0 .../test_BallDeviceAutoManualPlunger.py | 0 .../test_BallDeviceEnableCoil.py | 0 .../test_BallDeviceEventConfirmation.py | 0 .../test_BallDeviceEventEjector.py | 0 .../test_BallDeviceHoldCoil.py | 0 .../test_BallDeviceJamSwitch.py | 0 .../test_BallDeviceManualWithTarget.py | 0 ...test_BallDeviceModernTroughPlungerSetup.py | 0 .../test_BallDeviceNoPlungerSwitch.py | 0 .../test_BallDevicePlayfieldLock.py | 0 .../test_BallDevicePulseEject.py | 0 .../test_BallDeviceRouting.py | 0 .../test_BallDeviceSingle.py | 0 .../test_BallDeviceSwitchConfirmation.py | 0 .../test_BallDeviceTriggerEvents.py | 0 .../test_BallDevice_SmartVirtual.py | 0 mpf/{tests2 => tests}/test_BallHold.py | 0 mpf/{tests2 => tests}/test_BallRouting.py | 0 mpf/{tests2 => tests}/test_BallSave.py | 0 mpf/{tests2 => tests}/test_BallSearch.py | 0 mpf/{tests2 => tests}/test_BcpInterface.py | 0 mpf/{tests2 => tests}/test_BcpMc.py | 0 mpf/{tests2 => tests}/test_BcpServer.py | 0 mpf/{tests2 => tests}/test_BcpSocketClient.py | 0 mpf/{tests2 => tests}/test_Blinkenlight.py | 0 mpf/{tests2 => tests}/test_BlockingEvents.py | 0 mpf/{tests2 => tests}/test_Bonus.py | 0 mpf/{tests2 => tests}/test_CarouselMode.py | 0 mpf/{tests2 => tests}/test_Clock.py | 0 mpf/{tests2 => tests}/test_CoilPlayer.py | 0 mpf/{tests2 => tests}/test_ComboSwitches.py | 0 .../test_CommandCreateConfig.py | 0 mpf/{tests2 => tests}/test_Commands.py | 0 mpf/{tests2 => tests}/test_Config.py | 0 mpf/{tests2 => tests}/test_ConfigErrors.py | 0 mpf/{tests2 => tests}/test_ConfigLoader.py | 0 .../test_ConfigMissingVersion.py | 0 .../test_ConfigOldVersion.py | 0 mpf/{tests2 => tests}/test_ConfigPlayers.py | 0 mpf/{tests2 => tests}/test_ConfigProcessor.py | 0 mpf/{tests2 => tests}/test_CreditsMode.py | 0 mpf/{tests2 => tests}/test_CustomCode.py | 0 mpf/{tests2 => tests}/test_DataManager.py | 0 mpf/{tests2 => tests}/test_Delay.py | 0 .../test_DeviceCollection.py | 0 mpf/{tests2 => tests}/test_DeviceDriver.py | 0 mpf/{tests2 => tests}/test_DeviceFlasher.py | 0 mpf/{tests2 => tests}/test_DeviceGI.py | 0 mpf/{tests2 => tests}/test_DeviceLight.py | 0 mpf/{tests2 => tests}/test_DeviceManager.py | 0 .../test_DeviceMatrixLight.py | 0 mpf/{tests2 => tests}/test_DigitalOutput.py | 0 .../test_DigitalScoreReels.py | 0 mpf/{tests2 => tests}/test_Diverter.py | 0 mpf/{tests2 => tests}/test_Dmd.py | 0 mpf/{tests2 => tests}/test_DropTargets.py | 0 mpf/{tests2 => tests}/test_DualWoundCoil.py | 0 mpf/{tests2 => tests}/test_EventManager.py | 0 mpf/{tests2 => tests}/test_EventPlayer.py | 0 mpf/{tests2 => tests}/test_ExtraBall.py | 0 mpf/{tests2 => tests}/test_Fadecandy.py | 0 mpf/{tests2 => tests}/test_Fast.py | 0 mpf/{tests2 => tests}/test_Fast_Audio.py | 0 mpf/{tests2 => tests}/test_Fast_Dmd.py | 0 mpf/{tests2 => tests}/test_Fast_Exp.py | 0 mpf/{tests2 => tests}/test_Fast_Nano.py | 0 mpf/{tests2 => tests}/test_Fast_Neuron.py | 0 mpf/{tests2 => tests}/test_Fast_Retro.py | 0 mpf/{tests2 => tests}/test_Fast_Seg.py | 0 mpf/{tests2 => tests}/test_Flippers.py | 0 .../test_FlippersHoldNoEos.py | 0 .../test_FlippersSoftwareEosRepulse.py | 0 mpf/{tests2 => tests}/test_GottliebTrough.py | 0 mpf/{tests2 => tests}/test_Head2Head.py | 0 mpf/{tests2 => tests}/test_HighScoreMode.py | 0 .../test_HighScoreModeWithVars.py | 0 .../test_I2cServoController.py | 0 mpf/{tests2 => tests}/test_InfoLights.py | 0 mpf/{tests2 => tests}/test_Kickback.py | 0 mpf/{tests2 => tests}/test_LightGroups.py | 0 mpf/{tests2 => tests}/test_LightPlayer.py | 0 mpf/{tests2 => tests}/test_LightPositions.py | 0 .../test_LightSegmentDisplays.py | 0 mpf/{tests2 => tests}/test_LogicBlocks.py | 0 mpf/{tests2 => tests}/test_MMA8451.py | 0 .../test_MachineVariables.py | 0 mpf/{tests2 => tests}/test_Magnet.py | 0 mpf/{tests2 => tests}/test_MatchMode.py | 0 mpf/{tests2 => tests}/test_Modes.py | 0 .../test_ModesConfigValidation.py | 0 mpf/{tests2 => tests}/test_Motors.py | 0 mpf/{tests2 => tests}/test_MpfTestCase.py | 0 mpf/{tests2 => tests}/test_MultiBall.py | 0 mpf/{tests2 => tests}/test_MultiballLock.py | 0 mpf/{tests2 => tests}/test_MyPinballs.py | 0 mpf/{tests2 => tests}/test_OPP.py | 0 mpf/{tests2 => tests}/test_Openpixel.py | 0 mpf/{tests2 => tests}/test_Osc.py | 0 mpf/{tests2 => tests}/test_P3_Roc.py | 0 mpf/{tests2 => tests}/test_P_Roc.py | 0 .../test_PlaceholderManager.py | 0 mpf/{tests2 => tests}/test_Platform.py | 0 mpf/{tests2 => tests}/test_PlayerVars.py | 0 mpf/{tests2 => tests}/test_Playfield.py | 0 .../test_PlayfieldTransfer.py | 0 .../test_PluginConfigPlayer.py | 0 mpf/{tests2 => tests}/test_PololuMaestro.py | 0 mpf/{tests2 => tests}/test_PololuTic.py | 0 .../test_QueueEventPlayer.py | 0 mpf/{tests2 => tests}/test_RGBColor.py | 0 .../test_RandomEventPlayer.py | 0 mpf/{tests2 => tests}/test_Randomizer.py | 0 mpf/{tests2 => tests}/test_Rpi.py | 0 mpf/{tests2 => tests}/test_RpiDmd.py | 0 mpf/{tests2 => tests}/test_ScoreQueue.py | 0 mpf/{tests2 => tests}/test_ScoreReels.py | 0 mpf/{tests2 => tests}/test_SegmentDisplay.py | 0 mpf/{tests2 => tests}/test_SegmentMappings.py | 0 mpf/{tests2 => tests}/test_SequenceShot.py | 0 mpf/{tests2 => tests}/test_ServiceCli.py | 0 mpf/{tests2 => tests}/test_ServiceMode.py | 0 mpf/{tests2 => tests}/test_Servo.py | 0 mpf/{tests2 => tests}/test_Settings.py | 0 mpf/{tests2 => tests}/test_ShotGroups.py | 0 mpf/{tests2 => tests}/test_Shots.py | 0 mpf/{tests2 => tests}/test_ShowPools.py | 0 mpf/{tests2 => tests}/test_Shows.py | 0 mpf/{tests2 => tests}/test_SmartMatrix.py | 0 .../test_SmartVirtualPlatform.py | 0 mpf/{tests2 => tests}/test_Smbus2.py | 0 mpf/{tests2 => tests}/test_Snux.py | 0 mpf/{tests2 => tests}/test_SpiBitBang.py | 0 mpf/{tests2 => tests}/test_Spike.py | 0 mpf/{tests2 => tests}/test_Spinners.py | 0 mpf/{tests2 => tests}/test_StateMachine.py | 0 mpf/{tests2 => tests}/test_StepStick.py | 0 mpf/{tests2 => tests}/test_Stepper.py | 0 .../test_SwitchController.py | 0 mpf/{tests2 => tests}/test_SwitchPlayer.py | 0 mpf/{tests2 => tests}/test_SwitchPositions.py | 0 mpf/{tests2 => tests}/test_System11Trough.py | 0 mpf/{tests2 => tests}/test_Tilt.py | 0 mpf/{tests2 => tests}/test_TimedSwitch.py | 0 mpf/{tests2 => tests}/test_Timer.py | 0 .../test_TooLongExitCountDelay.py | 0 .../test_TrinamicsStepRocker.py | 0 .../test_TroughEntranceSwitch.py | 0 mpf/{tests2 => tests}/test_TwitchClient.py | 0 .../test_Utility_Functions.py | 0 mpf/{tests2 => tests}/test_VPX.py | 0 mpf/{tests2 => tests}/test_VariablePlayer.py | 0 mpf/{tests2 => tests}/test_Virtual.py | 0 mpf/{tests2 => tests}/test_VirtualPinball.py | 0 .../test_VirtualSegmentDisplayConnector.py | 0 .../test_VisualPinballEngine.py | 0 mpf/{tests2 => tests}/test_YamlInterface.py | 0 mpf/tests2/test_Lisy.py | 869 ------------------ 165 files changed, 869 deletions(-) rename mpf/{tests2 => tests}/test_Accelerometer.py (100%) rename mpf/{tests2 => tests}/test_Achievement.py (100%) rename mpf/{tests2 => tests}/test_AssetManager.py (100%) rename mpf/{tests2 => tests}/test_Attract.py (100%) rename mpf/{tests2 => tests}/test_Auditor.py (100%) rename mpf/{tests2 => tests}/test_Autofire.py (100%) rename mpf/{tests2 => tests}/test_BallController.py (100%) rename mpf/{tests2 => tests}/test_BallDevice.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceAutoManualPlunger.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceEnableCoil.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceEventConfirmation.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceEventEjector.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceHoldCoil.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceJamSwitch.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceManualWithTarget.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceModernTroughPlungerSetup.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceNoPlungerSwitch.py (100%) rename mpf/{tests2 => tests}/test_BallDevicePlayfieldLock.py (100%) rename mpf/{tests2 => tests}/test_BallDevicePulseEject.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceRouting.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceSingle.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceSwitchConfirmation.py (100%) rename mpf/{tests2 => tests}/test_BallDeviceTriggerEvents.py (100%) rename mpf/{tests2 => tests}/test_BallDevice_SmartVirtual.py (100%) rename mpf/{tests2 => tests}/test_BallHold.py (100%) rename mpf/{tests2 => tests}/test_BallRouting.py (100%) rename mpf/{tests2 => tests}/test_BallSave.py (100%) rename mpf/{tests2 => tests}/test_BallSearch.py (100%) rename mpf/{tests2 => tests}/test_BcpInterface.py (100%) rename mpf/{tests2 => tests}/test_BcpMc.py (100%) rename mpf/{tests2 => tests}/test_BcpServer.py (100%) rename mpf/{tests2 => tests}/test_BcpSocketClient.py (100%) rename mpf/{tests2 => tests}/test_Blinkenlight.py (100%) rename mpf/{tests2 => tests}/test_BlockingEvents.py (100%) rename mpf/{tests2 => tests}/test_Bonus.py (100%) rename mpf/{tests2 => tests}/test_CarouselMode.py (100%) rename mpf/{tests2 => tests}/test_Clock.py (100%) rename mpf/{tests2 => tests}/test_CoilPlayer.py (100%) rename mpf/{tests2 => tests}/test_ComboSwitches.py (100%) rename mpf/{tests2 => tests}/test_CommandCreateConfig.py (100%) rename mpf/{tests2 => tests}/test_Commands.py (100%) rename mpf/{tests2 => tests}/test_Config.py (100%) rename mpf/{tests2 => tests}/test_ConfigErrors.py (100%) rename mpf/{tests2 => tests}/test_ConfigLoader.py (100%) rename mpf/{tests2 => tests}/test_ConfigMissingVersion.py (100%) rename mpf/{tests2 => tests}/test_ConfigOldVersion.py (100%) rename mpf/{tests2 => tests}/test_ConfigPlayers.py (100%) rename mpf/{tests2 => tests}/test_ConfigProcessor.py (100%) rename mpf/{tests2 => tests}/test_CreditsMode.py (100%) rename mpf/{tests2 => tests}/test_CustomCode.py (100%) rename mpf/{tests2 => tests}/test_DataManager.py (100%) rename mpf/{tests2 => tests}/test_Delay.py (100%) rename mpf/{tests2 => tests}/test_DeviceCollection.py (100%) rename mpf/{tests2 => tests}/test_DeviceDriver.py (100%) rename mpf/{tests2 => tests}/test_DeviceFlasher.py (100%) rename mpf/{tests2 => tests}/test_DeviceGI.py (100%) rename mpf/{tests2 => tests}/test_DeviceLight.py (100%) rename mpf/{tests2 => tests}/test_DeviceManager.py (100%) rename mpf/{tests2 => tests}/test_DeviceMatrixLight.py (100%) rename mpf/{tests2 => tests}/test_DigitalOutput.py (100%) rename mpf/{tests2 => tests}/test_DigitalScoreReels.py (100%) rename mpf/{tests2 => tests}/test_Diverter.py (100%) rename mpf/{tests2 => tests}/test_Dmd.py (100%) rename mpf/{tests2 => tests}/test_DropTargets.py (100%) rename mpf/{tests2 => tests}/test_DualWoundCoil.py (100%) rename mpf/{tests2 => tests}/test_EventManager.py (100%) rename mpf/{tests2 => tests}/test_EventPlayer.py (100%) rename mpf/{tests2 => tests}/test_ExtraBall.py (100%) rename mpf/{tests2 => tests}/test_Fadecandy.py (100%) rename mpf/{tests2 => tests}/test_Fast.py (100%) rename mpf/{tests2 => tests}/test_Fast_Audio.py (100%) rename mpf/{tests2 => tests}/test_Fast_Dmd.py (100%) rename mpf/{tests2 => tests}/test_Fast_Exp.py (100%) rename mpf/{tests2 => tests}/test_Fast_Nano.py (100%) rename mpf/{tests2 => tests}/test_Fast_Neuron.py (100%) rename mpf/{tests2 => tests}/test_Fast_Retro.py (100%) rename mpf/{tests2 => tests}/test_Fast_Seg.py (100%) rename mpf/{tests2 => tests}/test_Flippers.py (100%) rename mpf/{tests2 => tests}/test_FlippersHoldNoEos.py (100%) rename mpf/{tests2 => tests}/test_FlippersSoftwareEosRepulse.py (100%) rename mpf/{tests2 => tests}/test_GottliebTrough.py (100%) rename mpf/{tests2 => tests}/test_Head2Head.py (100%) rename mpf/{tests2 => tests}/test_HighScoreMode.py (100%) rename mpf/{tests2 => tests}/test_HighScoreModeWithVars.py (100%) rename mpf/{tests2 => tests}/test_I2cServoController.py (100%) rename mpf/{tests2 => tests}/test_InfoLights.py (100%) rename mpf/{tests2 => tests}/test_Kickback.py (100%) rename mpf/{tests2 => tests}/test_LightGroups.py (100%) rename mpf/{tests2 => tests}/test_LightPlayer.py (100%) rename mpf/{tests2 => tests}/test_LightPositions.py (100%) rename mpf/{tests2 => tests}/test_LightSegmentDisplays.py (100%) rename mpf/{tests2 => tests}/test_LogicBlocks.py (100%) rename mpf/{tests2 => tests}/test_MMA8451.py (100%) rename mpf/{tests2 => tests}/test_MachineVariables.py (100%) rename mpf/{tests2 => tests}/test_Magnet.py (100%) rename mpf/{tests2 => tests}/test_MatchMode.py (100%) rename mpf/{tests2 => tests}/test_Modes.py (100%) rename mpf/{tests2 => tests}/test_ModesConfigValidation.py (100%) rename mpf/{tests2 => tests}/test_Motors.py (100%) rename mpf/{tests2 => tests}/test_MpfTestCase.py (100%) rename mpf/{tests2 => tests}/test_MultiBall.py (100%) rename mpf/{tests2 => tests}/test_MultiballLock.py (100%) rename mpf/{tests2 => tests}/test_MyPinballs.py (100%) rename mpf/{tests2 => tests}/test_OPP.py (100%) rename mpf/{tests2 => tests}/test_Openpixel.py (100%) rename mpf/{tests2 => tests}/test_Osc.py (100%) rename mpf/{tests2 => tests}/test_P3_Roc.py (100%) rename mpf/{tests2 => tests}/test_P_Roc.py (100%) rename mpf/{tests2 => tests}/test_PlaceholderManager.py (100%) rename mpf/{tests2 => tests}/test_Platform.py (100%) rename mpf/{tests2 => tests}/test_PlayerVars.py (100%) rename mpf/{tests2 => tests}/test_Playfield.py (100%) rename mpf/{tests2 => tests}/test_PlayfieldTransfer.py (100%) rename mpf/{tests2 => tests}/test_PluginConfigPlayer.py (100%) rename mpf/{tests2 => tests}/test_PololuMaestro.py (100%) rename mpf/{tests2 => tests}/test_PololuTic.py (100%) rename mpf/{tests2 => tests}/test_QueueEventPlayer.py (100%) rename mpf/{tests2 => tests}/test_RGBColor.py (100%) rename mpf/{tests2 => tests}/test_RandomEventPlayer.py (100%) rename mpf/{tests2 => tests}/test_Randomizer.py (100%) rename mpf/{tests2 => tests}/test_Rpi.py (100%) rename mpf/{tests2 => tests}/test_RpiDmd.py (100%) rename mpf/{tests2 => tests}/test_ScoreQueue.py (100%) rename mpf/{tests2 => tests}/test_ScoreReels.py (100%) rename mpf/{tests2 => tests}/test_SegmentDisplay.py (100%) rename mpf/{tests2 => tests}/test_SegmentMappings.py (100%) rename mpf/{tests2 => tests}/test_SequenceShot.py (100%) rename mpf/{tests2 => tests}/test_ServiceCli.py (100%) rename mpf/{tests2 => tests}/test_ServiceMode.py (100%) rename mpf/{tests2 => tests}/test_Servo.py (100%) rename mpf/{tests2 => tests}/test_Settings.py (100%) rename mpf/{tests2 => tests}/test_ShotGroups.py (100%) rename mpf/{tests2 => tests}/test_Shots.py (100%) rename mpf/{tests2 => tests}/test_ShowPools.py (100%) rename mpf/{tests2 => tests}/test_Shows.py (100%) rename mpf/{tests2 => tests}/test_SmartMatrix.py (100%) rename mpf/{tests2 => tests}/test_SmartVirtualPlatform.py (100%) rename mpf/{tests2 => tests}/test_Smbus2.py (100%) rename mpf/{tests2 => tests}/test_Snux.py (100%) rename mpf/{tests2 => tests}/test_SpiBitBang.py (100%) rename mpf/{tests2 => tests}/test_Spike.py (100%) rename mpf/{tests2 => tests}/test_Spinners.py (100%) rename mpf/{tests2 => tests}/test_StateMachine.py (100%) rename mpf/{tests2 => tests}/test_StepStick.py (100%) rename mpf/{tests2 => tests}/test_Stepper.py (100%) rename mpf/{tests2 => tests}/test_SwitchController.py (100%) rename mpf/{tests2 => tests}/test_SwitchPlayer.py (100%) rename mpf/{tests2 => tests}/test_SwitchPositions.py (100%) rename mpf/{tests2 => tests}/test_System11Trough.py (100%) rename mpf/{tests2 => tests}/test_Tilt.py (100%) rename mpf/{tests2 => tests}/test_TimedSwitch.py (100%) rename mpf/{tests2 => tests}/test_Timer.py (100%) rename mpf/{tests2 => tests}/test_TooLongExitCountDelay.py (100%) rename mpf/{tests2 => tests}/test_TrinamicsStepRocker.py (100%) rename mpf/{tests2 => tests}/test_TroughEntranceSwitch.py (100%) rename mpf/{tests2 => tests}/test_TwitchClient.py (100%) rename mpf/{tests2 => tests}/test_Utility_Functions.py (100%) rename mpf/{tests2 => tests}/test_VPX.py (100%) rename mpf/{tests2 => tests}/test_VariablePlayer.py (100%) rename mpf/{tests2 => tests}/test_Virtual.py (100%) rename mpf/{tests2 => tests}/test_VirtualPinball.py (100%) rename mpf/{tests2 => tests}/test_VirtualSegmentDisplayConnector.py (100%) rename mpf/{tests2 => tests}/test_VisualPinballEngine.py (100%) rename mpf/{tests2 => tests}/test_YamlInterface.py (100%) delete mode 100644 mpf/tests2/test_Lisy.py diff --git a/mpf/tests2/test_Accelerometer.py b/mpf/tests/test_Accelerometer.py similarity index 100% rename from mpf/tests2/test_Accelerometer.py rename to mpf/tests/test_Accelerometer.py diff --git a/mpf/tests2/test_Achievement.py b/mpf/tests/test_Achievement.py similarity index 100% rename from mpf/tests2/test_Achievement.py rename to mpf/tests/test_Achievement.py diff --git a/mpf/tests2/test_AssetManager.py b/mpf/tests/test_AssetManager.py similarity index 100% rename from mpf/tests2/test_AssetManager.py rename to mpf/tests/test_AssetManager.py diff --git a/mpf/tests2/test_Attract.py b/mpf/tests/test_Attract.py similarity index 100% rename from mpf/tests2/test_Attract.py rename to mpf/tests/test_Attract.py diff --git a/mpf/tests2/test_Auditor.py b/mpf/tests/test_Auditor.py similarity index 100% rename from mpf/tests2/test_Auditor.py rename to mpf/tests/test_Auditor.py diff --git a/mpf/tests2/test_Autofire.py b/mpf/tests/test_Autofire.py similarity index 100% rename from mpf/tests2/test_Autofire.py rename to mpf/tests/test_Autofire.py diff --git a/mpf/tests2/test_BallController.py b/mpf/tests/test_BallController.py similarity index 100% rename from mpf/tests2/test_BallController.py rename to mpf/tests/test_BallController.py diff --git a/mpf/tests2/test_BallDevice.py b/mpf/tests/test_BallDevice.py similarity index 100% rename from mpf/tests2/test_BallDevice.py rename to mpf/tests/test_BallDevice.py diff --git a/mpf/tests2/test_BallDeviceAutoManualPlunger.py b/mpf/tests/test_BallDeviceAutoManualPlunger.py similarity index 100% rename from mpf/tests2/test_BallDeviceAutoManualPlunger.py rename to mpf/tests/test_BallDeviceAutoManualPlunger.py diff --git a/mpf/tests2/test_BallDeviceEnableCoil.py b/mpf/tests/test_BallDeviceEnableCoil.py similarity index 100% rename from mpf/tests2/test_BallDeviceEnableCoil.py rename to mpf/tests/test_BallDeviceEnableCoil.py diff --git a/mpf/tests2/test_BallDeviceEventConfirmation.py b/mpf/tests/test_BallDeviceEventConfirmation.py similarity index 100% rename from mpf/tests2/test_BallDeviceEventConfirmation.py rename to mpf/tests/test_BallDeviceEventConfirmation.py diff --git a/mpf/tests2/test_BallDeviceEventEjector.py b/mpf/tests/test_BallDeviceEventEjector.py similarity index 100% rename from mpf/tests2/test_BallDeviceEventEjector.py rename to mpf/tests/test_BallDeviceEventEjector.py diff --git a/mpf/tests2/test_BallDeviceHoldCoil.py b/mpf/tests/test_BallDeviceHoldCoil.py similarity index 100% rename from mpf/tests2/test_BallDeviceHoldCoil.py rename to mpf/tests/test_BallDeviceHoldCoil.py diff --git a/mpf/tests2/test_BallDeviceJamSwitch.py b/mpf/tests/test_BallDeviceJamSwitch.py similarity index 100% rename from mpf/tests2/test_BallDeviceJamSwitch.py rename to mpf/tests/test_BallDeviceJamSwitch.py diff --git a/mpf/tests2/test_BallDeviceManualWithTarget.py b/mpf/tests/test_BallDeviceManualWithTarget.py similarity index 100% rename from mpf/tests2/test_BallDeviceManualWithTarget.py rename to mpf/tests/test_BallDeviceManualWithTarget.py diff --git a/mpf/tests2/test_BallDeviceModernTroughPlungerSetup.py b/mpf/tests/test_BallDeviceModernTroughPlungerSetup.py similarity index 100% rename from mpf/tests2/test_BallDeviceModernTroughPlungerSetup.py rename to mpf/tests/test_BallDeviceModernTroughPlungerSetup.py diff --git a/mpf/tests2/test_BallDeviceNoPlungerSwitch.py b/mpf/tests/test_BallDeviceNoPlungerSwitch.py similarity index 100% rename from mpf/tests2/test_BallDeviceNoPlungerSwitch.py rename to mpf/tests/test_BallDeviceNoPlungerSwitch.py diff --git a/mpf/tests2/test_BallDevicePlayfieldLock.py b/mpf/tests/test_BallDevicePlayfieldLock.py similarity index 100% rename from mpf/tests2/test_BallDevicePlayfieldLock.py rename to mpf/tests/test_BallDevicePlayfieldLock.py diff --git a/mpf/tests2/test_BallDevicePulseEject.py b/mpf/tests/test_BallDevicePulseEject.py similarity index 100% rename from mpf/tests2/test_BallDevicePulseEject.py rename to mpf/tests/test_BallDevicePulseEject.py diff --git a/mpf/tests2/test_BallDeviceRouting.py b/mpf/tests/test_BallDeviceRouting.py similarity index 100% rename from mpf/tests2/test_BallDeviceRouting.py rename to mpf/tests/test_BallDeviceRouting.py diff --git a/mpf/tests2/test_BallDeviceSingle.py b/mpf/tests/test_BallDeviceSingle.py similarity index 100% rename from mpf/tests2/test_BallDeviceSingle.py rename to mpf/tests/test_BallDeviceSingle.py diff --git a/mpf/tests2/test_BallDeviceSwitchConfirmation.py b/mpf/tests/test_BallDeviceSwitchConfirmation.py similarity index 100% rename from mpf/tests2/test_BallDeviceSwitchConfirmation.py rename to mpf/tests/test_BallDeviceSwitchConfirmation.py diff --git a/mpf/tests2/test_BallDeviceTriggerEvents.py b/mpf/tests/test_BallDeviceTriggerEvents.py similarity index 100% rename from mpf/tests2/test_BallDeviceTriggerEvents.py rename to mpf/tests/test_BallDeviceTriggerEvents.py diff --git a/mpf/tests2/test_BallDevice_SmartVirtual.py b/mpf/tests/test_BallDevice_SmartVirtual.py similarity index 100% rename from mpf/tests2/test_BallDevice_SmartVirtual.py rename to mpf/tests/test_BallDevice_SmartVirtual.py diff --git a/mpf/tests2/test_BallHold.py b/mpf/tests/test_BallHold.py similarity index 100% rename from mpf/tests2/test_BallHold.py rename to mpf/tests/test_BallHold.py diff --git a/mpf/tests2/test_BallRouting.py b/mpf/tests/test_BallRouting.py similarity index 100% rename from mpf/tests2/test_BallRouting.py rename to mpf/tests/test_BallRouting.py diff --git a/mpf/tests2/test_BallSave.py b/mpf/tests/test_BallSave.py similarity index 100% rename from mpf/tests2/test_BallSave.py rename to mpf/tests/test_BallSave.py diff --git a/mpf/tests2/test_BallSearch.py b/mpf/tests/test_BallSearch.py similarity index 100% rename from mpf/tests2/test_BallSearch.py rename to mpf/tests/test_BallSearch.py diff --git a/mpf/tests2/test_BcpInterface.py b/mpf/tests/test_BcpInterface.py similarity index 100% rename from mpf/tests2/test_BcpInterface.py rename to mpf/tests/test_BcpInterface.py diff --git a/mpf/tests2/test_BcpMc.py b/mpf/tests/test_BcpMc.py similarity index 100% rename from mpf/tests2/test_BcpMc.py rename to mpf/tests/test_BcpMc.py diff --git a/mpf/tests2/test_BcpServer.py b/mpf/tests/test_BcpServer.py similarity index 100% rename from mpf/tests2/test_BcpServer.py rename to mpf/tests/test_BcpServer.py diff --git a/mpf/tests2/test_BcpSocketClient.py b/mpf/tests/test_BcpSocketClient.py similarity index 100% rename from mpf/tests2/test_BcpSocketClient.py rename to mpf/tests/test_BcpSocketClient.py diff --git a/mpf/tests2/test_Blinkenlight.py b/mpf/tests/test_Blinkenlight.py similarity index 100% rename from mpf/tests2/test_Blinkenlight.py rename to mpf/tests/test_Blinkenlight.py diff --git a/mpf/tests2/test_BlockingEvents.py b/mpf/tests/test_BlockingEvents.py similarity index 100% rename from mpf/tests2/test_BlockingEvents.py rename to mpf/tests/test_BlockingEvents.py diff --git a/mpf/tests2/test_Bonus.py b/mpf/tests/test_Bonus.py similarity index 100% rename from mpf/tests2/test_Bonus.py rename to mpf/tests/test_Bonus.py diff --git a/mpf/tests2/test_CarouselMode.py b/mpf/tests/test_CarouselMode.py similarity index 100% rename from mpf/tests2/test_CarouselMode.py rename to mpf/tests/test_CarouselMode.py diff --git a/mpf/tests2/test_Clock.py b/mpf/tests/test_Clock.py similarity index 100% rename from mpf/tests2/test_Clock.py rename to mpf/tests/test_Clock.py diff --git a/mpf/tests2/test_CoilPlayer.py b/mpf/tests/test_CoilPlayer.py similarity index 100% rename from mpf/tests2/test_CoilPlayer.py rename to mpf/tests/test_CoilPlayer.py diff --git a/mpf/tests2/test_ComboSwitches.py b/mpf/tests/test_ComboSwitches.py similarity index 100% rename from mpf/tests2/test_ComboSwitches.py rename to mpf/tests/test_ComboSwitches.py diff --git a/mpf/tests2/test_CommandCreateConfig.py b/mpf/tests/test_CommandCreateConfig.py similarity index 100% rename from mpf/tests2/test_CommandCreateConfig.py rename to mpf/tests/test_CommandCreateConfig.py diff --git a/mpf/tests2/test_Commands.py b/mpf/tests/test_Commands.py similarity index 100% rename from mpf/tests2/test_Commands.py rename to mpf/tests/test_Commands.py diff --git a/mpf/tests2/test_Config.py b/mpf/tests/test_Config.py similarity index 100% rename from mpf/tests2/test_Config.py rename to mpf/tests/test_Config.py diff --git a/mpf/tests2/test_ConfigErrors.py b/mpf/tests/test_ConfigErrors.py similarity index 100% rename from mpf/tests2/test_ConfigErrors.py rename to mpf/tests/test_ConfigErrors.py diff --git a/mpf/tests2/test_ConfigLoader.py b/mpf/tests/test_ConfigLoader.py similarity index 100% rename from mpf/tests2/test_ConfigLoader.py rename to mpf/tests/test_ConfigLoader.py diff --git a/mpf/tests2/test_ConfigMissingVersion.py b/mpf/tests/test_ConfigMissingVersion.py similarity index 100% rename from mpf/tests2/test_ConfigMissingVersion.py rename to mpf/tests/test_ConfigMissingVersion.py diff --git a/mpf/tests2/test_ConfigOldVersion.py b/mpf/tests/test_ConfigOldVersion.py similarity index 100% rename from mpf/tests2/test_ConfigOldVersion.py rename to mpf/tests/test_ConfigOldVersion.py diff --git a/mpf/tests2/test_ConfigPlayers.py b/mpf/tests/test_ConfigPlayers.py similarity index 100% rename from mpf/tests2/test_ConfigPlayers.py rename to mpf/tests/test_ConfigPlayers.py diff --git a/mpf/tests2/test_ConfigProcessor.py b/mpf/tests/test_ConfigProcessor.py similarity index 100% rename from mpf/tests2/test_ConfigProcessor.py rename to mpf/tests/test_ConfigProcessor.py diff --git a/mpf/tests2/test_CreditsMode.py b/mpf/tests/test_CreditsMode.py similarity index 100% rename from mpf/tests2/test_CreditsMode.py rename to mpf/tests/test_CreditsMode.py diff --git a/mpf/tests2/test_CustomCode.py b/mpf/tests/test_CustomCode.py similarity index 100% rename from mpf/tests2/test_CustomCode.py rename to mpf/tests/test_CustomCode.py diff --git a/mpf/tests2/test_DataManager.py b/mpf/tests/test_DataManager.py similarity index 100% rename from mpf/tests2/test_DataManager.py rename to mpf/tests/test_DataManager.py diff --git a/mpf/tests2/test_Delay.py b/mpf/tests/test_Delay.py similarity index 100% rename from mpf/tests2/test_Delay.py rename to mpf/tests/test_Delay.py diff --git a/mpf/tests2/test_DeviceCollection.py b/mpf/tests/test_DeviceCollection.py similarity index 100% rename from mpf/tests2/test_DeviceCollection.py rename to mpf/tests/test_DeviceCollection.py diff --git a/mpf/tests2/test_DeviceDriver.py b/mpf/tests/test_DeviceDriver.py similarity index 100% rename from mpf/tests2/test_DeviceDriver.py rename to mpf/tests/test_DeviceDriver.py diff --git a/mpf/tests2/test_DeviceFlasher.py b/mpf/tests/test_DeviceFlasher.py similarity index 100% rename from mpf/tests2/test_DeviceFlasher.py rename to mpf/tests/test_DeviceFlasher.py diff --git a/mpf/tests2/test_DeviceGI.py b/mpf/tests/test_DeviceGI.py similarity index 100% rename from mpf/tests2/test_DeviceGI.py rename to mpf/tests/test_DeviceGI.py diff --git a/mpf/tests2/test_DeviceLight.py b/mpf/tests/test_DeviceLight.py similarity index 100% rename from mpf/tests2/test_DeviceLight.py rename to mpf/tests/test_DeviceLight.py diff --git a/mpf/tests2/test_DeviceManager.py b/mpf/tests/test_DeviceManager.py similarity index 100% rename from mpf/tests2/test_DeviceManager.py rename to mpf/tests/test_DeviceManager.py diff --git a/mpf/tests2/test_DeviceMatrixLight.py b/mpf/tests/test_DeviceMatrixLight.py similarity index 100% rename from mpf/tests2/test_DeviceMatrixLight.py rename to mpf/tests/test_DeviceMatrixLight.py diff --git a/mpf/tests2/test_DigitalOutput.py b/mpf/tests/test_DigitalOutput.py similarity index 100% rename from mpf/tests2/test_DigitalOutput.py rename to mpf/tests/test_DigitalOutput.py diff --git a/mpf/tests2/test_DigitalScoreReels.py b/mpf/tests/test_DigitalScoreReels.py similarity index 100% rename from mpf/tests2/test_DigitalScoreReels.py rename to mpf/tests/test_DigitalScoreReels.py diff --git a/mpf/tests2/test_Diverter.py b/mpf/tests/test_Diverter.py similarity index 100% rename from mpf/tests2/test_Diverter.py rename to mpf/tests/test_Diverter.py diff --git a/mpf/tests2/test_Dmd.py b/mpf/tests/test_Dmd.py similarity index 100% rename from mpf/tests2/test_Dmd.py rename to mpf/tests/test_Dmd.py diff --git a/mpf/tests2/test_DropTargets.py b/mpf/tests/test_DropTargets.py similarity index 100% rename from mpf/tests2/test_DropTargets.py rename to mpf/tests/test_DropTargets.py diff --git a/mpf/tests2/test_DualWoundCoil.py b/mpf/tests/test_DualWoundCoil.py similarity index 100% rename from mpf/tests2/test_DualWoundCoil.py rename to mpf/tests/test_DualWoundCoil.py diff --git a/mpf/tests2/test_EventManager.py b/mpf/tests/test_EventManager.py similarity index 100% rename from mpf/tests2/test_EventManager.py rename to mpf/tests/test_EventManager.py diff --git a/mpf/tests2/test_EventPlayer.py b/mpf/tests/test_EventPlayer.py similarity index 100% rename from mpf/tests2/test_EventPlayer.py rename to mpf/tests/test_EventPlayer.py diff --git a/mpf/tests2/test_ExtraBall.py b/mpf/tests/test_ExtraBall.py similarity index 100% rename from mpf/tests2/test_ExtraBall.py rename to mpf/tests/test_ExtraBall.py diff --git a/mpf/tests2/test_Fadecandy.py b/mpf/tests/test_Fadecandy.py similarity index 100% rename from mpf/tests2/test_Fadecandy.py rename to mpf/tests/test_Fadecandy.py diff --git a/mpf/tests2/test_Fast.py b/mpf/tests/test_Fast.py similarity index 100% rename from mpf/tests2/test_Fast.py rename to mpf/tests/test_Fast.py diff --git a/mpf/tests2/test_Fast_Audio.py b/mpf/tests/test_Fast_Audio.py similarity index 100% rename from mpf/tests2/test_Fast_Audio.py rename to mpf/tests/test_Fast_Audio.py diff --git a/mpf/tests2/test_Fast_Dmd.py b/mpf/tests/test_Fast_Dmd.py similarity index 100% rename from mpf/tests2/test_Fast_Dmd.py rename to mpf/tests/test_Fast_Dmd.py diff --git a/mpf/tests2/test_Fast_Exp.py b/mpf/tests/test_Fast_Exp.py similarity index 100% rename from mpf/tests2/test_Fast_Exp.py rename to mpf/tests/test_Fast_Exp.py diff --git a/mpf/tests2/test_Fast_Nano.py b/mpf/tests/test_Fast_Nano.py similarity index 100% rename from mpf/tests2/test_Fast_Nano.py rename to mpf/tests/test_Fast_Nano.py diff --git a/mpf/tests2/test_Fast_Neuron.py b/mpf/tests/test_Fast_Neuron.py similarity index 100% rename from mpf/tests2/test_Fast_Neuron.py rename to mpf/tests/test_Fast_Neuron.py diff --git a/mpf/tests2/test_Fast_Retro.py b/mpf/tests/test_Fast_Retro.py similarity index 100% rename from mpf/tests2/test_Fast_Retro.py rename to mpf/tests/test_Fast_Retro.py diff --git a/mpf/tests2/test_Fast_Seg.py b/mpf/tests/test_Fast_Seg.py similarity index 100% rename from mpf/tests2/test_Fast_Seg.py rename to mpf/tests/test_Fast_Seg.py diff --git a/mpf/tests2/test_Flippers.py b/mpf/tests/test_Flippers.py similarity index 100% rename from mpf/tests2/test_Flippers.py rename to mpf/tests/test_Flippers.py diff --git a/mpf/tests2/test_FlippersHoldNoEos.py b/mpf/tests/test_FlippersHoldNoEos.py similarity index 100% rename from mpf/tests2/test_FlippersHoldNoEos.py rename to mpf/tests/test_FlippersHoldNoEos.py diff --git a/mpf/tests2/test_FlippersSoftwareEosRepulse.py b/mpf/tests/test_FlippersSoftwareEosRepulse.py similarity index 100% rename from mpf/tests2/test_FlippersSoftwareEosRepulse.py rename to mpf/tests/test_FlippersSoftwareEosRepulse.py diff --git a/mpf/tests2/test_GottliebTrough.py b/mpf/tests/test_GottliebTrough.py similarity index 100% rename from mpf/tests2/test_GottliebTrough.py rename to mpf/tests/test_GottliebTrough.py diff --git a/mpf/tests2/test_Head2Head.py b/mpf/tests/test_Head2Head.py similarity index 100% rename from mpf/tests2/test_Head2Head.py rename to mpf/tests/test_Head2Head.py diff --git a/mpf/tests2/test_HighScoreMode.py b/mpf/tests/test_HighScoreMode.py similarity index 100% rename from mpf/tests2/test_HighScoreMode.py rename to mpf/tests/test_HighScoreMode.py diff --git a/mpf/tests2/test_HighScoreModeWithVars.py b/mpf/tests/test_HighScoreModeWithVars.py similarity index 100% rename from mpf/tests2/test_HighScoreModeWithVars.py rename to mpf/tests/test_HighScoreModeWithVars.py diff --git a/mpf/tests2/test_I2cServoController.py b/mpf/tests/test_I2cServoController.py similarity index 100% rename from mpf/tests2/test_I2cServoController.py rename to mpf/tests/test_I2cServoController.py diff --git a/mpf/tests2/test_InfoLights.py b/mpf/tests/test_InfoLights.py similarity index 100% rename from mpf/tests2/test_InfoLights.py rename to mpf/tests/test_InfoLights.py diff --git a/mpf/tests2/test_Kickback.py b/mpf/tests/test_Kickback.py similarity index 100% rename from mpf/tests2/test_Kickback.py rename to mpf/tests/test_Kickback.py diff --git a/mpf/tests2/test_LightGroups.py b/mpf/tests/test_LightGroups.py similarity index 100% rename from mpf/tests2/test_LightGroups.py rename to mpf/tests/test_LightGroups.py diff --git a/mpf/tests2/test_LightPlayer.py b/mpf/tests/test_LightPlayer.py similarity index 100% rename from mpf/tests2/test_LightPlayer.py rename to mpf/tests/test_LightPlayer.py diff --git a/mpf/tests2/test_LightPositions.py b/mpf/tests/test_LightPositions.py similarity index 100% rename from mpf/tests2/test_LightPositions.py rename to mpf/tests/test_LightPositions.py diff --git a/mpf/tests2/test_LightSegmentDisplays.py b/mpf/tests/test_LightSegmentDisplays.py similarity index 100% rename from mpf/tests2/test_LightSegmentDisplays.py rename to mpf/tests/test_LightSegmentDisplays.py diff --git a/mpf/tests2/test_LogicBlocks.py b/mpf/tests/test_LogicBlocks.py similarity index 100% rename from mpf/tests2/test_LogicBlocks.py rename to mpf/tests/test_LogicBlocks.py diff --git a/mpf/tests2/test_MMA8451.py b/mpf/tests/test_MMA8451.py similarity index 100% rename from mpf/tests2/test_MMA8451.py rename to mpf/tests/test_MMA8451.py diff --git a/mpf/tests2/test_MachineVariables.py b/mpf/tests/test_MachineVariables.py similarity index 100% rename from mpf/tests2/test_MachineVariables.py rename to mpf/tests/test_MachineVariables.py diff --git a/mpf/tests2/test_Magnet.py b/mpf/tests/test_Magnet.py similarity index 100% rename from mpf/tests2/test_Magnet.py rename to mpf/tests/test_Magnet.py diff --git a/mpf/tests2/test_MatchMode.py b/mpf/tests/test_MatchMode.py similarity index 100% rename from mpf/tests2/test_MatchMode.py rename to mpf/tests/test_MatchMode.py diff --git a/mpf/tests2/test_Modes.py b/mpf/tests/test_Modes.py similarity index 100% rename from mpf/tests2/test_Modes.py rename to mpf/tests/test_Modes.py diff --git a/mpf/tests2/test_ModesConfigValidation.py b/mpf/tests/test_ModesConfigValidation.py similarity index 100% rename from mpf/tests2/test_ModesConfigValidation.py rename to mpf/tests/test_ModesConfigValidation.py diff --git a/mpf/tests2/test_Motors.py b/mpf/tests/test_Motors.py similarity index 100% rename from mpf/tests2/test_Motors.py rename to mpf/tests/test_Motors.py diff --git a/mpf/tests2/test_MpfTestCase.py b/mpf/tests/test_MpfTestCase.py similarity index 100% rename from mpf/tests2/test_MpfTestCase.py rename to mpf/tests/test_MpfTestCase.py diff --git a/mpf/tests2/test_MultiBall.py b/mpf/tests/test_MultiBall.py similarity index 100% rename from mpf/tests2/test_MultiBall.py rename to mpf/tests/test_MultiBall.py diff --git a/mpf/tests2/test_MultiballLock.py b/mpf/tests/test_MultiballLock.py similarity index 100% rename from mpf/tests2/test_MultiballLock.py rename to mpf/tests/test_MultiballLock.py diff --git a/mpf/tests2/test_MyPinballs.py b/mpf/tests/test_MyPinballs.py similarity index 100% rename from mpf/tests2/test_MyPinballs.py rename to mpf/tests/test_MyPinballs.py diff --git a/mpf/tests2/test_OPP.py b/mpf/tests/test_OPP.py similarity index 100% rename from mpf/tests2/test_OPP.py rename to mpf/tests/test_OPP.py diff --git a/mpf/tests2/test_Openpixel.py b/mpf/tests/test_Openpixel.py similarity index 100% rename from mpf/tests2/test_Openpixel.py rename to mpf/tests/test_Openpixel.py diff --git a/mpf/tests2/test_Osc.py b/mpf/tests/test_Osc.py similarity index 100% rename from mpf/tests2/test_Osc.py rename to mpf/tests/test_Osc.py diff --git a/mpf/tests2/test_P3_Roc.py b/mpf/tests/test_P3_Roc.py similarity index 100% rename from mpf/tests2/test_P3_Roc.py rename to mpf/tests/test_P3_Roc.py diff --git a/mpf/tests2/test_P_Roc.py b/mpf/tests/test_P_Roc.py similarity index 100% rename from mpf/tests2/test_P_Roc.py rename to mpf/tests/test_P_Roc.py diff --git a/mpf/tests2/test_PlaceholderManager.py b/mpf/tests/test_PlaceholderManager.py similarity index 100% rename from mpf/tests2/test_PlaceholderManager.py rename to mpf/tests/test_PlaceholderManager.py diff --git a/mpf/tests2/test_Platform.py b/mpf/tests/test_Platform.py similarity index 100% rename from mpf/tests2/test_Platform.py rename to mpf/tests/test_Platform.py diff --git a/mpf/tests2/test_PlayerVars.py b/mpf/tests/test_PlayerVars.py similarity index 100% rename from mpf/tests2/test_PlayerVars.py rename to mpf/tests/test_PlayerVars.py diff --git a/mpf/tests2/test_Playfield.py b/mpf/tests/test_Playfield.py similarity index 100% rename from mpf/tests2/test_Playfield.py rename to mpf/tests/test_Playfield.py diff --git a/mpf/tests2/test_PlayfieldTransfer.py b/mpf/tests/test_PlayfieldTransfer.py similarity index 100% rename from mpf/tests2/test_PlayfieldTransfer.py rename to mpf/tests/test_PlayfieldTransfer.py diff --git a/mpf/tests2/test_PluginConfigPlayer.py b/mpf/tests/test_PluginConfigPlayer.py similarity index 100% rename from mpf/tests2/test_PluginConfigPlayer.py rename to mpf/tests/test_PluginConfigPlayer.py diff --git a/mpf/tests2/test_PololuMaestro.py b/mpf/tests/test_PololuMaestro.py similarity index 100% rename from mpf/tests2/test_PololuMaestro.py rename to mpf/tests/test_PololuMaestro.py diff --git a/mpf/tests2/test_PololuTic.py b/mpf/tests/test_PololuTic.py similarity index 100% rename from mpf/tests2/test_PololuTic.py rename to mpf/tests/test_PololuTic.py diff --git a/mpf/tests2/test_QueueEventPlayer.py b/mpf/tests/test_QueueEventPlayer.py similarity index 100% rename from mpf/tests2/test_QueueEventPlayer.py rename to mpf/tests/test_QueueEventPlayer.py diff --git a/mpf/tests2/test_RGBColor.py b/mpf/tests/test_RGBColor.py similarity index 100% rename from mpf/tests2/test_RGBColor.py rename to mpf/tests/test_RGBColor.py diff --git a/mpf/tests2/test_RandomEventPlayer.py b/mpf/tests/test_RandomEventPlayer.py similarity index 100% rename from mpf/tests2/test_RandomEventPlayer.py rename to mpf/tests/test_RandomEventPlayer.py diff --git a/mpf/tests2/test_Randomizer.py b/mpf/tests/test_Randomizer.py similarity index 100% rename from mpf/tests2/test_Randomizer.py rename to mpf/tests/test_Randomizer.py diff --git a/mpf/tests2/test_Rpi.py b/mpf/tests/test_Rpi.py similarity index 100% rename from mpf/tests2/test_Rpi.py rename to mpf/tests/test_Rpi.py diff --git a/mpf/tests2/test_RpiDmd.py b/mpf/tests/test_RpiDmd.py similarity index 100% rename from mpf/tests2/test_RpiDmd.py rename to mpf/tests/test_RpiDmd.py diff --git a/mpf/tests2/test_ScoreQueue.py b/mpf/tests/test_ScoreQueue.py similarity index 100% rename from mpf/tests2/test_ScoreQueue.py rename to mpf/tests/test_ScoreQueue.py diff --git a/mpf/tests2/test_ScoreReels.py b/mpf/tests/test_ScoreReels.py similarity index 100% rename from mpf/tests2/test_ScoreReels.py rename to mpf/tests/test_ScoreReels.py diff --git a/mpf/tests2/test_SegmentDisplay.py b/mpf/tests/test_SegmentDisplay.py similarity index 100% rename from mpf/tests2/test_SegmentDisplay.py rename to mpf/tests/test_SegmentDisplay.py diff --git a/mpf/tests2/test_SegmentMappings.py b/mpf/tests/test_SegmentMappings.py similarity index 100% rename from mpf/tests2/test_SegmentMappings.py rename to mpf/tests/test_SegmentMappings.py diff --git a/mpf/tests2/test_SequenceShot.py b/mpf/tests/test_SequenceShot.py similarity index 100% rename from mpf/tests2/test_SequenceShot.py rename to mpf/tests/test_SequenceShot.py diff --git a/mpf/tests2/test_ServiceCli.py b/mpf/tests/test_ServiceCli.py similarity index 100% rename from mpf/tests2/test_ServiceCli.py rename to mpf/tests/test_ServiceCli.py diff --git a/mpf/tests2/test_ServiceMode.py b/mpf/tests/test_ServiceMode.py similarity index 100% rename from mpf/tests2/test_ServiceMode.py rename to mpf/tests/test_ServiceMode.py diff --git a/mpf/tests2/test_Servo.py b/mpf/tests/test_Servo.py similarity index 100% rename from mpf/tests2/test_Servo.py rename to mpf/tests/test_Servo.py diff --git a/mpf/tests2/test_Settings.py b/mpf/tests/test_Settings.py similarity index 100% rename from mpf/tests2/test_Settings.py rename to mpf/tests/test_Settings.py diff --git a/mpf/tests2/test_ShotGroups.py b/mpf/tests/test_ShotGroups.py similarity index 100% rename from mpf/tests2/test_ShotGroups.py rename to mpf/tests/test_ShotGroups.py diff --git a/mpf/tests2/test_Shots.py b/mpf/tests/test_Shots.py similarity index 100% rename from mpf/tests2/test_Shots.py rename to mpf/tests/test_Shots.py diff --git a/mpf/tests2/test_ShowPools.py b/mpf/tests/test_ShowPools.py similarity index 100% rename from mpf/tests2/test_ShowPools.py rename to mpf/tests/test_ShowPools.py diff --git a/mpf/tests2/test_Shows.py b/mpf/tests/test_Shows.py similarity index 100% rename from mpf/tests2/test_Shows.py rename to mpf/tests/test_Shows.py diff --git a/mpf/tests2/test_SmartMatrix.py b/mpf/tests/test_SmartMatrix.py similarity index 100% rename from mpf/tests2/test_SmartMatrix.py rename to mpf/tests/test_SmartMatrix.py diff --git a/mpf/tests2/test_SmartVirtualPlatform.py b/mpf/tests/test_SmartVirtualPlatform.py similarity index 100% rename from mpf/tests2/test_SmartVirtualPlatform.py rename to mpf/tests/test_SmartVirtualPlatform.py diff --git a/mpf/tests2/test_Smbus2.py b/mpf/tests/test_Smbus2.py similarity index 100% rename from mpf/tests2/test_Smbus2.py rename to mpf/tests/test_Smbus2.py diff --git a/mpf/tests2/test_Snux.py b/mpf/tests/test_Snux.py similarity index 100% rename from mpf/tests2/test_Snux.py rename to mpf/tests/test_Snux.py diff --git a/mpf/tests2/test_SpiBitBang.py b/mpf/tests/test_SpiBitBang.py similarity index 100% rename from mpf/tests2/test_SpiBitBang.py rename to mpf/tests/test_SpiBitBang.py diff --git a/mpf/tests2/test_Spike.py b/mpf/tests/test_Spike.py similarity index 100% rename from mpf/tests2/test_Spike.py rename to mpf/tests/test_Spike.py diff --git a/mpf/tests2/test_Spinners.py b/mpf/tests/test_Spinners.py similarity index 100% rename from mpf/tests2/test_Spinners.py rename to mpf/tests/test_Spinners.py diff --git a/mpf/tests2/test_StateMachine.py b/mpf/tests/test_StateMachine.py similarity index 100% rename from mpf/tests2/test_StateMachine.py rename to mpf/tests/test_StateMachine.py diff --git a/mpf/tests2/test_StepStick.py b/mpf/tests/test_StepStick.py similarity index 100% rename from mpf/tests2/test_StepStick.py rename to mpf/tests/test_StepStick.py diff --git a/mpf/tests2/test_Stepper.py b/mpf/tests/test_Stepper.py similarity index 100% rename from mpf/tests2/test_Stepper.py rename to mpf/tests/test_Stepper.py diff --git a/mpf/tests2/test_SwitchController.py b/mpf/tests/test_SwitchController.py similarity index 100% rename from mpf/tests2/test_SwitchController.py rename to mpf/tests/test_SwitchController.py diff --git a/mpf/tests2/test_SwitchPlayer.py b/mpf/tests/test_SwitchPlayer.py similarity index 100% rename from mpf/tests2/test_SwitchPlayer.py rename to mpf/tests/test_SwitchPlayer.py diff --git a/mpf/tests2/test_SwitchPositions.py b/mpf/tests/test_SwitchPositions.py similarity index 100% rename from mpf/tests2/test_SwitchPositions.py rename to mpf/tests/test_SwitchPositions.py diff --git a/mpf/tests2/test_System11Trough.py b/mpf/tests/test_System11Trough.py similarity index 100% rename from mpf/tests2/test_System11Trough.py rename to mpf/tests/test_System11Trough.py diff --git a/mpf/tests2/test_Tilt.py b/mpf/tests/test_Tilt.py similarity index 100% rename from mpf/tests2/test_Tilt.py rename to mpf/tests/test_Tilt.py diff --git a/mpf/tests2/test_TimedSwitch.py b/mpf/tests/test_TimedSwitch.py similarity index 100% rename from mpf/tests2/test_TimedSwitch.py rename to mpf/tests/test_TimedSwitch.py diff --git a/mpf/tests2/test_Timer.py b/mpf/tests/test_Timer.py similarity index 100% rename from mpf/tests2/test_Timer.py rename to mpf/tests/test_Timer.py diff --git a/mpf/tests2/test_TooLongExitCountDelay.py b/mpf/tests/test_TooLongExitCountDelay.py similarity index 100% rename from mpf/tests2/test_TooLongExitCountDelay.py rename to mpf/tests/test_TooLongExitCountDelay.py diff --git a/mpf/tests2/test_TrinamicsStepRocker.py b/mpf/tests/test_TrinamicsStepRocker.py similarity index 100% rename from mpf/tests2/test_TrinamicsStepRocker.py rename to mpf/tests/test_TrinamicsStepRocker.py diff --git a/mpf/tests2/test_TroughEntranceSwitch.py b/mpf/tests/test_TroughEntranceSwitch.py similarity index 100% rename from mpf/tests2/test_TroughEntranceSwitch.py rename to mpf/tests/test_TroughEntranceSwitch.py diff --git a/mpf/tests2/test_TwitchClient.py b/mpf/tests/test_TwitchClient.py similarity index 100% rename from mpf/tests2/test_TwitchClient.py rename to mpf/tests/test_TwitchClient.py diff --git a/mpf/tests2/test_Utility_Functions.py b/mpf/tests/test_Utility_Functions.py similarity index 100% rename from mpf/tests2/test_Utility_Functions.py rename to mpf/tests/test_Utility_Functions.py diff --git a/mpf/tests2/test_VPX.py b/mpf/tests/test_VPX.py similarity index 100% rename from mpf/tests2/test_VPX.py rename to mpf/tests/test_VPX.py diff --git a/mpf/tests2/test_VariablePlayer.py b/mpf/tests/test_VariablePlayer.py similarity index 100% rename from mpf/tests2/test_VariablePlayer.py rename to mpf/tests/test_VariablePlayer.py diff --git a/mpf/tests2/test_Virtual.py b/mpf/tests/test_Virtual.py similarity index 100% rename from mpf/tests2/test_Virtual.py rename to mpf/tests/test_Virtual.py diff --git a/mpf/tests2/test_VirtualPinball.py b/mpf/tests/test_VirtualPinball.py similarity index 100% rename from mpf/tests2/test_VirtualPinball.py rename to mpf/tests/test_VirtualPinball.py diff --git a/mpf/tests2/test_VirtualSegmentDisplayConnector.py b/mpf/tests/test_VirtualSegmentDisplayConnector.py similarity index 100% rename from mpf/tests2/test_VirtualSegmentDisplayConnector.py rename to mpf/tests/test_VirtualSegmentDisplayConnector.py diff --git a/mpf/tests2/test_VisualPinballEngine.py b/mpf/tests/test_VisualPinballEngine.py similarity index 100% rename from mpf/tests2/test_VisualPinballEngine.py rename to mpf/tests/test_VisualPinballEngine.py diff --git a/mpf/tests2/test_YamlInterface.py b/mpf/tests/test_YamlInterface.py similarity index 100% rename from mpf/tests2/test_YamlInterface.py rename to mpf/tests/test_YamlInterface.py diff --git a/mpf/tests2/test_Lisy.py b/mpf/tests2/test_Lisy.py deleted file mode 100644 index 11f7cbe69..000000000 --- a/mpf/tests2/test_Lisy.py +++ /dev/null @@ -1,869 +0,0 @@ -import time - -from mpf.platforms.interfaces.segment_display_platform_interface import FlashingType -from mpf.platforms.lisy import lisy - -from mpf.tests.MpfTestCase import MpfTestCase, test_config, MagicMock -from mpf.tests.loop import MockSerial, MockSocket - -COMMAND_LENGTH = { - 0: 1, - 1: 1, - 2: 1, - 3: 1, - 4: 1, - 6: 1, - 7: 2, - 9: 1, - 11: 2, - 12: 2, - 19: 1, - 21: 2, - 22: 2, - 23: 2, - 24: 3, - 25: 3, - 40: 2, - 41: 1, - 51: 1, - 60: 11, - 100: 1, - 101: 1, -} - - -class MockLisySocket(MockSocket, MockSerial): - - def read(self, length): - del length - if not self.queue: - return b"" - msg = self.queue.pop() - return msg - - def read_ready(self): - return bool(self.queue) - - def write_ready(self): - return True - - def write(self, msg): - """Write message.""" - # print("Serial received: " + "".join("\\x%02x" % b for b in msg) + " len: " + str(len(msg))) - total_msg_len = len(msg) - while msg: - command = msg[0] - if command == 13: - command_length = 6 + msg[5] - elif 30 <= command <= 35: - if self.api_version >= 9: - command_length = 2 + msg[1] - else: - command_length = msg.index(b'\x00') + 1 - elif command in (50, 54): - command_length = 3 if self.api_version >= 9 else 2 - elif command == 51: - command_length = 2 if self.api_version >= 9 else 1 - elif command in (52, 53): - command_length = msg[3:].index(b'\x00') + 4 - else: - command_length = COMMAND_LENGTH.get(command, None) - if command_length is None: - raise AssertionError("Unknown command {} in {}".format(command, "".join("\\x%02x" % b for b in msg))) - if len(msg) < command_length: - raise AssertionError("Message too short ({}) for command {} with length {} in {}".format( - len(msg), command_length, command, - "".join("\\x%02x" % b for b in msg))) - - self._handle_msg(msg[0:command_length]) - msg = msg[command_length:] - - return total_msg_len - - def _handle_msg(self, msg): - if msg in self.permanent_commands and msg not in self.expected_commands: - if self.permanent_commands[msg] is not None: - self.queue.append(self.permanent_commands[msg]) - return len(msg) - - if msg not in self.expected_commands: - self.crashed = True - print("Unexpected command: " + "".join("\\x%02x" % b for b in msg) + " len: " + str(len(msg))) - raise AssertionError("Unexpected command: " + "".join("\\x%02x" % b for b in msg) + - " len: " + str(len(msg))) - - if self.expected_commands[msg] is not None: - self.queue.append(self.expected_commands[msg]) - - del self.expected_commands[msg] - return len(msg) - - def send(self, data): - return self.write(data) - - def recv(self, size): - return self.read(size) - - def __init__(self, api_version): - super().__init__() - self.name = "SerialMock" - self.expected_commands = {} - self.queue = [] - self.permanent_commands = {} - self.crashed = False - self.api_version = api_version - - -class TestLisy(MpfTestCase): - - def get_config_file(self): - return 'config.yaml' - - def get_machine_path(self): - return 'tests/machine_files/lisy/' - - def _mock_loop(self): - self.clock.mock_socket("localhost", 1234, self.serialMock) - - def tearDown(self): - self.assertFalse(self.serialMock.crashed) - super().tearDown() - - def get_platform(self): - return False - - def _wait_for_processing(self): - start = time.time() - while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - - def setUp(self): - self.expected_duration = 1.5 - self.serialMock = MockLisySocket(api_version=8) - - self.serialMock.permanent_commands = { - b'\x29': b'\x7F', # changed switches? -> no - b'\x65': b'\x00' # watchdog - } - - self.serialMock.expected_commands = { - b'\x00': b'LISY1\00', # hw LISY1 - b'\x01': b'4.01\00', # lisy version - b'\x02': b'0.08\00', # api version - b'\x64': b'\x00', # reset -> ok - b'\x03': b'\x28', # get number of lamps -> 40 - b'\x04': b'\x09', # get number of solenoids -> 9 - b'\x06': b'\x05', # get number of displays -> 5 - b'\x09': b'\x58', # get number of switches -> 88 - b'\x1e\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display - b'\x1f\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display - b'\x20\x20\x20\x20\x20\x20\x20\x20\x00': None, # clear display - } - - for number in range(88): - if number % 10 >= 8: - self.serialMock.expected_commands[bytes([40, number])] = b'\x02' - else: - self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' - - super().setUp() - - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_platform(self): - self.maxDiff = None - infos = """LISY connected via network at localhost:1234 -Hardware: LISY1 Lisy Version: 4.01 API Version: 0.8 -Input count: 88 Input map: ['0', '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'] -Coil count: 9 -Modern lights count: 0 -Traditional lights count: 40 -Display count: 5 -""" - - self.assertEqual(self.machine.default_platform.get_info_string(), infos) - - # wait for watchdog - self.serialMock.expected_commands = { - b'\x65': b'\x00' # watchdog - } - self._wait_for_processing() - - # test initial switch state - self.assertSwitchState("s_test00", False) - self.assertSwitchState("s_test37", True) - self.assertSwitchState("s_test77_nc", True) - - self.serialMock.expected_commands = { - b'\x29': b'\x25' # 37 turned inactive - } - self.advance_time_and_run(.1) - # turns inactive - self.assertSwitchState("s_test37", False) - - self.serialMock.expected_commands = { - b'\x29': b'\xA5' # 37 turned active (again) - } - self.advance_time_and_run(.1) - # turns active - self.assertSwitchState("s_test37", True) - - self.serialMock.expected_commands = { - b'\x29': b'\xCD' # 77 turned active - } - self.advance_time_and_run(.1) - # turns inactive (because of NC) - self.assertSwitchState("s_test77_nc", False) - - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # pulse trough eject. enable and disable in software - self.serialMock.expected_commands = { - b'\x18\x67\x00': None, # set pulse_ms to 10ms - b'\x15\x67': None # enable - } - self.machine.coils["c_trough_eject"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.advance_time_and_run(2) - self.serialMock.expected_commands = { - b'\x16\x67': None # disable - } - self.advance_time_and_run() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # enable coil - self.serialMock.expected_commands = { - b'\x18\x01\x0a': None, # set pulse_ms to 10ms - b'\x15\x01': None - } - self.machine.coils["c_test_allow_enable"].enable() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # disable coil - self.serialMock.expected_commands = { - b'\x16\x01': None - } - self.machine.coils["c_test_allow_enable"].disable() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test light enable (using light 3) - self.serialMock.expected_commands = { - b'\x0b\x03': None - } - self.machine.lights["test_light"].on(key="test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # disable light (using light 3) - self.serialMock.expected_commands = { - b'\x0c\x03': None - } - self.machine.lights["test_light"].remove_from_stack_by_key("test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # start ball. enable flipper (using light 1) - self.serialMock.expected_commands = { - b'\x0b\x01': None - } - self.post_event("ball_started") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.advance_time_and_run() - - # end ball. disable flipper (using light 1) - self.serialMock.expected_commands = { - b'\x0c\x01': None - } - self.post_event("ball_will_end") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set info display to TEST - self.serialMock.expected_commands = { - b'\x1E TEST\x00': None - } - self.machine.segment_displays["info_display"].add_text("TEST") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set player 1 display to 42000 - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None - } - self.machine.segment_displays["player1_display"].add_text("42000") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set player 1 display to flashing - self.machine.segment_displays["player1_display"].set_flashing(FlashingType.FLASH_ALL) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None, - b'\x1F \x00': None - } - - self.advance_time_and_run(1) - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F \x00': None - } - - self.advance_time_and_run(.5) - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x1F 42000\x00': None, - } - self.machine.segment_displays["player1_display"].set_flashing(FlashingType.NO_FLASH) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound - self.serialMock.expected_commands = { - b'\x32\x02': None - } - self.post_event("test2") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file - self.serialMock.expected_commands = { - b'\x34\x00some_file\x00': None - } - self.post_event("play_file") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file looping - self.serialMock.expected_commands = { - b'\x34\x01some_file\x00': None - } - self.post_event("play_file_loop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # text to speech - self.serialMock.expected_commands = { - b'\x35\x02Hello MPF\x00': None - } - self.post_event("play_text") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set volume to 50 (32 hex) - self.serialMock.expected_commands = { - b'\x36\x32': None - } - self.post_event("volume_05") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # increase volume by 0.1 -> 60 -> hex 3C - self.serialMock.expected_commands = { - b'\x36\x3C': None - } - self.post_event("increase_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # decrease volume by 0.01 -> 59 -> hex 3B - self.serialMock.expected_commands = { - b'\x36\x3B': None - } - self.post_event("decrease_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test another sound - self.serialMock.expected_commands = { - b'\x32\x03': None - } - self.post_event("test3") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # stop sound - self.serialMock.expected_commands = { - b'\x33': None - } - self.post_event("test_stop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - @test_config("config_system11.yaml") - def test_system11(self): - # test normal coil - self.serialMock.expected_commands = { - b'\x18\x00\x14': None, # set pulse_ms to 20ms - b'\x17\x00': None # pulse coil 0 - } - self.machine.coils["c_test"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x18\x08\x0a': None, # set pulse_ms to 10ms to A/C relay - b'\x15\x08': None, # enable A/C relay - b'\x18\x01\x14': None, # set pulse_ms to 20ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x15\x08': None, # enable A/C relay - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test A-side coil - self.serialMock.expected_commands = { - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_a_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x18\x01\x0f': None, # set pulse_ms to 15ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_a_side"].pulse(15) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test C-side coil - self.serialMock.expected_commands = { - b'\x15\x08': None, # enable A/C relay - b'\x18\x01\x14': None, # set pulse_ms to 20ms - b'\x17\x01': None # pulse coil 1 - } - self.machine.coils["c_test1_c_side"].pulse(20) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # wait for A/C disable - self.serialMock.expected_commands = { - b'\x16\x08': None, # disable A/C relay - } - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - -class TestAPC(MpfTestCase): - - def get_config_file(self): - return 'config.yaml' - - def get_machine_path(self): - return 'tests/machine_files/apc/' - - def _mock_loop(self): - self.clock.mock_serial("com1", self.serialMock) - - def tearDown(self): - self.assertFalse(self.serialMock.crashed) - super().tearDown() - - def get_platform(self): - return False - - def _wait_for_processing(self): - start = time.time() - while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - - def setUp(self): - self.expected_duration = 1.5 - self.serialMock = MockLisySocket(api_version=9) - - self.serialMock.permanent_commands = { - b'\x29': b'\x7F', # changed switches? -> no - b'\x65': b'\x00' # watchdog - } - - self.serialMock.expected_commands = { - b'\x00': b'APC\00', # hw APC - b'\x01': b'0.02\00', # APC version - b'\x02': b'0.09\00', # api version - b'\x64': b'\x00', # reset -> ok - b'\x03': b'\x28', # get number of lamps -> 40 - b'\x04': b'\x09', # get number of solenoids -> 9 - b'\x06': b'\x05', # get number of displays -> 5 - b'\x07\x00': b'\x02\x10', # get type of display 0 - b'\x07\x01': b'\x03\x05', # get type of display 1 - b'\x07\x02': b'\x04\x07', # get type of display 2 - b'\x07\x03': b'\x05\x03', # get type of display 3 - b'\x07\x04': b'\x06\x10', # get type of display 4 - b'\x09': b'\x58', # get number of switches -> 88 - b'\x13': b'\x00', # get number of modern lights -> 0 - b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display - b'\x1f\x05\x00\x00\x00\x00\x00': None, # clear display - b'\x20\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # clear display - b'\x21\x03\x20\x20\x20': None, # clear display - b'\x22\x10\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20': None, # clear display - b'\x19\x00\x0a': None, - b'\x19\x01\x0a': None, - b'\x19\x67\xff': None, - b'\x19\x05\x1e': None, - b'\x19\x06\x0a': None, - b'\x19\x07\x0a': None, - } - - for number in range(88): - if number % 10 >= 8: - self.serialMock.expected_commands[bytes([40, number])] = b'\x02' - else: - self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' - - # prevent changes on real hardware - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() - - super().setUp() - - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() - - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_platform(self): - # wait for watchdog - self.serialMock.expected_commands = { - b'\x65': b'\x00' # watchdog - } - self._wait_for_processing() - - # test sound - self.serialMock.expected_commands = { - b'\x32\x01\x02': None - } - self.post_event("test2") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound on track 2 - self.serialMock.expected_commands = { - b'\x32\x02\x05': None - } - self.post_event("test4") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file - self.serialMock.expected_commands = { - b'\x34\x01\x00some_file\x00': None - } - self.post_event("play_file") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test sound file looping - self.serialMock.expected_commands = { - b'\x34\x01\x01some_file\x00': None - } - self.post_event("play_file_loop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # text to speech - self.serialMock.expected_commands = { - b'\x35\x01\x02Hello MPF\x00': None - } - self.post_event("play_text") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set volume to 50 (32 hex) - self.serialMock.expected_commands = { - b'\x36\x01\x32': None - } - self.post_event("volume_05") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # increase volume by 0.1 -> 60 -> hex 3C - self.serialMock.expected_commands = { - b'\x36\x01\x3C': None - } - self.post_event("increase_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # decrease volume by 0.01 -> 59 -> hex 3B - self.serialMock.expected_commands = { - b'\x36\x01\x3B': None - } - self.post_event("decrease_volume") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test another sound - self.serialMock.expected_commands = { - b'\x32\x01\x03': None - } - self.post_event("test3") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # stop sound - self.serialMock.expected_commands = { - b'\x33\01': None - } - self.post_event("test_stop") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_rules(self): - """Test HW Rules.""" - self.serialMock.expected_commands = { - b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main - b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold - } - self.machine.flippers["f_test_hold_eos"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main - b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold - } - self.machine.flippers["f_test_hold_eos"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot - b'\x19\x07\x14': None - } - self.machine.autofire_coils["ac_slingshot"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot - } - self.machine.autofire_coils["ac_slingshot"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set info display to TEST - self.serialMock.expected_commands = { - b'\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x03\x07': None - } - self.machine.segment_displays["info_display"].add_text("1337") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test recycle - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - -class TestLisyV10(MpfTestCase): - - def get_config_file(self): - return 'config_modern.yaml' - - def get_machine_path(self): - return 'tests/machine_files/lisy/' - - def _mock_loop(self): - self.clock.mock_serial("com1", self.serialMock) - - def tearDown(self): - self.assertFalse(self.serialMock.crashed) - super().tearDown() - - def get_platform(self): - return False - - def _wait_for_processing(self): - start = time.time() - while self.serialMock.expected_commands and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - - def setUp(self): - self.expected_duration = 1.5 - self.serialMock = MockLisySocket(api_version=10) - - self.serialMock.permanent_commands = { - b'\x29': b'\x7F', # changed switches? -> no - b'\x65': b'\x00' # watchdog - } - - self.serialMock.expected_commands = { - b'\x00': b'FUTURE_HARDWARE\00', # hw not known yet - b'\x01': b'0.42\00', # hardware version - b'\x02': b'0.10\00', # api version - b'\x64': b'\x00', # reset -> ok - b'\x03': b'\x00', # get number of simple lamps -> 0 - b'\x04': b'\x09', # get number of solenoids -> 9 - b'\x06': b'\x00', # get number of displays -> 0 - b'\x09': b'\x58', # get number of switches -> 88 - b'\x13': b'\x02\x01', # get number of modern lights -> 512 + 1 = 513 modern lights - b'\x19\x00\x0a': None, - b'\x19\x01\x0a': None, - b'\x19\x05\x1e': None, - b'\x19\x06\x0a': None, - b'\x19\x07\x0a': None, - } - - for number in range(88): - if number % 10 >= 8: - self.serialMock.expected_commands[bytes([40, number])] = b'\x02' - else: - self.serialMock.expected_commands[bytes([40, number])] = b'\x00' if number != 37 else b'\x01' - - # prevent changes on real hardware - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial = MagicMock() - - super().setUp() - - lisy.LisyHardwarePlatform._disable_dts_on_start_of_serial.assert_called_with() - - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_rules(self): - """Test HW Rules.""" - # wait for watchdog - self.serialMock.expected_commands = { - b'\x65': b'\x00' # watchdog - } - self._wait_for_processing() - - self.serialMock.expected_commands = { - b'\x3c\x05\x01\x02\x00\x1e\xff\x00\x03\x02\x00': None, # create rule for main - b'\x3c\x06\x01\x00\x00\x0a\xff\xff\x03\x00\x00': None, # create rule for hold - } - self.machine.flippers["f_test_hold_eos"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for main - b'\x3c\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for hold - } - self.machine.flippers["f_test_hold_eos"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x03\x00\x00\x0a\xff\x00\x01\x00\x00': None, # add rule for slingshot - b'\x19\x07\x14': None - } - self.machine.autofire_coils["ac_slingshot"].enable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - self.serialMock.expected_commands = { - b'\x3c\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00': None, # remove rule for slingshot - } - self.machine.autofire_coils["ac_slingshot"].disable() - self.advance_time_and_run(.2) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # test recycle - # pulse coil - self.serialMock.expected_commands = { - b'\x18\x00\x0a': None, # set pulse_ms to 10ms - b'\x17\x00': None - } - self.machine.coils["c_test"].pulse() - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - def test_lights(self): - """Test lights.""" - # set color to one light without fade - self.serialMock.expected_commands = { - b'\x0d\x00\x00\x00\x00\x03\x11\x22\x33': None, # fade with 0ms fade time - } - self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], key="test") - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set color again (should do nothing) - self.machine.lights["test_light0"].remove_from_stack_by_key("test") - self.machine.lights["test_light0"].color([0x11, 0x22, 0x33], fade_ms=100) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # set color to the second light without fade - self.serialMock.expected_commands = { - b'\x0d\x00\x03\x00\x00\x04\x00\x11\x22\x11': None, # fade with 0ms fade time starting at channel 3 - # 4 channels because this is a RGBW light - } - self.machine.lights["test_light1"].color([0x11, 0x22, 0x33]) - self._wait_for_processing() - self.assertFalse(self.serialMock.expected_commands) - - # fade both lights together (fade depending on serial timing) - self.serialMock.expected_commands = { - b'\x0d\x00\x00\x01\x18\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x19\x07\xaa\xbb\xcc\x00\x11\x22\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x20\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x21\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - b'\x0d\x00\x00\x01\x22\x07\xaa\xbb\xcc\xdd\xee\xff\xdd': None, # fade with 300ms fade time - } - self.machine.lights["test_light0"].color([0xaa, 0xbb, 0xcc], fade_ms=300) - self.machine.lights["test_light1"].color([0xdd, 0xee, 0xff], fade_ms=300) - start = time.time() - while len(self.serialMock.expected_commands) > 4 and not self.serialMock.crashed and time.time() < start + 10: - self.advance_time_and_run(.01) - self.assertEqual(4, len(self.serialMock.expected_commands)) From ea6e2859bf83fc316566ee760c717134d870b60d Mon Sep 17 00:00:00 2001 From: Alex Lobascio Date: Thu, 12 Dec 2024 03:29:06 -0800 Subject: [PATCH 11/11] more debugging for weird 255 value --- mpf/tests/test_Spike.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mpf/tests/test_Spike.py b/mpf/tests/test_Spike.py index 3ea497b5d..bf81c50ed 100644 --- a/mpf/tests/test_Spike.py +++ b/mpf/tests/test_Spike.py @@ -19,6 +19,7 @@ def read(self, length): return b'' msg = self.queue.pop() + print(f"DQ: {msg}") return msg def read_ready(self): @@ -40,15 +41,19 @@ def write(self, encoded_msg): self.queue.append(b'MPF Spike Bridge!\r\n') return len(encoded_msg) if encoded_msg[0] == 0x00: + print("WR1") self._handle_msg(encoded_msg[0:1]) encoded_msg = encoded_msg[1:] elif encoded_msg[0] == 0x01: + print("WR2") self._handle_msg(encoded_msg[0:2]) encoded_msg = encoded_msg[2:] elif encoded_msg[0] == 0x80 and encoded_msg[2] == 0x90: + print("WR3") self._handle_msg(encoded_msg[0:2051]) encoded_msg = encoded_msg[2051:] else: + print("W4") msg_len = encoded_msg[1] + 3 self._handle_msg(encoded_msg[0:msg_len]) encoded_msg = encoded_msg[msg_len:] @@ -70,6 +75,7 @@ def _handle_msg(self, encoded_msg): msg = encoded_msg + print(f"HA: {msg}") msg = bytes(msg) if msg and msg[0] & 0x80 and (msg[2] == 0x11 or (msg[2] == 0xf0 and msg[3] == 0x10)):