|
- // Copyright 2014 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 redisx_test
-
- import (
- "net/textproto"
- "sync"
- "testing"
-
- "github.com/garyburd/redigo/internal/redistest"
- "github.com/garyburd/redigo/redis"
- "github.com/garyburd/redigo/redisx"
- )
-
- func TestConnMux(t *testing.T) {
- c, err := redistest.Dial()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- m := redisx.NewConnMux(c)
- defer m.Close()
-
- c1 := m.Get()
- c2 := m.Get()
- c1.Send("ECHO", "hello")
- c2.Send("ECHO", "world")
- c1.Flush()
- c2.Flush()
- s, err := redis.String(c1.Receive())
- if err != nil {
- t.Fatal(err)
- }
- if s != "hello" {
- t.Fatalf("echo returned %q, want %q", s, "hello")
- }
- s, err = redis.String(c2.Receive())
- if err != nil {
- t.Fatal(err)
- }
- if s != "world" {
- t.Fatalf("echo returned %q, want %q", s, "world")
- }
- c1.Close()
- c2.Close()
- }
-
- func TestConnMuxClose(t *testing.T) {
- c, err := redistest.Dial()
- if err != nil {
- t.Fatalf("error connection to database, %v", err)
- }
- m := redisx.NewConnMux(c)
- defer m.Close()
-
- c1 := m.Get()
- c2 := m.Get()
-
- if err := c1.Send("ECHO", "hello"); err != nil {
- t.Fatal(err)
- }
- if err := c1.Close(); err != nil {
- t.Fatal(err)
- }
-
- if err := c2.Send("ECHO", "world"); err != nil {
- t.Fatal(err)
- }
- if err := c2.Flush(); err != nil {
- t.Fatal(err)
- }
-
- s, err := redis.String(c2.Receive())
- if err != nil {
- t.Fatal(err)
- }
- if s != "world" {
- t.Fatalf("echo returned %q, want %q", s, "world")
- }
- c2.Close()
- }
-
- func BenchmarkConn(b *testing.B) {
- b.StopTimer()
- c, err := redistest.Dial()
- if err != nil {
- b.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- }
- }
-
- func BenchmarkConnMux(b *testing.B) {
- b.StopTimer()
- c, err := redistest.Dial()
- if err != nil {
- b.Fatalf("error connection to database, %v", err)
- }
- m := redisx.NewConnMux(c)
- defer m.Close()
-
- b.StartTimer()
-
- for i := 0; i < b.N; i++ {
- c := m.Get()
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- c.Close()
- }
- }
-
- func BenchmarkPool(b *testing.B) {
- b.StopTimer()
-
- p := redis.Pool{Dial: redistest.Dial, MaxIdle: 1}
- defer p.Close()
-
- // Fill the pool.
- c := p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- c.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()
- }
- }
-
- const numConcurrent = 10
-
- func BenchmarkConnMuxConcurrent(b *testing.B) {
- b.StopTimer()
- c, err := redistest.Dial()
- if err != nil {
- b.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- m := redisx.NewConnMux(c)
-
- var wg sync.WaitGroup
- wg.Add(numConcurrent)
-
- b.StartTimer()
-
- for i := 0; i < numConcurrent; i++ {
- go func() {
- defer wg.Done()
- for i := 0; i < b.N; i++ {
- c := m.Get()
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- c.Close()
- }
- }()
- }
- wg.Wait()
- }
-
- func BenchmarkPoolConcurrent(b *testing.B) {
- b.StopTimer()
-
- p := redis.Pool{Dial: redistest.Dial, MaxIdle: numConcurrent}
- defer p.Close()
-
- // Fill the pool.
- conns := make([]redis.Conn, numConcurrent)
- for i := range conns {
- c := p.Get()
- if err := c.Err(); err != nil {
- b.Fatal(err)
- }
- conns[i] = c
- }
- for _, c := range conns {
- c.Close()
- }
-
- var wg sync.WaitGroup
- wg.Add(numConcurrent)
-
- b.StartTimer()
-
- for i := 0; i < numConcurrent; i++ {
- go func() {
- defer wg.Done()
- for i := 0; i < b.N; i++ {
- c := p.Get()
- if _, err := c.Do("PING"); err != nil {
- b.Fatal(err)
- }
- c.Close()
- }
- }()
- }
- wg.Wait()
- }
-
- func BenchmarkPipelineConcurrency(b *testing.B) {
- b.StopTimer()
- c, err := redistest.Dial()
- if err != nil {
- b.Fatalf("error connection to database, %v", err)
- }
- defer c.Close()
-
- var wg sync.WaitGroup
- wg.Add(numConcurrent)
-
- var pipeline textproto.Pipeline
-
- b.StartTimer()
-
- for i := 0; i < numConcurrent; i++ {
- go func() {
- defer wg.Done()
- for i := 0; i < b.N; i++ {
- id := pipeline.Next()
- pipeline.StartRequest(id)
- c.Send("PING")
- c.Flush()
- pipeline.EndRequest(id)
- pipeline.StartResponse(id)
- _, err := c.Receive()
- if err != nil {
- b.Fatal(err)
- }
- pipeline.EndResponse(id)
- }
- }()
- }
- wg.Wait()
- }
|