github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/edit/async_reader_test.go (about) 1 package edit 2 3 import ( 4 "fmt" 5 "math/rand" 6 "os" 7 "testing" 8 "time" 9 10 "github.com/elves/elvish/sys" 11 ) 12 13 // Pretty arbitrary numbers. May not reveal deadlocks on all machines. 14 15 var ( 16 DeadlockNWrite = 1024 17 DeadlockRun = 64 18 DeadlockTimeout = 500 * time.Millisecond 19 DeadlockMaxJitter = time.Millisecond 20 ) 21 22 func jitter() { 23 time.Sleep(time.Duration(float64(DeadlockMaxJitter) * rand.Float64())) 24 } 25 26 func f(done chan struct{}) { 27 r, w, err := os.Pipe() 28 if err != nil { 29 panic(err) 30 } 31 defer r.Close() 32 defer w.Close() 33 34 ar := NewAsyncReader(r) 35 defer ar.Close() 36 fmt.Fprintf(w, "%*s", DeadlockNWrite, "") 37 go func() { 38 jitter() 39 ar.Run() 40 }() 41 jitter() 42 ar.Quit() 43 done <- struct{}{} 44 } 45 46 func TestAsyncReaderDeadlock(t *testing.T) { 47 done := make(chan struct{}) 48 isatty := sys.IsATTY(1) 49 rand.Seed(time.Now().UTC().UnixNano()) 50 51 timer := time.NewTimer(DeadlockTimeout) 52 for i := 0; i < DeadlockRun; i++ { 53 if isatty { 54 fmt.Printf("\r%d/%d ", i+1, DeadlockRun) 55 } 56 57 go f(done) 58 59 select { 60 case <-done: 61 // no deadlock trigerred 62 case <-timer.C: 63 // deadlock 64 t.Errorf("%s", sys.DumpStack()) 65 t.Fatalf("AsyncReader deadlock trigerred on run %d/%d, stack trace:\n%s", i, DeadlockRun, sys.DumpStack()) 66 } 67 timer.Reset(DeadlockTimeout) 68 } 69 if isatty { 70 fmt.Print("\r \r") 71 } 72 } 73 74 var ReadTimeout = time.Second 75 76 func TestAsyncReader(t *testing.T) { 77 r, w, err := os.Pipe() 78 if err != nil { 79 panic(err) 80 } 81 defer r.Close() 82 defer w.Close() 83 84 ar := NewAsyncReader(r) 85 defer ar.Close() 86 go ar.Run() 87 88 go func() { 89 var i rune 90 for i = 0; i <= 1280; i += 10 { 91 w.WriteString(string(i)) 92 } 93 }() 94 95 var i rune 96 timer := time.NewTimer(ReadTimeout) 97 for i = 0; i <= 1280; i += 10 { 98 select { 99 case r := <-ar.Chan(): 100 if r != i { 101 t.Fatalf("expect %q, got %q\n", i, r) 102 } 103 case <-timer.C: 104 t.Fatalf("read timeout (i = %d)", i) 105 } 106 timer.Reset(ReadTimeout) 107 } 108 ar.Quit() 109 }