pool_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2011 Gary Burd
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. package redis
  15. import (
  16. "io"
  17. "testing"
  18. "time"
  19. )
  20. type fakeConn struct {
  21. open *int
  22. err error
  23. }
  24. func (c *fakeConn) Close() error { *c.open -= 1; return nil }
  25. func (c *fakeConn) Err() error { return c.err }
  26. func (c *fakeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
  27. if commandName == "ERR" {
  28. c.err = args[0].(error)
  29. }
  30. return nil, nil
  31. }
  32. func (c *fakeConn) Send(commandName string, args ...interface{}) error {
  33. return nil
  34. }
  35. func (c *fakeConn) Flush() error {
  36. return nil
  37. }
  38. func (c *fakeConn) Receive() (reply interface{}, err error) {
  39. return nil, nil
  40. }
  41. func TestPoolReuse(t *testing.T) {
  42. var open, dialed int
  43. p := &Pool{
  44. MaxIdle: 2,
  45. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  46. }
  47. for i := 0; i < 10; i++ {
  48. c1 := p.Get()
  49. c1.Do("PING")
  50. c2 := p.Get()
  51. c2.Do("PING")
  52. c1.Close()
  53. c2.Close()
  54. }
  55. if open != 2 || dialed != 2 {
  56. t.Errorf("want open=2, got %d; want dialed=2, got %d", open, dialed)
  57. }
  58. }
  59. func TestPoolMaxIdle(t *testing.T) {
  60. var open, dialed int
  61. p := &Pool{
  62. MaxIdle: 2,
  63. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  64. }
  65. for i := 0; i < 10; i++ {
  66. c1 := p.Get()
  67. c1.Do("PING")
  68. c2 := p.Get()
  69. c2.Do("PING")
  70. c3 := p.Get()
  71. c3.Do("PING")
  72. c1.Close()
  73. c2.Close()
  74. c3.Close()
  75. }
  76. if open != 2 || dialed != 12 {
  77. t.Errorf("want open=2, got %d; want dialed=12, got %d", open, dialed)
  78. }
  79. }
  80. func TestPoolError(t *testing.T) {
  81. var open, dialed int
  82. p := &Pool{
  83. MaxIdle: 2,
  84. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  85. }
  86. c := p.Get()
  87. c.Do("ERR", io.EOF)
  88. if c.Err() == nil {
  89. t.Errorf("expected c.Err() != nil")
  90. }
  91. c.Close()
  92. c = p.Get()
  93. c.Do("ERR", io.EOF)
  94. c.Close()
  95. if open != 0 || dialed != 2 {
  96. t.Errorf("want open=0, got %d; want dialed=2, got %d", open, dialed)
  97. }
  98. }
  99. func TestPoolClose(t *testing.T) {
  100. var open, dialed int
  101. p := &Pool{
  102. MaxIdle: 2,
  103. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  104. }
  105. c1 := p.Get()
  106. c1.Do("PING")
  107. c2 := p.Get()
  108. c2.Do("PING")
  109. c3 := p.Get()
  110. c3.Do("PING")
  111. c1.Close()
  112. if _, err := c1.Do("PING"); err == nil {
  113. t.Errorf("expected error after connection closed")
  114. }
  115. c2.Close()
  116. p.Close()
  117. if open != 1 {
  118. t.Errorf("want open=1, got %d", open)
  119. }
  120. if _, err := c1.Do("PING"); err == nil {
  121. t.Errorf("expected error after connection and pool closed")
  122. }
  123. c3.Close()
  124. if open != 0 {
  125. t.Errorf("want open=0, got %d", open)
  126. }
  127. c1 = p.Get()
  128. if _, err := c1.Do("PING"); err == nil {
  129. t.Errorf("expected error after pool closed")
  130. }
  131. }
  132. func TestPoolTimeout(t *testing.T) {
  133. var open, dialed int
  134. p := &Pool{
  135. MaxIdle: 2,
  136. IdleTimeout: 300 * time.Second,
  137. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  138. }
  139. now := time.Now()
  140. nowFunc = func() time.Time { return now }
  141. defer func() { nowFunc = time.Now }()
  142. c := p.Get()
  143. c.Do("PING")
  144. c.Close()
  145. if open != 1 || dialed != 1 {
  146. t.Errorf("want open=1, got %d; want dialed=1, got %d", open, dialed)
  147. }
  148. now = now.Add(p.IdleTimeout)
  149. c = p.Get()
  150. c.Do("PING")
  151. c.Close()
  152. if open != 1 || dialed != 2 {
  153. t.Errorf("want open=1, got %d; want dialed=2, got %d", open, dialed)
  154. }
  155. }
  156. func TestBorrowCheck(t *testing.T) {
  157. var open, dialed int
  158. p := &Pool{
  159. MaxIdle: 2,
  160. Dial: func() (Conn, error) { open += 1; dialed += 1; return &fakeConn{open: &open}, nil },
  161. TestOnBorrow: func(Conn, time.Time) error { return Error("BLAH") },
  162. }
  163. for i := 0; i < 10; i++ {
  164. c := p.Get()
  165. c.Do("PING")
  166. c.Close()
  167. }
  168. if open != 1 || dialed != 10 {
  169. t.Errorf("want open=1, got %d; want dialed=10, got %d", open, dialed)
  170. }
  171. }