|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- // 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()
- }
|