mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-13 16:08:04 -05:00
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Co-authored-by: georgehao <haohongfan@gmail.com>
130 lines
2.9 KiB
Go
130 lines
2.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"sync/atomic"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// IsRunning 1 started, 0 not started.
|
|
func (c *Cmd) IsRunning() bool {
|
|
return atomic.LoadUint64(&c.isRunning) == 1
|
|
}
|
|
|
|
func (c *Cmd) runApp() {
|
|
fmt.Println("cmd:", append([]string{c.name}, c.args...))
|
|
if atomic.CompareAndSwapUint64(&c.isRunning, 0, 1) {
|
|
c.ErrChan <- c.app.Run()
|
|
}
|
|
}
|
|
|
|
// RunApp exec's the current binary using name as argv[0] which will trigger the
|
|
// reexec init function for that name (e.g. "geth-test" in cmd/geth/run_test.go)
|
|
func (c *Cmd) RunApp(waitResult func() bool) {
|
|
if waitResult != nil {
|
|
go func() {
|
|
c.runApp()
|
|
}()
|
|
waitResult()
|
|
} else {
|
|
c.runApp()
|
|
}
|
|
}
|
|
|
|
// WaitExit wait util process exit.
|
|
func (c *Cmd) WaitExit() {
|
|
if atomic.LoadUint64(&c.isRunning) == 0 {
|
|
return
|
|
}
|
|
// Wait all the check functions are finished, interrupt loop when appear error.
|
|
var err error
|
|
for err == nil && !c.checkFuncs.IsEmpty() {
|
|
select {
|
|
case err = <-c.ErrChan:
|
|
if err != nil {
|
|
fmt.Printf("%s appear error during running, err: %v\n", c.name, err)
|
|
}
|
|
default:
|
|
<-time.After(time.Millisecond * 500)
|
|
}
|
|
}
|
|
|
|
// Send interrupt signal.
|
|
_ = c.app.Process.Signal(os.Interrupt)
|
|
// should use `_ = c.app.Process.Wait()` here, but we have some bugs in coordinator's graceful exit,
|
|
// so we use `Kill` as a temp workaround. And since `WaitExit` is only used in integration tests, so
|
|
// it won't really affect our functionalities.
|
|
if err = c.app.Process.Signal(syscall.SIGTERM); err != nil {
|
|
_ = c.app.Process.Kill()
|
|
}
|
|
}
|
|
|
|
// Interrupt send interrupt signal.
|
|
func (c *Cmd) Interrupt() {
|
|
c.ErrChan <- c.app.Process.Signal(os.Interrupt)
|
|
}
|
|
|
|
// WaitResult return true when get the keyword during timeout.
|
|
func (c *Cmd) WaitResult(t *testing.T, timeout time.Duration, keyword string) bool {
|
|
if keyword == "" {
|
|
return false
|
|
}
|
|
okCh := make(chan struct{}, 1)
|
|
c.RegistFunc(keyword, func(buf string) {
|
|
if strings.Contains(buf, keyword) {
|
|
select {
|
|
case okCh <- struct{}{}:
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
})
|
|
defer c.UnRegistFunc(keyword)
|
|
select {
|
|
case <-okCh:
|
|
return true
|
|
case <-time.After(timeout):
|
|
assert.Fail(t, fmt.Sprintf("didn't get the desired result before timeout, keyword: %s", keyword))
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ExpectWithTimeout wait result during timeout time.
|
|
func (c *Cmd) ExpectWithTimeout(t *testing.T, parallel bool, timeout time.Duration, keyword string) {
|
|
if keyword == "" {
|
|
return
|
|
}
|
|
okCh := make(chan struct{}, 1)
|
|
c.RegistFunc(keyword, func(buf string) {
|
|
if strings.Contains(buf, keyword) {
|
|
select {
|
|
case okCh <- struct{}{}:
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
})
|
|
|
|
waitResult := func() {
|
|
defer c.UnRegistFunc(keyword)
|
|
select {
|
|
case <-okCh:
|
|
return
|
|
case <-time.After(timeout):
|
|
assert.Fail(t, fmt.Sprintf("didn't get the desired result before timeout, keyword: %s", keyword))
|
|
}
|
|
}
|
|
|
|
if parallel {
|
|
go waitResult()
|
|
} else {
|
|
waitResult()
|
|
}
|
|
}
|