mirror of
https://github.com/bybrooklyn/openbitdo.git
synced 2026-03-19 04:12:56 -04:00
release prep: rc.1 baseline and gating updates
This commit is contained in:
136
sdk/tests/candidate_readonly_gating.rs
Normal file
136
sdk/tests/candidate_readonly_gating.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
use bitdo_proto::{
|
||||
device_profile_for, BitdoError, DeviceSession, MockTransport, SessionConfig, SupportLevel,
|
||||
SupportTier, VidPid,
|
||||
};
|
||||
|
||||
const CANDIDATE_READONLY_PIDS: &[u16] = &[
|
||||
0x6002, 0x6003, 0x3010, 0x3011, 0x3012, 0x3013, 0x5200, 0x5201, 0x203a, 0x2049, 0x2028, 0x202e,
|
||||
0x3004, 0x3019, 0x3100, 0x3105, 0x2100, 0x2101, 0x901a, 0x6006, 0x5203, 0x5204, 0x301a, 0x9028,
|
||||
0x3026, 0x3027,
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn candidate_targets_are_candidate_readonly() {
|
||||
for pid in CANDIDATE_READONLY_PIDS {
|
||||
let profile = device_profile_for(VidPid::new(0x2dc8, *pid));
|
||||
assert_eq!(
|
||||
profile.support_tier,
|
||||
SupportTier::CandidateReadOnly,
|
||||
"expected candidate-readonly for pid={pid:#06x}"
|
||||
);
|
||||
assert_eq!(
|
||||
profile.support_level,
|
||||
SupportLevel::DetectOnly,
|
||||
"support_level remains detect-only until full promotion"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn candidate_standard_pid_allows_diag_read_but_blocks_write_and_unsafe() {
|
||||
let pid = 0x6002;
|
||||
let mut transport = MockTransport::default();
|
||||
// get_mode issues up to 3 reads; allow timeout outcome to prove it was permitted by policy.
|
||||
transport.push_read_timeout();
|
||||
transport.push_read_timeout();
|
||||
transport.push_read_timeout();
|
||||
|
||||
let mut session = DeviceSession::new(
|
||||
transport,
|
||||
VidPid::new(0x2dc8, pid),
|
||||
SessionConfig {
|
||||
experimental: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.expect("open session");
|
||||
|
||||
let mode_err = session
|
||||
.get_mode()
|
||||
.expect_err("candidate get_mode should execute and fail only at transport/response stage");
|
||||
assert!(matches!(
|
||||
mode_err,
|
||||
BitdoError::Timeout | BitdoError::MalformedResponse { .. }
|
||||
));
|
||||
|
||||
let write_err = session
|
||||
.set_mode(1)
|
||||
.expect_err("candidate safe-write must be blocked");
|
||||
assert!(matches!(write_err, BitdoError::UnsupportedForPid { .. }));
|
||||
|
||||
let unsafe_err = session
|
||||
.enter_bootloader()
|
||||
.expect_err("candidate unsafe command must be blocked");
|
||||
assert!(matches!(unsafe_err, BitdoError::UnsupportedForPid { .. }));
|
||||
|
||||
let _ = session.close();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn candidate_jp_pid_remains_diag_only() {
|
||||
let pid = 0x5200;
|
||||
let mut transport = MockTransport::default();
|
||||
transport.push_read_data({
|
||||
let mut response = vec![0u8; 64];
|
||||
response[0] = 0x02;
|
||||
response[1] = 0x05;
|
||||
response[4] = 0xC1;
|
||||
response
|
||||
});
|
||||
|
||||
let mut session = DeviceSession::new(
|
||||
transport,
|
||||
VidPid::new(0x2dc8, pid),
|
||||
SessionConfig {
|
||||
experimental: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.expect("open session");
|
||||
|
||||
let identify = session.identify().expect("identify allowed");
|
||||
assert_eq!(identify.target.pid, pid);
|
||||
let profile = device_profile_for(VidPid::new(0x2dc8, pid));
|
||||
assert_eq!(profile.support_tier, SupportTier::CandidateReadOnly);
|
||||
|
||||
let mode_err = session
|
||||
.get_mode()
|
||||
.expect_err("jp candidate should not expose mode read path");
|
||||
assert!(matches!(mode_err, BitdoError::UnsupportedForPid { .. }));
|
||||
|
||||
let _ = session.close();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wave2_candidate_standard_pid_allows_safe_reads_only() {
|
||||
let pid = 0x3100;
|
||||
let mut transport = MockTransport::default();
|
||||
transport.push_read_timeout();
|
||||
transport.push_read_timeout();
|
||||
transport.push_read_timeout();
|
||||
|
||||
let mut session = DeviceSession::new(
|
||||
transport,
|
||||
VidPid::new(0x2dc8, pid),
|
||||
SessionConfig {
|
||||
experimental: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.expect("open session");
|
||||
|
||||
let mode_err = session.get_mode().expect_err(
|
||||
"wave2 candidate get_mode should be permitted and fail at transport/response stage",
|
||||
);
|
||||
assert!(matches!(
|
||||
mode_err,
|
||||
BitdoError::Timeout | BitdoError::MalformedResponse { .. }
|
||||
));
|
||||
|
||||
let write_err = session
|
||||
.set_mode(1)
|
||||
.expect_err("wave2 candidate safe-write must be blocked");
|
||||
assert!(matches!(write_err, BitdoError::UnsupportedForPid { .. }));
|
||||
|
||||
let _ = session.close();
|
||||
}
|
||||
Reference in New Issue
Block a user