diff --git a/test/e2e_node/e2e_service.go b/test/e2e_node/e2e_service.go index 3bbb5e27c91..12c8d9e915a 100644 --- a/test/e2e_node/e2e_service.go +++ b/test/e2e_node/e2e_service.go @@ -433,10 +433,27 @@ func (s *server) String() string { // TODO(random-liu): Move this to util func readinessCheck(urls []string, errCh <-chan error) error { endTime := time.Now().Add(*serverStartTimeout) + blockCh := make(chan error) + defer close(blockCh) for endTime.After(time.Now()) { select { - case err := <-errCh: - return err + // We *always* want to run the health check if there is no error on the channel. + // With systemd, reads from errCh report nil because cmd.Run() waits + // on systemd-run, rather than the service process. systemd-run quickly + // exits with status 0, causing the channel to be closed with no error. In + // this case, you want to wait for the health check to complete, rather + // than returning from readinessCheck as soon as the channel is closed. + case err, ok := <-errCh: + if ok { // The channel is not closed, this is a real error + if err != nil { // If there is an error, return it + return err + } + // If not, keep checking readiness. + } else { // The channel is closed, this is only a zero value. + // Replace the errCh with blockCh to avoid busy loop, + // and keep checking readiness. + errCh = blockCh + } case <-time.After(time.Second): ready := true for _, url := range urls {