conn_test.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  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_test
  15. import (
  16. "bytes"
  17. "crypto/tls"
  18. "crypto/x509"
  19. "fmt"
  20. "io"
  21. "math"
  22. "net"
  23. "os"
  24. "reflect"
  25. "strings"
  26. "testing"
  27. "time"
  28. "github.com/gomodule/redigo/redis"
  29. )
  30. type testConn struct {
  31. io.Reader
  32. io.Writer
  33. readDeadline time.Time
  34. writeDeadline time.Time
  35. }
  36. func (*testConn) Close() error { return nil }
  37. func (*testConn) LocalAddr() net.Addr { return nil }
  38. func (*testConn) RemoteAddr() net.Addr { return nil }
  39. func (c *testConn) SetDeadline(t time.Time) error { c.readDeadline = t; c.writeDeadline = t; return nil }
  40. func (c *testConn) SetReadDeadline(t time.Time) error { c.readDeadline = t; return nil }
  41. func (c *testConn) SetWriteDeadline(t time.Time) error { c.writeDeadline = t; return nil }
  42. func dialTestConn(r string, w io.Writer) redis.DialOption {
  43. return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
  44. return &testConn{Reader: strings.NewReader(r), Writer: w}, nil
  45. })
  46. }
  47. type tlsTestConn struct {
  48. net.Conn
  49. done chan struct{}
  50. }
  51. func (c *tlsTestConn) Close() error {
  52. c.Conn.Close()
  53. <-c.done
  54. return nil
  55. }
  56. func dialTestConnTLS(r string, w io.Writer) redis.DialOption {
  57. return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
  58. client, server := net.Pipe()
  59. tlsServer := tls.Server(server, &serverTLSConfig)
  60. go io.Copy(tlsServer, strings.NewReader(r))
  61. done := make(chan struct{})
  62. go func() {
  63. io.Copy(w, tlsServer)
  64. close(done)
  65. }()
  66. return &tlsTestConn{Conn: client, done: done}, nil
  67. })
  68. }
  69. type durationArg struct {
  70. time.Duration
  71. }
  72. func (t durationArg) RedisArg() interface{} {
  73. return t.Seconds()
  74. }
  75. type recursiveArg int
  76. func (v recursiveArg) RedisArg() interface{} { return v }
  77. var writeTests = []struct {
  78. args []interface{}
  79. expected string
  80. }{
  81. {
  82. []interface{}{"SET", "key", "value"},
  83. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
  84. },
  85. {
  86. []interface{}{"SET", "key", "value"},
  87. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
  88. },
  89. {
  90. []interface{}{"SET", "key", byte(100)},
  91. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
  92. },
  93. {
  94. []interface{}{"SET", "key", 100},
  95. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
  96. },
  97. {
  98. []interface{}{"SET", "key", int64(math.MinInt64)},
  99. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$20\r\n-9223372036854775808\r\n",
  100. },
  101. {
  102. []interface{}{"SET", "key", float64(1349673917.939762)},
  103. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$21\r\n1.349673917939762e+09\r\n",
  104. },
  105. {
  106. []interface{}{"SET", "key", ""},
  107. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
  108. },
  109. {
  110. []interface{}{"SET", "key", nil},
  111. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
  112. },
  113. {
  114. []interface{}{"SET", "key", durationArg{time.Minute}},
  115. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$2\r\n60\r\n",
  116. },
  117. {
  118. []interface{}{"SET", "key", recursiveArg(123)},
  119. "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n123\r\n",
  120. },
  121. {
  122. []interface{}{"ECHO", true, false},
  123. "*3\r\n$4\r\nECHO\r\n$1\r\n1\r\n$1\r\n0\r\n",
  124. },
  125. }
  126. func TestWrite(t *testing.T) {
  127. for _, tt := range writeTests {
  128. var buf bytes.Buffer
  129. c, _ := redis.Dial("", "", dialTestConn("", &buf))
  130. err := c.Send(tt.args[0].(string), tt.args[1:]...)
  131. if err != nil {
  132. t.Errorf("Send(%v) returned error %v", tt.args, err)
  133. continue
  134. }
  135. c.Flush()
  136. actual := buf.String()
  137. if actual != tt.expected {
  138. t.Errorf("Send(%v) = %q, want %q", tt.args, actual, tt.expected)
  139. }
  140. }
  141. }
  142. var errorSentinel = &struct{}{}
  143. var readTests = []struct {
  144. reply string
  145. expected interface{}
  146. }{
  147. {
  148. "+OK\r\n",
  149. "OK",
  150. },
  151. {
  152. "+PONG\r\n",
  153. "PONG",
  154. },
  155. {
  156. "+OK\n\n", // no \r
  157. errorSentinel,
  158. },
  159. {
  160. "@OK\r\n",
  161. errorSentinel,
  162. },
  163. {
  164. "$6\r\nfoobar\r\n",
  165. []byte("foobar"),
  166. },
  167. {
  168. "$-1\r\n",
  169. nil,
  170. },
  171. {
  172. ":1\r\n",
  173. int64(1),
  174. },
  175. {
  176. ":-2\r\n",
  177. int64(-2),
  178. },
  179. {
  180. "*0\r\n",
  181. []interface{}{},
  182. },
  183. {
  184. "*-1\r\n",
  185. nil,
  186. },
  187. {
  188. "*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n",
  189. []interface{}{[]byte("foo"), []byte("bar"), []byte("Hello"), []byte("World")},
  190. },
  191. {
  192. "*3\r\n$3\r\nfoo\r\n$-1\r\n$3\r\nbar\r\n",
  193. []interface{}{[]byte("foo"), nil, []byte("bar")},
  194. },
  195. {
  196. // "" is not a valid length
  197. "$\r\nfoobar\r\n",
  198. errorSentinel,
  199. },
  200. {
  201. // "x" is not a valid length
  202. "$x\r\nfoobar\r\n",
  203. errorSentinel,
  204. },
  205. {
  206. // -2 is not a valid length
  207. "$-2\r\n",
  208. errorSentinel,
  209. },
  210. {
  211. // "" is not a valid integer
  212. ":\r\n",
  213. errorSentinel,
  214. },
  215. {
  216. // "x" is not a valid integer
  217. ":x\r\n",
  218. errorSentinel,
  219. },
  220. {
  221. // missing \r\n following value
  222. "$6\r\nfoobar",
  223. errorSentinel,
  224. },
  225. {
  226. // short value
  227. "$6\r\nxx",
  228. errorSentinel,
  229. },
  230. {
  231. // long value
  232. "$6\r\nfoobarx\r\n",
  233. errorSentinel,
  234. },
  235. }
  236. func TestRead(t *testing.T) {
  237. for _, tt := range readTests {
  238. c, _ := redis.Dial("", "", dialTestConn(tt.reply, nil))
  239. actual, err := c.Receive()
  240. if tt.expected == errorSentinel {
  241. if err == nil {
  242. t.Errorf("Receive(%q) did not return expected error", tt.reply)
  243. }
  244. } else {
  245. if err != nil {
  246. t.Errorf("Receive(%q) returned error %v", tt.reply, err)
  247. continue
  248. }
  249. if !reflect.DeepEqual(actual, tt.expected) {
  250. t.Errorf("Receive(%q) = %v, want %v", tt.reply, actual, tt.expected)
  251. }
  252. }
  253. }
  254. }
  255. func TestReadString(t *testing.T) {
  256. // n is value of bufio.defaultBufSize
  257. const n = 4096
  258. // Test read string lengths near bufio.Reader buffer boundaries.
  259. testRanges := [][2]int{{0, 64}, {n - 64, n + 64}, {2*n - 64, 2*n + 64}}
  260. p := make([]byte, 2*n+64)
  261. for i := range p {
  262. p[i] = byte('a' + i%26)
  263. }
  264. s := string(p)
  265. for _, r := range testRanges {
  266. for i := r[0]; i < r[1]; i++ {
  267. c, _ := redis.Dial("", "", dialTestConn("+"+s[:i]+"\r\n", nil))
  268. actual, err := c.Receive()
  269. if err != nil || actual != s[:i] {
  270. t.Fatalf("Receive(string len %d) -> err=%v, equal=%v", i, err, actual != s[:i])
  271. }
  272. }
  273. }
  274. }
  275. var testCommands = []struct {
  276. args []interface{}
  277. expected interface{}
  278. }{
  279. {
  280. []interface{}{"PING"},
  281. "PONG",
  282. },
  283. {
  284. []interface{}{"SET", "foo", "bar"},
  285. "OK",
  286. },
  287. {
  288. []interface{}{"GET", "foo"},
  289. []byte("bar"),
  290. },
  291. {
  292. []interface{}{"GET", "nokey"},
  293. nil,
  294. },
  295. {
  296. []interface{}{"MGET", "nokey", "foo"},
  297. []interface{}{nil, []byte("bar")},
  298. },
  299. {
  300. []interface{}{"INCR", "mycounter"},
  301. int64(1),
  302. },
  303. {
  304. []interface{}{"LPUSH", "mylist", "foo"},
  305. int64(1),
  306. },
  307. {
  308. []interface{}{"LPUSH", "mylist", "bar"},
  309. int64(2),
  310. },
  311. {
  312. []interface{}{"LRANGE", "mylist", 0, -1},
  313. []interface{}{[]byte("bar"), []byte("foo")},
  314. },
  315. {
  316. []interface{}{"MULTI"},
  317. "OK",
  318. },
  319. {
  320. []interface{}{"LRANGE", "mylist", 0, -1},
  321. "QUEUED",
  322. },
  323. {
  324. []interface{}{"PING"},
  325. "QUEUED",
  326. },
  327. {
  328. []interface{}{"EXEC"},
  329. []interface{}{
  330. []interface{}{[]byte("bar"), []byte("foo")},
  331. "PONG",
  332. },
  333. },
  334. }
  335. func TestDoCommands(t *testing.T) {
  336. c, err := redis.DialDefaultServer()
  337. if err != nil {
  338. t.Fatalf("error connection to database, %v", err)
  339. }
  340. defer c.Close()
  341. for _, cmd := range testCommands {
  342. actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...)
  343. if err != nil {
  344. t.Errorf("Do(%v) returned error %v", cmd.args, err)
  345. continue
  346. }
  347. if !reflect.DeepEqual(actual, cmd.expected) {
  348. t.Errorf("Do(%v) = %v, want %v", cmd.args, actual, cmd.expected)
  349. }
  350. }
  351. }
  352. func TestPipelineCommands(t *testing.T) {
  353. c, err := redis.DialDefaultServer()
  354. if err != nil {
  355. t.Fatalf("error connection to database, %v", err)
  356. }
  357. defer c.Close()
  358. for _, cmd := range testCommands {
  359. if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
  360. t.Fatalf("Send(%v) returned error %v", cmd.args, err)
  361. }
  362. }
  363. if err := c.Flush(); err != nil {
  364. t.Errorf("Flush() returned error %v", err)
  365. }
  366. for _, cmd := range testCommands {
  367. actual, err := c.Receive()
  368. if err != nil {
  369. t.Fatalf("Receive(%v) returned error %v", cmd.args, err)
  370. }
  371. if !reflect.DeepEqual(actual, cmd.expected) {
  372. t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
  373. }
  374. }
  375. }
  376. func TestBlankCommmand(t *testing.T) {
  377. c, err := redis.DialDefaultServer()
  378. if err != nil {
  379. t.Fatalf("error connection to database, %v", err)
  380. }
  381. defer c.Close()
  382. for _, cmd := range testCommands {
  383. if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
  384. t.Fatalf("Send(%v) returned error %v", cmd.args, err)
  385. }
  386. }
  387. reply, err := redis.Values(c.Do(""))
  388. if err != nil {
  389. t.Fatalf("Do() returned error %v", err)
  390. }
  391. if len(reply) != len(testCommands) {
  392. t.Fatalf("len(reply)=%d, want %d", len(reply), len(testCommands))
  393. }
  394. for i, cmd := range testCommands {
  395. actual := reply[i]
  396. if !reflect.DeepEqual(actual, cmd.expected) {
  397. t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
  398. }
  399. }
  400. }
  401. func TestRecvBeforeSend(t *testing.T) {
  402. c, err := redis.DialDefaultServer()
  403. if err != nil {
  404. t.Fatalf("error connection to database, %v", err)
  405. }
  406. defer c.Close()
  407. done := make(chan struct{})
  408. go func() {
  409. c.Receive()
  410. close(done)
  411. }()
  412. time.Sleep(time.Millisecond)
  413. c.Send("PING")
  414. c.Flush()
  415. <-done
  416. _, err = c.Do("")
  417. if err != nil {
  418. t.Fatalf("error=%v", err)
  419. }
  420. }
  421. func TestError(t *testing.T) {
  422. c, err := redis.DialDefaultServer()
  423. if err != nil {
  424. t.Fatalf("error connection to database, %v", err)
  425. }
  426. defer c.Close()
  427. c.Do("SET", "key", "val")
  428. _, err = c.Do("HSET", "key", "fld", "val")
  429. if err == nil {
  430. t.Errorf("Expected err for HSET on string key.")
  431. }
  432. if c.Err() != nil {
  433. t.Errorf("Conn has Err()=%v, expect nil", c.Err())
  434. }
  435. _, err = c.Do("SET", "key", "val")
  436. if err != nil {
  437. t.Errorf("Do(SET, key, val) returned error %v, expected nil.", err)
  438. }
  439. }
  440. func TestReadTimeout(t *testing.T) {
  441. l, err := net.Listen("tcp", "127.0.0.1:0")
  442. if err != nil {
  443. t.Fatalf("net.Listen returned %v", err)
  444. }
  445. defer l.Close()
  446. go func() {
  447. for {
  448. c, err := l.Accept()
  449. if err != nil {
  450. return
  451. }
  452. go func() {
  453. time.Sleep(time.Second)
  454. c.Write([]byte("+OK\r\n"))
  455. c.Close()
  456. }()
  457. }
  458. }()
  459. // Do
  460. c1, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
  461. if err != nil {
  462. t.Fatalf("redis.Dial returned %v", err)
  463. }
  464. defer c1.Close()
  465. _, err = c1.Do("PING")
  466. if err == nil {
  467. t.Fatalf("c1.Do() returned nil, expect error")
  468. }
  469. if c1.Err() == nil {
  470. t.Fatalf("c1.Err() = nil, expect error")
  471. }
  472. // Send/Flush/Receive
  473. c2, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
  474. if err != nil {
  475. t.Fatalf("redis.Dial returned %v", err)
  476. }
  477. defer c2.Close()
  478. c2.Send("PING")
  479. c2.Flush()
  480. _, err = c2.Receive()
  481. if err == nil {
  482. t.Fatalf("c2.Receive() returned nil, expect error")
  483. }
  484. if c2.Err() == nil {
  485. t.Fatalf("c2.Err() = nil, expect error")
  486. }
  487. }
  488. var dialErrors = []struct {
  489. rawurl string
  490. expectedError string
  491. }{
  492. {
  493. "localhost",
  494. "invalid redis URL scheme",
  495. },
  496. // The error message for invalid hosts is different in different
  497. // versions of Go, so just check that there is an error message.
  498. {
  499. "redis://weird url",
  500. "",
  501. },
  502. {
  503. "redis://foo:bar:baz",
  504. "",
  505. },
  506. {
  507. "http://www.google.com",
  508. "invalid redis URL scheme: http",
  509. },
  510. {
  511. "redis://localhost:6379/abc123",
  512. "invalid database: abc123",
  513. },
  514. }
  515. func TestDialURLErrors(t *testing.T) {
  516. for _, d := range dialErrors {
  517. _, err := redis.DialURL(d.rawurl)
  518. if err == nil || !strings.Contains(err.Error(), d.expectedError) {
  519. t.Errorf("DialURL did not return expected error (expected %v to contain %s)", err, d.expectedError)
  520. }
  521. }
  522. }
  523. func TestDialURLPort(t *testing.T) {
  524. checkPort := func(network, address string) (net.Conn, error) {
  525. if address != "localhost:6379" {
  526. t.Errorf("DialURL did not set port to 6379 by default (got %v)", address)
  527. }
  528. return nil, nil
  529. }
  530. _, err := redis.DialURL("redis://localhost", redis.DialNetDial(checkPort))
  531. if err != nil {
  532. t.Error("dial error:", err)
  533. }
  534. }
  535. func TestDialURLHost(t *testing.T) {
  536. checkHost := func(network, address string) (net.Conn, error) {
  537. if address != "localhost:6379" {
  538. t.Errorf("DialURL did not set host to localhost by default (got %v)", address)
  539. }
  540. return nil, nil
  541. }
  542. _, err := redis.DialURL("redis://:6379", redis.DialNetDial(checkHost))
  543. if err != nil {
  544. t.Error("dial error:", err)
  545. }
  546. }
  547. var dialURLTests = []struct {
  548. description string
  549. url string
  550. r string
  551. w string
  552. }{
  553. {"password", "redis://x:abc123@localhost", "+OK\r\n", "*2\r\n$4\r\nAUTH\r\n$6\r\nabc123\r\n"},
  554. {"database 3", "redis://localhost/3", "+OK\r\n", "*2\r\n$6\r\nSELECT\r\n$1\r\n3\r\n"},
  555. {"database 99", "redis://localhost/99", "+OK\r\n", "*2\r\n$6\r\nSELECT\r\n$2\r\n99\r\n"},
  556. {"no database", "redis://localhost/", "+OK\r\n", ""},
  557. }
  558. func TestDialURL(t *testing.T) {
  559. for _, tt := range dialURLTests {
  560. var buf bytes.Buffer
  561. // UseTLS should be ignored in all of these tests.
  562. _, err := redis.DialURL(tt.url, dialTestConn(tt.r, &buf), redis.DialUseTLS(true))
  563. if err != nil {
  564. t.Errorf("%s dial error: %v", tt.description, err)
  565. continue
  566. }
  567. if w := buf.String(); w != tt.w {
  568. t.Errorf("%s commands = %q, want %q", tt.description, w, tt.w)
  569. }
  570. }
  571. }
  572. func checkPingPong(t *testing.T, buf *bytes.Buffer, c redis.Conn) {
  573. resp, err := c.Do("PING")
  574. if err != nil {
  575. t.Fatal("ping error:", err)
  576. }
  577. // Close connection to ensure that writes to buf are complete.
  578. c.Close()
  579. expected := "*1\r\n$4\r\nPING\r\n"
  580. actual := buf.String()
  581. if actual != expected {
  582. t.Errorf("commands = %q, want %q", actual, expected)
  583. }
  584. if resp != "PONG" {
  585. t.Errorf("resp = %v, want %v", resp, "PONG")
  586. }
  587. }
  588. const pingResponse = "+PONG\r\n"
  589. func TestDialURLTLS(t *testing.T) {
  590. var buf bytes.Buffer
  591. c, err := redis.DialURL("rediss://example.com/",
  592. redis.DialTLSConfig(&clientTLSConfig),
  593. dialTestConnTLS(pingResponse, &buf))
  594. if err != nil {
  595. t.Fatal("dial error:", err)
  596. }
  597. checkPingPong(t, &buf, c)
  598. }
  599. func TestDialUseTLS(t *testing.T) {
  600. var buf bytes.Buffer
  601. c, err := redis.Dial("tcp", "example.com:6379",
  602. redis.DialTLSConfig(&clientTLSConfig),
  603. dialTestConnTLS(pingResponse, &buf),
  604. redis.DialUseTLS(true))
  605. if err != nil {
  606. t.Fatal("dial error:", err)
  607. }
  608. checkPingPong(t, &buf, c)
  609. }
  610. func TestDialTLSSKipVerify(t *testing.T) {
  611. var buf bytes.Buffer
  612. c, err := redis.Dial("tcp", "example.com:6379",
  613. dialTestConnTLS(pingResponse, &buf),
  614. redis.DialTLSSkipVerify(true),
  615. redis.DialUseTLS(true))
  616. if err != nil {
  617. t.Fatal("dial error:", err)
  618. }
  619. checkPingPong(t, &buf, c)
  620. }
  621. func TestDialClientName(t *testing.T) {
  622. var buf bytes.Buffer
  623. _, err := redis.Dial("tcp", ":6379",
  624. dialTestConn(pingResponse, &buf),
  625. redis.DialClientName("redis-connection"),
  626. )
  627. if err != nil {
  628. t.Fatal("dial error:", err)
  629. }
  630. expected := "*3\r\n$6\r\nCLIENT\r\n$7\r\nSETNAME\r\n$16\r\nredis-connection\r\n"
  631. if w := buf.String(); w != expected {
  632. t.Errorf("got %q, want %q", w, expected)
  633. }
  634. // testing against a real server
  635. connectionName := "test-connection"
  636. c, err := redis.DialDefaultServer(redis.DialClientName(connectionName))
  637. if err != nil {
  638. t.Fatalf("error connection to database, %v", err)
  639. }
  640. defer c.Close()
  641. v, err := c.Do("CLIENT", "GETNAME")
  642. if err != nil {
  643. t.Fatalf("CLIENT GETNAME returned error %v", err)
  644. }
  645. vs, err := redis.String(v, nil)
  646. if err != nil {
  647. t.Fatalf("String(v) returned error %v", err)
  648. }
  649. if vs != connectionName {
  650. t.Fatalf("wrong connection name. Got '%s', expected '%s'", vs, connectionName)
  651. }
  652. }
  653. // Connect to local instance of Redis running on the default port.
  654. func ExampleDial() {
  655. c, err := redis.Dial("tcp", ":6379")
  656. if err != nil {
  657. // handle error
  658. }
  659. defer c.Close()
  660. }
  661. // Connect to remote instance of Redis using a URL.
  662. func ExampleDialURL() {
  663. c, err := redis.DialURL(os.Getenv("REDIS_URL"))
  664. if err != nil {
  665. // handle connection error
  666. }
  667. defer c.Close()
  668. }
  669. // TextExecError tests handling of errors in a transaction. See
  670. // http://redis.io/topics/transactions for information on how Redis handles
  671. // errors in a transaction.
  672. func TestExecError(t *testing.T) {
  673. c, err := redis.DialDefaultServer()
  674. if err != nil {
  675. t.Fatalf("error connection to database, %v", err)
  676. }
  677. defer c.Close()
  678. // Execute commands that fail before EXEC is called.
  679. c.Do("DEL", "k0")
  680. c.Do("ZADD", "k0", 0, 0)
  681. c.Send("MULTI")
  682. c.Send("NOTACOMMAND", "k0", 0, 0)
  683. c.Send("ZINCRBY", "k0", 0, 0)
  684. v, err := c.Do("EXEC")
  685. if err == nil {
  686. t.Fatalf("EXEC returned values %v, expected error", v)
  687. }
  688. // Execute commands that fail after EXEC is called. The first command
  689. // returns an error.
  690. c.Do("DEL", "k1")
  691. c.Do("ZADD", "k1", 0, 0)
  692. c.Send("MULTI")
  693. c.Send("HSET", "k1", 0, 0)
  694. c.Send("ZINCRBY", "k1", 0, 0)
  695. v, err = c.Do("EXEC")
  696. if err != nil {
  697. t.Fatalf("EXEC returned error %v", err)
  698. }
  699. vs, err := redis.Values(v, nil)
  700. if err != nil {
  701. t.Fatalf("Values(v) returned error %v", err)
  702. }
  703. if len(vs) != 2 {
  704. t.Fatalf("len(vs) == %d, want 2", len(vs))
  705. }
  706. if _, ok := vs[0].(error); !ok {
  707. t.Fatalf("first result is type %T, expected error", vs[0])
  708. }
  709. if _, ok := vs[1].([]byte); !ok {
  710. t.Fatalf("second result is type %T, expected []byte", vs[1])
  711. }
  712. // Execute commands that fail after EXEC is called. The second command
  713. // returns an error.
  714. c.Do("ZADD", "k2", 0, 0)
  715. c.Send("MULTI")
  716. c.Send("ZINCRBY", "k2", 0, 0)
  717. c.Send("HSET", "k2", 0, 0)
  718. v, err = c.Do("EXEC")
  719. if err != nil {
  720. t.Fatalf("EXEC returned error %v", err)
  721. }
  722. vs, err = redis.Values(v, nil)
  723. if err != nil {
  724. t.Fatalf("Values(v) returned error %v", err)
  725. }
  726. if len(vs) != 2 {
  727. t.Fatalf("len(vs) == %d, want 2", len(vs))
  728. }
  729. if _, ok := vs[0].([]byte); !ok {
  730. t.Fatalf("first result is type %T, expected []byte", vs[0])
  731. }
  732. if _, ok := vs[1].(error); !ok {
  733. t.Fatalf("second result is type %T, expected error", vs[2])
  734. }
  735. }
  736. func BenchmarkDoEmpty(b *testing.B) {
  737. b.StopTimer()
  738. c, err := redis.DialDefaultServer()
  739. if err != nil {
  740. b.Fatal(err)
  741. }
  742. defer c.Close()
  743. b.StartTimer()
  744. for i := 0; i < b.N; i++ {
  745. if _, err := c.Do(""); err != nil {
  746. b.Fatal(err)
  747. }
  748. }
  749. }
  750. func BenchmarkDoPing(b *testing.B) {
  751. b.StopTimer()
  752. c, err := redis.DialDefaultServer()
  753. if err != nil {
  754. b.Fatal(err)
  755. }
  756. defer c.Close()
  757. b.StartTimer()
  758. for i := 0; i < b.N; i++ {
  759. if _, err := c.Do("PING"); err != nil {
  760. b.Fatal(err)
  761. }
  762. }
  763. }
  764. var clientTLSConfig, serverTLSConfig tls.Config
  765. func init() {
  766. // The certificate and key for testing TLS dial options was created
  767. // using the command
  768. //
  769. // go run GOROOT/src/crypto/tls/generate_cert.go \
  770. // --rsa-bits 1024 \
  771. // --host 127.0.0.1,::1,example.com --ca \
  772. // --start-date "Jan 1 00:00:00 1970" \
  773. // --duration=1000000h
  774. //
  775. // where GOROOT is the value of GOROOT reported by go env.
  776. localhostCert := []byte(`
  777. -----BEGIN CERTIFICATE-----
  778. MIICFDCCAX2gAwIBAgIRAJfBL4CUxkXcdlFurb3K+iowDQYJKoZIhvcNAQELBQAw
  779. EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
  780. MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
  781. gYkCgYEArizw8WxMUQ3bGHLeuJ4fDrEpy+L2pqrbYRlKk1DasJ/VkB8bImzIpe6+
  782. LGjiYIxvnDCOJ3f3QplcQuiuMyl6f2irJlJsbFT8Lo/3obnuTKAIaqUdJUqBg6y+
  783. JaL8Auk97FvunfKFv8U1AIhgiLzAfQ/3Eaq1yi87Ra6pMjGbTtcCAwEAAaNoMGYw
  784. DgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQF
  785. MAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAAAAAAAAAA
  786. AAAAAAEwDQYJKoZIhvcNAQELBQADgYEAdZ8daIVkyhVwflt5I19m0oq1TycbGO1+
  787. ach7T6cZiBQeNR/SJtxr/wKPEpmvUgbv2BfFrKJ8QoIHYsbNSURTWSEa02pfw4k9
  788. 6RQhij3ZkG79Ituj5OYRORV6Z0HUW32r670BtcuHuAhq7YA6Nxy4FtSt7bAlVdRt
  789. rrKgNsltzMk=
  790. -----END CERTIFICATE-----`)
  791. localhostKey := []byte(`
  792. -----BEGIN RSA PRIVATE KEY-----
  793. MIICXAIBAAKBgQCuLPDxbExRDdsYct64nh8OsSnL4vamqtthGUqTUNqwn9WQHxsi
  794. bMil7r4saOJgjG+cMI4nd/dCmVxC6K4zKXp/aKsmUmxsVPwuj/ehue5MoAhqpR0l
  795. SoGDrL4lovwC6T3sW+6d8oW/xTUAiGCIvMB9D/cRqrXKLztFrqkyMZtO1wIDAQAB
  796. AoGACrc5G6FOEK6JjDeE/Fa+EmlT6PdNtXNNi+vCas3Opo8u1G8VfEi1D4BgstrB
  797. Eq+RLkrOdB8tVyuYQYWPMhabMqF+hhKJN72j0OwfuPlVvTInwb/cKjo/zbH1IA+Y
  798. HenHNK4ywv7/p/9/MvQPJ3I32cQBCgGUW5chVSH5M1sj5gECQQDabQAI1X0uDqCm
  799. KbX9gXVkAgxkFddrt6LBHt57xujFcqEKFE7nwKhDh7DweVs/VEJ+kpid4z+UnLOw
  800. KjtP9JolAkEAzCNBphQ//IsbH5rNs10wIUw3Ks/Oepicvr6kUFbIv+neRzi1iJHa
  801. m6H7EayK3PWgax6BAsR/t0Jc9XV7r2muSwJAVzN09BHnK+ADGtNEKLTqXMbEk6B0
  802. pDhn7ZmZUOkUPN+Kky+QYM11X6Bob1jDqQDGmymDbGUxGO+GfSofC8inUQJAGfci
  803. Eo3g1a6b9JksMPRZeuLG4ZstGErxJRH6tH1Va5PDwitka8qhk8o2tTjNMO3NSdLH
  804. diKoXBcE2/Pll5pJoQJBAIMiiMIzXJhnN4mX8may44J/HvMlMf2xuVH2gNMwmZuc
  805. Bjqn3yoLHaoZVvbWOi0C2TCN4FjXjaLNZGifQPbIcaA=
  806. -----END RSA PRIVATE KEY-----`)
  807. cert, err := tls.X509KeyPair(localhostCert, localhostKey)
  808. if err != nil {
  809. panic(fmt.Sprintf("error creating key pair: %v", err))
  810. }
  811. serverTLSConfig.Certificates = []tls.Certificate{cert}
  812. certificate, err := x509.ParseCertificate(serverTLSConfig.Certificates[0].Certificate[0])
  813. if err != nil {
  814. panic(fmt.Sprintf("error parsing x509 certificate: %v", err))
  815. }
  816. clientTLSConfig.RootCAs = x509.NewCertPool()
  817. clientTLSConfig.RootCAs.AddCert(certificate)
  818. }
  819. func TestWithTimeout(t *testing.T) {
  820. for _, recv := range []bool{true, false} {
  821. for _, defaultTimout := range []time.Duration{0, time.Minute} {
  822. var buf bytes.Buffer
  823. nc := &testConn{Reader: strings.NewReader("+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n"), Writer: &buf}
  824. c, _ := redis.Dial("", "", redis.DialReadTimeout(defaultTimout), redis.DialNetDial(func(network, addr string) (net.Conn, error) { return nc, nil }))
  825. for i := 0; i < 4; i++ {
  826. var minDeadline, maxDeadline time.Time
  827. // Alternate between default and specified timeout.
  828. if i%2 == 0 {
  829. if defaultTimout != 0 {
  830. minDeadline = time.Now().Add(defaultTimout)
  831. }
  832. if recv {
  833. c.Receive()
  834. } else {
  835. c.Do("PING")
  836. }
  837. if defaultTimout != 0 {
  838. maxDeadline = time.Now().Add(defaultTimout)
  839. }
  840. } else {
  841. timeout := 10 * time.Minute
  842. minDeadline = time.Now().Add(timeout)
  843. if recv {
  844. redis.ReceiveWithTimeout(c, timeout)
  845. } else {
  846. redis.DoWithTimeout(c, timeout, "PING")
  847. }
  848. maxDeadline = time.Now().Add(timeout)
  849. }
  850. // Expect set deadline in expected range.
  851. if nc.readDeadline.Before(minDeadline) || nc.readDeadline.After(maxDeadline) {
  852. t.Errorf("recv %v, %d: do deadline error: %v, %v, %v", recv, i, minDeadline, nc.readDeadline, maxDeadline)
  853. }
  854. }
  855. }
  856. }
  857. }