Skip to content

Commit 55f42b2

Browse files
committed
Semaphore: Add a regress test for reliability.
1 parent f316e90 commit 55f42b2

12 files changed

Lines changed: 435 additions & 9 deletions

File tree

right/src/debug.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#define DEBUG_MODE false
1717
#define DEBUG_STRESS_UART false
1818
#define DEBUG_STRESS_GATT false
19-
#define DEBUG_STRESS_REPORTS false
2019
#define DEBUG_TEST_RTT false
2120
#define DEBUG_LOG_UART true
2221
#define DEBUG_LOG_MESSAGES false

right/src/hid/transport.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern "C" {
2020
#include "jitter_test.h"
2121
#include "usb_state.h"
2222
#include "utils.h"
23+
#include "test_suite/test_hooks.h"
2324
}
2425
#include "command_app.hpp"
2526
#include "controls_app.hpp"
@@ -36,6 +37,7 @@ typedef enum {
3637
ReportSink_Usb,
3738
ReportSink_BleHid,
3839
ReportSink_Dongle,
40+
ReportSink_TestSuite,
3941
} report_sink_t;
4042

4143
// Exponential moving average (alpha=1/8) of the measured delay between a
@@ -53,6 +55,8 @@ static uint32_t dispatchTimeMs = 0;
5355
// callback then reduces the estimate to "now + interval".
5456
static constexpr uint32_t USB_REPORT_INTERVAL_MS = 1;
5557

58+
bool UnreliableTransportTestMode = false;
59+
5660
static uint32_t reportIntervalForSink(report_sink_t sink)
5761
{
5862
switch (sink) {
@@ -66,7 +70,7 @@ static uint32_t reportIntervalForSink(report_sink_t sink)
6670
return 11;
6771
#endif
6872
default:
69-
return 0;
73+
return 1;
7074
}
7175
}
7276

@@ -109,9 +113,14 @@ extern "C" void HidTransport_NoteNusReportSent(void)
109113

110114
static report_sink_t determineSink()
111115
{
116+
if (TestHooks_Active) {
117+
return ReportSink_TestSuite;
118+
}
119+
112120
#if DEVICE_IS_UHK_DONGLE || DEVICE_IS_UHK60
113121
return ReportSink_Usb;
114122
#else
123+
115124
connection_type_t connectionType = Connections_Type(ActiveHostConnectionId);
116125

117126
if (!Connections_IsReady(ActiveHostConnectionId)) {
@@ -174,8 +183,8 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
174183
noteReportDispatched(sink);
175184
Trace_Printf("z11,%d", sink);
176185
errno_t err;
177-
if (DEBUG_STRESS_REPORTS && Utils_Random() % 16 == 0) {
178-
return 1;
186+
if (UnreliableTransportTestMode && Utils_Random() % 7 == 0) {
187+
return -EAGAIN;
179188
}
180189
switch (sink) {
181190
case ReportSink_Usb:
@@ -196,6 +205,11 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
196205
}
197206
break;
198207
#endif
208+
case ReportSink_TestSuite:
209+
err = 0;
210+
TestHooks_CaptureReport(report);
211+
Hid_KeyboardReportSentCallback(HID_TRANSPORT_USB);
212+
break;
199213
default:
200214
#ifdef __ZEPHYR__
201215
printk("Unhandled and unexpected switch state!\n");
@@ -209,8 +223,7 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
209223

210224
extern "C" void Hid_KeyboardReportSentCallback(hid_transport_t transport)
211225
{
212-
if (DEBUG_STRESS_REPORTS && Utils_Random() % 16 == 0) {
213-
// 666
226+
if (UnreliableTransportTestMode && Utils_Random() % 7 == 0) {
214227
return;
215228
}
216229
UsbReportUpdater_ConfirmKeyboardReportSent();

right/src/hid/transport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef enum
2626

2727

2828
extern float HidReportBleLatencyAvgMs;
29+
extern bool UnreliableTransportTestMode;
2930

3031
void Hid_TransportStateChanged(hid_transport_t transport, bool enabled);
3132

right/src/test_suite/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ All actions are defined as macros in `test_actions.h`. The struct backing them i
2929
| `TEST_SET_GENERIC_ACTION(key_id, action)` | Base only |
3030
| `TEST_SET_EMPTY(key_id)` | Base only |
3131
| `TEST_SET_CONFIG(config_text)` | Runs a `set` command (no key mapping) |
32+
| `TEST_SET_BOOL(bool_ptr, bool_value)` | Writes `bool_value` to the `bool` at `bool_ptr` (e.g. toggling a test-mode flag) |
3233

3334
`shortcut` strings go through `MacroShortcutParser_Parse` — same syntax as in macros (e.g. `"LS-i"`, `"sLA-tab"`, `"tab"`).
3435

right/src/test_suite/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ target_sources(${PROJECT_NAME} PRIVATE
1818
tests/test_parser_benevolence.c
1919
tests/test_sticky.c
2020
tests/test_playtime.c
21+
tests/test_transport.c
2122
)

right/src/test_suite/test_actions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@
7272
#define TEST_SET_CONFIG(config_text) \
7373
{ .type = TestAction_SetConfig, .configText = (config_text) }
7474

75+
// SetBool: write a bool value to the bool pointed to by bool_ptr
76+
#define TEST_SET_BOOL(bool_ptr, bool_value) \
77+
{ .type = TestAction_SetBool, .boolPtr = (bool_ptr), .boolValue = (bool_value) }
78+
7579
#define TEST_END() \
7680
{ .type = TestAction_End }
7781

@@ -89,6 +93,7 @@ typedef enum {
8993
TestAction_SetSecondaryRole,
9094
TestAction_SetGenericAction,
9195
TestAction_SetConfig,
96+
TestAction_SetBool,
9297
TestAction_Expect, // OutputMachine only
9398
TestAction_ExpectMaybe, // OutputMachine only, optional
9499
TestAction_CheckNow, // Both machines
@@ -101,6 +106,8 @@ typedef struct {
101106
uint8_t switchLayerMode; // For SetLayerHold (0 = Hold, see SwitchLayerMode enum)
102107
uint8_t primaryScancode; // For SetSecondaryRole
103108
uint8_t secondaryRoleId; // For SetSecondaryRole
109+
bool *boolPtr; // For SetBool
110+
bool boolValue; // For SetBool
104111
union {
105112
uint16_t delayMs;
106113
const char *expectShortcuts; // Space-separated shortcut strings

right/src/test_suite/test_input_machine.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,14 @@ void InputMachine_Tick(void) {
342342
break;
343343
}
344344

345+
case TestAction_SetBool:
346+
if (action->boolPtr != NULL) {
347+
*action->boolPtr = action->boolValue;
348+
}
349+
LOG_VERBOSE("[TEST] > SetBool %s\n", action->boolValue ? "true" : "false");
350+
InputMachine_ActionIndex++;
351+
break;
352+
345353
case TestAction_CheckNow:
346354
if (!validateReport(action->expectShortcuts, true)) { // Always log failures
347355
InputMachine_Failed = true;

right/src/test_suite/test_output_machine.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ void OutputMachine_OnReportChange(const usb_basic_keyboard_report_t *report) {
9595
case TestAction_SetSecondaryRole:
9696
case TestAction_SetGenericAction:
9797
case TestAction_SetConfig:
98+
case TestAction_SetBool:
9899
OutputMachine_ActionIndex++;
99100
break;
100101

0 commit comments

Comments
 (0)