the PCDU handler is already required
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
This commit is contained in:
parent
37b32a9008
commit
7606767f63
@ -6,7 +6,7 @@ use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use satrs::spacepackets::SpHeader;
|
||||
use satrs_example::{DeviceMode, TimestampHelper};
|
||||
use satrs_minisim::acs::lis3mdl::{
|
||||
MgmLis3MdlReply, FIELD_LSB_PER_GAUSS_4_SENS, GAUSS_TO_MICROTESLA_FACTOR,
|
||||
MgmLis3MdlReply, MgmLis3RawValues, FIELD_LSB_PER_GAUSS_4_SENS, GAUSS_TO_MICROTESLA_FACTOR,
|
||||
};
|
||||
use satrs_minisim::acs::MgmRequestLis3Mdl;
|
||||
use satrs_minisim::{SerializableSimMsgPayload, SimReply, SimRequest};
|
||||
@ -47,18 +47,16 @@ pub trait SpiInterface {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SpiDummyInterface {
|
||||
pub dummy_val_0: i16,
|
||||
pub dummy_val_1: i16,
|
||||
pub dummy_val_2: i16,
|
||||
pub dummy_values: MgmLis3RawValues,
|
||||
}
|
||||
|
||||
impl SpiInterface for SpiDummyInterface {
|
||||
type Error = ();
|
||||
|
||||
fn transfer(&mut self, _tx: &[u8], rx: &mut [u8]) -> Result<(), Self::Error> {
|
||||
rx[X_LOWBYTE_IDX..X_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_val_0.to_le_bytes());
|
||||
rx[Y_LOWBYTE_IDX..Y_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_val_1.to_be_bytes());
|
||||
rx[Z_LOWBYTE_IDX..Z_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_val_2.to_be_bytes());
|
||||
rx[X_LOWBYTE_IDX..X_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_values.x.to_le_bytes());
|
||||
rx[Y_LOWBYTE_IDX..Y_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_values.y.to_be_bytes());
|
||||
rx[Z_LOWBYTE_IDX..Z_LOWBYTE_IDX + 2].copy_from_slice(&self.dummy_values.z.to_be_bytes());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -74,18 +72,27 @@ impl SpiInterface for SpiSimInterface {
|
||||
// Right now, we only support requesting sensor data and not configuration of the sensor.
|
||||
fn transfer(&mut self, _tx: &[u8], rx: &mut [u8]) -> Result<(), Self::Error> {
|
||||
let mgm_sensor_request = MgmRequestLis3Mdl::RequestSensorData;
|
||||
self.sim_request_tx
|
||||
if let Err(e) = self
|
||||
.sim_request_tx
|
||||
.send(SimRequest::new_with_epoch_time(mgm_sensor_request))
|
||||
.expect("failed to send request");
|
||||
let sim_reply = self
|
||||
.sim_reply_rx
|
||||
.recv_timeout(Duration::from_millis(100))
|
||||
.expect("reply timeout");
|
||||
let sim_reply_lis3 =
|
||||
MgmLis3MdlReply::from_sim_message(&sim_reply).expect("failed to parse LIS3 reply");
|
||||
rx[X_LOWBYTE_IDX..X_LOWBYTE_IDX + 2].copy_from_slice(&sim_reply_lis3.raw.x.to_le_bytes());
|
||||
rx[Y_LOWBYTE_IDX..Y_LOWBYTE_IDX + 2].copy_from_slice(&sim_reply_lis3.raw.y.to_le_bytes());
|
||||
rx[Z_LOWBYTE_IDX..Z_LOWBYTE_IDX + 2].copy_from_slice(&sim_reply_lis3.raw.z.to_le_bytes());
|
||||
{
|
||||
log::error!("failed to send MGM LIS3 request: {}", e);
|
||||
}
|
||||
match self.sim_reply_rx.recv_timeout(Duration::from_millis(50)) {
|
||||
Ok(sim_reply) => {
|
||||
let sim_reply_lis3 = MgmLis3MdlReply::from_sim_message(&sim_reply)
|
||||
.expect("failed to parse LIS3 reply");
|
||||
rx[X_LOWBYTE_IDX..X_LOWBYTE_IDX + 2]
|
||||
.copy_from_slice(&sim_reply_lis3.raw.x.to_le_bytes());
|
||||
rx[Y_LOWBYTE_IDX..Y_LOWBYTE_IDX + 2]
|
||||
.copy_from_slice(&sim_reply_lis3.raw.y.to_le_bytes());
|
||||
rx[Z_LOWBYTE_IDX..Z_LOWBYTE_IDX + 2]
|
||||
.copy_from_slice(&sim_reply_lis3.raw.z.to_le_bytes());
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("MGM LIS3 SIM reply timeout: {}", e);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
1
satrs-example/src/eps/mod.rs
Normal file
1
satrs-example/src/eps/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod pcdu;
|
44
satrs-example/src/eps/pcdu.rs
Normal file
44
satrs-example/src/eps/pcdu.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{mpsc, Arc, Mutex},
|
||||
};
|
||||
|
||||
use derive_new::new;
|
||||
use satrs::{
|
||||
mode::ModeAndSubmode,
|
||||
power::SwitchState,
|
||||
pus::EcssTmSender,
|
||||
request::{GenericMessage, UniqueApidTargetId},
|
||||
};
|
||||
use satrs_example::TimestampHelper;
|
||||
|
||||
use crate::{acs::mgm::MpscModeLeafInterface, pus::hk::HkReply, requests::CompositeRequest};
|
||||
|
||||
pub trait SerialInterface {}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[repr(u32)]
|
||||
pub enum SwitchId {
|
||||
Mgm0 = 0,
|
||||
Mgt = 1,
|
||||
}
|
||||
|
||||
pub type SwitchMap = HashMap<SwitchId, SwitchState>;
|
||||
|
||||
/// Example PCDU device handler.
|
||||
#[derive(new)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub struct PcduHandler<ComInterface: SerialInterface, TmSender: EcssTmSender> {
|
||||
id: UniqueApidTargetId,
|
||||
dev_str: &'static str,
|
||||
mode_interface: MpscModeLeafInterface,
|
||||
composite_request_rx: mpsc::Receiver<GenericMessage<CompositeRequest>>,
|
||||
hk_reply_tx: mpsc::Sender<GenericMessage<HkReply>>,
|
||||
tm_sender: TmSender,
|
||||
pub com_interface: ComInterface,
|
||||
shared_switch_map: Arc<Mutex<SwitchMap>>,
|
||||
#[new(value = "ModeAndSubmode::new(satrs_example::DeviceMode::Off as u32, 0)")]
|
||||
mode_and_submode: ModeAndSubmode,
|
||||
#[new(default)]
|
||||
stamp_helper: TimestampHelper,
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
mod acs;
|
||||
mod eps;
|
||||
mod events;
|
||||
mod hk;
|
||||
mod interface;
|
||||
|
@ -15,7 +15,7 @@ use satrs_minisim::{
|
||||
|
||||
use crate::time::current_millis;
|
||||
|
||||
// Earth magnetic field varies between -30 uT and 30 uT
|
||||
// Earth magnetic field varies between roughly -30 uT and 30 uT
|
||||
const AMPLITUDE_MGM_UT: f32 = 30.0;
|
||||
// Lets start with a simple frequency here.
|
||||
const FREQUENCY_MGM: f32 = 1.0;
|
||||
@ -26,14 +26,9 @@ const PHASE_Z: f32 = 0.2;
|
||||
|
||||
/// Simple model for a magnetometer where the measure magnetic fields are modeled with sine waves.
|
||||
///
|
||||
/// Please note that that a more realistic MGM model wouold include the following components
|
||||
/// which are not included here to simplify the model:
|
||||
///
|
||||
/// 1. It would probably generate signed [i16] values which need to be converted to SI units
|
||||
/// because it is a digital sensor
|
||||
/// 2. It would sample the magnetic field at a high fixed rate. This might not be possible for
|
||||
/// a general purpose OS, but self self-sampling at a relatively high rate (20-40 ms) might
|
||||
/// stil lbe possible.
|
||||
/// An ideal sensor would sample the magnetic field at a high fixed rate. This might not be
|
||||
/// possible for a general purpose OS, but self self-sampling at a relatively high rate (20-40 ms)
|
||||
/// might still be possible and is probably sufficient for many OBSW needs.
|
||||
pub struct MagnetometerModel<ReplyProvider: MgmReplyProvider> {
|
||||
pub switch_state: SwitchStateBinary,
|
||||
pub periodicity: Duration,
|
||||
|
@ -236,6 +236,7 @@ pub mod acs {
|
||||
y: -30.0,
|
||||
z: 30.0,
|
||||
};
|
||||
pub const ALL_ONES_SENSOR_VAL: i16 = 0xffff_u16 as i16;
|
||||
|
||||
pub mod lis3mdl {
|
||||
use super::*;
|
||||
@ -264,6 +265,16 @@ pub mod acs {
|
||||
|
||||
impl MgmLis3MdlReply {
|
||||
pub fn new(common: MgmReplyCommon) -> Self {
|
||||
match common.switch_state {
|
||||
SwitchStateBinary::Off => Self {
|
||||
common,
|
||||
raw: MgmLis3RawValues {
|
||||
x: ALL_ONES_SENSOR_VAL,
|
||||
y: ALL_ONES_SENSOR_VAL,
|
||||
z: ALL_ONES_SENSOR_VAL,
|
||||
},
|
||||
},
|
||||
SwitchStateBinary::On => {
|
||||
let mut raw_reply: [u8; 7] = [0; 7];
|
||||
let raw_x: i16 = (common.sensor_values.x
|
||||
/ (GAUSS_TO_MICROTESLA_FACTOR as f32 * FIELD_LSB_PER_GAUSS_4_SENS))
|
||||
@ -288,6 +299,8 @@ pub mod acs {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializableSimMsgPayload<SimReply> for MgmLis3MdlReply {
|
||||
const TARGET: SimComponent = SimComponent::MgmLis3Mdl;
|
||||
|
@ -1,22 +1,15 @@
|
||||
use derive_new::new;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "std")]
|
||||
#[allow(unused_imports)]
|
||||
pub use std_mod::*;
|
||||
|
||||
/// Generic trait for a device capable of switching itself on or off.
|
||||
pub trait PowerSwitch {
|
||||
type Error;
|
||||
|
||||
fn switch_on(&mut self) -> Result<(), Self::Error>;
|
||||
fn switch_off(&mut self) -> Result<(), Self::Error>;
|
||||
|
||||
fn is_switch_on(&self) -> bool {
|
||||
self.switch_state() == SwitchState::On
|
||||
}
|
||||
|
||||
fn switch_state(&self) -> SwitchState;
|
||||
}
|
||||
use crate::request::MessageMetadata;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum SwitchState {
|
||||
Off = 0,
|
||||
On = 1,
|
||||
@ -26,6 +19,7 @@ pub enum SwitchState {
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum SwitchStateBinary {
|
||||
Off = 0,
|
||||
On = 1,
|
||||
@ -66,18 +60,26 @@ pub type SwitchId = u16;
|
||||
pub trait PowerSwitcherCommandSender {
|
||||
type Error;
|
||||
|
||||
fn send_switch_on_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error>;
|
||||
fn send_switch_off_cmd(&mut self, switch_id: SwitchId) -> Result<(), Self::Error>;
|
||||
fn send_switch_on_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error>;
|
||||
fn send_switch_off_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
pub trait PowerSwitchInfo {
|
||||
type Error;
|
||||
|
||||
/// Retrieve the switch state
|
||||
fn get_switch_state(&mut self, switch_id: SwitchId) -> Result<SwitchState, Self::Error>;
|
||||
fn switch_state(&self, switch_id: SwitchId) -> Result<SwitchState, Self::Error>;
|
||||
|
||||
fn get_is_switch_on(&mut self, switch_id: SwitchId) -> Result<bool, Self::Error> {
|
||||
Ok(self.get_switch_state(switch_id)? == SwitchState::On)
|
||||
fn is_switch_on(&self, switch_id: SwitchId) -> Result<bool, Self::Error> {
|
||||
Ok(self.switch_state(switch_id)? == SwitchState::On)
|
||||
}
|
||||
|
||||
/// The maximum delay it will take to change a switch.
|
||||
@ -87,52 +89,222 @@ pub trait PowerSwitchInfo {
|
||||
fn switch_delay_ms(&self) -> u32;
|
||||
}
|
||||
|
||||
#[derive(new)]
|
||||
pub struct SwitchRequest {
|
||||
switch_id: SwitchId,
|
||||
target_state: SwitchStateBinary,
|
||||
}
|
||||
|
||||
impl SwitchRequest {
|
||||
pub fn switch_id(&self) -> SwitchId {
|
||||
self.switch_id
|
||||
}
|
||||
|
||||
pub fn target_state(&self) -> SwitchStateBinary {
|
||||
self.target_state
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod std_mod {
|
||||
use std::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
queue::GenericSendError,
|
||||
request::{GenericMessage, MessageMetadata},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub type MpscSwitchCmdSender = mpsc::Sender<GenericMessage<SwitchRequest>>;
|
||||
pub type MpscSwitchCmdSenderBounded = mpsc::SyncSender<GenericMessage<SwitchRequest>>;
|
||||
|
||||
impl PowerSwitcherCommandSender for MpscSwitchCmdSender {
|
||||
type Error = GenericSendError;
|
||||
|
||||
fn send_switch_on_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.send(GenericMessage::new(
|
||||
requestor_info,
|
||||
SwitchRequest::new(switch_id, SwitchStateBinary::On),
|
||||
))
|
||||
.map_err(|_| GenericSendError::RxDisconnected)
|
||||
}
|
||||
|
||||
fn send_switch_off_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.send(GenericMessage::new(
|
||||
requestor_info,
|
||||
SwitchRequest::new(switch_id, SwitchStateBinary::Off),
|
||||
))
|
||||
.map_err(|_| GenericSendError::RxDisconnected)
|
||||
}
|
||||
}
|
||||
|
||||
impl PowerSwitcherCommandSender for MpscSwitchCmdSenderBounded {
|
||||
type Error = GenericSendError;
|
||||
|
||||
fn send_switch_on_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.try_send(GenericMessage::new(
|
||||
requestor_info,
|
||||
SwitchRequest::new(switch_id, SwitchStateBinary::On),
|
||||
))
|
||||
.map_err(|e| match e {
|
||||
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
||||
mpsc::TrySendError::Disconnected(_) => GenericSendError::RxDisconnected,
|
||||
})
|
||||
}
|
||||
|
||||
fn send_switch_off_cmd(
|
||||
&self,
|
||||
requestor_info: MessageMetadata,
|
||||
switch_id: SwitchId,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.try_send(GenericMessage::new(
|
||||
requestor_info,
|
||||
SwitchRequest::new(switch_id, SwitchStateBinary::Off),
|
||||
))
|
||||
.map_err(|e| match e {
|
||||
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
||||
mpsc::TrySendError::Disconnected(_) => GenericSendError::RxDisconnected,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(dead_code)]
|
||||
// TODO: Add unittests for PowerSwitcherCommandSender impls for mpsc.
|
||||
|
||||
use std::sync::mpsc::{self, TryRecvError};
|
||||
|
||||
use crate::{queue::GenericSendError, request::GenericMessage, ComponentId};
|
||||
|
||||
use super::*;
|
||||
use std::boxed::Box;
|
||||
|
||||
struct Pcdu {
|
||||
switch_rx: std::sync::mpsc::Receiver<(SwitchId, u16)>,
|
||||
const TEST_REQ_ID: u32 = 2;
|
||||
const TEST_SENDER_ID: ComponentId = 5;
|
||||
|
||||
const TEST_SWITCH_ID: u16 = 0x1ff;
|
||||
|
||||
fn common_checks(request: &GenericMessage<SwitchRequest>) {
|
||||
assert_eq!(request.requestor_info.sender_id(), TEST_SENDER_ID);
|
||||
assert_eq!(request.requestor_info.request_id(), TEST_REQ_ID);
|
||||
assert_eq!(request.message.switch_id(), TEST_SWITCH_ID);
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
enum DeviceState {
|
||||
OFF,
|
||||
SwitchingPower,
|
||||
ON,
|
||||
SETUP,
|
||||
IDLE,
|
||||
}
|
||||
struct MyComplexDevice {
|
||||
power_switcher: Box<dyn PowerSwitcherCommandSender<Error = ()>>,
|
||||
power_info: Box<dyn PowerSwitchInfo<Error = ()>>,
|
||||
switch_id: SwitchId,
|
||||
some_state: u16,
|
||||
dev_state: DeviceState,
|
||||
mode: u32,
|
||||
submode: u16,
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_regular_on_cmd() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::channel::<GenericMessage<SwitchRequest>>();
|
||||
switch_cmd_tx
|
||||
.send_switch_on_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
)
|
||||
.expect("sending switch cmd failed");
|
||||
let request = switch_cmd_rx
|
||||
.recv()
|
||||
.expect("receiving switch request failed");
|
||||
common_checks(&request);
|
||||
assert_eq!(request.message.target_state(), SwitchStateBinary::On);
|
||||
}
|
||||
|
||||
impl MyComplexDevice {
|
||||
pub fn periodic_op(&mut self) {
|
||||
// .. mode command coming in
|
||||
let mode = 1;
|
||||
if mode == 1 {
|
||||
if self.dev_state == DeviceState::OFF {
|
||||
self.power_switcher
|
||||
.send_switch_on_cmd(self.switch_id)
|
||||
.expect("sending siwthc cmd failed");
|
||||
self.dev_state = DeviceState::SwitchingPower;
|
||||
}
|
||||
if self.dev_state == DeviceState::SwitchingPower {
|
||||
if self.power_info.get_is_switch_on(0).unwrap() {
|
||||
self.dev_state = DeviceState::ON;
|
||||
self.mode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_regular_off_cmd() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::channel::<GenericMessage<SwitchRequest>>();
|
||||
switch_cmd_tx
|
||||
.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
)
|
||||
.expect("sending switch cmd failed");
|
||||
let request = switch_cmd_rx
|
||||
.recv()
|
||||
.expect("receiving switch request failed");
|
||||
common_checks(&request);
|
||||
assert_eq!(request.message.target_state(), SwitchStateBinary::Off);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_regular_rx_disconnected() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::channel::<GenericMessage<SwitchRequest>>();
|
||||
drop(switch_cmd_rx);
|
||||
let result = switch_cmd_tx.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
);
|
||||
assert!(result.is_err());
|
||||
matches!(result.unwrap_err(), GenericSendError::RxDisconnected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_sync_on_cmd() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::sync_channel::<GenericMessage<SwitchRequest>>(3);
|
||||
switch_cmd_tx
|
||||
.send_switch_on_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
)
|
||||
.expect("sending switch cmd failed");
|
||||
let request = switch_cmd_rx
|
||||
.recv()
|
||||
.expect("receiving switch request failed");
|
||||
common_checks(&request);
|
||||
assert_eq!(request.message.target_state(), SwitchStateBinary::On);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_sync_off_cmd() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::sync_channel::<GenericMessage<SwitchRequest>>(3);
|
||||
switch_cmd_tx
|
||||
.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
)
|
||||
.expect("sending switch cmd failed");
|
||||
let request = switch_cmd_rx
|
||||
.recv()
|
||||
.expect("receiving switch request failed");
|
||||
common_checks(&request);
|
||||
assert_eq!(request.message.target_state(), SwitchStateBinary::Off);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_sync_rx_disconnected() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::sync_channel::<GenericMessage<SwitchRequest>>(1);
|
||||
drop(switch_cmd_rx);
|
||||
let result = switch_cmd_tx.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
);
|
||||
assert!(result.is_err());
|
||||
matches!(result.unwrap_err(), GenericSendError::RxDisconnected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comand_switch_sending_mpsc_sync_queue_full() {
|
||||
let (switch_cmd_tx, switch_cmd_rx) = mpsc::sync_channel::<GenericMessage<SwitchRequest>>(1);
|
||||
let mut result = switch_cmd_tx.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
result = switch_cmd_tx.send_switch_off_cmd(
|
||||
MessageMetadata::new(TEST_REQ_ID, TEST_SENDER_ID),
|
||||
TEST_SWITCH_ID,
|
||||
);
|
||||
assert!(result.is_err());
|
||||
matches!(result.unwrap_err(), GenericSendError::QueueFull(None));
|
||||
matches!(switch_cmd_rx.try_recv(), Err(TryRecvError::Empty));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user