github.com/dubbogo/gost@v1.14.0/sync/connection_pool_test.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package gxsync 19 20 import ( 21 "runtime" 22 "sync" 23 "sync/atomic" 24 "testing" 25 "time" 26 ) 27 28 import ( 29 "github.com/stretchr/testify/assert" 30 ) 31 32 func TestConnectionPool(t *testing.T) { 33 t.Run("Count", func(t *testing.T) { 34 p := NewConnectionPool(WorkerPoolConfig{ 35 NumWorkers: 100, 36 NumQueues: runtime.NumCPU(), 37 QueueSize: 10, 38 Logger: nil, 39 Enable: true, 40 }) 41 var count int64 42 wg := new(sync.WaitGroup) 43 for i := 1; i <= 100; i++ { 44 wg.Add(1) 45 value := i 46 err := p.Submit(func() { 47 defer wg.Done() 48 atomic.AddInt64(&count, int64(value)) 49 }) 50 assert.Nil(t, err) 51 } 52 wg.Wait() 53 assert.Equal(t, int64(5050), count) 54 55 p.Close() 56 }) 57 58 t.Run("PoolBusyErr", func(t *testing.T) { 59 p := NewConnectionPool(WorkerPoolConfig{ 60 NumWorkers: 1, 61 NumQueues: 1, 62 QueueSize: 0, 63 Logger: nil, 64 Enable: true, 65 }) 66 67 wg := new(sync.WaitGroup) 68 wg.Add(1) 69 err := p.Submit(func() { 70 wg.Wait() 71 }) 72 assert.Nil(t, err) 73 74 err = p.Submit(func() {}) 75 assert.Equal(t, PoolBusyErr, err) 76 77 wg.Done() 78 time.Sleep(100 * time.Millisecond) 79 err = p.Submit(func() {}) 80 assert.Nil(t, err) 81 82 p.Close() 83 }) 84 85 t.Run("Close", func(t *testing.T) { 86 p := NewConnectionPool(WorkerPoolConfig{ 87 NumWorkers: runtime.NumCPU(), 88 NumQueues: runtime.NumCPU(), 89 QueueSize: 100, 90 Enable: true, 91 Logger: nil, 92 }) 93 94 assert.Equal(t, runtime.NumCPU(), int(p.NumWorkers())) 95 96 p.Close() 97 assert.True(t, p.IsClosed()) 98 99 assert.Panics(t, func() { 100 _ = p.Submit(func() {}) 101 }) 102 }) 103 104 t.Run("BorderCondition", func(t *testing.T) { 105 p := NewConnectionPool(WorkerPoolConfig{ 106 NumWorkers: 0, 107 NumQueues: runtime.NumCPU(), 108 Enable: true, 109 QueueSize: 100, 110 Logger: nil, 111 }) 112 assert.Equal(t, 1, int(p.NumWorkers())) 113 p.Close() 114 115 p = NewConnectionPool(WorkerPoolConfig{ 116 NumWorkers: 1, 117 NumQueues: 0, 118 Enable: true, 119 QueueSize: 0, 120 Logger: nil, 121 }) 122 err := p.Submit(func() {}) 123 assert.Nil(t, err) 124 p.Close() 125 126 p = NewConnectionPool(WorkerPoolConfig{ 127 NumWorkers: 1, 128 NumQueues: 1, 129 QueueSize: -1, 130 Logger: nil, 131 Enable: true, 132 }) 133 134 err = p.Submit(func() {}) 135 assert.Nil(t, err) 136 p.Close() 137 }) 138 139 t.Run("NilTask", func(t *testing.T) { 140 p := NewConnectionPool(WorkerPoolConfig{ 141 NumWorkers: 1, 142 NumQueues: 1, 143 Enable: true, 144 QueueSize: 0, 145 Logger: nil, 146 }) 147 148 err := p.Submit(nil) 149 assert.NotNil(t, err) 150 p.Close() 151 }) 152 153 t.Run("CountTask", func(t *testing.T) { 154 p := NewConnectionPool(WorkerPoolConfig{ 155 NumWorkers: runtime.NumCPU(), 156 NumQueues: runtime.NumCPU(), 157 QueueSize: 10, 158 Logger: nil, 159 Enable: true, 160 }) 161 162 task, v := newCountTask() 163 wg := new(sync.WaitGroup) 164 wg.Add(100) 165 for i := 0; i < 100; i++ { 166 if err := p.Submit(func() { 167 defer wg.Done() 168 task() 169 }); err != nil { 170 i-- 171 } 172 } 173 174 wg.Wait() 175 assert.Equal(t, 100, int(*v)) 176 p.Close() 177 }) 178 179 t.Run("CountTaskSync", func(t *testing.T) { 180 p := NewConnectionPool(WorkerPoolConfig{ 181 NumWorkers: runtime.NumCPU(), 182 NumQueues: runtime.NumCPU(), 183 QueueSize: 10, 184 Logger: nil, 185 Enable: true, 186 }) 187 188 task, v := newCountTask() 189 for i := 0; i < 100; i++ { 190 err := p.SubmitSync(task) 191 assert.Nil(t, err) 192 } 193 194 assert.Equal(t, 100, int(*v)) 195 p.Close() 196 }) 197 } 198 199 func BenchmarkConnectionPool(b *testing.B) { 200 p := NewConnectionPool(WorkerPoolConfig{ 201 NumWorkers: 100, 202 NumQueues: runtime.NumCPU(), 203 QueueSize: 100, 204 Enable: true, 205 Logger: nil, 206 }) 207 208 b.Run("CountTask", func(b *testing.B) { 209 task, _ := newCountTask() 210 b.RunParallel(func(pb *testing.PB) { 211 for pb.Next() { 212 _ = p.Submit(task) 213 } 214 }) 215 }) 216 217 b.Run("CPUTask", func(b *testing.B) { 218 task, _ := newCPUTask() 219 b.RunParallel(func(pb *testing.PB) { 220 for pb.Next() { 221 _ = p.Submit(task) 222 } 223 }) 224 }) 225 226 b.Run("IOTask", func(b *testing.B) { 227 task, _ := newIOTask() 228 b.RunParallel(func(pb *testing.PB) { 229 for pb.Next() { 230 _ = p.Submit(task) 231 } 232 }) 233 }) 234 235 b.Run("RandomTask", func(b *testing.B) { 236 task, _ := newRandomTask() 237 b.RunParallel(func(pb *testing.PB) { 238 for pb.Next() { 239 _ = p.Submit(task) 240 } 241 }) 242 }) 243 }