forked from processout/grpc-go-pool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool_test.go
174 lines (154 loc) · 4.54 KB
/
pool_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package grpcpool
import (
"context"
"testing"
"time"
"google.golang.org/grpc"
)
func TestNew(t *testing.T) {
p, err := New(func() (*grpc.ClientConn, error) {
return grpc.Dial("example.com", grpc.WithInsecure())
}, 1, 3, 0)
if err != nil {
t.Errorf("The pool returned an error: %s", err.Error())
}
if a := p.Available(); a != 3 {
t.Errorf("The pool available was %d but should be 3", a)
}
if a := p.Capacity(); a != 3 {
t.Errorf("The pool capacity was %d but should be 3", a)
}
// Get a client
client, err := p.Get(context.Background())
if err != nil {
t.Errorf("Get returned an error: %s", err.Error())
}
if client == nil {
t.Error("client was nil")
}
if a := p.Available(); a != 2 {
t.Errorf("The pool available was %d but should be 2", a)
}
if a := p.Capacity(); a != 3 {
t.Errorf("The pool capacity was %d but should be 3", a)
}
// Return the client
err = client.Close()
if err != nil {
t.Errorf("Close returned an error: %s", err.Error())
}
if a := p.Available(); a != 3 {
t.Errorf("The pool available was %d but should be 3", a)
}
if a := p.Capacity(); a != 3 {
t.Errorf("The pool capacity was %d but should be 3", a)
}
// Attempt to return the client again
err = client.Close()
if err != ErrAlreadyClosed {
t.Errorf("Expected error \"%s\" but got \"%s\"",
ErrAlreadyClosed.Error(), err.Error())
}
// Take 3 clients
cl1, err1 := p.Get(context.Background())
cl2, err2 := p.Get(context.Background())
cl3, err3 := p.Get(context.Background())
if err1 != nil {
t.Errorf("Err1 was not nil: %s", err1.Error())
}
if err2 != nil {
t.Errorf("Err2 was not nil: %s", err2.Error())
}
if err3 != nil {
t.Errorf("Err3 was not nil: %s", err3.Error())
}
if a := p.Available(); a != 0 {
t.Errorf("The pool available was %d but should be 0", a)
}
if a := p.Capacity(); a != 3 {
t.Errorf("The pool capacity was %d but should be 3", a)
}
// Returning all of them
err1 = cl1.Close()
if err1 != nil {
t.Errorf("Close returned an error: %s", err1.Error())
}
err2 = cl2.Close()
if err2 != nil {
t.Errorf("Close returned an error: %s", err2.Error())
}
err3 = cl3.Close()
if err3 != nil {
t.Errorf("Close returned an error: %s", err3.Error())
}
}
func TestTimeout(t *testing.T) {
p, err := New(func() (*grpc.ClientConn, error) {
return grpc.Dial("example.com", grpc.WithInsecure())
}, 1, 1, 0)
if err != nil {
t.Errorf("The pool returned an error: %s", err.Error())
}
_, err = p.Get(context.Background())
if err != nil {
t.Errorf("Get returned an error: %s", err.Error())
}
if a := p.Available(); a != 0 {
t.Errorf("The pool available was %d but expected 0", a)
}
// We want to fetch a second one, with a timeout. If the timeout was
// ommitted, the pool would wait indefinitely as it'd wait for another
// client to get back into the queue
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(10*time.Millisecond))
_, err2 := p.Get(ctx)
if err2 != ErrTimeout {
t.Errorf("Expected error \"%s\" but got \"%s\"", ErrTimeout, err2.Error())
}
}
func TestMaxLifeDuration(t *testing.T) {
p, err := New(func() (*grpc.ClientConn, error) {
return grpc.Dial("example.com", grpc.WithInsecure())
}, 1, 1, 0, 1)
if err != nil {
t.Errorf("The pool returned an error: %s", err.Error())
}
c, err := p.Get(context.Background())
if err != nil {
t.Errorf("Get returned an error: %s", err.Error())
}
// The max life of the connection was very low (1ns), so when we close
// the connection it should get marked as unhealthy
if err := c.Close(); err != nil {
t.Errorf("Close returned an error: %s", err.Error())
}
if !c.unhealthy {
t.Errorf("the connection should've been marked as unhealthy")
}
// Let's also make sure we don't prematurely close the connection
count := 0
p, err = New(func() (*grpc.ClientConn, error) {
count++
return grpc.Dial("example.com", grpc.WithInsecure())
}, 1, 1, 0, time.Minute)
if err != nil {
t.Errorf("The pool returned an error: %s", err.Error())
}
for i := 0; i < 3; i++ {
c, err = p.Get(context.Background())
if err != nil {
t.Errorf("Get returned an error: %s", err.Error())
}
// The max life of the connection is high, so when we close
// the connection it shouldn't be marked as unhealthy
if err := c.Close(); err != nil {
t.Errorf("Close returned an error: %s", err.Error())
}
if c.unhealthy {
t.Errorf("the connection shouldn't have been marked as unhealthy")
}
}
// Count should have been 1 as dial function should only have been called once
if count > 1 {
t.Errorf("Dial function has been called multiple times")
}
}