diff --git a/plugins/Kaleidoscope-EEPROM-Settings/src/kaleidoscope/plugin/EEPROM-Settings.h b/plugins/Kaleidoscope-EEPROM-Settings/src/kaleidoscope/plugin/EEPROM-Settings.h index d8c7291404..efac2d9e1f 100644 --- a/plugins/Kaleidoscope-EEPROM-Settings/src/kaleidoscope/plugin/EEPROM-Settings.h +++ b/plugins/Kaleidoscope-EEPROM-Settings/src/kaleidoscope/plugin/EEPROM-Settings.h @@ -88,8 +88,8 @@ class EEPROMSettings : public kaleidoscope::Plugin { *startAddress = start; // Load the data if the slice is initialized - Runtime.storage().get(start, *data); // Directly load data into the provided address if (!Runtime.storage().isSliceUninitialized(start, size)) { + Runtime.storage().get(start, *data); // Directly load data into the provided address return true; } diff --git a/testing/device-testing/.gitignore b/testing/device-testing/.gitignore new file mode 100644 index 0000000000..c18dd8d83c --- /dev/null +++ b/testing/device-testing/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/testing/device-testing/Makefile b/testing/device-testing/Makefile new file mode 100644 index 0000000000..bde80127a1 --- /dev/null +++ b/testing/device-testing/Makefile @@ -0,0 +1,20 @@ +# Makefile for running Python tests + +# Shell to use with Make +SHELL := /bin/bash + +# Find all Python test scripts +TEST_SCRIPTS := $(shell find . -type f -name 'test.py' ) + +.PHONY: test + +test-on-hardware-wiping-your-device: + @for script in $(TEST_SCRIPTS) ; do \ + echo "Running $$script..." ; \ + python -m unittest $$script ; \ + if [ $$? -ne 0 ]; then \ + echo "Test failed: $$script" ; \ + exit 1 ; \ + fi ; \ + done + diff --git a/testing/device-testing/mouse-keys-defaults/test.py b/testing/device-testing/mouse-keys-defaults/test.py new file mode 100644 index 0000000000..9441fb85e5 --- /dev/null +++ b/testing/device-testing/mouse-keys-defaults/test.py @@ -0,0 +1,68 @@ +import subprocess +import unittest +import time +def run_focus_command(command, hide_stderr=False): + """Execute a focus send command, print the command and its output, and return its output.""" + stderr_setting = subprocess.DEVNULL if hide_stderr else subprocess.PIPE + print(f"Running command: {command}") + completed_process = subprocess.run(f"focus send {command}", shell=True, stdout=subprocess.PIPE, stderr=stderr_setting, text=True) + print(f"Result: {completed_process.stdout.strip()}") + if completed_process.returncode != 0 and not hide_stderr: + print(f"Error: {completed_process.stderr.strip()}" if completed_process.stderr else "Command failed with no error output.") + return completed_process.stdout.strip(), completed_process.returncode + +class TestFocusCommands(unittest.TestCase): + def test_mousekeys_base_speed_persistence(self): + _, _ = run_focus_command("version") + + # Initially try to erase eeprom and expect an error + _, returncode = run_focus_command("eeprom.erase", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Eeprom erase should fail but did not.") + + #erasing eeprom takes a moment + time.sleep(5) + + # Verify initial mousekeys.base_speed is '1' + initial_mode, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(initial_mode, '50', "Initial mousekeys.base_speed should be '50'") + + # Change mousekeys.base_speed to 50 and verify + run_focus_command("mousekeys.base_speed 60") + mode_after_setting_to_60, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(mode_after_setting_to_60, '60', "mousekeys.base_speed should be '60' after setting to 60") + + # Reset device and expect an error + _, returncode = run_focus_command("device.reset", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Device reset should fail but did not.") + time.sleep(5) # Wait for the device to potentially reset + + # Verify mousekeys.base_speed is still 0 after reset + mode_after_reset, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(mode_after_reset, '60', "mousekeys.base_speed should remain '60' after reset") + + # Change mousekeys.base_speed to 1 and verify + run_focus_command("mousekeys.base_speed 250") + mode_after_setting_to_250, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(mode_after_setting_to_250, '250', "mousekeys.base_speed should be '250' after setting to 250") + + # Reset device again and expect an error + _, returncode = run_focus_command("device.reset", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Device reset should fail but did not.") + time.sleep(5) # Wait for the device to potentially reset + + # Verify mousekeys.base_speed is still 1 after reset + mode_final, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(mode_final, '250', "mousekeys.base_speed should remain '250' after final reset") + + # Try to erase eeprom again and expect an error + _, returncode = run_focus_command("eeprom.erase", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Eeprom erase should fail but did not.") + + time.sleep(5) # Wait for the device to potentially reset + + # Verify mousekeys.base_speed is still 1 after attempting to erase eeprom + mode_after_erase, _ = run_focus_command("mousekeys.base_speed") + self.assertEqual(mode_after_erase, '50', "mousekeys.base_speed should remain '50' after attempting to erase eeprom") + +if __name__ == '__main__': + unittest.main() diff --git a/testing/device-testing/spacecadet-off/space_cadet_off_after_reboot_and_reset.py b/testing/device-testing/spacecadet-off/test.py similarity index 100% rename from testing/device-testing/spacecadet-off/space_cadet_off_after_reboot_and_reset.py rename to testing/device-testing/spacecadet-off/test.py diff --git a/testing/device-testing/sticky-keys-off/test.py b/testing/device-testing/sticky-keys-off/test.py new file mode 100644 index 0000000000..d9a32a56e1 --- /dev/null +++ b/testing/device-testing/sticky-keys-off/test.py @@ -0,0 +1,68 @@ +import subprocess +import unittest +import time +def run_focus_command(command, hide_stderr=False): + """Execute a focus send command, print the command and its output, and return its output.""" + stderr_setting = subprocess.DEVNULL if hide_stderr else subprocess.PIPE + print(f"Running command: {command}") + completed_process = subprocess.run(f"focus send {command}", shell=True, stdout=subprocess.PIPE, stderr=stderr_setting, text=True) + print(f"Result: {completed_process.stdout.strip()}") + if completed_process.returncode != 0 and not hide_stderr: + print(f"Error: {completed_process.stderr.strip()}" if completed_process.stderr else "Command failed with no error output.") + return completed_process.stdout.strip(), completed_process.returncode + +class TestFocusCommands(unittest.TestCase): + def test_oneshot_auto_mods_persistence(self): + _, _ = run_focus_command("version") + + # Initially try to erase eeprom and expect an error + _, returncode = run_focus_command("eeprom.erase", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Eeprom erase should fail but did not.") + + #erasing eeprom takes a moment + time.sleep(5) + + # Verify initial oneshot.auto_mods is '1' + initial_mode, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(initial_mode, '0', "Initial oneshot.auto_mods should be '0'") + + # Change oneshot.auto_mods to 0 and verify + run_focus_command("oneshot.auto_mods 0") + mode_after_setting_to_0, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(mode_after_setting_to_0, '0', "oneshot.auto_mods should be '0' after setting to 0") + + # Reset device and expect an error + _, returncode = run_focus_command("device.reset", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Device reset should fail but did not.") + time.sleep(5) # Wait for the device to potentially reset + + # Verify oneshot.auto_mods is still 0 after reset + mode_after_reset, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(mode_after_reset, '0', "oneshot.auto_mods should remain '0' after reset") + + # Change oneshot.auto_mods to 1 and verify + run_focus_command("oneshot.auto_mods 1") + mode_after_setting_to_1, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(mode_after_setting_to_1, '1', "oneshot.auto_mods should be '1' after setting to 1") + + # Reset device again and expect an error + _, returncode = run_focus_command("device.reset", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Device reset should fail but did not.") + time.sleep(5) # Wait for the device to potentially reset + + # Verify oneshot.auto_mods is still 1 after reset + mode_final, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(mode_final, '1', "oneshot.auto_mods should remain '1' after final reset") + + # Try to erase eeprom again and expect an error + _, returncode = run_focus_command("eeprom.erase", hide_stderr=True) + self.assertNotEqual(returncode, 0, "Eeprom erase should fail but did not.") + + time.sleep(5) # Wait for the device to potentially reset + + # Verify oneshot.auto_mods is still 1 after attempting to erase eeprom + mode_after_erase, _ = run_focus_command("oneshot.auto_mods") + self.assertEqual(mode_after_erase, '0', "oneshot.auto_mods should remain '0' after attempting to erase eeprom") + +if __name__ == '__main__': + unittest.main()