Skip to content

Commit 65523c0

Browse files
committed
feat: qa tests
1 parent ca1fc9d commit 65523c0

File tree

8 files changed

+185
-7
lines changed

8 files changed

+185
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ gen_version = []
5858
bat_dev_lcd = []
5959
release_build = []
6060
e2e = []
61+
qa = []
6162

6263
[profile.dev]
6364
# Rust debug is too slow.

src/lcd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pub async fn lcd_task(
129129
lcd_driver.display_on_lcd(&mut lcd);
130130
}
131131

132-
#[cfg(not(feature = "e2e"))]
132+
#[cfg(not(any(feature = "e2e", feature = "qa")))]
133133
if !sleep_state()
134134
&& (Instant::now() - last_update).as_millis() > SLEEP_AFTER_MS
135135
&& current_scene.can_sleep()
@@ -144,7 +144,7 @@ pub async fn lcd_task(
144144
}
145145
}
146146

147-
#[cfg(not(feature = "e2e"))]
147+
#[cfg(not(any(feature = "e2e", feature = "qa")))]
148148
if sleep_state()
149149
&& !deeper_sleep_state()
150150
&& (Instant::now() - last_update).as_millis() > DEEPER_SLEEP_AFTER_MS

src/main.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ mod utils;
3434
mod version;
3535
mod ws;
3636

