gitee.com/quant1x/gox@v1.7.6/pool/channel_rpc_test.go (about)

     1  package pool
     2  
     3  import (
     4  	"math/rand"
     5  	"net"
     6  	"net/http"
     7  	"net/rpc"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  var (
    14  	InitialCap = 5
    15  	MaxIdleCap = 10
    16  	MaximumCap = 100
    17  	network    = "tcp"
    18  	address    = "127.0.0.1:7777"
    19  	//factory    = func() (interface{}, error) { return net.Dial(network, address) }
    20  	factory = func() (interface{}, error) {
    21  		return rpc.DialHTTP("tcp", address)
    22  	}
    23  	closeFac = func(v interface{}) error {
    24  		nc := v.(*rpc.Client)
    25  		return nc.Close()
    26  	}
    27  )
    28  
    29  func init() {
    30  	// used for factory function
    31  	go rpcServer()
    32  	time.Sleep(time.Millisecond * 300) // wait until tcp server has been settled
    33  
    34  	rand.Seed(time.Now().UTC().UnixNano())
    35  }
    36  
    37  func TestNew(t *testing.T) {
    38  	p, err := newChannelPool()
    39  	defer p.Release()
    40  	if err != nil {
    41  		t.Errorf("New error: %s", err)
    42  	}
    43  }
    44  func TestPool_Get_Impl(t *testing.T) {
    45  	p, _ := newChannelPool()
    46  	defer p.Release()
    47  
    48  	conn, err := p.Get()
    49  	if err != nil {
    50  		t.Errorf("Get error: %s", err)
    51  	}
    52  	_, ok := conn.(*rpc.Client)
    53  	if !ok {
    54  		t.Errorf("Conn is not of type poolConn")
    55  	}
    56  	p.Put(conn)
    57  }
    58  
    59  func TestPool_Get(t *testing.T) {
    60  	p, _ := newChannelPool()
    61  	defer p.Release()
    62  
    63  	_, err := p.Get()
    64  	if err != nil {
    65  		t.Errorf("Get error: %s", err)
    66  	}
    67  
    68  	// after one get, current capacity should be lowered by one.
    69  	if p.Len() != (InitialCap - 1) {
    70  		t.Errorf("Get error. Expecting %d, got %d",
    71  			(InitialCap - 1), p.Len())
    72  	}
    73  
    74  	// get them all
    75  	var wg sync.WaitGroup
    76  	for i := 0; i < (MaximumCap - 1); i++ {
    77  		wg.Add(1)
    78  		go func() {
    79  			defer wg.Done()
    80  			_, err := p.Get()
    81  			if err != nil {
    82  				t.Errorf("Get error: %s", err)
    83  			}
    84  		}()
    85  	}
    86  	wg.Wait()
    87  
    88  	if p.Len() != 0 {
    89  		t.Errorf("Get error. Expecting %d, got %d",
    90  			(InitialCap - 1), p.Len())
    91  	}
    92  
    93  	_, err = p.Get()
    94  	if err != ErrMaxActiveConnReached {
    95  		t.Errorf("Get error: %s", err)
    96  	}
    97  
    98  }
    99  
   100  func TestPool_Put(t *testing.T) {
   101  	pconf := Config{InitialCap: InitialCap, MaxCap: MaximumCap, Factory: factory, Close: closeFac, IdleTimeout: time.Second * 20,
   102  		MaxIdle:MaxIdleCap}
   103  	p, err := NewChannelPool(&pconf)
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  	defer p.Release()
   108  
   109  	// get/create from the pool
   110  	conns := make([]interface{}, MaximumCap)
   111  	for i := 0; i < MaximumCap; i++ {
   112  		conn, _ := p.Get()
   113  		conns[i] = conn
   114  	}
   115  
   116  	// now put them all back
   117  	for _, conn := range conns {
   118  		p.Put(conn)
   119  	}
   120  
   121  	if p.Len() != MaxIdleCap {
   122  		t.Errorf("Put error len. Expecting %d, got %d",
   123  			1, p.Len())
   124  	}
   125  
   126  	p.Release() // close pool
   127  
   128  }
   129  
   130  func TestPool_UsedCapacity(t *testing.T) {
   131  	p, _ := newChannelPool()
   132  	defer p.Release()
   133  
   134  	if p.Len() != InitialCap {
   135  		t.Errorf("InitialCap error. Expecting %d, got %d",
   136  			InitialCap, p.Len())
   137  	}
   138  }
   139  
   140  func TestPool_Close(t *testing.T) {
   141  	p, _ := newChannelPool()
   142  
   143  	// now close it and test all cases we are expecting.
   144  	p.Release()
   145  
   146  	c := p.(*channelPool)
   147  
   148  	if c.conns != nil {
   149  		t.Errorf("Close error, conns channel should be nil")
   150  	}
   151  
   152  	if c.factory != nil {
   153  		t.Errorf("Close error, factory should be nil")
   154  	}
   155  
   156  	_, err := p.Get()
   157  	if err == nil {
   158  		t.Errorf("Close error, get conn should return an error")
   159  	}
   160  
   161  	if p.Len() != 0 {
   162  		t.Errorf("Close error used capacity. Expecting 0, got %d", p.Len())
   163  	}
   164  }
   165  
   166  func TestPoolConcurrent(t *testing.T) {
   167  	p, _ := newChannelPool()
   168  	pipe := make(chan interface{}, 0)
   169  
   170  	go func() {
   171  		p.Release()
   172  	}()
   173  
   174  	for i := 0; i < MaximumCap; i++ {
   175  		go func() {
   176  			conn, _ := p.Get()
   177  
   178  			pipe <- conn
   179  		}()
   180  
   181  		go func() {
   182  			conn := <-pipe
   183  			if conn == nil {
   184  				return
   185  			}
   186  			p.Put(conn)
   187  		}()
   188  	}
   189  }
   190  
   191  func TestPoolWriteRead(t *testing.T) {
   192  	//p, _ := NewChannelPool(0, 30, factory)
   193  	p, _ := newChannelPool()
   194  	conn, _ := p.Get()
   195  	cli := conn.(*rpc.Client)
   196  	var resp int
   197  	err := cli.Call("Arith.Multiply", Args{1, 2}, &resp)
   198  	if err != nil {
   199  		t.Error(err)
   200  	}
   201  	if resp != 2 {
   202  		t.Error("rpc.err")
   203  	}
   204  }
   205  
   206  func TestPoolConcurrent2(t *testing.T) {
   207  	//p, _ := NewChannelPool(0, 30, factory)
   208  	p, _ := newChannelPool()
   209  
   210  	var wg sync.WaitGroup
   211  
   212  	go func() {
   213  		for i := 0; i < 10; i++ {
   214  			wg.Add(1)
   215  			go func(i int) {
   216  				conn, _ := p.Get()
   217  				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
   218  				p.Close(conn)
   219  				wg.Done()
   220  			}(i)
   221  		}
   222  	}()
   223  
   224  	for i := 0; i < 10; i++ {
   225  		wg.Add(1)
   226  		go func(i int) {
   227  			conn, _ := p.Get()
   228  			time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
   229  			p.Close(conn)
   230  			wg.Done()
   231  		}(i)
   232  	}
   233  
   234  	wg.Wait()
   235  }
   236  
   237  //
   238  //func TestPoolConcurrent3(t *testing.T) {
   239  //	p, _ := NewChannelPool(0, 1, factory)
   240  //
   241  //	var wg sync.WaitGroup
   242  //
   243  //	wg.Add(1)
   244  //	go func() {
   245  //		p.Close()
   246  //		wg.Done()
   247  //	}()
   248  //
   249  //	if conn, err := p.Get(); err == nil {
   250  //		conn.Close()
   251  //	}
   252  //
   253  //	wg.Wait()
   254  //}
   255  
   256  func newChannelPool() (Pool, error) {
   257  	pconf := Config{InitialCap: InitialCap, MaxCap: MaximumCap, Factory: factory, Close: closeFac, IdleTimeout: time.Second * 20,
   258  		MaxIdle:MaxIdleCap}
   259  	return NewChannelPool(&pconf)
   260  }
   261  
   262  func rpcServer() {
   263  	arith := new(Arith)
   264  	rpc.Register(arith)
   265  	rpc.HandleHTTP()
   266  
   267  	l, e := net.Listen("tcp", address)
   268  	if e != nil {
   269  		panic(e)
   270  	}
   271  	go http.Serve(l, nil)
   272  }
   273  
   274  type Args struct {
   275  	A, B int
   276  }
   277  
   278  type Arith int
   279  
   280  func (t *Arith) Multiply(args *Args, reply *int) error {
   281  	*reply = args.A * args.B
   282  	return nil
   283  }