Skip to content

Commit

Permalink
Added test
Browse files Browse the repository at this point in the history
  • Loading branch information
lpusok committed Jul 26, 2022
1 parent c03fb9e commit fe13255
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 21 deletions.
9 changes: 9 additions & 0 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,12 @@ workflows:
is_always_run: false
inputs:
- content: exit 0

hang-test:
title: hangs
description: Workflow will hang
steps:
- script:
title: Hang
inputs:
- content: sleep 3000
26 changes: 15 additions & 11 deletions tools/hangdetector/hang_detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ type HangDetector interface {
}

type hangDetector struct {
ticker time.Ticker
intervalCount uint64
maxIntervals uint64
notification chan bool
ticker Ticker
elapsedIntervalCount uint64
maxIntervals uint64
notification chan bool

writers []HangDetectorWriter
writers []io.Writer
}

func NewHangDetector(timeout time.Duration) HangDetector {
tickerInterval := time.Second * 30
func NewDefaultHangDetector(timeout time.Duration) HangDetector {
const tickerInterval = time.Second * 30
maxIntervals := uint64(timeout / tickerInterval)

return newHangDetector(NewTicker(tickerInterval), maxIntervals)
}

func newHangDetector(ticker Ticker, maxIntervals uint64) HangDetector {
detector := hangDetector{
ticker: *time.NewTicker(tickerInterval),
ticker: ticker,
maxIntervals: maxIntervals,
notification: make(chan bool),
}
Expand All @@ -35,7 +39,7 @@ func NewHangDetector(timeout time.Duration) HangDetector {
}

func (h *hangDetector) WrapWriter(writer io.Writer) io.Writer {
hangWriter := NewHangDetectorWriter(writer, &h.intervalCount)
hangWriter := newWriter(writer, &h.elapsedIntervalCount)
h.writers = append(h.writers, hangWriter)

return hangWriter
Expand All @@ -47,8 +51,8 @@ func (h *hangDetector) C() chan bool {

func (h hangDetector) checkHang() {
go func() {
for range h.ticker.C {
count := atomic.AddUint64(&h.intervalCount, 1)
for range h.ticker.C() {
count := atomic.AddUint64(&h.elapsedIntervalCount, 1)
if count >= h.maxIntervals {
h.notification <- true
}
Expand Down
14 changes: 14 additions & 0 deletions tools/hangdetector/hang_detector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package hangdetector

import (
"testing"
)

func Test_GivenNoWriter_WhenTimeout_ThenHangs_(t *testing.T) {
ticker := NewMockTicker()
detector := newHangDetector(ticker, 5)

ticker.DoTicks(5)

<-detector.C()
}
14 changes: 5 additions & 9 deletions tools/hangdetector/hang_detector_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ import (
"sync/atomic"
)

type HangDetectorWriter interface {
io.Writer
}

type hangDetectorWriter struct {
type writer struct {
writer io.Writer
count *uint64
}

func NewHangDetectorWriter(writer io.Writer, count *uint64) HangDetectorWriter {
return hangDetectorWriter{
writer: writer,
func newWriter(wrappedWriter io.Writer, count *uint64) io.Writer {
return writer{
writer: wrappedWriter,
count: count,
}
}

func (h hangDetectorWriter) Write(p []byte) (int, error) {
func (h writer) Write(p []byte) (int, error) {
atomic.StoreUint64(h.count, 0)
return h.writer.Write(p)
}
49 changes: 49 additions & 0 deletions tools/hangdetector/ticker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package hangdetector

import "time"

type Ticker interface {
C() <-chan time.Time
Stop()
}

type ticker struct {
ticker *time.Ticker
}

func NewTicker(d time.Duration) Ticker {
return ticker{
ticker: time.NewTicker(d),
}
}

func (t ticker) C() <-chan time.Time {
return t.ticker.C
}

func (t ticker) Stop() {
t.ticker.Stop()
}

type MockTicker struct {
Channel chan time.Time
}

func NewMockTicker() MockTicker {
return MockTicker{
Channel: make(chan time.Time),
}
}

func (t MockTicker) C() <-chan time.Time {
return t.Channel
}

func (t MockTicker) Stop() {
}

func (t MockTicker) DoTicks(n int) {
for i := 0; i < n; i++ {
t.Channel <- time.Now()
}
}
2 changes: 1 addition & 1 deletion tools/timeoutcmd/timeoutcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func New(hangTimeout time.Duration, dir, name string, args ...string) Command {
c.cmd.Dir = dir

if hangTimeout != 0 {
c.hangDetector = hangdetector.NewHangDetector(hangTimeout)
c.hangDetector = hangdetector.NewDefaultHangDetector(hangTimeout)
}

return c
Expand Down

0 comments on commit fe13255

Please sign in to comment.