github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/buffer/buffer_test.go (about) 1 package queue 2 3 import ( 4 "sync" 5 "testing" 6 ) 7 8 func TestBuffer(t *testing.T) { 9 buffer := New[string](2) 10 test1 := "test1" 11 test2 := "test2" 12 test3 := "test3" 13 14 if str, ok := buffer.Take(); ok { 15 t.Fatalf("buffer must be empty, but returned: %s", *str) 16 } 17 18 if buffer.Size() != 0 { 19 t.Fatalf("buffer must have size 0 but now %d", buffer.Size()) 20 } 21 22 if !buffer.Put(&test1) { 23 t.Fatal("can't put in buffer, but buffer must be not full") 24 } 25 26 if buffer.Size() != 1 { 27 t.Fatalf("buffer must have size 1 but now %d", buffer.Size()) 28 } 29 30 if !buffer.Put(&test2) { 31 t.Fatal("can't put in buffer, but buffer must be not full") 32 } 33 34 if buffer.Size() != 2 { 35 t.Fatalf("buffer must have size 2 but now %d", buffer.Size()) 36 } 37 38 if buffer.Put(&test3) { 39 t.Fatal("can put in buffer, but buffer must be full") 40 } 41 42 if buffer.Size() != 2 { 43 t.Fatalf("buffer must have size 2 but now %d", buffer.Size()) 44 } 45 46 str, ok := buffer.Take() 47 if !ok { 48 t.Fatalf("buffer must be not empty, but data not returned") 49 } 50 51 if *str != test1 { 52 t.Fatalf("string must be %q but returned %q", test1, *str) 53 } 54 55 if buffer.Size() != 1 { 56 t.Fatalf("buffer must have size 1 but now %d", buffer.Size()) 57 } 58 59 str, ok = buffer.Take() 60 if !ok { 61 t.Fatalf("buffer must be not empty, but data not returned") 62 } 63 64 if *str != test2 { 65 t.Fatalf("string must be %q but returned %q", test2, *str) 66 } 67 68 if buffer.Size() != 0 { 69 t.Fatalf("buffer must have size 0 but now %d", buffer.Size()) 70 } 71 72 if str, ok = buffer.Take(); ok { 73 t.Fatalf("buffer must be empty, but returned: %s", *str) 74 } 75 76 if !buffer.Put(&test3) { 77 t.Fatal("can't put in buffer, but buffer must be not full") 78 } 79 80 if buffer.Size() != 1 { 81 t.Fatalf("buffer must have size 1 but now %d", buffer.Size()) 82 } 83 } 84 85 func TestParallel(t *testing.T) { 86 const n = 100 87 const elements = 1000 88 89 queue := New[int](n * elements) 90 wg := sync.WaitGroup{} 91 mu := sync.Mutex{} 92 m := make(map[int]struct{}) 93 94 for i := 0; i < n; i++ { 95 wg.Add(1) 96 97 n := elements * 100 * (i + 1) 98 99 if i == 0 { 100 wg.Add(1) 101 102 go func(base int) { 103 defer wg.Done() 104 105 for i := 0; i < n*elements; i++ { 106 item := base + i 107 108 queue.Put(&item) 109 } 110 }(n) 111 } 112 113 go func() { 114 defer wg.Done() 115 116 localM := make(map[int]struct{}) 117 118 for i := 0; i < elements; i++ { 119 item, ok := queue.Take() 120 if !ok { 121 i-- 122 continue 123 } 124 125 localM[*item] = struct{}{} 126 } 127 128 mu.Lock() 129 130 for k, v := range localM { 131 m[k] = v 132 } 133 134 mu.Unlock() 135 }() 136 } 137 138 wg.Wait() 139 140 if len(m) != elements*n { 141 t.Fatalf("bad elements count in map: %d, expected: %d", len(m), elements*n) 142 } 143 } 144 145 func BenchmarkNew(b *testing.B) { 146 queue := New[int](10) 147 148 for i := 0; i < b.N; i++ { 149 queue.Put(&i) 150 151 v, ok := queue.Take() 152 if !ok || *v != i { 153 b.Fatal("bad value") 154 } 155 } 156 }