github.com/hdt3213/godis@v1.2.9/lib/pool/pool_test.go (about) 1 package pool 2 3 import ( 4 "errors" 5 "testing" 6 "time" 7 ) 8 9 type mockConn struct { 10 open bool 11 } 12 13 func TestPool(t *testing.T) { 14 connNum := 0 15 factory := func() (interface{}, error) { 16 connNum++ 17 return &mockConn{ 18 open: true, 19 }, nil 20 } 21 finalizer := func(x interface{}) { 22 connNum-- 23 c := x.(*mockConn) 24 c.open = false 25 } 26 cfg := Config{ 27 MaxIdle: 20, 28 MaxActive: 40, 29 } 30 pool := New(factory, finalizer, cfg) 31 var borrowed []*mockConn 32 for i := 0; i < int(cfg.MaxActive); i++ { 33 x, err := pool.Get() 34 if err != nil { 35 t.Error(err) 36 return 37 } 38 c := x.(*mockConn) 39 if !c.open { 40 t.Error("conn is not open") 41 return 42 } 43 borrowed = append(borrowed, c) 44 } 45 for _, c := range borrowed { 46 pool.Put(c) 47 } 48 borrowed = nil 49 // borrow returned 50 for i := 0; i < int(cfg.MaxActive); i++ { 51 x, err := pool.Get() 52 if err != nil { 53 t.Error(err) 54 return 55 } 56 c := x.(*mockConn) 57 if !c.open { 58 t.Error("conn is not open") 59 return 60 } 61 borrowed = append(borrowed, c) 62 } 63 for i, c := range borrowed { 64 if i < len(borrowed)-1 { 65 pool.Put(c) 66 } 67 } 68 pool.Close() 69 pool.Close() // test close twice 70 pool.Put(borrowed[len(borrowed)-1]) 71 if connNum != 0 { 72 t.Errorf("%d connections has not closed", connNum) 73 } 74 _, err := pool.Get() 75 if err != ErrClosed { 76 t.Error("expect err closed") 77 } 78 } 79 80 func TestPool_Waiting(t *testing.T) { 81 factory := func() (interface{}, error) { 82 return &mockConn{ 83 open: true, 84 }, nil 85 } 86 finalizer := func(x interface{}) { 87 c := x.(*mockConn) 88 c.open = false 89 } 90 cfg := Config{ 91 MaxIdle: 2, 92 MaxActive: 4, 93 } 94 pool := New(factory, finalizer, cfg) 95 var borrowed []*mockConn 96 for i := 0; i < int(cfg.MaxActive); i++ { 97 x, err := pool.Get() 98 if err != nil { 99 t.Error(err) 100 return 101 } 102 c := x.(*mockConn) 103 if !c.open { 104 t.Error("conn is not open") 105 return 106 } 107 borrowed = append(borrowed, c) 108 } 109 getResult := make(chan bool, 0) 110 go func() { 111 x, err := pool.Get() 112 if err != nil { 113 t.Error(err) 114 getResult <- false 115 return 116 } 117 c := x.(*mockConn) 118 if !c.open { 119 t.Error("conn is not open") 120 getResult <- false 121 return 122 } 123 getResult <- true 124 }() 125 time.Sleep(time.Second) 126 pool.Put(borrowed[0]) 127 if ret := <-getResult; !ret { 128 t.Error("get and waiting returned failed") 129 } 130 } 131 132 func TestPool_CreateErr(t *testing.T) { 133 makeErr := true 134 factory := func() (interface{}, error) { 135 if makeErr { 136 makeErr = false 137 return nil, errors.New("mock err") 138 } 139 return &mockConn{ 140 open: true, 141 }, nil 142 } 143 finalizer := func(x interface{}) { 144 c := x.(*mockConn) 145 c.open = false 146 } 147 cfg := Config{ 148 MaxIdle: 2, 149 MaxActive: 4, 150 } 151 pool := New(factory, finalizer, cfg) 152 _, err := pool.Get() 153 if err == nil { 154 t.Error("expecting err") 155 return 156 } 157 x, err := pool.Get() 158 if err != nil { 159 t.Error("get err") 160 return 161 } 162 pool.Put(x) 163 _, err = pool.Get() 164 if err != nil { 165 t.Error("get err") 166 return 167 } 168 169 }