1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2023 Google LLC 2*cf78ab8cSAndroid Build Coastguard Worker // 3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*cf78ab8cSAndroid Build Coastguard Worker // 7*cf78ab8cSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*cf78ab8cSAndroid Build Coastguard Worker // 9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License. 14*cf78ab8cSAndroid Build Coastguard Worker 15*cf78ab8cSAndroid Build Coastguard Worker // Device.rs 16*cf78ab8cSAndroid Build Coastguard Worker 17*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip; 18*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip::Chip; 19*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::chip::ChipIdentifier; 20*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::devices_handler::PoseManager; 21*cf78ab8cSAndroid Build Coastguard Worker use crate::wireless::WirelessAdaptorImpl; 22*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::common::ChipKind as ProtoChipKind; 23*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::frontend::patch_device_request::PatchDeviceFields as ProtoPatchDeviceFields; 24*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::model::Device as ProtoDevice; 25*cf78ab8cSAndroid Build Coastguard Worker use netsim_proto::stats::NetsimRadioStats as ProtoRadioStats; 26*cf78ab8cSAndroid Build Coastguard Worker use std::collections::BTreeMap; 27*cf78ab8cSAndroid Build Coastguard Worker use std::fmt; 28*cf78ab8cSAndroid Build Coastguard Worker use std::sync::atomic::{AtomicBool, Ordering}; 29*cf78ab8cSAndroid Build Coastguard Worker use std::sync::{Arc, RwLock}; 30*cf78ab8cSAndroid Build Coastguard Worker 31*cf78ab8cSAndroid Build Coastguard Worker #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialOrd, PartialEq)] 32*cf78ab8cSAndroid Build Coastguard Worker pub struct DeviceIdentifier(pub u32); 33*cf78ab8cSAndroid Build Coastguard Worker 34*cf78ab8cSAndroid Build Coastguard Worker impl fmt::Display for DeviceIdentifier { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result35*cf78ab8cSAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 36*cf78ab8cSAndroid Build Coastguard Worker write!(f, "{}", self.0) 37*cf78ab8cSAndroid Build Coastguard Worker } 38*cf78ab8cSAndroid Build Coastguard Worker } 39*cf78ab8cSAndroid Build Coastguard Worker 40*cf78ab8cSAndroid Build Coastguard Worker impl fmt::Debug for DeviceIdentifier { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result41*cf78ab8cSAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 42*cf78ab8cSAndroid Build Coastguard Worker write!(f, "{}", self.0) 43*cf78ab8cSAndroid Build Coastguard Worker } 44*cf78ab8cSAndroid Build Coastguard Worker } 45*cf78ab8cSAndroid Build Coastguard Worker 46*cf78ab8cSAndroid Build Coastguard Worker pub struct Device { 47*cf78ab8cSAndroid Build Coastguard Worker pub id: DeviceIdentifier, 48*cf78ab8cSAndroid Build Coastguard Worker pub guid: String, 49*cf78ab8cSAndroid Build Coastguard Worker pub name: String, 50*cf78ab8cSAndroid Build Coastguard Worker pub visible: AtomicBool, 51*cf78ab8cSAndroid Build Coastguard Worker pub chips: RwLock<BTreeMap<ChipIdentifier, Arc<Chip>>>, 52*cf78ab8cSAndroid Build Coastguard Worker pub builtin: bool, 53*cf78ab8cSAndroid Build Coastguard Worker } 54*cf78ab8cSAndroid Build Coastguard Worker impl Device { new( id: DeviceIdentifier, guid: impl Into<String>, name: impl Into<String>, builtin: bool, ) -> Self55*cf78ab8cSAndroid Build Coastguard Worker pub fn new( 56*cf78ab8cSAndroid Build Coastguard Worker id: DeviceIdentifier, 57*cf78ab8cSAndroid Build Coastguard Worker guid: impl Into<String>, 58*cf78ab8cSAndroid Build Coastguard Worker name: impl Into<String>, 59*cf78ab8cSAndroid Build Coastguard Worker builtin: bool, 60*cf78ab8cSAndroid Build Coastguard Worker ) -> Self { 61*cf78ab8cSAndroid Build Coastguard Worker Device { 62*cf78ab8cSAndroid Build Coastguard Worker id, 63*cf78ab8cSAndroid Build Coastguard Worker guid: guid.into(), 64*cf78ab8cSAndroid Build Coastguard Worker name: name.into(), 65*cf78ab8cSAndroid Build Coastguard Worker visible: AtomicBool::new(true), 66*cf78ab8cSAndroid Build Coastguard Worker chips: RwLock::new(BTreeMap::new()), 67*cf78ab8cSAndroid Build Coastguard Worker builtin, 68*cf78ab8cSAndroid Build Coastguard Worker } 69*cf78ab8cSAndroid Build Coastguard Worker } 70*cf78ab8cSAndroid Build Coastguard Worker } 71*cf78ab8cSAndroid Build Coastguard Worker 72*cf78ab8cSAndroid Build Coastguard Worker #[derive(Debug, Clone)] 73*cf78ab8cSAndroid Build Coastguard Worker pub struct AddChipResult { 74*cf78ab8cSAndroid Build Coastguard Worker pub device_id: DeviceIdentifier, 75*cf78ab8cSAndroid Build Coastguard Worker pub chip_id: ChipIdentifier, 76*cf78ab8cSAndroid Build Coastguard Worker } 77*cf78ab8cSAndroid Build Coastguard Worker 78*cf78ab8cSAndroid Build Coastguard Worker impl Device { get(&self, pose_manager: Arc<PoseManager>) -> Result<ProtoDevice, String>79*cf78ab8cSAndroid Build Coastguard Worker pub fn get(&self, pose_manager: Arc<PoseManager>) -> Result<ProtoDevice, String> { 80*cf78ab8cSAndroid Build Coastguard Worker let mut device = ProtoDevice::new(); 81*cf78ab8cSAndroid Build Coastguard Worker device.id = self.id.0; 82*cf78ab8cSAndroid Build Coastguard Worker device.name.clone_from(&self.name); 83*cf78ab8cSAndroid Build Coastguard Worker device.visible = Some(self.visible.load(Ordering::SeqCst)); 84*cf78ab8cSAndroid Build Coastguard Worker device.position = protobuf::MessageField::from(pose_manager.get_position(&self.id)); 85*cf78ab8cSAndroid Build Coastguard Worker device.orientation = protobuf::MessageField::from(pose_manager.get_orientation(&self.id)); 86*cf78ab8cSAndroid Build Coastguard Worker for chip in self.chips.read().unwrap().values() { 87*cf78ab8cSAndroid Build Coastguard Worker device.chips.push(chip.get()?); 88*cf78ab8cSAndroid Build Coastguard Worker } 89*cf78ab8cSAndroid Build Coastguard Worker Ok(device) 90*cf78ab8cSAndroid Build Coastguard Worker } 91*cf78ab8cSAndroid Build Coastguard Worker 92*cf78ab8cSAndroid Build Coastguard Worker /// Patch a device and its chips. patch( &self, patch: &ProtoPatchDeviceFields, pose_manager: Arc<PoseManager>, ) -> Result<(), String>93*cf78ab8cSAndroid Build Coastguard Worker pub fn patch( 94*cf78ab8cSAndroid Build Coastguard Worker &self, 95*cf78ab8cSAndroid Build Coastguard Worker patch: &ProtoPatchDeviceFields, 96*cf78ab8cSAndroid Build Coastguard Worker pose_manager: Arc<PoseManager>, 97*cf78ab8cSAndroid Build Coastguard Worker ) -> Result<(), String> { 98*cf78ab8cSAndroid Build Coastguard Worker if patch.visible.is_some() { 99*cf78ab8cSAndroid Build Coastguard Worker self.visible.store(patch.visible.unwrap(), Ordering::SeqCst); 100*cf78ab8cSAndroid Build Coastguard Worker } 101*cf78ab8cSAndroid Build Coastguard Worker if patch.position.is_some() { 102*cf78ab8cSAndroid Build Coastguard Worker pose_manager.set_position(self.id, &patch.position); 103*cf78ab8cSAndroid Build Coastguard Worker } 104*cf78ab8cSAndroid Build Coastguard Worker if patch.orientation.is_some() { 105*cf78ab8cSAndroid Build Coastguard Worker pose_manager.set_orientation(self.id, &patch.orientation); 106*cf78ab8cSAndroid Build Coastguard Worker } 107*cf78ab8cSAndroid Build Coastguard Worker // iterate over patched ProtoChip entries and patch matching chip 108*cf78ab8cSAndroid Build Coastguard Worker for patch_chip in patch.chips.iter() { 109*cf78ab8cSAndroid Build Coastguard Worker let mut patch_chip_kind = patch_chip.kind.enum_value_or_default(); 110*cf78ab8cSAndroid Build Coastguard Worker // Check if chip is given when kind is not given. 111*cf78ab8cSAndroid Build Coastguard Worker // TODO: Fix patch device request body in CLI to include ChipKind, and remove if block below. 112*cf78ab8cSAndroid Build Coastguard Worker if patch_chip_kind == ProtoChipKind::UNSPECIFIED { 113*cf78ab8cSAndroid Build Coastguard Worker if patch_chip.has_bt() { 114*cf78ab8cSAndroid Build Coastguard Worker patch_chip_kind = ProtoChipKind::BLUETOOTH; 115*cf78ab8cSAndroid Build Coastguard Worker } else if patch_chip.has_ble_beacon() { 116*cf78ab8cSAndroid Build Coastguard Worker patch_chip_kind = ProtoChipKind::BLUETOOTH_BEACON; 117*cf78ab8cSAndroid Build Coastguard Worker } else if patch_chip.has_wifi() { 118*cf78ab8cSAndroid Build Coastguard Worker patch_chip_kind = ProtoChipKind::WIFI; 119*cf78ab8cSAndroid Build Coastguard Worker } else if patch_chip.has_uwb() { 120*cf78ab8cSAndroid Build Coastguard Worker patch_chip_kind = ProtoChipKind::UWB; 121*cf78ab8cSAndroid Build Coastguard Worker } else { 122*cf78ab8cSAndroid Build Coastguard Worker break; 123*cf78ab8cSAndroid Build Coastguard Worker } 124*cf78ab8cSAndroid Build Coastguard Worker } 125*cf78ab8cSAndroid Build Coastguard Worker let patch_chip_name = &patch_chip.name; 126*cf78ab8cSAndroid Build Coastguard Worker // Find the matching chip and patch the proto chip 127*cf78ab8cSAndroid Build Coastguard Worker let target = self.match_target_chip(patch_chip_kind, patch_chip_name)?; 128*cf78ab8cSAndroid Build Coastguard Worker match target { 129*cf78ab8cSAndroid Build Coastguard Worker Some(chip) => chip.patch(patch_chip)?, 130*cf78ab8cSAndroid Build Coastguard Worker None => { 131*cf78ab8cSAndroid Build Coastguard Worker return Err(format!( 132*cf78ab8cSAndroid Build Coastguard Worker "Chip {} not found in device {}", 133*cf78ab8cSAndroid Build Coastguard Worker patch_chip_name, self.name 134*cf78ab8cSAndroid Build Coastguard Worker )) 135*cf78ab8cSAndroid Build Coastguard Worker } 136*cf78ab8cSAndroid Build Coastguard Worker } 137*cf78ab8cSAndroid Build Coastguard Worker } 138*cf78ab8cSAndroid Build Coastguard Worker Ok(()) 139*cf78ab8cSAndroid Build Coastguard Worker } 140*cf78ab8cSAndroid Build Coastguard Worker match_target_chip( &self, patch_chip_kind: ProtoChipKind, patch_chip_name: &str, ) -> Result<Option<Arc<Chip>>, String>141*cf78ab8cSAndroid Build Coastguard Worker fn match_target_chip( 142*cf78ab8cSAndroid Build Coastguard Worker &self, 143*cf78ab8cSAndroid Build Coastguard Worker patch_chip_kind: ProtoChipKind, 144*cf78ab8cSAndroid Build Coastguard Worker patch_chip_name: &str, 145*cf78ab8cSAndroid Build Coastguard Worker ) -> Result<Option<Arc<Chip>>, String> { 146*cf78ab8cSAndroid Build Coastguard Worker let mut multiple_matches = false; 147*cf78ab8cSAndroid Build Coastguard Worker let mut target: Option<Arc<Chip>> = None; 148*cf78ab8cSAndroid Build Coastguard Worker for chip in self.chips.read().unwrap().values() { 149*cf78ab8cSAndroid Build Coastguard Worker // Check for specified chip kind and matching chip name 150*cf78ab8cSAndroid Build Coastguard Worker if chip.kind == patch_chip_kind && chip.name.contains(patch_chip_name) { 151*cf78ab8cSAndroid Build Coastguard Worker // Check for exact match 152*cf78ab8cSAndroid Build Coastguard Worker if chip.name == patch_chip_name { 153*cf78ab8cSAndroid Build Coastguard Worker multiple_matches = false; 154*cf78ab8cSAndroid Build Coastguard Worker target = Some(Arc::clone(chip)); 155*cf78ab8cSAndroid Build Coastguard Worker break; 156*cf78ab8cSAndroid Build Coastguard Worker } 157*cf78ab8cSAndroid Build Coastguard Worker // Check for ambiguous match 158*cf78ab8cSAndroid Build Coastguard Worker if target.is_none() { 159*cf78ab8cSAndroid Build Coastguard Worker target = Some(Arc::clone(chip)); 160*cf78ab8cSAndroid Build Coastguard Worker } else { 161*cf78ab8cSAndroid Build Coastguard Worker // Return if no chip name is supplied but multiple chips of specified kind exist 162*cf78ab8cSAndroid Build Coastguard Worker if patch_chip_name.is_empty() { 163*cf78ab8cSAndroid Build Coastguard Worker return Err(format!( 164*cf78ab8cSAndroid Build Coastguard Worker "No chip name is supplied but multiple chips of chip kind {:?} exist.", 165*cf78ab8cSAndroid Build Coastguard Worker chip.kind 166*cf78ab8cSAndroid Build Coastguard Worker )); 167*cf78ab8cSAndroid Build Coastguard Worker } 168*cf78ab8cSAndroid Build Coastguard Worker // Multiple matches were found - continue to look for possible exact match 169*cf78ab8cSAndroid Build Coastguard Worker multiple_matches = true; 170*cf78ab8cSAndroid Build Coastguard Worker } 171*cf78ab8cSAndroid Build Coastguard Worker } 172*cf78ab8cSAndroid Build Coastguard Worker } 173*cf78ab8cSAndroid Build Coastguard Worker if multiple_matches { 174*cf78ab8cSAndroid Build Coastguard Worker return Err(format!( 175*cf78ab8cSAndroid Build Coastguard Worker "Multiple ambiguous matches were found with chip name {}", 176*cf78ab8cSAndroid Build Coastguard Worker patch_chip_name 177*cf78ab8cSAndroid Build Coastguard Worker )); 178*cf78ab8cSAndroid Build Coastguard Worker } 179*cf78ab8cSAndroid Build Coastguard Worker Ok(target) 180*cf78ab8cSAndroid Build Coastguard Worker } 181*cf78ab8cSAndroid Build Coastguard Worker 182*cf78ab8cSAndroid Build Coastguard Worker /// Remove a chip from a device. remove_chip(&self, chip_id: &ChipIdentifier) -> Result<Vec<ProtoRadioStats>, String>183*cf78ab8cSAndroid Build Coastguard Worker pub fn remove_chip(&self, chip_id: &ChipIdentifier) -> Result<Vec<ProtoRadioStats>, String> { 184*cf78ab8cSAndroid Build Coastguard Worker let radio_stats = self 185*cf78ab8cSAndroid Build Coastguard Worker .chips 186*cf78ab8cSAndroid Build Coastguard Worker .read() 187*cf78ab8cSAndroid Build Coastguard Worker .unwrap() 188*cf78ab8cSAndroid Build Coastguard Worker .get(chip_id) 189*cf78ab8cSAndroid Build Coastguard Worker .ok_or(format!("RemoveChip chip id {chip_id} not found"))? 190*cf78ab8cSAndroid Build Coastguard Worker .get_stats(); 191*cf78ab8cSAndroid Build Coastguard Worker // Chip and emulated chip will be dropped 192*cf78ab8cSAndroid Build Coastguard Worker self.chips.write().unwrap().remove(chip_id); 193*cf78ab8cSAndroid Build Coastguard Worker chip::remove_chip(chip_id); 194*cf78ab8cSAndroid Build Coastguard Worker Ok(radio_stats) 195*cf78ab8cSAndroid Build Coastguard Worker } 196*cf78ab8cSAndroid Build Coastguard Worker add_chip( &mut self, chip_create_params: &chip::CreateParams, chip_id: ChipIdentifier, wireless_adaptor: WirelessAdaptorImpl, ) -> Result<(DeviceIdentifier, ChipIdentifier), String>197*cf78ab8cSAndroid Build Coastguard Worker pub fn add_chip( 198*cf78ab8cSAndroid Build Coastguard Worker &mut self, 199*cf78ab8cSAndroid Build Coastguard Worker chip_create_params: &chip::CreateParams, 200*cf78ab8cSAndroid Build Coastguard Worker chip_id: ChipIdentifier, 201*cf78ab8cSAndroid Build Coastguard Worker wireless_adaptor: WirelessAdaptorImpl, 202*cf78ab8cSAndroid Build Coastguard Worker ) -> Result<(DeviceIdentifier, ChipIdentifier), String> { 203*cf78ab8cSAndroid Build Coastguard Worker for chip in self.chips.read().unwrap().values() { 204*cf78ab8cSAndroid Build Coastguard Worker if chip.kind == chip_create_params.kind 205*cf78ab8cSAndroid Build Coastguard Worker && chip_create_params.name.clone().is_some_and(|name| name == chip.name) 206*cf78ab8cSAndroid Build Coastguard Worker { 207*cf78ab8cSAndroid Build Coastguard Worker return Err(format!("Device::AddChip - duplicate at id {}, skipping.", chip.id)); 208*cf78ab8cSAndroid Build Coastguard Worker } 209*cf78ab8cSAndroid Build Coastguard Worker } 210*cf78ab8cSAndroid Build Coastguard Worker let device_id = self.id; 211*cf78ab8cSAndroid Build Coastguard Worker let chip = chip::new(chip_id, device_id, &self.name, chip_create_params, wireless_adaptor)?; 212*cf78ab8cSAndroid Build Coastguard Worker self.chips.write().unwrap().insert(chip_id, chip); 213*cf78ab8cSAndroid Build Coastguard Worker 214*cf78ab8cSAndroid Build Coastguard Worker Ok((device_id, chip_id)) 215*cf78ab8cSAndroid Build Coastguard Worker } 216*cf78ab8cSAndroid Build Coastguard Worker 217*cf78ab8cSAndroid Build Coastguard Worker /// Reset a device to its default state. reset(&self) -> Result<(), String>218*cf78ab8cSAndroid Build Coastguard Worker pub fn reset(&self) -> Result<(), String> { 219*cf78ab8cSAndroid Build Coastguard Worker self.visible.store(true, Ordering::SeqCst); 220*cf78ab8cSAndroid Build Coastguard Worker for chip in self.chips.read().unwrap().values() { 221*cf78ab8cSAndroid Build Coastguard Worker chip.reset()?; 222*cf78ab8cSAndroid Build Coastguard Worker } 223*cf78ab8cSAndroid Build Coastguard Worker Ok(()) 224*cf78ab8cSAndroid Build Coastguard Worker } 225*cf78ab8cSAndroid Build Coastguard Worker } 226*cf78ab8cSAndroid Build Coastguard Worker 227*cf78ab8cSAndroid Build Coastguard Worker #[cfg(test)] 228*cf78ab8cSAndroid Build Coastguard Worker mod tests { 229*cf78ab8cSAndroid Build Coastguard Worker use super::*; 230*cf78ab8cSAndroid Build Coastguard Worker use crate::wireless::mocked; 231*cf78ab8cSAndroid Build Coastguard Worker use std::sync::atomic::{AtomicU32, Ordering}; 232*cf78ab8cSAndroid Build Coastguard Worker static PATCH_CHIP_KIND: ProtoChipKind = ProtoChipKind::BLUETOOTH; 233*cf78ab8cSAndroid Build Coastguard Worker static TEST_DEVICE_NAME: &str = "test_device"; 234*cf78ab8cSAndroid Build Coastguard Worker static TEST_CHIP_NAME_1: &str = "test-bt-chip-1"; 235*cf78ab8cSAndroid Build Coastguard Worker static TEST_CHIP_NAME_2: &str = "test-bt-chip-2"; 236*cf78ab8cSAndroid Build Coastguard Worker static IDS: AtomicU32 = AtomicU32::new(1000); 237*cf78ab8cSAndroid Build Coastguard Worker create_test_device() -> Result<Device, String>238*cf78ab8cSAndroid Build Coastguard Worker fn create_test_device() -> Result<Device, String> { 239*cf78ab8cSAndroid Build Coastguard Worker let mut device = Device::new(DeviceIdentifier(0), "0", TEST_DEVICE_NAME, false); 240*cf78ab8cSAndroid Build Coastguard Worker let chip_id_1 = ChipIdentifier(IDS.fetch_add(1, Ordering::SeqCst)); 241*cf78ab8cSAndroid Build Coastguard Worker let chip_id_2 = ChipIdentifier(IDS.fetch_add(1, Ordering::SeqCst)); 242*cf78ab8cSAndroid Build Coastguard Worker device.add_chip( 243*cf78ab8cSAndroid Build Coastguard Worker &chip::CreateParams { 244*cf78ab8cSAndroid Build Coastguard Worker kind: ProtoChipKind::BLUETOOTH, 245*cf78ab8cSAndroid Build Coastguard Worker address: "".to_string(), 246*cf78ab8cSAndroid Build Coastguard Worker name: Some(TEST_CHIP_NAME_1.to_string()), 247*cf78ab8cSAndroid Build Coastguard Worker manufacturer: "test_manufacturer".to_string(), 248*cf78ab8cSAndroid Build Coastguard Worker product_name: "test_product_name".to_string(), 249*cf78ab8cSAndroid Build Coastguard Worker }, 250*cf78ab8cSAndroid Build Coastguard Worker chip_id_1, 251*cf78ab8cSAndroid Build Coastguard Worker mocked::new(&mocked::CreateParams { chip_kind: ProtoChipKind::UNSPECIFIED }, chip_id_1), 252*cf78ab8cSAndroid Build Coastguard Worker )?; 253*cf78ab8cSAndroid Build Coastguard Worker device.add_chip( 254*cf78ab8cSAndroid Build Coastguard Worker &chip::CreateParams { 255*cf78ab8cSAndroid Build Coastguard Worker kind: ProtoChipKind::BLUETOOTH, 256*cf78ab8cSAndroid Build Coastguard Worker address: "".to_string(), 257*cf78ab8cSAndroid Build Coastguard Worker name: Some(TEST_CHIP_NAME_2.to_string()), 258*cf78ab8cSAndroid Build Coastguard Worker manufacturer: "test_manufacturer".to_string(), 259*cf78ab8cSAndroid Build Coastguard Worker product_name: "test_product_name".to_string(), 260*cf78ab8cSAndroid Build Coastguard Worker }, 261*cf78ab8cSAndroid Build Coastguard Worker chip_id_2, 262*cf78ab8cSAndroid Build Coastguard Worker mocked::new(&mocked::CreateParams { chip_kind: ProtoChipKind::UNSPECIFIED }, chip_id_1), 263*cf78ab8cSAndroid Build Coastguard Worker )?; 264*cf78ab8cSAndroid Build Coastguard Worker Ok(device) 265*cf78ab8cSAndroid Build Coastguard Worker } 266*cf78ab8cSAndroid Build Coastguard Worker 267*cf78ab8cSAndroid Build Coastguard Worker #[ignore = "TODO: include thread_id in names and ids"] 268*cf78ab8cSAndroid Build Coastguard Worker #[test] test_exact_target_match()269*cf78ab8cSAndroid Build Coastguard Worker fn test_exact_target_match() { 270*cf78ab8cSAndroid Build Coastguard Worker let device = create_test_device().unwrap(); 271*cf78ab8cSAndroid Build Coastguard Worker let result = device.match_target_chip(PATCH_CHIP_KIND, TEST_CHIP_NAME_1); 272*cf78ab8cSAndroid Build Coastguard Worker assert!(result.is_ok()); 273*cf78ab8cSAndroid Build Coastguard Worker let target = result.unwrap(); 274*cf78ab8cSAndroid Build Coastguard Worker assert!(target.is_some()); 275*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(target.unwrap().name, TEST_CHIP_NAME_1); 276*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(device.name, TEST_DEVICE_NAME); 277*cf78ab8cSAndroid Build Coastguard Worker } 278*cf78ab8cSAndroid Build Coastguard Worker 279*cf78ab8cSAndroid Build Coastguard Worker #[ignore = "TODO: include thread_id in names and ids"] 280*cf78ab8cSAndroid Build Coastguard Worker #[test] test_substring_target_match()281*cf78ab8cSAndroid Build Coastguard Worker fn test_substring_target_match() { 282*cf78ab8cSAndroid Build Coastguard Worker let device = create_test_device().unwrap(); 283*cf78ab8cSAndroid Build Coastguard Worker let result = device.match_target_chip(PATCH_CHIP_KIND, "chip-1"); 284*cf78ab8cSAndroid Build Coastguard Worker assert!(result.is_ok()); 285*cf78ab8cSAndroid Build Coastguard Worker let target = result.unwrap(); 286*cf78ab8cSAndroid Build Coastguard Worker assert!(target.is_some()); 287*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(target.unwrap().name, TEST_CHIP_NAME_1); 288*cf78ab8cSAndroid Build Coastguard Worker assert_eq!(device.name, TEST_DEVICE_NAME); 289*cf78ab8cSAndroid Build Coastguard Worker } 290*cf78ab8cSAndroid Build Coastguard Worker 291*cf78ab8cSAndroid Build Coastguard Worker #[ignore = "TODO: include thread_id in names and ids"] 292*cf78ab8cSAndroid Build Coastguard Worker #[test] test_ambiguous_target_match()293*cf78ab8cSAndroid Build Coastguard Worker fn test_ambiguous_target_match() { 294*cf78ab8cSAndroid Build Coastguard Worker let device = create_test_device().unwrap(); 295*cf78ab8cSAndroid Build Coastguard Worker let result = device.match_target_chip(PATCH_CHIP_KIND, "chip"); 296*cf78ab8cSAndroid Build Coastguard Worker assert!(result.is_err()); 297*cf78ab8cSAndroid Build Coastguard Worker assert_eq!( 298*cf78ab8cSAndroid Build Coastguard Worker result.err(), 299*cf78ab8cSAndroid Build Coastguard Worker Some("Multiple ambiguous matches were found with chip name chip".to_string()) 300*cf78ab8cSAndroid Build Coastguard Worker ); 301*cf78ab8cSAndroid Build Coastguard Worker } 302*cf78ab8cSAndroid Build Coastguard Worker 303*cf78ab8cSAndroid Build Coastguard Worker #[ignore = "TODO: include thread_id in names and ids"] 304*cf78ab8cSAndroid Build Coastguard Worker #[test] test_ambiguous_empty_target_match()305*cf78ab8cSAndroid Build Coastguard Worker fn test_ambiguous_empty_target_match() { 306*cf78ab8cSAndroid Build Coastguard Worker let device = create_test_device().unwrap(); 307*cf78ab8cSAndroid Build Coastguard Worker let result = device.match_target_chip(PATCH_CHIP_KIND, ""); 308*cf78ab8cSAndroid Build Coastguard Worker assert!(result.is_err()); 309*cf78ab8cSAndroid Build Coastguard Worker assert_eq!( 310*cf78ab8cSAndroid Build Coastguard Worker result.err(), 311*cf78ab8cSAndroid Build Coastguard Worker Some(format!( 312*cf78ab8cSAndroid Build Coastguard Worker "No chip name is supplied but multiple chips of chip kind {:?} exist.", 313*cf78ab8cSAndroid Build Coastguard Worker PATCH_CHIP_KIND 314*cf78ab8cSAndroid Build Coastguard Worker )) 315*cf78ab8cSAndroid Build Coastguard Worker ); 316*cf78ab8cSAndroid Build Coastguard Worker } 317*cf78ab8cSAndroid Build Coastguard Worker 318*cf78ab8cSAndroid Build Coastguard Worker #[ignore = "TODO: include thread_id in names and ids"] 319*cf78ab8cSAndroid Build Coastguard Worker #[test] test_no_target_match()320*cf78ab8cSAndroid Build Coastguard Worker fn test_no_target_match() { 321*cf78ab8cSAndroid Build Coastguard Worker let device = create_test_device().unwrap(); 322*cf78ab8cSAndroid Build Coastguard Worker let invalid_chip_name = "invalid-chip"; 323*cf78ab8cSAndroid Build Coastguard Worker let result = device.match_target_chip(PATCH_CHIP_KIND, invalid_chip_name); 324*cf78ab8cSAndroid Build Coastguard Worker assert!(result.is_ok()); 325*cf78ab8cSAndroid Build Coastguard Worker let target = result.unwrap(); 326*cf78ab8cSAndroid Build Coastguard Worker assert!(target.is_none()); 327*cf78ab8cSAndroid Build Coastguard Worker } 328*cf78ab8cSAndroid Build Coastguard Worker } 329