Skip to content

Commit

Permalink
Add exiter to test os.Exit case
Browse files Browse the repository at this point in the history
  • Loading branch information
jingdi.zhu committed Jan 19, 2025
1 parent 0811477 commit 2c74951
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 3 deletions.
15 changes: 12 additions & 3 deletions runner/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (

// Engine ...
type Engine struct {
config *Config
config *Config

exiter exiter
proxy *Proxy
logger *logger
watcher filenotify.FileWatcher
Expand Down Expand Up @@ -50,6 +52,7 @@ func NewEngineWithConfig(cfg *Config, debugMode bool) (*Engine, error) {
}
e := Engine{
config: cfg,
exiter: defaultExiter{},
proxy: NewProxy(&cfg.Proxy),
logger: logger,
watcher: watcher,
Expand Down Expand Up @@ -655,8 +658,14 @@ func (e *Engine) stopBin() {
close(exitCode)
}
})
if ret := <-exitCode; ret != 0 {
os.Exit(ret)

select {
case ret := <-exitCode:
if ret != 0 {
e.exiter.Exit(ret) // Use exiter instead of direct os.Exit, it's for tests purpose.
}
case <-time.After(5 * time.Second):
e.mainDebug("timed out waiting for process exit")

Check warning on line 668 in runner/engine.go

View check run for this annotation

Codecov / codecov/patch

runner/engine.go#L665-L668

Added lines #L665 - L668 were not covered by tests
}
}

Expand Down
83 changes: 83 additions & 0 deletions runner/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,3 +1058,86 @@ include_file = ["main.sh"]
}
assert.Equal(t, []byte("modified"), bytes)
}

type testExiter struct {
t *testing.T
called bool
expectCode int
}

func (te *testExiter) Exit(code int) {
te.called = true
if code != te.expectCode {
te.t.Fatalf("expected exit code %d, got %d", te.expectCode, code)
}
}

func TestEngineExit(t *testing.T) {
tests := []struct {
name string
setup func(*Engine, chan<- int)
expectCode int
wantCalled bool
}{
{
name: "normal exit - no error",
setup: func(_ *Engine, exitCode chan<- int) {
go func() {
exitCode <- 0
}()
},
expectCode: 0,
wantCalled: false,
},
{
name: "error exit - non-zero code",
setup: func(_ *Engine, exitCode chan<- int) {
go func() {
exitCode <- 1
}()
},
expectCode: 1,
wantCalled: true,
},
{
name: "process timeout",
setup: func(_ *Engine, _ chan<- int) {
},
expectCode: 0,
wantCalled: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e, err := NewEngine("", true)
if err != nil {
t.Fatal(err)
}

exiter := &testExiter{
t: t,
expectCode: tt.expectCode,
}
e.exiter = exiter

exitCode := make(chan int)

if tt.setup != nil {
tt.setup(e, exitCode)
}
select {
case ret := <-exitCode:
if ret != 0 {
e.exiter.Exit(ret)
}
case <-time.After(1 * time.Millisecond):
// timeout case
}

if tt.wantCalled != exiter.called {
t.Errorf("Exit() called = %v, want %v", exiter.called, tt.wantCalled)
}
})
}
}
13 changes: 13 additions & 0 deletions runner/exiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package runner

import "os"

type exiter interface {
Exit(code int)
}

type defaultExiter struct{}

func (d defaultExiter) Exit(code int) {
os.Exit(code)

Check warning on line 12 in runner/exiter.go

View check run for this annotation

Codecov / codecov/patch

runner/exiter.go#L11-L12

Added lines #L11 - L12 were not covered by tests
}

0 comments on commit 2c74951

Please sign in to comment.