37+
#[cfg(feature = "qa")]
38+
mod qa;
39+
3740
pub fn custom_rng(buf: &mut [u8]) -> Result<(), getrandom::Error> {
3841
for chunk in buf.chunks_mut(4) {
3942
let random_u32 = unsafe { &*esp_hal::peripherals::RNG::PTR }
@@ -138,6 +141,9 @@ async fn main(spawner: Spawner) {
138141
global_state.clone(),
139142
));
140143

144+
#[cfg(feature = "qa")]
145+
spawner.must_spawn(qa::qa_processor(global_state.clone()));
146+
141147
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
142148
wm_settings.ssid.clear();
143149
_ = core::fmt::write(
@@ -221,13 +227,13 @@ async fn main(spawner: Spawner) {
221227
utils::backtrace_store::read_saved_backtrace().await;
222228

223229
let ws_sleep_sig = Rc::new(Signal::new());
224-
_ = spawner.spawn(ws::ws_task(
230+
spawner.must_spawn(ws::ws_task(
225231
wifi_res.sta_stack,
226232
ws_url,
227233
global_state.clone(),
228234
ws_sleep_sig.clone(),
229235
));
230-
_ = spawner.spawn(logger_task(global_state.clone()));
236+
spawner.must_spawn(logger_task(global_state.clone()));
231237

232238
set_brownout_detection(true);
233239
global_state.state.lock().await.scene = Scene::WaitingForCompetitor;

src/qa.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
use alloc::format;
2+
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal};
3+
4+
use crate::state::GlobalState;
5+
6+
static BACK_SIGNAL: Signal<CriticalSectionRawMutex, QaSignal> = Signal::new();
7+
#[derive(Debug)]
8+
pub enum QaSignal {
9+
ButtonDown(u8),
10+
ButtonUp(u8),
11+
Rfid(u128),
12+
StackmatConnected,
13+
Stackmat(u64),
14+
}
15+
16+
#[embassy_executor::task]
17+
pub async fn qa_processor(global_state: GlobalState) {
18+
let res = qa_inner(&global_state).await;
19+
20+
if res {
21+
global_state.state.lock().await.custom_message =
22+
Some((format!("PERIPHERALS QA"), format!("PASSED")));
23+
} else {
24+
global_state.state.lock().await.custom_message =
25+
Some((format!("PERIPHERALS QA"), format!("NOT GOOD")));
26+
}
27+
}
28+
29+
async fn qa_inner(global_state: &GlobalState) -> bool {
30+
for i in 1..5 {
31+
global_state.state.lock().await.custom_message =
32+
Some((format!("Button {i}"), format!("Down")));
33+
34+
loop {
35+
let val = BACK_SIGNAL.wait().await;
36+
if let QaSignal::ButtonDown(bin) = val {
37+
if bin_to_btn_number(bin) == i {
38+
break;
39+
}
40+
}
41+
42+
return false;
43+
}
44+
45+
global_state.state.lock().await.custom_message =
46+
Some((format!("Button {i}"), format!("Up")));
47+
48+
loop {
49+
let val = BACK_SIGNAL.wait().await;
50+
if let QaSignal::ButtonUp(bin) = val {
51+
if bin_to_btn_number(bin) == i {
52+
break;
53+
}
54+
}
55+
56+
return false;
57+
}
58+
}
59+
60+
let first_card_scan;
61+
global_state.state.lock().await.custom_message = Some((format!("Scan card"), format!("1")));
62+
loop {
63+
let val = BACK_SIGNAL.wait().await;
64+
if let QaSignal::Rfid(card) = val {
65+
first_card_scan = card;
66+
break;
67+
}
68+
69+
return false;
70+
}
71+
72+
global_state.state.lock().await.custom_message =
73+
Some((format!("Scan card"), format!("1 again")));
74+
loop {
75+
let val = BACK_SIGNAL.wait().await;
76+
if let QaSignal::Rfid(card) = val {
77+
if card == first_card_scan {
78+
break;
79+
}
80+
}
81+
82+
return false;
83+
}
84+
85+
global_state.state.lock().await.custom_message = Some((format!("Scan card"), format!("2")));
86+
loop {
87+
let val = BACK_SIGNAL.wait().await;
88+
if let QaSignal::Rfid(card) = val {
89+
if card != first_card_scan {
90+
break;
91+
}
92+
}
93+
94+
return false;
95+
}
96+
97+
global_state.state.lock().await.custom_message =
98+
Some((format!("Connect"), format!("Stackmat")));
99+
loop {
100+
let val = BACK_SIGNAL.wait().await;
101+
if let QaSignal::StackmatConnected = val {
102+
break;
103+
}
104+
105+
return false;
106+
}
107+
108+
global_state.state.lock().await.custom_message =
109+
Some((format!("Stackmat solve"), format!("> 1s")));
110+
loop {
111+
let val = BACK_SIGNAL.wait().await;
112+
if let QaSignal::Stackmat(time) = val {
113+
if time > 1000 {
114+
break;
115+
}
116+
}
117+
118+
return false;
119+
}
120+
121+
return true;
122+
}
123+
124+
pub fn send_qa_resp(val: QaSignal) {
125+
BACK_SIGNAL.signal(val);
126+
}
127+
128+
fn bin_to_btn_number(bin: u8) -> u8 {
129+
match bin {
130+
0b00000001 => 1,
131+
0b00000010 => 2,
132+
0b00000100 => 3,
133+
0b00001000 => 4,
134+
_ => u8::MAX,
135+
}
136+
}

src/rfid.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,16 @@ pub async fn rfid_task(
117117
else {
118118
continue;
119119
};
120-
121120
log::info!("Card UID: {card_uid}");
121+
122+
#[cfg(feature = "qa")]
123+
{
124+
crate::qa::send_qa_resp(crate::qa::QaSignal::Rfid(card_uid));
125+
126+
_ = mfrc522.picc_halta().await;
127+
continue;
128+
}
129+
122130
let resp = crate::ws::send_request::<CardInfoResponsePacket>(
123131
crate::structs::TimerPacketInner::CardInfoRequest {
124132
card_id: card_uid as u64,

src/stackmat.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ pub async fn stackmat_task(
126126
if last_state != Some(true) {
127127
global_state.state.lock().await.stackmat_connected = Some(true);
128128
last_state = Some(true);
129+
130+
#[cfg(feature = "qa")]
131+
crate::qa::send_qa_resp(crate::qa::QaSignal::StackmatConnected);
129132
}
130133

131134
if parsed.0 != last_stackmat_state {
@@ -140,7 +143,7 @@ pub async fn stackmat_task(
140143
}
141144
} else if parsed.0 == StackmatTimerState::Stopped {
142145
let mut state = global_state.state.lock().await;
143-
let last_solve_diff = if cfg!(not(feature = "e2e")) {
146+
let last_solve_diff = if cfg!(not(any(feature = "e2e", feature = "qa"))) {
144147
state.last_solve_time.unwrap_or(0).abs_diff(parsed.1)
145148
} else {
146149
1000
@@ -177,12 +180,16 @@ pub async fn stackmat_task(
177180
state.scene = Scene::WaitingForCompetitor;
178181
}
179182

183+
#[cfg(not(feature = "qa"))]
180184
if let Some(saved_state) = state.to_saved_global_state() {
181185
saved_state.to_nvs(&global_state.nvs).await;
182186
}
183187

184188
let time_str = ms_to_time_str(parsed.1);
185189
display.set_data(&time_str_to_display(&time_str));
190+
191+
#[cfg(feature = "qa")]
192+
crate::qa::send_qa_resp(crate::qa::QaSignal::Stackmat(parsed.1));
186193
} else if state.scene == Scene::Timer {
187194
// this will only happen on e2e (i dont think any human is capable of
188195
// pausing timer two times in a row at the same time)

src/utils/buttons.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ impl ButtonsHandler {
8383
#[cfg(feature = "e2e")]
8484
let mut send_ack = false;
8585

86+
#[cfg(feature = "qa")]
87+
let mut last_button_down = None;
88+
8689
loop {
8790
let mut out_val = 0;
8891

@@ -132,10 +135,26 @@ impl ButtonsHandler {
132135
let duration = esp_hal::time::Instant::now() - debounce_time;
133136
if duration.as_millis() > 50 || sleep_state() {
134137
if old_debounced == 0 {
138+
#[cfg(not(feature = "qa"))]
135139
self.button_down((out_val as u8).into(), state).await;
140+
141+
#[cfg(feature = "qa")]
142+
{
143+
crate::qa::send_qa_resp(crate::qa::QaSignal::ButtonDown(out_val as u8));
144+
last_button_down = Some(out_val as u8);
145+
}
136146
} else {
147+
#[cfg(not(feature = "qa"))]
137148
self.button_up(state).await;
138149

150+
#[cfg(feature = "qa")]
151+
{
152+
if let Some(button) = last_button_down {
153+
crate::qa::send_qa_resp(crate::qa::QaSignal::ButtonUp(button));
154+
last_button_down = None;
155+
}
156+
}
157+
139158
#[cfg(feature = "e2e")]
140159
if send_ack {
141160
crate::ws::send_test_ack(&state).await;
@@ -150,6 +169,7 @@ impl ButtonsHandler {
150169
}
151170

152171
if old_debounced != 0 {
172+
#[cfg(not(feature = "qa"))]
153173
self.button_hold(state).await;
154174
}
155175

src/utils/logger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl log::Log for FkmLogger {
5656

5757
esp_println::println!("{}{} - {}{}", color, record.level(), record.args(), reset);
5858

59-
#[cfg(not(feature = "bat_dev_lcd"))]
59+
#[cfg(not(any(feature = "bat_dev_lcd", feature = "qa")))]
6060
if !ota_state() && !sleep_state() {
6161
if LOGS_CHANNEL.is_full() {
6262
_ = LOGS_CHANNEL.try_receive();

0 commit comments

Comments
 (0)