Skip to content

Commit

Permalink
Fix: e2e defunct process (#192)
Browse files Browse the repository at this point in the history
* TestServer: kill process group

* fix lint

* Makefile test add '-count=1' ignore cache

* Makefile test command add build dependency

* Ctrl-C kill process group

* fix mockStore.GetReceiptsByHash concurrent error

* never release reserved port

* never use the same port

* fix lint

* build tag support unix environment
  • Loading branch information
0xcb9ff9 authored Sep 22, 2022
1 parent ec87ccd commit 85538b4
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ lint:
golangci-lint run -c lint-rule.yaml --timeout=2m

.PHONY: test
test:
PATH=$(shell pwd):${PATH} go test -coverprofile coverage.out -timeout 28m ./...
test: build
PATH=$(shell pwd):${PATH} go test -count=1 -coverprofile coverage.out -timeout 28m ./...

.PHONY: generate-bsd-licenses
generate-bsd-licenses:
Expand Down
23 changes: 23 additions & 0 deletions e2e/framework/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos

package framework

import (
"os/exec"
)

func registerPID(cmd *exec.Cmd) {
// ignore
}

func execCommand(workdir, name string, args ...string) *exec.Cmd {
cmd := exec.Command(binaryName, args...)
cmd.Dir = workdir

return cmd
}

func processKill(cmd *exec.Cmd) error {
return cmd.Process.Kill()
}
58 changes: 58 additions & 0 deletions e2e/framework/cmd_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos

package framework

import (
"errors"
"os"
"os/exec"
"os/signal"
"syscall"
)

var pids = []int{}

func init() {
go func() {
// wait os.Interrupt signal
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

for sig := range c {
if sig == os.Interrupt {
// kill the whole process group
for _, pid := range pids {
_ = syscall.Kill(-pid, syscall.SIGKILL)
}
}

os.Exit(1)
}
}()
}

func registerPID(cmd *exec.Cmd) {
pids = append(pids, cmd.Process.Pid)
}

func execCommand(workdir, name string, args ...string) *exec.Cmd {
cmd := exec.Command(binaryName, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
Pgid: 0,
}
cmd.Dir = workdir

return cmd
}

func processKill(cmd *exec.Cmd) error {
// kill the whole process group
err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
if errors.Is(syscall.ESRCH, err) {
return nil
}

return err
}
23 changes: 23 additions & 0 deletions e2e/framework/cmd_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build windows
// +build windows

package framework

import (
"os/exec"
)

func registerPID(cmd *exec.Cmd) {
// ignore
}

func execCommand(workdir, name string, args ...string) *exec.Cmd {
cmd := exec.Command(binaryName, args...)
cmd.Dir = workdir

return cmd
}

func processKill(cmd *exec.Cmd) error {
return cmd.Process.Kill()
}
9 changes: 3 additions & 6 deletions e2e/framework/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,18 +381,15 @@ func FindAvailablePort(from, to int) *ReservedPort {
}

func FindAvailablePorts(n, from, to int) ([]ReservedPort, error) {
ports := make([]ReservedPort, 0, n)
ports := []ReservedPort{}
nextFrom := from

for i := 0; i < n; i++ {
newPort := FindAvailablePort(nextFrom, to)
if newPort == nil {
// Close current reserved ports
for _, p := range ports {
p.Close()
}
nextFrom++

return nil, errors.New("couldn't reserve required number of ports")
continue
}

ports = append(ports, *newPort)
Expand Down
40 changes: 25 additions & 15 deletions e2e/framework/testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -44,11 +45,13 @@ import (
type TestServerConfigCallback func(*TestServerConfig)

const (
serverIP = "127.0.0.1"
initialPort = 12000
binaryName = "dogechain"
serverIP = "127.0.0.1"
binaryName = "dogechain"
)

var lock sync.Mutex
var initialPort = 12000

type TestServer struct {
t *testing.T

Expand All @@ -59,12 +62,17 @@ type TestServer struct {
func NewTestServer(t *testing.T, rootDir string, callback TestServerConfigCallback) *TestServer {
t.Helper()

// Reserve ports
ports, err := FindAvailablePorts(3, initialPort, initialPort+10000)
lock.Lock()
defer lock.Unlock()

// never use the same port
ports, err := FindAvailablePorts(3, initialPort, 65534)
if err != nil {
t.Fatal(err)
}

initialPort = ports[2].Port() + 1

// Sets the services to start on open ports
config := &TestServerConfig{
ReservedPorts: ports,
Expand Down Expand Up @@ -170,7 +178,7 @@ func (t *TestServer) Stop() {
t.ReleaseReservedPorts()

if t.cmd != nil {
if err := t.cmd.Process.Kill(); err != nil {
if err := processKill(t.cmd); err != nil {
t.t.Error(err)
}
}
Expand All @@ -194,9 +202,7 @@ func (t *TestServer) SecretsInit() (*InitIBFTResult, error) {
args = append(args, commandSlice...)
args = append(args, "--data-dir", t.Config.IBFTDir)

cmd := exec.Command(binaryName, args...)
cmd.Dir = t.Config.RootDir

cmd := execCommand(t.Config.RootDir, binaryName, args...)
if _, err := cmd.Output(); err != nil {
return nil, err
}
Expand Down Expand Up @@ -312,8 +318,7 @@ func (t *TestServer) GenerateGenesis() error {
args = append(args, "--bridge-signer", signer.String())
}

cmd := exec.Command(binaryName, args...)
cmd.Dir = t.Config.RootDir
cmd := execCommand(t.Config.RootDir, binaryName, args...)

return cmd.Run()
}
Expand Down Expand Up @@ -374,8 +379,7 @@ func (t *TestServer) Start(ctx context.Context) error {
t.ReleaseReservedPorts()

// Start the server
t.cmd = exec.Command(binaryName, args...)
t.cmd.Dir = t.Config.RootDir
t.cmd = execCommand(t.Config.RootDir, binaryName, args...)

if t.Config.ShowsLog {
stdout := io.Writer(os.Stdout)
Expand All @@ -387,6 +391,13 @@ func (t *TestServer) Start(ctx context.Context) error {
return err
}

registerPID(t.cmd)

// fix defunct process
go func() {
_ = t.cmd.Wait()
}()

_, err := tests.RetryUntilTimeout(ctx, func() (interface{}, bool) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
Expand Down Expand Up @@ -426,8 +437,7 @@ func (t *TestServer) SwitchIBFTType(typ ibft.MechanismType, from uint64, to, dep
}

// Start the server
t.cmd = exec.Command(binaryName, args...)
t.cmd.Dir = t.Config.RootDir
t.cmd = execCommand(t.Config.RootDir, binaryName, args...)

if t.Config.ShowsLog {
stdout := io.Writer(os.Stdout)
Expand Down
3 changes: 3 additions & 0 deletions jsonrpc/mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func (m *mockStore) emitEvent(evnt *mockEvent) {
OldChain: []*types.Header{},
}

m.receiptsLock.Lock()
defer m.receiptsLock.Unlock()

for _, i := range evnt.NewChain {
m.receipts[i.header.Hash] = i.receipts
bEvnt.NewChain = append(bEvnt.NewChain, i.header)
Expand Down
5 changes: 4 additions & 1 deletion protocol/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ func CreateSyncer(t *testing.T, blockchain blockchainShim, serverCfg *func(c *ne
}

srv, createErr := network.CreateServer(&network.CreateServerParams{
ConfigCallback: *serverCfg,
ConfigCallback: func(c *network.Config) {
c.DataDir = t.TempDir()
(*serverCfg)(c)
},
})
if createErr != nil {
t.Fatalf("Unable to create networking server, %v", createErr)
Expand Down

0 comments on commit 85538b4

Please sign in to comment.