| 69 | } |
| 70 | |
| 71 | func TestStressBufferPool(t *testing.T) { |
| 72 | if testing.Short() { |
| 73 | t.Skip() |
| 74 | } |
| 75 | |
| 76 | const routines = 10 |
| 77 | const runtime = 2 * time.Second |
| 78 | |
| 79 | bp := newBufferPool() |
| 80 | t0 := time.Now() |
| 81 | |
| 82 | var wg sync.WaitGroup |
| 83 | fail := make(chan struct{}, routines) |
| 84 | for i := 0; i < routines; i++ { |
| 85 | wg.Go(func() { |
| 86 | for time.Since(t0) < runtime { |
| 87 | blocks := make([][]byte, 10) |
| 88 | for i := range blocks { |
| 89 | // Request a block of random size with the range |
| 90 | // covering smaller-than-min to larger-than-max and |
| 91 | // everything in between. |
| 92 | want := rand.Intn(1.5 * MaxBlockSize) |
| 93 | blocks[i] = bp.Get(want) |
| 94 | if len(blocks[i]) != want { |
| 95 | fail <- struct{}{} |
| 96 | return |
| 97 | } |
| 98 | } |
| 99 | for i := range blocks { |
| 100 | bp.Put(blocks[i]) |
| 101 | } |
| 102 | } |
| 103 | }) |
| 104 | } |
| 105 | |
| 106 | wg.Wait() |
| 107 | select { |
| 108 | case <-fail: |
| 109 | t.Fatal("a block was bad size") |
| 110 | default: |
| 111 | } |
| 112 | |
| 113 | t.Log(bp.puts.Load(), bp.skips.Load(), bp.misses.Load(), bp.hits) |
| 114 | if bp.puts.Load() == 0 || bp.skips.Load() == 0 || bp.misses.Load() == 0 { |
| 115 | t.Error("didn't exercise some paths") |
| 116 | } |
| 117 | var hits int64 |
| 118 | for i := range bp.hits { |
| 119 | hits += bp.hits[i].Load() |
| 120 | } |
| 121 | if hits == 0 { |
| 122 | t.Error("didn't exercise some paths") |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | func shouldPanic(t *testing.T, fn func()) { |
| 127 | defer func() { |