summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/garyburd/redigo/redis
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/garyburd/redigo/redis')
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn_test.go659
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool_test.go684
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub_test.go148
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply_test.go179
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan_test.go440
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/script_test.go92
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/test_test.go177
-rw-r--r--Godeps/_workspace/src/github.com/garyburd/redigo/redis/zpop_example_test.go113
8 files changed, 0 insertions, 2492 deletions
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn_test.go
deleted file mode 100644
index 24887cf03..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/conn_test.go
+++ /dev/null
@@ -1,659 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "bytes"
- "io"
- "math"
- "net"
- "os"
- "reflect"
- "strings"
- "testing"
- "time"
-
- "github.com/garyburd/redigo/redis"
-)
-
-type testConn struct {
- io.Reader
- io.Writer
-}
-
-func (*testConn) Close() error { return nil }
-func (*testConn) LocalAddr() net.Addr { return nil }
-func (*testConn) RemoteAddr() net.Addr { return nil }
-func (*testConn) SetDeadline(t time.Time) error { return nil }
-func (*testConn) SetReadDeadline(t time.Time) error { return nil }
-func (*testConn) SetWriteDeadline(t time.Time) error { return nil }
-
-func dialTestConn(r io.Reader, w io.Writer) redis.DialOption {
- return redis.DialNetDial(func(net, addr string) (net.Conn, error) {
- return &testConn{Reader: r, Writer: w}, nil
- })
-}
-
-var writeTests = []struct {
- args []interface{}
- expected string
-}{
- {
- []interface{}{"SET", "key", "value"},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
- },
- {
- []interface{}{"SET", "key", "value"},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
- },
- {
- []interface{}{"SET", "key", byte(100)},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
- },
- {
- []interface{}{"SET", "key", 100},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
- },
- {
- []interface{}{"SET", "key", int64(math.MinInt64)},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$20\r\n-9223372036854775808\r\n",
- },
- {
- []interface{}{"SET", "key", float64(1349673917.939762)},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$21\r\n1.349673917939762e+09\r\n",
- },
- {
- []interface{}{"SET", "key", ""},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
- },
- {
- []interface{}{"SET", "key", nil},
- "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
- },
- {
- []interface{}{"ECHO", true, false},
- "*3\r\n$4\r\nECHO\r\n$1\r\n1\r\n$1\r\n0\r\n",
- },
-}
-
-func TestWrite(t *testing.T) {
- for _, tt := range writeTests {
- var buf bytes.Buffer
- c, _ := redis.Dial("", "", dialTestConn(nil, &buf))
- err := c.Send(tt.args[0].(string), tt.args[1:]...)
- if err != nil {
- t.Errorf("Send(%v) returned error %v", tt.args, err)
- continue
- }
- c.Flush()
- actual := buf.String()
- if actual != tt.expected {
- t.Errorf("Send(%v) = %q, want %q", tt.args, actual, tt.expected)
- }
- }
-}
-
-var errorSentinel = &struct{}{}
-
-var readTests = []struct {
- reply string
- expected interface{}
-}{
- {
- "+OK\r\n",
- "OK",
- },
- {
- "+PONG\r\n",
- "PONG",
- },
- {
- "@OK\r\n",
- errorSentinel,
- },
- {
- "$6\r\nfoobar\r\n",
- []byte("foobar"),
- },
- {
- "$-1\r\n",
- nil,
- },
- {
- ":1\r\n",
- int64(1),
- },
- {
- ":-2\r\n",
- int64(-2),
- },
- {
- "*0\r\n",
- []interface{}{},
- },
- {
- "*-1\r\n",
- nil,
- },
- {
- "*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n",
- []interface{}{[]byte("foo"), []byte("bar"), []byte("Hello"), []byte("World")},
- },
- {
- "*3\r\n$3\r\nfoo\r\n$-1\r\n$3\r\nbar\r\n",
- []interface{}{[]byte("foo"), nil, []byte("bar")},
- },
-
- {
- // "x" is not a valid length
- "$x\r\nfoobar\r\n",
- errorSentinel,
- },
- {
- // -2 is not a valid length
- "$-2\r\n",
- errorSentinel,
- },
- {
- // "x" is not a valid integer
- ":x\r\n",
- errorSentinel,
- },
- {
- // missing \r\n following value
- "$6\r\nfoobar",
- errorSentinel,
- },
- {
- // short value
- "$6\r\nxx",
- errorSentinel,
- },
- {
- // long value
- "$6\r\nfoobarx\r\n",
- errorSentinel,
- },
-}
-
-func TestRead(t *testing.T) {
- for _, tt := range readTests {
- c, _ := redis.Dial("", "", dialTestConn(strings.NewReader(tt.reply), nil))
- actual, err := c.Receive()
- if tt.expected == errorSentinel {
- if err == nil {
- t.Errorf("Receive(%q) did not return expected error", tt.reply)
- }
- } else {
- if err != nil {
- t.Errorf("Receive(%q) returned error %v", tt.reply, err)
- continue
- }
- if !reflect.DeepEqual(actual, tt.expected) {
- t.Errorf("Receive(%q) = %v, want %v", tt.reply, actual, tt.expected)
- }
- }
- }
-}
-
-var testCommands = []struct {
- args []interface{}
- expected interface{}
-}{
- {
- []interface{}{"PING"},
- "PONG",
- },
- {
- []interface{}{"SET", "foo", "bar"},
- "OK",
- },
- {
- []interface{}{"GET", "foo"},
- []byte("bar"),
- },
- {
- []interface{}{"GET", "nokey"},
- nil,
- },
- {
- []interface{}{"MGET", "nokey", "foo"},
- []interface{}{nil, []byte("bar")},
- },
- {
- []interface{}{"INCR", "mycounter"},
- int64(1),
- },
- {
- []interface{}{"LPUSH", "mylist", "foo"},
- int64(1),
- },
- {
- []interface{}{"LPUSH", "mylist", "bar"},
- int64(2),
- },
- {
- []interface{}{"LRANGE", "mylist", 0, -1},
- []interface{}{[]byte("bar"), []byte("foo")},
- },
- {
- []interface{}{"MULTI"},
- "OK",
- },
- {
- []interface{}{"LRANGE", "mylist", 0, -1},
- "QUEUED",
- },
- {
- []interface{}{"PING"},
- "QUEUED",
- },
- {
- []interface{}{"EXEC"},
- []interface{}{
- []interface{}{[]byte("bar"), []byte("foo")},
- "PONG",
- },
- },
-}
-
-func TestDoCommands(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- for _, cmd := range testCommands {
- actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...)
- if err != nil {
- t.Errorf("Do(%v) returned error %v", cmd.args, err)
- continue
- }
- if !reflect.DeepEqual(actual, cmd.expected) {
- t.Errorf("Do(%v) = %v, want %v", cmd.args, actual, cmd.expected)
- }
- }
-}
-
-func TestPipelineCommands(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- for _, cmd := range testCommands {
- if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
- t.Fatalf("Send(%v) returned error %v", cmd.args, err)
- }
- }
- if err := c.Flush(); err != nil {
- t.Errorf("Flush() returned error %v", err)
- }
- for _, cmd := range testCommands {
- actual, err := c.Receive()
- if err != nil {
- t.Fatalf("Receive(%v) returned error %v", cmd.args, err)
- }
- if !reflect.DeepEqual(actual, cmd.expected) {
- t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
- }
- }
-}
-
-func TestBlankCommmand(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- for _, cmd := range testCommands {
- if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
- t.Fatalf("Send(%v) returned error %v", cmd.args, err)
- }
- }
- reply, err := redis.Values(c.Do(""))
- if err != nil {
- t.Fatalf("Do() returned error %v", err)
- }
- if len(reply) != len(testCommands) {
- t.Fatalf("len(reply)=%d, want %d", len(reply), len(testCommands))
- }
- for i, cmd := range testCommands {
- actual := reply[i]
- if !reflect.DeepEqual(actual, cmd.expected) {
- t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
- }
- }
-}
-
-func TestRecvBeforeSend(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
- done := make(chan struct{})
- go func() {
- c.Receive()
- close(done)
- }()
- time.Sleep(time.Millisecond)
- c.Send("PING")
- c.Flush()
- <-done
- _, err = c.Do("")
- if err != nil {
- t.Fatalf("error=%v", err)
- }
-}
-
-func TestError(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- c.Do("SET", "key", "val")
- _, err = c.Do("HSET", "key", "fld", "val")
- if err == nil {
- t.Errorf("Expected err for HSET on string key.")
- }
- if c.Err() != nil {
- t.Errorf("Conn has Err()=%v, expect nil", c.Err())
- }
- _, err = c.Do("SET", "key", "val")
- if err != nil {
- t.Errorf("Do(SET, key, val) returned error %v, expected nil.", err)
- }
-}
-
-func TestReadTimeout(t *testing.T) {
- l, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatalf("net.Listen returned %v", err)
- }
- defer l.Close()
-
- go func() {
- for {
- c, err := l.Accept()
- if err != nil {
- return
- }
- go func() {
- time.Sleep(time.Second)
- c.Write([]byte("+OK\r\n"))
- c.Close()
- }()
- }
- }()
-
- // Do
-
- c1, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
- if err != nil {
- t.Fatalf("redis.Dial returned %v", err)
- }
- defer c1.Close()
-
- _, err = c1.Do("PING")
- if err == nil {
- t.Fatalf("c1.Do() returned nil, expect error")
- }
- if c1.Err() == nil {
- t.Fatalf("c1.Err() = nil, expect error")
- }
-
- // Send/Flush/Receive
-
- c2, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
- if err != nil {
- t.Fatalf("redis.Dial returned %v", err)
- }
- defer c2.Close()
-
- c2.Send("PING")
- c2.Flush()
- _, err = c2.Receive()
- if err == nil {
- t.Fatalf("c2.Receive() returned nil, expect error")
- }
- if c2.Err() == nil {
- t.Fatalf("c2.Err() = nil, expect error")
- }
-}
-
-var dialErrors = []struct {
- rawurl string
- expectedError string
-}{
- {
- "localhost",
- "invalid redis URL scheme",
- },
- // The error message for invalid hosts is diffferent in different
- // versions of Go, so just check that there is an error message.
- {
- "redis://weird url",
- "",
- },
- {
- "redis://foo:bar:baz",
- "",
- },
- {
- "http://www.google.com",
- "invalid redis URL scheme: http",
- },
- {
- "redis://localhost:6379/abc123",
- "invalid database: abc123",
- },
-}
-
-func TestDialURLErrors(t *testing.T) {
- for _, d := range dialErrors {
- _, err := redis.DialURL(d.rawurl)
- if err == nil || !strings.Contains(err.Error(), d.expectedError) {
- t.Errorf("DialURL did not return expected error (expected %v to contain %s)", err, d.expectedError)
- }
- }
-}
-
-func TestDialURLPort(t *testing.T) {
- checkPort := func(network, address string) (net.Conn, error) {
- if address != "localhost:6379" {
- t.Errorf("DialURL did not set port to 6379 by default (got %v)", address)
- }
- return nil, nil
- }
- _, err := redis.DialURL("redis://localhost", redis.DialNetDial(checkPort))
- if err != nil {
- t.Error("dial error:", err)
- }
-}
-
-func TestDialURLHost(t *testing.T) {
- checkHost := func(network, address string) (net.Conn, error) {
- if address != "localhost:6379" {
- t.Errorf("DialURL did not set host to localhost by default (got %v)", address)
- }
- return nil, nil
- }
- _, err := redis.DialURL("redis://:6379", redis.DialNetDial(checkHost))
- if err != nil {
- t.Error("dial error:", err)
- }
-}
-
-func TestDialURLPassword(t *testing.T) {
- var buf bytes.Buffer
- _, err := redis.DialURL("redis://x:abc123@localhost", dialTestConn(strings.NewReader("+OK\r\n"), &buf))
- if err != nil {
- t.Error("dial error:", err)
- }
- expected := "*2\r\n$4\r\nAUTH\r\n$6\r\nabc123\r\n"
- actual := buf.String()
- if actual != expected {
- t.Errorf("commands = %q, want %q", actual, expected)
- }
-}
-
-func TestDialURLDatabase(t *testing.T) {
- var buf bytes.Buffer
- _, err := redis.DialURL("redis://localhost/3", dialTestConn(strings.NewReader("+OK\r\n"), &buf))
- if err != nil {
- t.Error("dial error:", err)
- }
- expected := "*2\r\n$6\r\nSELECT\r\n$1\r\n3\r\n"
- actual := buf.String()
- if actual != expected {
- t.Errorf("commands = %q, want %q", actual, expected)
- }
-}
-
-// Connect to local instance of Redis running on the default port.
-func ExampleDial(x int) {
- c, err := redis.Dial("tcp", ":6379")
- if err != nil {
- // handle error
- }
- defer c.Close()
-}
-
-// Connect to remote instance of Redis using a URL.
-func ExampleDialURL() {
- c, err := redis.DialURL(os.Getenv("REDIS_URL"))
- if err != nil {
- // handle connection error
- }
- defer c.Close()
-}
-
-// TextExecError tests handling of errors in a transaction. See
-// http://redis.io/topics/transactions for information on how Redis handles
-// errors in a transaction.
-func TestExecError(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- // Execute commands that fail before EXEC is called.
-
- c.Do("DEL", "k0")
- c.Do("ZADD", "k0", 0, 0)
- c.Send("MULTI")
- c.Send("NOTACOMMAND", "k0", 0, 0)
- c.Send("ZINCRBY", "k0", 0, 0)
- v, err := c.Do("EXEC")
- if err == nil {
- t.Fatalf("EXEC returned values %v, expected error", v)
- }
-
- // Execute commands that fail after EXEC is called. The first command
- // returns an error.
-
- c.Do("DEL", "k1")
- c.Do("ZADD", "k1", 0, 0)
- c.Send("MULTI")
- c.Send("HSET", "k1", 0, 0)
- c.Send("ZINCRBY", "k1", 0, 0)
- v, err = c.Do("EXEC")
- if err != nil {
- t.Fatalf("EXEC returned error %v", err)
- }
-
- vs, err := redis.Values(v, nil)
- if err != nil {
- t.Fatalf("Values(v) returned error %v", err)
- }
-
- if len(vs) != 2 {
- t.Fatalf("len(vs) == %d, want 2", len(vs))
- }
-
- if _, ok := vs[0].(error); !ok {
- t.Fatalf("first result is type %T, expected error", vs[0])
- }
-
- if _, ok := vs[1].([]byte); !ok {
- t.Fatalf("second result is type %T, expected []byte", vs[1])
- }
-
- // Execute commands that fail after EXEC is called. The second command
- // returns an error.
-
- c.Do("ZADD", "k2", 0, 0)
- c.Send("MULTI")
- c.Send("ZINCRBY", "k2", 0, 0)
- c.Send("HSET", "k2", 0, 0)
- v, err = c.Do("EXEC")
- if err != nil {
- t.Fatalf("EXEC returned error %v", err)
- }
-
- vs, err = redis.Values(v, nil)
- if err != nil {
- t.Fatalf("Values(v) returned error %v", err)
- }
-
- if len(vs) != 2 {
- t.Fatalf("len(vs) == %d, want 2", len(vs))
- }
-
- if _, ok := vs[0].([]byte); !ok {
- t.Fatalf("first result is type %T, expected []byte", vs[0])
- }
-
- if _, ok := vs[1].(error); !ok {
- t.Fatalf("second result is type %T, expected error", vs[2])
- }
-}
-
-func BenchmarkDoEmpty(b *testing.B) {
- b.StopTimer()
- c, err := redis.DialDefaultServer()
- if err != nil {
- b.Fatal(err)
- }
- defer c.Close()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- if _, err := c.Do(""); err != nil {
- b.Fatal(err)
- }
- }
-}
-
-func BenchmarkDoPing(b *testing.B) {
- b.StopTimer()
- c, err := redis.DialDefaultServer()
- if err != nil {
- b.Fatal(err)
- }
- defer c.Close()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool_test.go
deleted file mode 100644
index 9419a128f..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pool_test.go
+++ /dev/null
@@ -1,684 +0,0 @@
-// Copyright 2011 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "errors"
- "io"
- "reflect"
- "sync"
- "testing"
- "time"
-
- "github.com/garyburd/redigo/redis"
-)
-
-type poolTestConn struct {
- d *poolDialer
- err error
- redis.Conn
-}
-
-func (c *poolTestConn) Close() error {
- c.d.mu.Lock()
- c.d.open -= 1
- c.d.mu.Unlock()
- return c.Conn.Close()
-}
-
-func (c *poolTestConn) Err() error { return c.err }
-
-func (c *poolTestConn) Do(commandName string, args ...interface{}) (interface{}, error) {
- if commandName == "ERR" {
- c.err = args[0].(error)
- commandName = "PING"
- }
- if commandName != "" {
- c.d.commands = append(c.d.commands, commandName)
- }
- return c.Conn.Do(commandName, args...)
-}
-
-func (c *poolTestConn) Send(commandName string, args ...interface{}) error {
- c.d.commands = append(c.d.commands, commandName)
- return c.Conn.Send(commandName, args...)
-}
-
-type poolDialer struct {
- mu sync.Mutex
- t *testing.T
- dialed int
- open int
- commands []string
- dialErr error
-}
-
-func (d *poolDialer) dial() (redis.Conn, error) {
- d.mu.Lock()
- d.dialed += 1
- dialErr := d.dialErr
- d.mu.Unlock()
- if dialErr != nil {
- return nil, d.dialErr
- }
- c, err := redis.DialDefaultServer()
- if err != nil {
- return nil, err
- }
- d.mu.Lock()
- d.open += 1
- d.mu.Unlock()
- return &poolTestConn{d: d, Conn: c}, nil
-}
-
-func (d *poolDialer) check(message string, p *redis.Pool, dialed, open int) {
- d.mu.Lock()
- if d.dialed != dialed {
- d.t.Errorf("%s: dialed=%d, want %d", message, d.dialed, dialed)
- }
- if d.open != open {
- d.t.Errorf("%s: open=%d, want %d", message, d.open, open)
- }
- if active := p.ActiveCount(); active != open {
- d.t.Errorf("%s: active=%d, want %d", message, active, open)
- }
- d.mu.Unlock()
-}
-
-func TestPoolReuse(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- Dial: d.dial,
- }
-
- for i := 0; i < 10; i++ {
- c1 := p.Get()
- c1.Do("PING")
- c2 := p.Get()
- c2.Do("PING")
- c1.Close()
- c2.Close()
- }
-
- d.check("before close", p, 2, 2)
- p.Close()
- d.check("after close", p, 2, 0)
-}
-
-func TestPoolMaxIdle(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- for i := 0; i < 10; i++ {
- c1 := p.Get()
- c1.Do("PING")
- c2 := p.Get()
- c2.Do("PING")
- c3 := p.Get()
- c3.Do("PING")
- c1.Close()
- c2.Close()
- c3.Close()
- }
- d.check("before close", p, 12, 2)
- p.Close()
- d.check("after close", p, 12, 0)
-}
-
-func TestPoolError(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c := p.Get()
- c.Do("ERR", io.EOF)
- if c.Err() == nil {
- t.Errorf("expected c.Err() != nil")
- }
- c.Close()
-
- c = p.Get()
- c.Do("ERR", io.EOF)
- c.Close()
-
- d.check(".", p, 2, 0)
-}
-
-func TestPoolClose(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c1 := p.Get()
- c1.Do("PING")
- c2 := p.Get()
- c2.Do("PING")
- c3 := p.Get()
- c3.Do("PING")
-
- c1.Close()
- if _, err := c1.Do("PING"); err == nil {
- t.Errorf("expected error after connection closed")
- }
-
- c2.Close()
- c2.Close()
-
- p.Close()
-
- d.check("after pool close", p, 3, 1)
-
- if _, err := c1.Do("PING"); err == nil {
- t.Errorf("expected error after connection and pool closed")
- }
-
- c3.Close()
-
- d.check("after conn close", p, 3, 0)
-
- c1 = p.Get()
- if _, err := c1.Do("PING"); err == nil {
- t.Errorf("expected error after pool closed")
- }
-}
-
-func TestPoolTimeout(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- IdleTimeout: 300 * time.Second,
- Dial: d.dial,
- }
- defer p.Close()
-
- now := time.Now()
- redis.SetNowFunc(func() time.Time { return now })
- defer redis.SetNowFunc(time.Now)
-
- c := p.Get()
- c.Do("PING")
- c.Close()
-
- d.check("1", p, 1, 1)
-
- now = now.Add(p.IdleTimeout)
-
- c = p.Get()
- c.Do("PING")
- c.Close()
-
- d.check("2", p, 2, 1)
-}
-
-func TestPoolConcurrenSendReceive(t *testing.T) {
- p := &redis.Pool{
- Dial: redis.DialDefaultServer,
- }
- defer p.Close()
-
- c := p.Get()
- done := make(chan error, 1)
- go func() {
- _, err := c.Receive()
- done <- err
- }()
- c.Send("PING")
- c.Flush()
- err := <-done
- if err != nil {
- t.Fatalf("Receive() returned error %v", err)
- }
- _, err = c.Do("")
- if err != nil {
- t.Fatalf("Do() returned error %v", err)
- }
- c.Close()
-}
-
-func TestPoolBorrowCheck(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- Dial: d.dial,
- TestOnBorrow: func(redis.Conn, time.Time) error { return redis.Error("BLAH") },
- }
- defer p.Close()
-
- for i := 0; i < 10; i++ {
- c := p.Get()
- c.Do("PING")
- c.Close()
- }
- d.check("1", p, 10, 1)
-}
-
-func TestPoolMaxActive(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- MaxActive: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c1 := p.Get()
- c1.Do("PING")
- c2 := p.Get()
- c2.Do("PING")
-
- d.check("1", p, 2, 2)
-
- c3 := p.Get()
- if _, err := c3.Do("PING"); err != redis.ErrPoolExhausted {
- t.Errorf("expected pool exhausted")
- }
-
- c3.Close()
- d.check("2", p, 2, 2)
- c2.Close()
- d.check("3", p, 2, 2)
-
- c3 = p.Get()
- if _, err := c3.Do("PING"); err != nil {
- t.Errorf("expected good channel, err=%v", err)
- }
- c3.Close()
-
- d.check("4", p, 2, 2)
-}
-
-func TestPoolMonitorCleanup(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- MaxActive: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c := p.Get()
- c.Send("MONITOR")
- c.Close()
-
- d.check("", p, 1, 0)
-}
-
-func TestPoolPubSubCleanup(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- MaxActive: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c := p.Get()
- c.Send("SUBSCRIBE", "x")
- c.Close()
-
- want := []string{"SUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-
- c = p.Get()
- c.Send("PSUBSCRIBE", "x*")
- c.Close()
-
- want = []string{"PSUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-}
-
-func TestPoolTransactionCleanup(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 2,
- MaxActive: 2,
- Dial: d.dial,
- }
- defer p.Close()
-
- c := p.Get()
- c.Do("WATCH", "key")
- c.Do("PING")
- c.Close()
-
- want := []string{"WATCH", "PING", "UNWATCH"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-
- c = p.Get()
- c.Do("WATCH", "key")
- c.Do("UNWATCH")
- c.Do("PING")
- c.Close()
-
- want = []string{"WATCH", "UNWATCH", "PING"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-
- c = p.Get()
- c.Do("WATCH", "key")
- c.Do("MULTI")
- c.Do("PING")
- c.Close()
-
- want = []string{"WATCH", "MULTI", "PING", "DISCARD"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-
- c = p.Get()
- c.Do("WATCH", "key")
- c.Do("MULTI")
- c.Do("DISCARD")
- c.Do("PING")
- c.Close()
-
- want = []string{"WATCH", "MULTI", "DISCARD", "PING"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-
- c = p.Get()
- c.Do("WATCH", "key")
- c.Do("MULTI")
- c.Do("EXEC")
- c.Do("PING")
- c.Close()
-
- want = []string{"WATCH", "MULTI", "EXEC", "PING"}
- if !reflect.DeepEqual(d.commands, want) {
- t.Errorf("got commands %v, want %v", d.commands, want)
- }
- d.commands = nil
-}
-
-func startGoroutines(p *redis.Pool, cmd string, args ...interface{}) chan error {
- errs := make(chan error, 10)
- for i := 0; i < cap(errs); i++ {
- go func() {
- c := p.Get()
- _, err := c.Do(cmd, args...)
- errs <- err
- c.Close()
- }()
- }
-
- // Wait for goroutines to block.
- time.Sleep(time.Second / 4)
-
- return errs
-}
-
-func TestWaitPool(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 1,
- MaxActive: 1,
- Dial: d.dial,
- Wait: true,
- }
- defer p.Close()
-
- c := p.Get()
- errs := startGoroutines(p, "PING")
- d.check("before close", p, 1, 1)
- c.Close()
- timeout := time.After(2 * time.Second)
- for i := 0; i < cap(errs); i++ {
- select {
- case err := <-errs:
- if err != nil {
- t.Fatal(err)
- }
- case <-timeout:
- t.Fatalf("timeout waiting for blocked goroutine %d", i)
- }
- }
- d.check("done", p, 1, 1)
-}
-
-func TestWaitPoolClose(t *testing.T) {
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 1,
- MaxActive: 1,
- Dial: d.dial,
- Wait: true,
- }
- defer p.Close()
-
- c := p.Get()
- if _, err := c.Do("PING"); err != nil {
- t.Fatal(err)
- }
- errs := startGoroutines(p, "PING")
- d.check("before close", p, 1, 1)
- p.Close()
- timeout := time.After(2 * time.Second)
- for i := 0; i < cap(errs); i++ {
- select {
- case err := <-errs:
- switch err {
- case nil:
- t.Fatal("blocked goroutine did not get error")
- case redis.ErrPoolExhausted:
- t.Fatal("blocked goroutine got pool exhausted error")
- }
- case <-timeout:
- t.Fatal("timeout waiting for blocked goroutine")
- }
- }
- c.Close()
- d.check("done", p, 1, 0)
-}
-
-func TestWaitPoolCommandError(t *testing.T) {
- testErr := errors.New("test")
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 1,
- MaxActive: 1,
- Dial: d.dial,
- Wait: true,
- }
- defer p.Close()
-
- c := p.Get()
- errs := startGoroutines(p, "ERR", testErr)
- d.check("before close", p, 1, 1)
- c.Close()
- timeout := time.After(2 * time.Second)
- for i := 0; i < cap(errs); i++ {
- select {
- case err := <-errs:
- if err != nil {
- t.Fatal(err)
- }
- case <-timeout:
- t.Fatalf("timeout waiting for blocked goroutine %d", i)
- }
- }
- d.check("done", p, cap(errs), 0)
-}
-
-func TestWaitPoolDialError(t *testing.T) {
- testErr := errors.New("test")
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: 1,
- MaxActive: 1,
- Dial: d.dial,
- Wait: true,
- }
- defer p.Close()
-
- c := p.Get()
- errs := startGoroutines(p, "ERR", testErr)
- d.check("before close", p, 1, 1)
-
- d.dialErr = errors.New("dial")
- c.Close()
-
- nilCount := 0
- errCount := 0
- timeout := time.After(2 * time.Second)
- for i := 0; i < cap(errs); i++ {
- select {
- case err := <-errs:
- switch err {
- case nil:
- nilCount++
- case d.dialErr:
- errCount++
- default:
- t.Fatalf("expected dial error or nil, got %v", err)
- }
- case <-timeout:
- t.Fatalf("timeout waiting for blocked goroutine %d", i)
- }
- }
- if nilCount != 1 {
- t.Errorf("expected one nil error, got %d", nilCount)
- }
- if errCount != cap(errs)-1 {
- t.Errorf("expected %d dial erors, got %d", cap(errs)-1, errCount)
- }
- d.check("done", p, cap(errs), 0)
-}
-
-// Borrowing requires us to iterate over the idle connections, unlock the pool,
-// and perform a blocking operation to check the connection still works. If
-// TestOnBorrow fails, we must reacquire the lock and continue iteration. This
-// test ensures that iteration will work correctly if multiple threads are
-// iterating simultaneously.
-func TestLocking_TestOnBorrowFails_PoolDoesntCrash(t *testing.T) {
- const count = 100
-
- // First we'll Create a pool where the pilfering of idle connections fails.
- d := poolDialer{t: t}
- p := &redis.Pool{
- MaxIdle: count,
- MaxActive: count,
- Dial: d.dial,
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
- return errors.New("No way back into the real world.")
- },
- }
- defer p.Close()
-
- // Fill the pool with idle connections.
- conns := make([]redis.Conn, count)
- for i := range conns {
- conns[i] = p.Get()
- }
- for i := range conns {
- conns[i].Close()
- }
-
- // Spawn a bunch of goroutines to thrash the pool.
- var wg sync.WaitGroup
- wg.Add(count)
- for i := 0; i < count; i++ {
- go func() {
- c := p.Get()
- if c.Err() != nil {
- t.Errorf("pool get failed: %v", c.Err())
- }
- c.Close()
- wg.Done()
- }()
- }
- wg.Wait()
- if d.dialed != count*2 {
- t.Errorf("Expected %d dials, got %d", count*2, d.dialed)
- }
-}
-
-func BenchmarkPoolGet(b *testing.B) {
- b.StopTimer()
- p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2}
- c := p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- c.Close()
- defer p.Close()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c = p.Get()
- c.Close()
- }
-}
-
-func BenchmarkPoolGetErr(b *testing.B) {
- b.StopTimer()
- p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2}
- c := p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- c.Close()
- defer p.Close()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c = p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- c.Close()
- }
-}
-
-func BenchmarkPoolGetPing(b *testing.B) {
- b.StopTimer()
- p := redis.Pool{Dial: redis.DialDefaultServer, MaxIdle: 2}
- c := p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- c.Close()
- defer p.Close()
- b.StartTimer()
- for i := 0; i < b.N; i++ {
- c = p.Get()
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- c.Close()
- }
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub_test.go
deleted file mode 100644
index a3ed84e68..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/pubsub_test.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "fmt"
- "reflect"
- "sync"
- "testing"
-
- "github.com/garyburd/redigo/redis"
-)
-
-func publish(channel, value interface{}) {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
- c.Do("PUBLISH", channel, value)
-}
-
-// Applications can receive pushed messages from one goroutine and manage subscriptions from another goroutine.
-func ExamplePubSubConn() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
- var wg sync.WaitGroup
- wg.Add(2)
-
- psc := redis.PubSubConn{Conn: c}
-
- // This goroutine receives and prints pushed notifications from the server.
- // The goroutine exits when the connection is unsubscribed from all
- // channels or there is an error.
- go func() {
- defer wg.Done()
- for {
- switch n := psc.Receive().(type) {
- case redis.Message:
- fmt.Printf("Message: %s %s\n", n.Channel, n.Data)
- case redis.PMessage:
- fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data)
- case redis.Subscription:
- fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count)
- if n.Count == 0 {
- return
- }
- case error:
- fmt.Printf("error: %v\n", n)
- return
- }
- }
- }()
-
- // This goroutine manages subscriptions for the connection.
- go func() {
- defer wg.Done()
-
- psc.Subscribe("example")
- psc.PSubscribe("p*")
-
- // The following function calls publish a message using another
- // connection to the Redis server.
- publish("example", "hello")
- publish("example", "world")
- publish("pexample", "foo")
- publish("pexample", "bar")
-
- // Unsubscribe from all connections. This will cause the receiving
- // goroutine to exit.
- psc.Unsubscribe()
- psc.PUnsubscribe()
- }()
-
- wg.Wait()
-
- // Output:
- // Subscription: subscribe example 1
- // Subscription: psubscribe p* 2
- // Message: example hello
- // Message: example world
- // PMessage: p* pexample foo
- // PMessage: p* pexample bar
- // Subscription: unsubscribe example 1
- // Subscription: punsubscribe p* 0
-}
-
-func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) {
- actual := c.Receive()
- if !reflect.DeepEqual(actual, expected) {
- t.Errorf("%s = %v, want %v", message, actual, expected)
- }
-}
-
-func TestPushed(t *testing.T) {
- pc, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer pc.Close()
-
- sc, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer sc.Close()
-
- c := redis.PubSubConn{Conn: sc}
-
- c.Subscribe("c1")
- expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1})
- c.Subscribe("c2")
- expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2})
- c.PSubscribe("p1")
- expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3})
- c.PSubscribe("p2")
- expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4})
- c.PUnsubscribe()
- expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3})
- expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2})
-
- pc.Do("PUBLISH", "c1", "hello")
- expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")})
-
- c.Ping("hello")
- expectPushed(t, c, `Ping("hello")`, redis.Pong{"hello"})
-
- c.Conn.Send("PING")
- c.Conn.Flush()
- expectPushed(t, c, `Send("PING")`, redis.Pong{})
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply_test.go
deleted file mode 100644
index 2c774866d..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/reply_test.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "fmt"
- "reflect"
- "testing"
-
- "github.com/garyburd/redigo/redis"
-)
-
-type valueError struct {
- v interface{}
- err error
-}
-
-func ve(v interface{}, err error) valueError {
- return valueError{v, err}
-}
-
-var replyTests = []struct {
- name interface{}
- actual valueError
- expected valueError
-}{
- {
- "ints([v1, v2])",
- ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)),
- ve([]int{4, 5}, nil),
- },
- {
- "ints(nil)",
- ve(redis.Ints(nil, nil)),
- ve([]int(nil), redis.ErrNil),
- },
- {
- "strings([v1, v2])",
- ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
- ve([]string{"v1", "v2"}, nil),
- },
- {
- "strings(nil)",
- ve(redis.Strings(nil, nil)),
- ve([]string(nil), redis.ErrNil),
- },
- {
- "byteslices([v1, v2])",
- ve(redis.ByteSlices([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
- ve([][]byte{[]byte("v1"), []byte("v2")}, nil),
- },
- {
- "byteslices(nil)",
- ve(redis.ByteSlices(nil, nil)),
- ve([][]byte(nil), redis.ErrNil),
- },
- {
- "values([v1, v2])",
- ve(redis.Values([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
- ve([]interface{}{[]byte("v1"), []byte("v2")}, nil),
- },
- {
- "values(nil)",
- ve(redis.Values(nil, nil)),
- ve([]interface{}(nil), redis.ErrNil),
- },
- {
- "float64(1.0)",
- ve(redis.Float64([]byte("1.0"), nil)),
- ve(float64(1.0), nil),
- },
- {
- "float64(nil)",
- ve(redis.Float64(nil, nil)),
- ve(float64(0.0), redis.ErrNil),
- },
- {
- "uint64(1)",
- ve(redis.Uint64(int64(1), nil)),
- ve(uint64(1), nil),
- },
- {
- "uint64(-1)",
- ve(redis.Uint64(int64(-1), nil)),
- ve(uint64(0), redis.ErrNegativeInt),
- },
-}
-
-func TestReply(t *testing.T) {
- for _, rt := range replyTests {
- if rt.actual.err != rt.expected.err {
- t.Errorf("%s returned err %v, want %v", rt.name, rt.actual.err, rt.expected.err)
- continue
- }
- if !reflect.DeepEqual(rt.actual.v, rt.expected.v) {
- t.Errorf("%s=%+v, want %+v", rt.name, rt.actual.v, rt.expected.v)
- }
- }
-}
-
-// dial wraps DialDefaultServer() with a more suitable function name for examples.
-func dial() (redis.Conn, error) {
- return redis.DialDefaultServer()
-}
-
-func ExampleBool() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Do("SET", "foo", 1)
- exists, _ := redis.Bool(c.Do("EXISTS", "foo"))
- fmt.Printf("%#v\n", exists)
- // Output:
- // true
-}
-
-func ExampleInt() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Do("SET", "k1", 1)
- n, _ := redis.Int(c.Do("GET", "k1"))
- fmt.Printf("%#v\n", n)
- n, _ = redis.Int(c.Do("INCR", "k1"))
- fmt.Printf("%#v\n", n)
- // Output:
- // 1
- // 2
-}
-
-func ExampleInts() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Do("SADD", "set_with_integers", 4, 5, 6)
- ints, _ := redis.Ints(c.Do("SMEMBERS", "set_with_integers"))
- fmt.Printf("%#v\n", ints)
- // Output:
- // []int{4, 5, 6}
-}
-
-func ExampleString() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Do("SET", "hello", "world")
- s, err := redis.String(c.Do("GET", "hello"))
- fmt.Printf("%#v\n", s)
- // Output:
- // "world"
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan_test.go
deleted file mode 100644
index d364dff42..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/scan_test.go
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "fmt"
- "math"
- "reflect"
- "testing"
-
- "github.com/garyburd/redigo/redis"
-)
-
-var scanConversionTests = []struct {
- src interface{}
- dest interface{}
-}{
- {[]byte("-inf"), math.Inf(-1)},
- {[]byte("+inf"), math.Inf(1)},
- {[]byte("0"), float64(0)},
- {[]byte("3.14159"), float64(3.14159)},
- {[]byte("3.14"), float32(3.14)},
- {[]byte("-100"), int(-100)},
- {[]byte("101"), int(101)},
- {int64(102), int(102)},
- {[]byte("103"), uint(103)},
- {int64(104), uint(104)},
- {[]byte("105"), int8(105)},
- {int64(106), int8(106)},
- {[]byte("107"), uint8(107)},
- {int64(108), uint8(108)},
- {[]byte("0"), false},
- {int64(0), false},
- {[]byte("f"), false},
- {[]byte("1"), true},
- {int64(1), true},
- {[]byte("t"), true},
- {"hello", "hello"},
- {[]byte("hello"), "hello"},
- {[]byte("world"), []byte("world")},
- {[]interface{}{[]byte("foo")}, []interface{}{[]byte("foo")}},
- {[]interface{}{[]byte("foo")}, []string{"foo"}},
- {[]interface{}{[]byte("hello"), []byte("world")}, []string{"hello", "world"}},
- {[]interface{}{[]byte("bar")}, [][]byte{[]byte("bar")}},
- {[]interface{}{[]byte("1")}, []int{1}},
- {[]interface{}{[]byte("1"), []byte("2")}, []int{1, 2}},
- {[]interface{}{[]byte("1"), []byte("2")}, []float64{1, 2}},
- {[]interface{}{[]byte("1")}, []byte{1}},
- {[]interface{}{[]byte("1")}, []bool{true}},
-}
-
-func TestScanConversion(t *testing.T) {
- for _, tt := range scanConversionTests {
- values := []interface{}{tt.src}
- dest := reflect.New(reflect.TypeOf(tt.dest))
- values, err := redis.Scan(values, dest.Interface())
- if err != nil {
- t.Errorf("Scan(%v) returned error %v", tt, err)
- continue
- }
- if !reflect.DeepEqual(tt.dest, dest.Elem().Interface()) {
- t.Errorf("Scan(%v) returned %v, want %v", tt, dest.Elem().Interface(), tt.dest)
- }
- }
-}
-
-var scanConversionErrorTests = []struct {
- src interface{}
- dest interface{}
-}{
- {[]byte("1234"), byte(0)},
- {int64(1234), byte(0)},
- {[]byte("-1"), byte(0)},
- {int64(-1), byte(0)},
- {[]byte("junk"), false},
- {redis.Error("blah"), false},
-}
-
-func TestScanConversionError(t *testing.T) {
- for _, tt := range scanConversionErrorTests {
- values := []interface{}{tt.src}
- dest := reflect.New(reflect.TypeOf(tt.dest))
- values, err := redis.Scan(values, dest.Interface())
- if err == nil {
- t.Errorf("Scan(%v) did not return error", tt)
- }
- }
-}
-
-func ExampleScan() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Send("HMSET", "album:1", "title", "Red", "rating", 5)
- c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1)
- c.Send("HMSET", "album:3", "title", "Beat")
- c.Send("LPUSH", "albums", "1")
- c.Send("LPUSH", "albums", "2")
- c.Send("LPUSH", "albums", "3")
- values, err := redis.Values(c.Do("SORT", "albums",
- "BY", "album:*->rating",
- "GET", "album:*->title",
- "GET", "album:*->rating"))
- if err != nil {
- fmt.Println(err)
- return
- }
-
- for len(values) > 0 {
- var title string
- rating := -1 // initialize to illegal value to detect nil.
- values, err = redis.Scan(values, &title, &rating)
- if err != nil {
- fmt.Println(err)
- return
- }
- if rating == -1 {
- fmt.Println(title, "not-rated")
- } else {
- fmt.Println(title, rating)
- }
- }
- // Output:
- // Beat not-rated
- // Earthbound 1
- // Red 5
-}
-
-type s0 struct {
- X int
- Y int `redis:"y"`
- Bt bool
-}
-
-type s1 struct {
- X int `redis:"-"`
- I int `redis:"i"`
- U uint `redis:"u"`
- S string `redis:"s"`
- P []byte `redis:"p"`
- B bool `redis:"b"`
- Bt bool
- Bf bool
- s0
-}
-
-var scanStructTests = []struct {
- title string
- reply []string
- value interface{}
-}{
- {"basic",
- []string{"i", "-1234", "u", "5678", "s", "hello", "p", "world", "b", "t", "Bt", "1", "Bf", "0", "X", "123", "y", "456"},
- &s1{I: -1234, U: 5678, S: "hello", P: []byte("world"), B: true, Bt: true, Bf: false, s0: s0{X: 123, Y: 456}},
- },
-}
-
-func TestScanStruct(t *testing.T) {
- for _, tt := range scanStructTests {
-
- var reply []interface{}
- for _, v := range tt.reply {
- reply = append(reply, []byte(v))
- }
-
- value := reflect.New(reflect.ValueOf(tt.value).Type().Elem())
-
- if err := redis.ScanStruct(reply, value.Interface()); err != nil {
- t.Fatalf("ScanStruct(%s) returned error %v", tt.title, err)
- }
-
- if !reflect.DeepEqual(value.Interface(), tt.value) {
- t.Fatalf("ScanStruct(%s) returned %v, want %v", tt.title, value.Interface(), tt.value)
- }
- }
-}
-
-func TestBadScanStructArgs(t *testing.T) {
- x := []interface{}{"A", "b"}
- test := func(v interface{}) {
- if err := redis.ScanStruct(x, v); err == nil {
- t.Errorf("Expect error for ScanStruct(%T, %T)", x, v)
- }
- }
-
- test(nil)
-
- var v0 *struct{}
- test(v0)
-
- var v1 int
- test(&v1)
-
- x = x[:1]
- v2 := struct{ A string }{}
- test(&v2)
-}
-
-var scanSliceTests = []struct {
- src []interface{}
- fieldNames []string
- ok bool
- dest interface{}
-}{
- {
- []interface{}{[]byte("1"), nil, []byte("-1")},
- nil,
- true,
- []int{1, 0, -1},
- },
- {
- []interface{}{[]byte("1"), nil, []byte("2")},
- nil,
- true,
- []uint{1, 0, 2},
- },
- {
- []interface{}{[]byte("-1")},
- nil,
- false,
- []uint{1},
- },
- {
- []interface{}{[]byte("hello"), nil, []byte("world")},
- nil,
- true,
- [][]byte{[]byte("hello"), nil, []byte("world")},
- },
- {
- []interface{}{[]byte("hello"), nil, []byte("world")},
- nil,
- true,
- []string{"hello", "", "world"},
- },
- {
- []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
- nil,
- true,
- []struct{ A, B string }{{"a1", "b1"}, {"a2", "b2"}},
- },
- {
- []interface{}{[]byte("a1"), []byte("b1")},
- nil,
- false,
- []struct{ A, B, C string }{{"a1", "b1", ""}},
- },
- {
- []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
- nil,
- true,
- []*struct{ A, B string }{{"a1", "b1"}, {"a2", "b2"}},
- },
- {
- []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
- []string{"A", "B"},
- true,
- []struct{ A, C, B string }{{"a1", "", "b1"}, {"a2", "", "b2"}},
- },
- {
- []interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
- nil,
- false,
- []struct{}{},
- },
-}
-
-func TestScanSlice(t *testing.T) {
- for _, tt := range scanSliceTests {
-
- typ := reflect.ValueOf(tt.dest).Type()
- dest := reflect.New(typ)
-
- err := redis.ScanSlice(tt.src, dest.Interface(), tt.fieldNames...)
- if tt.ok != (err == nil) {
- t.Errorf("ScanSlice(%v, []%s, %v) returned error %v", tt.src, typ, tt.fieldNames, err)
- continue
- }
- if tt.ok && !reflect.DeepEqual(dest.Elem().Interface(), tt.dest) {
- t.Errorf("ScanSlice(src, []%s) returned %#v, want %#v", typ, dest.Elem().Interface(), tt.dest)
- }
- }
-}
-
-func ExampleScanSlice() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- c.Send("HMSET", "album:1", "title", "Red", "rating", 5)
- c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1)
- c.Send("HMSET", "album:3", "title", "Beat", "rating", 4)
- c.Send("LPUSH", "albums", "1")
- c.Send("LPUSH", "albums", "2")
- c.Send("LPUSH", "albums", "3")
- values, err := redis.Values(c.Do("SORT", "albums",
- "BY", "album:*->rating",
- "GET", "album:*->title",
- "GET", "album:*->rating"))
- if err != nil {
- fmt.Println(err)
- return
- }
-
- var albums []struct {
- Title string
- Rating int
- }
- if err := redis.ScanSlice(values, &albums); err != nil {
- fmt.Println(err)
- return
- }
- fmt.Printf("%v\n", albums)
- // Output:
- // [{Earthbound 1} {Beat 4} {Red 5}]
-}
-
-var argsTests = []struct {
- title string
- actual redis.Args
- expected redis.Args
-}{
- {"struct ptr",
- redis.Args{}.AddFlat(&struct {
- I int `redis:"i"`
- U uint `redis:"u"`
- S string `redis:"s"`
- P []byte `redis:"p"`
- M map[string]string `redis:"m"`
- Bt bool
- Bf bool
- }{
- -1234, 5678, "hello", []byte("world"), map[string]string{"hello": "world"}, true, false,
- }),
- redis.Args{"i", int(-1234), "u", uint(5678), "s", "hello", "p", []byte("world"), "m", map[string]string{"hello": "world"}, "Bt", true, "Bf", false},
- },
- {"struct",
- redis.Args{}.AddFlat(struct{ I int }{123}),
- redis.Args{"I", 123},
- },
- {"slice",
- redis.Args{}.Add(1).AddFlat([]string{"a", "b", "c"}).Add(2),
- redis.Args{1, "a", "b", "c", 2},
- },
- {"struct omitempty",
- redis.Args{}.AddFlat(&struct {
- I int `redis:"i,omitempty"`
- U uint `redis:"u,omitempty"`
- S string `redis:"s,omitempty"`
- P []byte `redis:"p,omitempty"`
- M map[string]string `redis:"m,omitempty"`
- Bt bool `redis:"Bt,omitempty"`
- Bf bool `redis:"Bf,omitempty"`
- }{
- 0, 0, "", []byte{}, map[string]string{}, true, false,
- }),
- redis.Args{"Bt", true},
- },
-}
-
-func TestArgs(t *testing.T) {
- for _, tt := range argsTests {
- if !reflect.DeepEqual(tt.actual, tt.expected) {
- t.Fatalf("%s is %v, want %v", tt.title, tt.actual, tt.expected)
- }
- }
-}
-
-func ExampleArgs() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- var p1, p2 struct {
- Title string `redis:"title"`
- Author string `redis:"author"`
- Body string `redis:"body"`
- }
-
- p1.Title = "Example"
- p1.Author = "Gary"
- p1.Body = "Hello"
-
- if _, err := c.Do("HMSET", redis.Args{}.Add("id1").AddFlat(&p1)...); err != nil {
- fmt.Println(err)
- return
- }
-
- m := map[string]string{
- "title": "Example2",
- "author": "Steve",
- "body": "Map",
- }
-
- if _, err := c.Do("HMSET", redis.Args{}.Add("id2").AddFlat(m)...); err != nil {
- fmt.Println(err)
- return
- }
-
- for _, id := range []string{"id1", "id2"} {
-
- v, err := redis.Values(c.Do("HGETALL", id))
- if err != nil {
- fmt.Println(err)
- return
- }
-
- if err := redis.ScanStruct(v, &p2); err != nil {
- fmt.Println(err)
- return
- }
-
- fmt.Printf("%+v\n", p2)
- }
-
- // Output:
- // {Title:Example Author:Gary Body:Hello}
- // {Title:Example2 Author:Steve Body:Map}
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script_test.go
deleted file mode 100644
index 42f3c0363..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/script_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "fmt"
- "reflect"
- "testing"
- "time"
-
- "github.com/garyburd/redigo/redis"
-)
-
-func ExampleScript(c redis.Conn, reply interface{}, err error) {
- // Initialize a package-level variable with a script.
- var getScript = redis.NewScript(1, `return redis.call('get', KEYS[1])`)
-
- // In a function, use the script Do method to evaluate the script. The Do
- // method optimistically uses the EVALSHA command. If the script is not
- // loaded, then the Do method falls back to the EVAL command.
- reply, err = getScript.Do(c, "foo")
-}
-
-func TestScript(t *testing.T) {
- c, err := redis.DialDefaultServer()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- // To test fall back in Do, we make script unique by adding comment with current time.
- script := fmt.Sprintf("--%d\nreturn {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", time.Now().UnixNano())
- s := redis.NewScript(2, script)
- reply := []interface{}{[]byte("key1"), []byte("key2"), []byte("arg1"), []byte("arg2")}
-
- v, err := s.Do(c, "key1", "key2", "arg1", "arg2")
- if err != nil {
- t.Errorf("s.Do(c, ...) returned %v", err)
- }
-
- if !reflect.DeepEqual(v, reply) {
- t.Errorf("s.Do(c, ..); = %v, want %v", v, reply)
- }
-
- err = s.Load(c)
- if err != nil {
- t.Errorf("s.Load(c) returned %v", err)
- }
-
- err = s.SendHash(c, "key1", "key2", "arg1", "arg2")
- if err != nil {
- t.Errorf("s.SendHash(c, ...) returned %v", err)
- }
-
- err = c.Flush()
- if err != nil {
- t.Errorf("c.Flush() returned %v", err)
- }
-
- v, err = c.Receive()
- if !reflect.DeepEqual(v, reply) {
- t.Errorf("s.SendHash(c, ..); c.Receive() = %v, want %v", v, reply)
- }
-
- err = s.Send(c, "key1", "key2", "arg1", "arg2")
- if err != nil {
- t.Errorf("s.Send(c, ...) returned %v", err)
- }
-
- err = c.Flush()
- if err != nil {
- t.Errorf("c.Flush() returned %v", err)
- }
-
- v, err = c.Receive()
- if !reflect.DeepEqual(v, reply) {
- t.Errorf("s.Send(c, ..); c.Receive() = %v, want %v", v, reply)
- }
-
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/test_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/test_test.go
deleted file mode 100644
index 7240fa1f3..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/test_test.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
- "bufio"
- "errors"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "strconv"
- "strings"
- "sync"
- "testing"
- "time"
-)
-
-func SetNowFunc(f func() time.Time) {
- nowFunc = f
-}
-
-var (
- ErrNegativeInt = errNegativeInt
-
- serverPath = flag.String("redis-server", "redis-server", "Path to redis server binary")
- serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers")
- serverLogName = flag.String("redis-log", "", "Write Redis server logs to `filename`")
- serverLog = ioutil.Discard
-
- defaultServerMu sync.Mutex
- defaultServer *Server
- defaultServerErr error
-)
-
-type Server struct {
- name string
- cmd *exec.Cmd
- done chan struct{}
-}
-
-func NewServer(name string, args ...string) (*Server, error) {
- s := &Server{
- name: name,
- cmd: exec.Command(*serverPath, args...),
- done: make(chan struct{}),
- }
-
- r, err := s.cmd.StdoutPipe()
- if err != nil {
- return nil, err
- }
-
- err = s.cmd.Start()
- if err != nil {
- return nil, err
- }
-
- ready := make(chan error, 1)
- go s.watch(r, ready)
-
- select {
- case err = <-ready:
- case <-time.After(time.Second * 10):
- err = errors.New("timeout waiting for server to start")
- }
-
- if err != nil {
- s.Stop()
- return nil, err
- }
-
- return s, nil
-}
-
-func (s *Server) watch(r io.Reader, ready chan error) {
- fmt.Fprintf(serverLog, "%d START %s \n", s.cmd.Process.Pid, s.name)
- var listening bool
- var text string
- scn := bufio.NewScanner(r)
- for scn.Scan() {
- text = scn.Text()
- fmt.Fprintf(serverLog, "%s\n", text)
- if !listening {
- if strings.Contains(text, "The server is now ready to accept connections on port") {
- listening = true
- ready <- nil
- }
- }
- }
- if !listening {
- ready <- fmt.Errorf("server exited: %s", text)
- }
- s.cmd.Wait()
- fmt.Fprintf(serverLog, "%d STOP %s \n", s.cmd.Process.Pid, s.name)
- close(s.done)
-}
-
-func (s *Server) Stop() {
- s.cmd.Process.Signal(os.Interrupt)
- <-s.done
-}
-
-// stopDefaultServer stops the server created by DialDefaultServer.
-func stopDefaultServer() {
- defaultServerMu.Lock()
- defer defaultServerMu.Unlock()
- if defaultServer != nil {
- defaultServer.Stop()
- defaultServer = nil
- }
-}
-
-// startDefaultServer starts the default server if not already running.
-func startDefaultServer() error {
- defaultServerMu.Lock()
- defer defaultServerMu.Unlock()
- if defaultServer != nil || defaultServerErr != nil {
- return defaultServerErr
- }
- defaultServer, defaultServerErr = NewServer(
- "default",
- "--port", strconv.Itoa(*serverBasePort),
- "--save", "",
- "--appendonly", "no")
- return defaultServerErr
-}
-
-// DialDefaultServer starts the test server if not already started and dials a
-// connection to the server.
-func DialDefaultServer() (Conn, error) {
- if err := startDefaultServer(); err != nil {
- return nil, err
- }
- c, err := Dial("tcp", fmt.Sprintf(":%d", *serverBasePort), DialReadTimeout(1*time.Second), DialWriteTimeout(1*time.Second))
- if err != nil {
- return nil, err
- }
- c.Do("FLUSHDB")
- return c, nil
-}
-
-func TestMain(m *testing.M) {
- os.Exit(func() int {
- flag.Parse()
-
- var f *os.File
- if *serverLogName != "" {
- var err error
- f, err = os.OpenFile(*serverLogName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error opening redis-log: %v\n", err)
- return 1
- }
- defer f.Close()
- serverLog = f
- }
-
- defer stopDefaultServer()
-
- return m.Run()
- }())
-}
diff --git a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/zpop_example_test.go b/Godeps/_workspace/src/github.com/garyburd/redigo/redis/zpop_example_test.go
deleted file mode 100644
index 1d86ee6ce..000000000
--- a/Godeps/_workspace/src/github.com/garyburd/redigo/redis/zpop_example_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2013 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
- "fmt"
- "github.com/garyburd/redigo/redis"
-)
-
-// zpop pops a value from the ZSET key using WATCH/MULTI/EXEC commands.
-func zpop(c redis.Conn, key string) (result string, err error) {
-
- defer func() {
- // Return connection to normal state on error.
- if err != nil {
- c.Do("DISCARD")
- }
- }()
-
- // Loop until transaction is successful.
- for {
- if _, err := c.Do("WATCH", key); err != nil {
- return "", err
- }
-
- members, err := redis.Strings(c.Do("ZRANGE", key, 0, 0))
- if err != nil {
- return "", err
- }
- if len(members) != 1 {
- return "", redis.ErrNil
- }
-
- c.Send("MULTI")
- c.Send("ZREM", key, members[0])
- queued, err := c.Do("EXEC")
- if err != nil {
- return "", err
- }
-
- if queued != nil {
- result = members[0]
- break
- }
- }
-
- return result, nil
-}
-
-// zpopScript pops a value from a ZSET.
-var zpopScript = redis.NewScript(1, `
- local r = redis.call('ZRANGE', KEYS[1], 0, 0)
- if r ~= nil then
- r = r[1]
- redis.call('ZREM', KEYS[1], r)
- end
- return r
-`)
-
-// This example implements ZPOP as described at
-// http://redis.io/topics/transactions using WATCH/MULTI/EXEC and scripting.
-func Example_zpop() {
- c, err := dial()
- if err != nil {
- fmt.Println(err)
- return
- }
- defer c.Close()
-
- // Add test data using a pipeline.
-
- for i, member := range []string{"red", "blue", "green"} {
- c.Send("ZADD", "zset", i, member)
- }
- if _, err := c.Do(""); err != nil {
- fmt.Println(err)
- return
- }
-
- // Pop using WATCH/MULTI/EXEC
-
- v, err := zpop(c, "zset")
- if err != nil {
- fmt.Println(err)
- return
- }
- fmt.Println(v)
-
- // Pop using a script.
-
- v, err = redis.String(zpopScript.Do(c, "zset"))
- if err != nil {
- fmt.Println(err)
- return
- }
- fmt.Println(v)
-
- // Output:
- // red
- // blue
-}