@@ -1089,18 +1089,18 @@ func TestWait(t *testing.T) {
1089
1089
1090
1090
cases := []struct {
1091
1091
name string
1092
- stop func (m * Machine )
1092
+ stop func (m * Machine , cancel context. CancelFunc )
1093
1093
}{
1094
1094
{
1095
1095
name : "StopVMM" ,
1096
- stop : func (m * Machine ) {
1096
+ stop : func (m * Machine , _ context. CancelFunc ) {
1097
1097
err := m .StopVMM ()
1098
1098
require .NoError (t , err )
1099
1099
},
1100
1100
},
1101
1101
{
1102
1102
name : "Kill" ,
1103
- stop : func (m * Machine ) {
1103
+ stop : func (m * Machine , cancel context. CancelFunc ) {
1104
1104
pid , err := m .PID ()
1105
1105
require .NoError (t , err )
1106
1106
@@ -1111,6 +1111,17 @@ func TestWait(t *testing.T) {
1111
1111
},
1112
1112
{
1113
1113
name : "Context Cancel" ,
1114
+ stop : func (m * Machine , cancel context.CancelFunc ) {
1115
+ cancel ()
1116
+ },
1117
+ },
1118
+ {
1119
+ name : "StopVMM + Context Cancel" ,
1120
+ stop : func (m * Machine , cancel context.CancelFunc ) {
1121
+ m .StopVMM ()
1122
+ time .Sleep (1 * time .Second )
1123
+ cancel ()
1124
+ },
1114
1125
},
1115
1126
}
1116
1127
@@ -1123,50 +1134,42 @@ func TestWait(t *testing.T) {
1123
1134
defer os .Remove (socketPath )
1124
1135
1125
1136
cfg := createValidConfig (t , socketPath )
1126
- cmd := VMCommandBuilder {}.
1127
- WithSocketPath (cfg .SocketPath ).
1128
- WithBin (getFirecrackerBinaryPath ()).
1129
- Build (vmContext )
1130
- m , err := NewMachine (ctx , cfg , WithProcessRunner (cmd ))
1137
+ m , err := NewMachine (ctx , cfg , func (m * Machine ) {
1138
+ // Rewriting m.cmd partially wouldn't work since Cmd has
1139
+ // some unexported members
1140
+ args := m .cmd .Args [1 :]
1141
+ m .cmd = exec .Command (getFirecrackerBinaryPath (), args ... )
1142
+ })
1131
1143
require .NoError (t , err )
1132
1144
1133
- err = m .Start (ctx )
1145
+ err = m .Start (vmContext )
1134
1146
require .NoError (t , err )
1135
1147
1136
1148
pid , err := m .PID ()
1137
1149
require .NoError (t , err )
1138
1150
1151
+ var wg sync.WaitGroup
1152
+ wg .Add (1 )
1139
1153
go func () {
1140
- if c .stop != nil {
1141
- c .stop (m )
1142
- } else {
1143
- vmCancel ()
1144
- }
1154
+ defer wg .Done ()
1155
+ c .stop (m , vmCancel )
1145
1156
}()
1146
1157
1147
1158
err = m .Wait (ctx )
1148
1159
require .Error (t , err , "Firecracker was killed and it must be reported" )
1160
+ t .Logf ("err = %v" , err )
1149
1161
1150
- alive , err := isProcessAlive (pid )
1151
- require .False (t , alive , "pid=%d is still there" , pid )
1152
- })
1153
- }
1154
- }
1162
+ proc , err := os .FindProcess (pid )
1163
+ // Having an error here doesn't mean the process is not there.
1164
+ // In fact it won't be non-nil on Unix systems
1165
+ require .NoError (t , err )
1155
1166
1156
- func isProcessAlive (pid int ) (bool , error ) {
1157
- // Using kill(2) with signal=0 to check the existence of the process,
1158
- // because os.FindProcess always returns a process, regardless of whether the process is
1159
- // alive or not.
1160
- // https://golang.org/pkg/os/#FindProcess
1161
- err := syscall .Kill (pid , syscall .Signal (0 ))
1162
- if err != nil {
1163
- if errno , ok := err .(syscall.Errno ); ok {
1164
- if errno == syscall .ESRCH {
1165
- return false , nil
1166
- }
1167
- }
1167
+ err = proc .Signal (syscall .Signal (0 ))
1168
+ require .Equal (t , "os: process already finished" , err .Error ())
1169
+
1170
+ wg .Wait ()
1171
+ })
1168
1172
}
1169
- return true , nil
1170
1173
}
1171
1174
1172
1175
func TestWaitWithInvalidBinary (t * testing.T ) {
0 commit comments