11use std:: path:: PathBuf ;
2- use std:: process:: { Command , Stdio } ;
2+ use std:: process:: { Command , ExitStatus , Stdio } ;
33use std:: io:: Result as IoResult ;
44
55use bon:: bon;
@@ -42,13 +42,73 @@ impl TestRunner {
4242 args : & [ & str ] ,
4343 fixture_name : Option < & str > ,
4444 env_vars : Option < & [ ( & str , & str ) ] > ,
45+ users : Option < & [ & str ] > ,
46+ groups : Option < & [ & str ] > ,
4547 ) -> IoResult < CommandResult > {
4648 // If a fixture is specified, update the configuration
4749 if let Some ( fixture) = fixture_name {
4850 if let Err ( e) = self . config_manager . load_fixture ( & fixture. into ( ) ) {
4951 eprintln ! ( "Warning: Failed to load fixture '{}': {}" , fixture, e) ;
5052 }
5153 }
54+ let mut added_users = Vec :: new ( ) ;
55+ let mut added_groups = Vec :: new ( ) ;
56+ if let Some ( user_list) = users {
57+ // Check if users exist and create them if necessary
58+ for & user in user_list {
59+ let user_check = Command :: new ( "id" )
60+ . arg ( user)
61+ . stdout ( Stdio :: null ( ) )
62+ . stderr ( Stdio :: null ( ) )
63+ . status ( ) ;
64+ match user_check {
65+ Ok ( _) => { }
66+ Err ( e) => {
67+ //check if error is due to user not existing
68+ if e. kind ( ) != std:: io:: ErrorKind :: NotFound {
69+ eprintln ! ( "Warning: Failed to check user '{}': {}" , user, e) ;
70+ continue ;
71+ }
72+ // User does not exist, attempt to create
73+ let create_status = Command :: new ( "sudo" )
74+ . args ( & [ "useradd" , "-m" , user] )
75+ . status ( ) ;
76+ if let Err ( e) = create_status {
77+ eprintln ! ( "Warning: Failed to create user '{}': {}" , user, e) ;
78+ }
79+ added_users. push ( user. to_string ( ) ) ;
80+ }
81+ }
82+ }
83+ }
84+ if let Some ( group_list) = groups {
85+ // Check if groups exist and create them if necessary
86+ for & group in group_list {
87+ let group_check = Command :: new ( "getent" )
88+ . args ( & [ "group" , group] )
89+ . stdout ( Stdio :: null ( ) )
90+ . stderr ( Stdio :: null ( ) )
91+ . status ( ) ;
92+ match group_check {
93+ Ok ( _) => { }
94+ Err ( e) => {
95+ //check if error is due to group not existing
96+ if e. kind ( ) != std:: io:: ErrorKind :: NotFound {
97+ eprintln ! ( "Warning: Failed to check group '{}': {}" , group, e) ;
98+ continue ;
99+ }
100+ // Group does not exist, attempt to create
101+ let create_status = Command :: new ( "sudo" )
102+ . args ( & [ "groupadd" , group] )
103+ . status ( ) ;
104+ if let Err ( e) = create_status {
105+ eprintln ! ( "Warning: Failed to create group '{}': {}" , group, e) ;
106+ }
107+ added_groups. push ( group. to_string ( ) ) ;
108+ }
109+ }
110+ }
111+ }
52112 let mut command = Command :: new ( & self . binary_path ) ;
53113 command
54114 . args ( args)
@@ -57,6 +117,18 @@ impl TestRunner {
57117 . stderr ( Stdio :: piped ( ) ) ;
58118
59119 let output = command. output ( ) ?;
120+
121+ // Clean up any users or groups we added
122+ for user in added_users {
123+ let _ = Command :: new ( "sudo" )
124+ . args ( & [ "userdel" , "-r" , & user] )
125+ . status ( ) ;
126+ }
127+ for group in added_groups {
128+ let _ = Command :: new ( "sudo" )
129+ . args ( & [ "groupdel" , & group] )
130+ . status ( ) ;
131+ }
60132
61133 Ok ( CommandResult {
62134 success : output. status . success ( ) ,
0 commit comments