use super::*; extern crate lazy_static; use async_std::task; use lazy_static::lazy_static; use minreq; use serde_derive::Deserialize; use std::collections::HashMap; use std::io::{Error, ErrorKind}; use std::sync::Arc; use std::sync::Mutex; use std::thread; static IP_AND_PORT: &str = "127.0.0.1:8123"; lazy_static! { static ref TESTEE_THREAD_HANDLE: Arc>>> = { let config = RestApiConfig { ip_and_port: String::from(IP_AND_PORT), get_channels, get_pulses_by_channel, }; let hdl = Arc::new(Mutex::new(Some(thread::spawn(move || { task::block_on(start(&config.clone())).unwrap(); })))); println!("Server thread spawned"); thread::sleep(std::time::Duration::from_millis(5)); hdl }; static ref CHANNEL_LIST: Mutex> = Mutex::new(Vec::new()); static ref CHANNEL_PULSES: Mutex>> = Mutex::new(HashMap::new()); } fn get_channels() -> Vec { CHANNEL_LIST.lock().unwrap().to_vec() } fn get_pulses_by_channel(channel_id: usize) -> Result, std::io::Error> { let mut pulse_channel_map = CHANNEL_PULSES.lock().unwrap(); match pulse_channel_map.get_mut(&channel_id) { Some(pulse_list) => Ok(pulse_list.drain(0..).collect()), None => Err(Error::new( ErrorKind::NotFound, format!("Channel {} does not exist", &channel_id), )), } } fn launch_testee() { let _hdl = &*TESTEE_THREAD_HANDLE.clone(); } fn print_response(_context: &str, _response: &minreq::Response) { return; /* let mut r_str = String::new(); r_str.push_str(format!("Response in {}:\n", &_context).as_str()); r_str.push_str(format!(" status: {}\n", &_response.status_code).as_str()); r_str.push_str(format!(" reason: '{}'\n", &_response.reason_phrase).as_str()); r_str.push_str(format!(" headers:\n").as_str()); for (key, value) in _response.headers.iter() { r_str.push_str(format!(" {}: '{}'\n", key, value).as_str()); } r_str.push_str(format!(" body: '{}'\n", &_response.as_str().unwrap()).as_str()); println!("{}\n---", &r_str); */ } fn set_channel_list(mut new_channel_list: Vec) { match CHANNEL_LIST.lock() { Ok(mut channel_list) => { channel_list.clear(); channel_list.append(&mut new_channel_list); } Err(_) => assert!(false, "ERROR: Could not access CHANNEL_LIST"), } } fn set_channel_pulses(channel_id: usize, mut channel_pulses: Vec) { let mut pulse_channel_map = CHANNEL_PULSES.lock().unwrap(); let pulse_list = pulse_channel_map.entry(channel_id).or_insert(vec![]); pulse_list.clear(); pulse_list.append(&mut channel_pulses) } #[test] fn rest_api_fetch_api_versions() { launch_testee(); let response = minreq::get(format!("http://{}/api_versions", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); assert_eq!(response.status_code, 200); print_response("get_api_versions", &response) } #[test] fn rest_api_fetch_channels() { #[derive(Debug, Deserialize)] struct ChannelList { channels: Vec, } launch_testee(); set_channel_list(vec![]); let response = minreq::get(format!("http://{}/v1/channels", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); // print_response("get_channels", &response); assert_eq!(response.status_code, 200); assert_eq!(response.headers["content-type"], "application/json"); let response_json = &response.json::().unwrap(); assert_eq!(&response_json.channels, &*CHANNEL_LIST.lock().unwrap()); set_channel_list(vec![1, 3]); let response = minreq::get(format!("http://{}/v1/channels", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); let response_json = &response.json::().unwrap(); assert_eq!(&response_json.channels, &*CHANNEL_LIST.lock().unwrap()); set_channel_list(vec![2, 3, 5, 6, 7, 8]); let response = minreq::get(format!("http://{}/v1/channels", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); let response_json = &response.json::().unwrap(); assert_eq!(&response_json.channels, &*CHANNEL_LIST.lock().unwrap()); } #[test] fn rest_api_fetch_channel() { #[derive(Debug, Deserialize)] struct ChannelPulsesList { channel: usize, pulses: Vec, } launch_testee(); let response = minreq::get(format!("http://{}/v1/channel/1/pulses", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); print_response("rest_api_fetch_channel", &response); assert_eq!( response.status_code, tide::http::StatusCode::NotFound as i32 ); set_channel_pulses(1, vec![]); let response = minreq::get(format!("http://{}/v1/channel/2/pulses", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); print_response("rest_api_fetch_channel", &response); assert_eq!( response.status_code, tide::http::StatusCode::NotFound as i32 ); let response = minreq::get(format!("http://{}/v1/channel/1/pulses", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); print_response("rest_api_fetch_channel", &response); assert_eq!(response.status_code, tide::http::StatusCode::Ok as i32); let response_json = &response.json::().unwrap(); assert_eq!(response_json.channel, 1); assert_eq!(response_json.pulses.len(), 0); let pulses = vec![ PulseInfo { timestamp_ns: 1234u64, pin_id: 1, level: true, }, PulseInfo { timestamp_ns: 1256u64, pin_id: 1, level: false, }, PulseInfo { timestamp_ns: 1278u64, pin_id: 1, level: true, }, PulseInfo { timestamp_ns: 1290u64, pin_id: 1, level: false, }, ]; set_channel_pulses(1, pulses); let response = minreq::get(format!("http://{}/v1/channel/1/pulses", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); print_response("rest_api_fetch_channel", &response); assert_eq!(response.status_code, tide::http::StatusCode::Ok as i32); let response_json = &response.json::().unwrap(); assert_eq!(response_json.channel, 1); assert_eq!(response_json.pulses.len(), 4); assert_eq!(response_json.pulses.get(0).unwrap().timestamp_ns, 1234u64); assert_eq!(response_json.pulses.get(0).unwrap().pin_id, 1); assert_eq!(response_json.pulses.get(0).unwrap().level, true); assert_eq!(response_json.pulses.get(1).unwrap().timestamp_ns, 1256u64); assert_eq!(response_json.pulses.get(1).unwrap().pin_id, 1); assert_eq!(response_json.pulses.get(1).unwrap().level, false); assert_eq!(response_json.pulses.get(2).unwrap().timestamp_ns, 1278u64); assert_eq!(response_json.pulses.get(2).unwrap().pin_id, 1); assert_eq!(response_json.pulses.get(2).unwrap().level, true); assert_eq!(response_json.pulses.get(3).unwrap().timestamp_ns, 1290u64); assert_eq!(response_json.pulses.get(3).unwrap().pin_id, 1); assert_eq!(response_json.pulses.get(3).unwrap().level, false); let response = minreq::get(format!("http://{}/v1/channel/1/pulses", &IP_AND_PORT)).send(); assert!(&response.is_ok()); let response = response.unwrap(); print_response("rest_api_fetch_channel", &response); assert_eq!(response.status_code, tide::http::StatusCode::Ok as i32); let response_json = &response.json::().unwrap(); assert_eq!(response_json.channel, 1); assert_eq!(response_json.pulses.len(), 0); }