@@ -63,7 +63,14 @@ impl DendriteInstance {
6363 args. push ( socket_addr. to_string ( ) ) ;
6464 }
6565
66- let mut child = tokio:: process:: Command :: new ( "dpd" )
66+ let ( dpd_bin, p4_dir) = get_dpd_path ( ) ;
67+ let mut cmd = tokio:: process:: Command :: new ( dpd_bin) ;
68+ if let Some ( ref p4_dir) = p4_dir {
69+ if std:: env:: var ( "P4_DIR" ) . is_err ( ) {
70+ cmd. env ( "P4_DIR" , p4_dir) ;
71+ }
72+ }
73+ let mut child = cmd
6774 . args ( & args)
6875 . stdin ( Stdio :: null ( ) )
6976 . stdout ( Stdio :: from ( redirect_file (
@@ -110,6 +117,26 @@ impl DendriteInstance {
110117 }
111118}
112119
120+ fn get_dpd_path ( ) -> ( PathBuf , Option < PathBuf > ) {
121+ // On macOS, std::env::current_exe() does not resolve symlinks.
122+ let dpd_path = Path :: new ( "dpd" ) ;
123+ let resolved_dpd = std:: env:: var_os ( "PATH" )
124+ . and_then ( |paths| {
125+ std:: env:: split_paths ( & paths)
126+ . map ( |dir| dir. join ( "dpd" ) )
127+ . find ( |p| p. is_file ( ) )
128+ } )
129+ . and_then ( |p| std:: fs:: canonicalize ( & p) . ok ( ) ) ;
130+
131+ // Rebuild the p4 directory path from dpd path
132+ let p4_dir = resolved_dpd. as_ref ( ) . and_then ( |p| {
133+ p. parent ( ) . and_then ( |p| p. parent ( ) ) . map ( |p| p. join ( "sidecar" ) )
134+ } ) ;
135+
136+ let dpd_bin = resolved_dpd. as_deref ( ) . unwrap_or ( dpd_path) . to_owned ( ) ;
137+ ( dpd_bin, p4_dir)
138+ }
139+
113140impl Drop for DendriteInstance {
114141 fn drop ( & mut self ) {
115142 if self . child . is_some ( ) || self . data_dir . is_some ( ) {
@@ -206,6 +233,8 @@ async fn find_dendrite_port_in_log(
206233
207234#[ cfg( test) ]
208235mod tests {
236+ use crate :: dev:: dendrite:: get_dpd_path;
237+
209238 use super :: find_dendrite_port_in_log;
210239 use std:: io:: Write ;
211240 use std:: process:: Stdio ;
@@ -216,7 +245,8 @@ mod tests {
216245 #[ tokio:: test]
217246 async fn test_dpd_in_path ( ) {
218247 // With no arguments, we expect to see the default help message.
219- tokio:: process:: Command :: new ( "dpd" )
248+ let ( dpd_bin, _) = get_dpd_path ( ) ;
249+ tokio:: process:: Command :: new ( dpd_bin)
220250 . stdin ( Stdio :: null ( ) )
221251 . stdout ( Stdio :: null ( ) )
222252 . stderr ( Stdio :: null ( ) )
0 commit comments