edge_impulse_runner/inference/
mod.rs1pub mod messages;
2pub mod model;
3#[cfg(test)]
6mod tests {
7 use crate::{EdgeImpulseError, EdgeImpulseModel};
8 use std::env;
9 use std::fs::File;
10 use std::io::Write;
11 use std::path::Path;
12 use std::process::Command;
13 use tempfile;
14
15 fn create_mock_eim() -> std::path::PathBuf {
22 let manifest_dir =
23 env::var("CARGO_MANIFEST_DIR").expect("Failed to get manifest directory");
24 let mock_path = Path::new(&manifest_dir).join("mock_eim.sh");
25 let response_path = Path::new(&manifest_dir).join("mock_response.json");
26
27 let response_json = r#"{"success":true,"id":1,"model_parameters":{"axis_count":3,"frequency":62.5,"has_anomaly":1,"image_channel_count":0,"image_input_frames":0,"image_input_height":0,"image_input_width":0,"image_resize_mode":"none","inferencing_engine":4,"input_features_count":375,"interval_ms":16,"label_count":6,"labels":["drink","fistbump","idle","snake","updown","wave"],"model_type":"classification","sensor":2,"slice_size":31,"threshold":0.6,"use_continuous_mode":false},"project":{"deploy_version":271,"id":1,"name":"Test Project","owner":"Test Owner"}}"#;
29 std::fs::write(&response_path, response_json).unwrap();
30
31 let mock_script = format!(
33 r#"#!/bin/sh
34SOCKET_PATH=$1
35socat UNIX-LISTEN:$SOCKET_PATH,fork SYSTEM:'cat {}'"#,
36 response_path.display()
37 );
38
39 let mut file = File::create(&mock_path).unwrap();
40 file.write_all(mock_script.as_bytes()).unwrap();
41
42 use std::os::unix::fs::PermissionsExt;
44 let mut perms = std::fs::metadata(&mock_path).unwrap().permissions();
45 perms.set_mode(0o755);
46 std::fs::set_permissions(&mock_path, perms).unwrap();
47
48 mock_path
49 }
50
51 #[test]
52 fn test_missing_file_error() {
53 let temp_dir = tempfile::tempdir().unwrap();
55 let socket_path = temp_dir.path().join("test.socket");
56
57 let result = EdgeImpulseModel::new_with_socket(
59 std::path::Path::new("unknown.eim"),
60 socket_path.as_path(),
61 );
62 match result {
63 Err(EdgeImpulseError::ExecutionError(msg)) if msg.contains("No such file") => (),
64 other => panic!("Expected ExecutionError for missing file, got {:?}", other),
65 }
66 }
67
68 #[test]
69 fn test_invalid_extension() {
70 let temp_file = std::env::temp_dir().join("test.txt");
72 std::fs::write(&temp_file, "dummy content").unwrap();
73
74 let result = EdgeImpulseModel::new(temp_file.as_path());
75 match result {
76 Err(EdgeImpulseError::InvalidPath) => (),
77 _ => panic!("Expected InvalidPath when file has wrong extension"),
78 }
79 }
80
81 #[test]
82 fn test_successful_connection() {
83 let socat_check = Command::new("which")
85 .arg("socat")
86 .output()
87 .expect("Failed to check for socat");
88
89 if !socat_check.status.success() {
90 println!("Skipping test: socat is not installed");
91 return;
92 }
93
94 let temp_dir = tempfile::tempdir().unwrap();
96 let socket_path = temp_dir.path().join("test.socket");
97
98 let mock_path = create_mock_eim();
100 let response_path = mock_path.with_extension("json");
101 let mut mock_path_with_eim = mock_path.clone();
102 mock_path_with_eim.set_extension("eim");
103 std::fs::rename(&mock_path, &mock_path_with_eim).unwrap();
104
105 let result =
107 EdgeImpulseModel::new_with_socket(mock_path_with_eim.as_path(), socket_path.as_path());
108 assert!(
109 result.is_ok(),
110 "Failed to create EIM model: {:?}",
111 result.err()
112 );
113
114 if mock_path_with_eim.exists() {
116 std::fs::remove_file(&mock_path_with_eim).unwrap_or_else(|e| {
117 println!("Warning: Failed to remove mock EIM file: {}", e);
118 });
119 }
120 if response_path.exists() {
121 std::fs::remove_file(&response_path).unwrap_or_else(|e| {
122 println!("Warning: Failed to remove response file: {}", e);
123 });
124 }
125 }
126
127 #[test]
128 fn test_connection_timeout() {
129 let temp_dir = tempfile::tempdir().unwrap();
131 let socket_path = temp_dir.path().join("test.socket");
132 let model_path = temp_dir.path().join("dummy.eim");
133
134 let script = "#!/bin/sh\nsleep 10\n"; std::fs::write(&model_path, script).unwrap();
137
138 #[cfg(unix)]
139 {
140 use std::os::unix::fs::PermissionsExt;
141 let mut perms = std::fs::metadata(&model_path).unwrap().permissions();
142 perms.set_mode(0o755);
143 std::fs::set_permissions(&model_path, perms).unwrap();
144 }
145
146 let result = EdgeImpulseModel::new_with_socket(model_path.as_path(), socket_path.as_path());
148 assert!(
149 matches!(result,
150 Err(EdgeImpulseError::SocketError(ref msg)) if msg.contains("Timeout waiting for socket")
151 ),
152 "Expected timeout error, got {:?}",
153 result
154 );
155 }
156}