@@ -185,111 +185,15 @@ impl ExecutorLifecycle for ProcmgrLifecycle {
185185#[ cfg( test) ]
186186mod tests {
187187 use super :: * ;
188- use procmgr :: process_manager_server :: { ProcessManager , ProcessManagerServer } ;
189- use std:: sync:: { Arc , Mutex } ;
190- use tonic:: { Request , Response , Status } ;
188+ use crate :: test_support :: { FakeProcmgr , serve_procmgr } ;
189+ use std:: sync:: Arc ;
190+ use tonic:: Status ;
191191
192192 const TEST_PROCESS_NAME : & str = "datadog-agent-action-executor" ;
193193
194- #[ derive( Default ) ]
195- struct FakeProcmgr {
196- state : Mutex < Option < i32 > > ,
197- start_result : Mutex < Option < Status > > ,
198- starts : Mutex < u32 > ,
199- stops : Mutex < u32 > ,
200- hang : bool ,
201- }
202-
203- /// Newtype so the trait impl has a local self type: under Bazel the generated
204- /// bindings live in a foreign crate, so implementing a foreign trait for
205- /// `Arc<FakeProcmgr>` would break the orphan rule even though it compiles
206- /// under `cargo`, where `include_proto!` generates the trait locally.
207- #[ derive( Clone ) ]
208- struct FakeService ( Arc < FakeProcmgr > ) ;
209-
210- #[ tonic:: async_trait]
211- impl ProcessManager for FakeService {
212- async fn describe (
213- & self ,
214- _: Request < procmgr:: DescribeRequest > ,
215- ) -> Result < Response < procmgr:: DescribeResponse > , Status > {
216- if self . 0 . hang {
217- tokio:: time:: sleep ( Duration :: from_secs ( 3600 ) ) . await ;
218- }
219- let state = * self . 0 . state . lock ( ) . unwrap ( ) ;
220- Ok ( Response :: new ( procmgr:: DescribeResponse {
221- detail : state. map ( |state| procmgr:: ProcessDetail {
222- name : TEST_PROCESS_NAME . to_string ( ) ,
223- state,
224- ..Default :: default ( )
225- } ) ,
226- } ) )
227- }
228-
229- async fn start (
230- & self ,
231- _: Request < procmgr:: StartRequest > ,
232- ) -> Result < Response < procmgr:: StartResponse > , Status > {
233- * self . 0 . starts . lock ( ) . unwrap ( ) += 1 ;
234- if let Some ( status) = self . 0 . start_result . lock ( ) . unwrap ( ) . clone ( ) {
235- return Err ( status) ;
236- }
237- Ok ( Response :: new ( procmgr:: StartResponse :: default ( ) ) )
238- }
239-
240- async fn stop (
241- & self ,
242- _: Request < procmgr:: StopRequest > ,
243- ) -> Result < Response < procmgr:: StopResponse > , Status > {
244- * self . 0 . stops . lock ( ) . unwrap ( ) += 1 ;
245- Ok ( Response :: new ( procmgr:: StopResponse :: default ( ) ) )
246- }
247-
248- async fn list (
249- & self ,
250- _: Request < procmgr:: ListRequest > ,
251- ) -> Result < Response < procmgr:: ListResponse > , Status > {
252- Err ( Status :: unimplemented ( "list" ) )
253- }
254- async fn get_status (
255- & self ,
256- _: Request < procmgr:: GetStatusRequest > ,
257- ) -> Result < Response < procmgr:: GetStatusResponse > , Status > {
258- Err ( Status :: unimplemented ( "get_status" ) )
259- }
260- async fn create (
261- & self ,
262- _: Request < procmgr:: CreateRequest > ,
263- ) -> Result < Response < procmgr:: CreateResponse > , Status > {
264- Err ( Status :: unimplemented ( "create" ) )
265- }
266- async fn reload_config (
267- & self ,
268- _: Request < procmgr:: ReloadConfigRequest > ,
269- ) -> Result < Response < procmgr:: ReloadConfigResponse > , Status > {
270- Err ( Status :: unimplemented ( "reload_config" ) )
271- }
272- async fn get_config (
273- & self ,
274- _: Request < procmgr:: GetConfigRequest > ,
275- ) -> Result < Response < procmgr:: GetConfigResponse > , Status > {
276- Err ( Status :: unimplemented ( "get_config" ) )
277- }
278- }
279-
280194 #[ cfg( unix) ]
281- async fn serve ( fake : Arc < FakeProcmgr > ) -> ( ProcmgrLifecycle , tempfile:: TempDir ) {
282- use tokio_stream:: wrappers:: UnixListenerStream ;
283-
284- let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
285- let socket = dir. path ( ) . join ( "dd-procmgrd.sock" ) ;
286- let listener = tokio:: net:: UnixListener :: bind ( & socket) . unwrap ( ) ;
287- tokio:: spawn ( async move {
288- let _ = tonic:: transport:: Server :: builder ( )
289- . add_service ( ProcessManagerServer :: new ( FakeService ( fake) ) )
290- . serve_with_incoming ( UnixListenerStream :: new ( listener) )
291- . await ;
292- } ) ;
195+ async fn lifecycle_for ( fake : Arc < FakeProcmgr > ) -> ( ProcmgrLifecycle , tempfile:: TempDir ) {
196+ let ( socket, dir) = serve_procmgr ( fake) . await ;
293197 (
294198 ProcmgrLifecycle :: new ( & socket, TEST_PROCESS_NAME . to_string ( ) ) ,
295199 dir,
@@ -308,19 +212,15 @@ mod tests {
308212 procmgr:: ProcessState :: Running ,
309213 procmgr:: ProcessState :: Stopping ,
310214 ] {
311- let fake = Arc :: new ( FakeProcmgr {
312- state : Mutex :: new ( Some ( state as i32 ) ) ,
313- ..Default :: default ( )
314- } ) ;
315- let ( lifecycle, _dir) = serve ( Arc :: clone ( & fake) ) . await ;
215+ let fake = FakeProcmgr :: in_state ( state) ;
216+ let ( lifecycle, _dir) = lifecycle_for ( Arc :: clone ( & fake) ) . await ;
316217
317218 lifecycle
318219 . ensure_started ( )
319220 . await
320221 . unwrap_or_else ( |e| panic ! ( "state {state:?} should be adopted: {e:#}" ) ) ;
321- assert_eq ! (
322- * fake. starts. lock( ) . unwrap( ) ,
323- 0 ,
222+ assert ! (
223+ fake. started( ) . is_empty( ) ,
324224 "state {state:?} is alive; Start must not be issued"
325225 ) ;
326226 }
@@ -330,29 +230,26 @@ mod tests {
330230 #[ cfg( unix) ]
331231 #[ tokio:: test]
332232 async fn ensure_started_tolerates_a_start_race ( ) {
333- let fake = Arc :: new ( FakeProcmgr {
334- state : Mutex :: new ( Some ( procmgr:: ProcessState :: Exited as i32 ) ) ,
335- start_result : Mutex :: new ( Some ( Status :: failed_precondition ( "already running" ) ) ) ,
336- ..Default :: default ( )
337- } ) ;
338- let ( lifecycle, _dir) = serve ( Arc :: clone ( & fake) ) . await ;
233+ let fake = FakeProcmgr :: failing_start (
234+ procmgr:: ProcessState :: Exited ,
235+ Status :: failed_precondition ( "already running" ) ,
236+ ) ;
237+ let ( lifecycle, _dir) = lifecycle_for ( Arc :: clone ( & fake) ) . await ;
339238
340239 lifecycle. ensure_started ( ) . await . expect ( "race is not fatal" ) ;
341- assert_eq ! ( * fake. starts . lock ( ) . unwrap ( ) , 1 ) ;
240+ assert_eq ! ( fake. started ( ) . len ( ) , 1 ) ;
342241 }
343242
344243 #[ cfg( unix) ]
345244 #[ tokio:: test]
346245 async fn ensure_started_propagates_other_failures ( ) {
347- let fake = Arc :: new ( FakeProcmgr {
348- state : Mutex :: new ( Some ( procmgr:: ProcessState :: Exited as i32 ) ) ,
349- start_result : Mutex :: new ( Some ( Status :: not_found ( "no such process" ) ) ) ,
350- ..Default :: default ( )
351- } ) ;
352- let ( lifecycle, _dir) = serve ( fake) . await ;
246+ let fake = FakeProcmgr :: failing_start (
247+ procmgr:: ProcessState :: Exited ,
248+ Status :: not_found ( "no such process" ) ,
249+ ) ;
250+ let ( lifecycle, _dir) = lifecycle_for ( fake) . await ;
353251
354- let error = lifecycle. ensure_started ( ) . await . unwrap_err ( ) ;
355- let rendered = format ! ( "{error:#}" ) ;
252+ let rendered = format ! ( "{:#}" , lifecycle. ensure_started( ) . await . unwrap_err( ) ) ;
356253 assert ! ( rendered. contains( "Start failed" ) , "{rendered}" ) ;
357254 assert ! ( rendered. contains( "no such process" ) , "{rendered}" ) ;
358255 }
@@ -363,24 +260,18 @@ mod tests {
363260 #[ cfg( unix) ]
364261 #[ tokio:: test]
365262 async fn rpcs_time_out_against_an_unresponsive_daemon ( ) {
366- let fake = Arc :: new ( FakeProcmgr {
367- hang : true ,
368- ..Default :: default ( )
369- } ) ;
370- let ( mut lifecycle, _dir) = serve ( fake) . await ;
263+ let ( mut lifecycle, _dir) = lifecycle_for ( FakeProcmgr :: unresponsive ( ) ) . await ;
371264 lifecycle. rpc_timeout = Duration :: from_millis ( 50 ) ;
372265
373- let error = lifecycle. is_running ( ) . await . unwrap_err ( ) ;
374- let rendered = format ! ( "{error:#}" ) ;
266+ let rendered = format ! ( "{:#}" , lifecycle. is_running( ) . await . unwrap_err( ) ) ;
375267 assert ! ( rendered. contains( "did not respond within" ) , "{rendered}" ) ;
376268 }
377269
378270 /// A missing definition means there is nothing to reap or report on.
379271 #[ cfg( unix) ]
380272 #[ tokio:: test]
381273 async fn reports_a_vanished_process_as_exited ( ) {
382- let fake = Arc :: new ( FakeProcmgr :: default ( ) ) ;
383- let ( lifecycle, _dir) = serve ( fake) . await ;
274+ let ( lifecycle, _dir) = lifecycle_for ( FakeProcmgr :: vanished ( ) ) . await ;
384275
385276 assert ! ( lifecycle. has_exited( ) . await . unwrap( ) ) ;
386277 assert ! ( !lifecycle. is_running( ) . await . unwrap( ) ) ;
0 commit comments