1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crate::args::{self, Command}; 16 use frontend_client_cxx::ffi::GrpcMethod; 17 18 impl args::Command { 19 /// Return the respective GrpcMethod for the command grpc_method(&self) -> GrpcMethod20 pub fn grpc_method(&self) -> GrpcMethod { 21 match self { 22 Command::Version => GrpcMethod::GetVersion, 23 Command::Radio(_) => GrpcMethod::PatchDevice, 24 Command::Move(_) => GrpcMethod::PatchDevice, 25 Command::Devices(_) => GrpcMethod::GetDevices, 26 Command::Reset => GrpcMethod::Reset, 27 Command::Pcap(cmd) => match cmd { 28 args::Pcap::List(_) => GrpcMethod::ListCapture, 29 args::Pcap::Get(_) => GrpcMethod::GetCapture, 30 args::Pcap::Patch(_) => GrpcMethod::PatchCapture, 31 }, 32 Command::Gui => { 33 panic!("No GrpcMethod for Ui Command."); 34 } 35 } 36 } 37 } 38 39 #[cfg(test)] 40 mod tests { 41 use super::*; 42 use args::{BinaryProtobuf, NetsimArgs}; 43 use clap::Parser; 44 use frontend_proto::{ 45 common::ChipKind, 46 frontend, 47 model::{ 48 self, 49 chip::{Bluetooth as Chip_Bluetooth, Radio as Chip_Radio}, 50 Device, Position, State, 51 }, 52 }; 53 use protobuf::Message; 54 test_command( command: &str, expected_grpc_method: GrpcMethod, expected_request_byte_str: BinaryProtobuf, )55 fn test_command( 56 command: &str, 57 expected_grpc_method: GrpcMethod, 58 expected_request_byte_str: BinaryProtobuf, 59 ) { 60 let command = NetsimArgs::parse_from(command.split_whitespace()).command; 61 assert_eq!(expected_grpc_method, command.grpc_method()); 62 let request = command.get_request_bytes(); 63 assert_eq!(request, expected_request_byte_str); 64 } 65 66 #[test] test_version_request()67 fn test_version_request() { 68 test_command("netsim-cli version", GrpcMethod::GetVersion, Vec::new()) 69 } 70 get_expected_radio(name: &str, radio_type: &str, state: &str) -> BinaryProtobuf71 fn get_expected_radio(name: &str, radio_type: &str, state: &str) -> BinaryProtobuf { 72 let mut chip = model::Chip { ..Default::default() }; 73 let chip_state = match state { 74 "up" => State::ON, 75 _ => State::OFF, 76 }; 77 if radio_type == "wifi" { 78 let mut wifi_chip = Chip_Radio::new(); 79 wifi_chip.state = chip_state.into(); 80 chip.set_wifi(wifi_chip); 81 chip.kind = ChipKind::WIFI.into(); 82 } else if radio_type == "uwb" { 83 let mut uwb_chip = Chip_Radio::new(); 84 uwb_chip.state = chip_state.into(); 85 chip.set_uwb(uwb_chip); 86 chip.kind = ChipKind::UWB.into(); 87 } else { 88 let mut bt_chip = Chip_Bluetooth::new(); 89 let mut bt_chip_radio = Chip_Radio::new(); 90 bt_chip_radio.state = chip_state.into(); 91 if radio_type == "ble" { 92 bt_chip.low_energy = Some(bt_chip_radio).into(); 93 } else { 94 bt_chip.classic = Some(bt_chip_radio).into(); 95 } 96 chip.kind = ChipKind::BLUETOOTH.into(); 97 chip.set_bt(bt_chip); 98 } 99 let mut result = frontend::PatchDeviceRequest::new(); 100 let mut device = Device::new(); 101 device.name = name.to_owned(); 102 device.chips.push(chip); 103 result.device = Some(device).into(); 104 result.write_to_bytes().unwrap() 105 } 106 107 #[test] test_radio_ble()108 fn test_radio_ble() { 109 test_command( 110 "netsim-cli radio ble down 1000", 111 GrpcMethod::PatchDevice, 112 get_expected_radio("1000", "ble", "down"), 113 ); 114 test_command( 115 "netsim-cli radio ble up 1000", 116 GrpcMethod::PatchDevice, 117 get_expected_radio("1000", "ble", "up"), 118 ); 119 } 120 121 #[test] test_radio_ble_aliases()122 fn test_radio_ble_aliases() { 123 test_command( 124 "netsim-cli radio ble Down 1000", 125 GrpcMethod::PatchDevice, 126 get_expected_radio("1000", "ble", "down"), 127 ); 128 test_command( 129 "netsim-cli radio ble Up 1000", 130 GrpcMethod::PatchDevice, 131 get_expected_radio("1000", "ble", "up"), 132 ); 133 test_command( 134 "netsim-cli radio ble DOWN 1000", 135 GrpcMethod::PatchDevice, 136 get_expected_radio("1000", "ble", "down"), 137 ); 138 test_command( 139 "netsim-cli radio ble UP 1000", 140 GrpcMethod::PatchDevice, 141 get_expected_radio("1000", "ble", "up"), 142 ); 143 } 144 145 #[test] test_radio_classic()146 fn test_radio_classic() { 147 test_command( 148 "netsim-cli radio classic down 100", 149 GrpcMethod::PatchDevice, 150 get_expected_radio("100", "classic", "down"), 151 ); 152 test_command( 153 "netsim-cli radio classic up 100", 154 GrpcMethod::PatchDevice, 155 get_expected_radio("100", "classic", "up"), 156 ); 157 } 158 159 #[test] test_radio_wifi()160 fn test_radio_wifi() { 161 test_command( 162 "netsim-cli radio wifi down a", 163 GrpcMethod::PatchDevice, 164 get_expected_radio("a", "wifi", "down"), 165 ); 166 test_command( 167 "netsim-cli radio wifi up b", 168 GrpcMethod::PatchDevice, 169 get_expected_radio("b", "wifi", "up"), 170 ); 171 } 172 173 #[test] test_radio_uwb()174 fn test_radio_uwb() { 175 test_command( 176 "netsim-cli radio uwb down a", 177 GrpcMethod::PatchDevice, 178 get_expected_radio("a", "uwb", "down"), 179 ); 180 test_command( 181 "netsim-cli radio uwb up b", 182 GrpcMethod::PatchDevice, 183 get_expected_radio("b", "uwb", "up"), 184 ); 185 } 186 get_expected_move(name: &str, x: f32, y: f32, z: Option<f32>) -> BinaryProtobuf187 fn get_expected_move(name: &str, x: f32, y: f32, z: Option<f32>) -> BinaryProtobuf { 188 let mut result = frontend::PatchDeviceRequest::new(); 189 let mut device = Device::new(); 190 let position = Position { x, y, z: z.unwrap_or_default(), ..Default::default() }; 191 device.name = name.to_owned(); 192 device.position = Some(position).into(); 193 result.device = Some(device).into(); 194 result.write_to_bytes().unwrap() 195 } 196 197 #[test] test_move_int()198 fn test_move_int() { 199 test_command( 200 "netsim-cli move 1 1 2 3", 201 GrpcMethod::PatchDevice, 202 get_expected_move("1", 1.0, 2.0, Some(3.0)), 203 ) 204 } 205 206 #[test] test_move_float()207 fn test_move_float() { 208 test_command( 209 "netsim-cli move 1000 1.2 3.4 5.6", 210 GrpcMethod::PatchDevice, 211 get_expected_move("1000", 1.2, 3.4, Some(5.6)), 212 ) 213 } 214 215 #[test] test_move_mixed()216 fn test_move_mixed() { 217 test_command( 218 "netsim-cli move 1000 1.1 2 3.4", 219 GrpcMethod::PatchDevice, 220 get_expected_move("1000", 1.1, 2.0, Some(3.4)), 221 ) 222 } 223 224 #[test] test_move_no_z()225 fn test_move_no_z() { 226 test_command( 227 "netsim-cli move 1000 1.2 3.4", 228 GrpcMethod::PatchDevice, 229 get_expected_move("1000", 1.2, 3.4, None), 230 ) 231 } 232 233 #[test] test_devices()234 fn test_devices() { 235 test_command("netsim-cli devices", GrpcMethod::GetDevices, Vec::new()) 236 } 237 238 #[test] test_reset()239 fn test_reset() { 240 test_command("netsim-cli reset", GrpcMethod::Reset, Vec::new()) 241 } 242 243 #[test] test_pcap_list()244 fn test_pcap_list() { 245 test_command("netsim-cli pcap list", GrpcMethod::ListCapture, Vec::new()) 246 } 247 248 //TODO: Add pcap patch and get tests once able to run tests with cxx definitions 249 } 250