conn_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2012 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. "bufio"
  17. "bytes"
  18. "errors"
  19. "reflect"
  20. "strings"
  21. "testing"
  22. )
  23. var sendTests = []struct {
  24. args []interface{}
  25. expected string
  26. }{
  27. {
  28. []interface{}{"SET", "foo", "bar"},
  29. "*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
  30. },
  31. {
  32. []interface{}{"SET", "foo", "bar"},
  33. "*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
  34. },
  35. {
  36. []interface{}{"SET", "foo", 100},
  37. "*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\n100\r\n",
  38. },
  39. {
  40. []interface{}{"SET", "", []byte("foo")},
  41. "*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",
  42. },
  43. {
  44. []interface{}{"SET", nil, []byte("foo")},
  45. "*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",
  46. },
  47. }
  48. func TestSend(t *testing.T) {
  49. for _, tt := range sendTests {
  50. var buf bytes.Buffer
  51. c := conn{rw: bufio.ReadWriter{Writer: bufio.NewWriter(&buf)}}
  52. err := c.Send(tt.args[0].(string), tt.args[1:]...)
  53. if err != nil {
  54. t.Errorf("Send(%v) returned error %v", tt.args, err)
  55. continue
  56. }
  57. c.rw.Flush()
  58. actual := buf.String()
  59. if actual != tt.expected {
  60. t.Errorf("Send(%v) = %q, want %q", tt.args, actual, tt.expected)
  61. }
  62. }
  63. }
  64. var errorSentinel = &struct{}{}
  65. var receiveTests = []struct {
  66. reply string
  67. expected interface{}
  68. }{
  69. {
  70. "+OK\r\n",
  71. "OK",
  72. },
  73. {
  74. "@OK\r\n",
  75. errorSentinel,
  76. },
  77. {
  78. "$6\r\nfoobar\r\n",
  79. []byte("foobar"),
  80. },
  81. {
  82. "$-1\r\n",
  83. nil,
  84. },
  85. {
  86. ":1\r\n",
  87. int64(1),
  88. },
  89. {
  90. "*0\r\n",
  91. []interface{}{},
  92. },
  93. {
  94. "*-1\r\n",
  95. nil,
  96. },
  97. {
  98. "*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n",
  99. []interface{}{[]byte("foo"), []byte("bar"), []byte("Hello"), []byte("World")},
  100. },
  101. {
  102. "*3\r\n$3\r\nfoo\r\n$-1\r\n$3\r\nbar\r\n",
  103. []interface{}{[]byte("foo"), nil, []byte("bar")},
  104. },
  105. }
  106. func TestReceive(t *testing.T) {
  107. for _, tt := range receiveTests {
  108. c := conn{rw: bufio.ReadWriter{
  109. Reader: bufio.NewReader(strings.NewReader(tt.reply)),
  110. Writer: bufio.NewWriter(nil), // writer need to support Flush
  111. }}
  112. actual, err := c.Receive()
  113. if tt.expected == errorSentinel {
  114. if err == nil {
  115. t.Errorf("Receive(%q) did not return expected error", tt.reply)
  116. }
  117. } else {
  118. if err != nil {
  119. t.Errorf("Receive(%q) returned error %v", tt.reply, err)
  120. continue
  121. }
  122. if !reflect.DeepEqual(actual, tt.expected) {
  123. t.Errorf("Receive(%q) = %v, want %v", tt.reply, actual, tt.expected)
  124. }
  125. }
  126. }
  127. }
  128. func connect() (Conn, error) {
  129. c, err := Dial("tcp", ":6379")
  130. if err != nil {
  131. return nil, err
  132. }
  133. reply, err := c.Do("SELECT", "9")
  134. if err != nil {
  135. return nil, err
  136. }
  137. reply, err = c.Do("DBSIZE")
  138. if err != nil {
  139. return nil, err
  140. }
  141. if reply, ok := reply.(int); !ok && reply != 0 {
  142. return nil, errors.New("Database #9 is not empty, test can not continue")
  143. }
  144. return c, nil
  145. }
  146. func disconnect(c Conn) error {
  147. _, err := c.Do("SELECT", "9")
  148. if err != nil {
  149. return nil
  150. }
  151. _, err = c.Do("FLUSHDB")
  152. return err
  153. }
  154. var testCommands = []struct {
  155. args []interface{}
  156. expected interface{}
  157. }{
  158. {
  159. []interface{}{"PING"},
  160. "PONG",
  161. },
  162. {
  163. []interface{}{"SET", "foo", "bar"},
  164. "OK",
  165. },
  166. {
  167. []interface{}{"GET", "foo"},
  168. []byte("bar"),
  169. },
  170. {
  171. []interface{}{"GET", "nokey"},
  172. nil,
  173. },
  174. {
  175. []interface{}{"INCR", "mycounter"},
  176. int64(1),
  177. },
  178. {
  179. []interface{}{"LPUSH", "mylist", "foo"},
  180. int64(1),
  181. },
  182. {
  183. []interface{}{"LPUSH", "mylist", "bar"},
  184. int64(2),
  185. },
  186. {
  187. []interface{}{"LRANGE", "mylist", 0, -1},
  188. []interface{}{[]byte("bar"), []byte("foo")},
  189. },
  190. {
  191. []interface{}{"MULTI"},
  192. "OK",
  193. },
  194. {
  195. []interface{}{"LRANGE", "mylist", 0, -1},
  196. "QUEUED",
  197. },
  198. {
  199. []interface{}{"PING"},
  200. "QUEUED",
  201. },
  202. {
  203. []interface{}{"EXEC"},
  204. []interface{}{
  205. []interface{}{[]byte("bar"), []byte("foo")},
  206. "PONG",
  207. },
  208. },
  209. }
  210. func TestDoCommands(t *testing.T) {
  211. c, err := connect()
  212. if err != nil {
  213. t.Fatalf("Error connection to database, %v", err)
  214. }
  215. defer disconnect(c)
  216. for _, cmd := range testCommands {
  217. actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...)
  218. if err != nil {
  219. t.Errorf("Do(%v) returned error %v", cmd.args, err)
  220. continue
  221. }
  222. if !reflect.DeepEqual(actual, cmd.expected) {
  223. t.Errorf("Do(%v) = %v, want %v", cmd.args, actual, cmd.expected)
  224. }
  225. }
  226. }
  227. func TestPipelineCommands(t *testing.T) {
  228. c, err := connect()
  229. if err != nil {
  230. t.Fatalf("Error connection to database, %v", err)
  231. }
  232. defer disconnect(c)
  233. for _, cmd := range testCommands {
  234. err := c.Send(cmd.args[0].(string), cmd.args[1:]...)
  235. if err != nil {
  236. t.Errorf("Send(%v) returned error %v", cmd.args, err)
  237. continue
  238. }
  239. }
  240. for _, cmd := range testCommands {
  241. actual, err := c.Receive()
  242. if err != nil {
  243. t.Errorf("Receive(%v) returned error %v", cmd.args, err)
  244. continue
  245. }
  246. if !reflect.DeepEqual(actual, cmd.expected) {
  247. t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
  248. }
  249. }
  250. }