mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
clientv3/integration: test large KV requests
Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
This commit is contained in:
parent
497412c588
commit
f38593bbad
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/coreos/etcd/pkg/testutil"
|
"github.com/coreos/etcd/pkg/testutil"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestKVPutError(t *testing.T) {
|
func TestKVPutError(t *testing.T) {
|
||||||
@ -861,3 +862,95 @@ func TestKVPutAtMostOnce(t *testing.T) {
|
|||||||
t.Fatalf("expected version <= 10, got %+v", resp.Kvs[0])
|
t.Fatalf("expected version <= 10, got %+v", resp.Kvs[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestKVLargeRequests tests various client/server side request limits.
|
||||||
|
func TestKVLargeRequests(t *testing.T) {
|
||||||
|
defer testutil.AfterTest(t)
|
||||||
|
tests := []struct {
|
||||||
|
// make sure that "MaxCallSendMsgSize" < server-side default send/recv limit
|
||||||
|
maxRequestBytesServer uint
|
||||||
|
maxCallSendBytesClient int
|
||||||
|
maxCallRecvBytesClient int
|
||||||
|
|
||||||
|
valueSize int
|
||||||
|
expectError error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
maxRequestBytesServer: 1,
|
||||||
|
maxCallSendBytesClient: 0,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 1024,
|
||||||
|
expectError: rpctypes.ErrRequestTooLarge,
|
||||||
|
},
|
||||||
|
|
||||||
|
// without proper client-side receive size limit
|
||||||
|
// "code = ResourceExhausted desc = grpc: received message larger than max (5242929 vs. 4194304)"
|
||||||
|
{
|
||||||
|
|
||||||
|
maxRequestBytesServer: 7*1024*1024 + 512*1024,
|
||||||
|
maxCallSendBytesClient: 7 * 1024 * 1024,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 5 * 1024 * 1024,
|
||||||
|
expectError: nil,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
maxRequestBytesServer: 10 * 1024 * 1024,
|
||||||
|
maxCallSendBytesClient: 100 * 1024 * 1024,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 10 * 1024 * 1024,
|
||||||
|
expectError: rpctypes.ErrRequestTooLarge,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxRequestBytesServer: 10 * 1024 * 1024,
|
||||||
|
maxCallSendBytesClient: 10 * 1024 * 1024,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 10 * 1024 * 1024,
|
||||||
|
expectError: grpc.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", 10485770, 10485760),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxRequestBytesServer: 10 * 1024 * 1024,
|
||||||
|
maxCallSendBytesClient: 100 * 1024 * 1024,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 10*1024*1024 + 5,
|
||||||
|
expectError: rpctypes.ErrRequestTooLarge,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxRequestBytesServer: 10 * 1024 * 1024,
|
||||||
|
maxCallSendBytesClient: 10 * 1024 * 1024,
|
||||||
|
maxCallRecvBytesClient: 0,
|
||||||
|
valueSize: 10*1024*1024 + 5,
|
||||||
|
expectError: grpc.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", 10485775, 10485760),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, test := range tests {
|
||||||
|
clus := integration.NewClusterV3(t,
|
||||||
|
&integration.ClusterConfig{
|
||||||
|
Size: 1,
|
||||||
|
MaxRequestBytes: test.maxRequestBytesServer,
|
||||||
|
ClientMaxCallSendMsgSize: test.maxCallSendBytesClient,
|
||||||
|
ClientMaxCallRecvMsgSize: test.maxCallRecvBytesClient,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
cli := clus.Client(0)
|
||||||
|
_, err := cli.Put(context.TODO(), "foo", strings.Repeat("a", test.valueSize))
|
||||||
|
|
||||||
|
if _, ok := err.(rpctypes.EtcdError); ok {
|
||||||
|
if err != test.expectError {
|
||||||
|
t.Errorf("#%d: expected %v, got %v", i, test.expectError, err)
|
||||||
|
}
|
||||||
|
} else if err != nil && err.Error() != test.expectError.Error() {
|
||||||
|
t.Errorf("#%d: expected %v, got %v", i, test.expectError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// put request went through, now expects large response back
|
||||||
|
if err == nil {
|
||||||
|
_, err = cli.Get(context.TODO(), "foo")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("#%d: get expected no error, got %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clus.Terminate(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -105,6 +105,9 @@ type ClusterConfig struct {
|
|||||||
GRPCKeepAliveTimeout time.Duration
|
GRPCKeepAliveTimeout time.Duration
|
||||||
// SkipCreatingClient to skip creating clients for each member.
|
// SkipCreatingClient to skip creating clients for each member.
|
||||||
SkipCreatingClient bool
|
SkipCreatingClient bool
|
||||||
|
|
||||||
|
ClientMaxCallSendMsgSize int
|
||||||
|
ClientMaxCallRecvMsgSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
type cluster struct {
|
type cluster struct {
|
||||||
@ -232,15 +235,17 @@ func (c *cluster) HTTPMembers() []client.Member {
|
|||||||
func (c *cluster) mustNewMember(t *testing.T) *member {
|
func (c *cluster) mustNewMember(t *testing.T) *member {
|
||||||
m := mustNewMember(t,
|
m := mustNewMember(t,
|
||||||
memberConfig{
|
memberConfig{
|
||||||
name: c.name(rand.Int()),
|
name: c.name(rand.Int()),
|
||||||
peerTLS: c.cfg.PeerTLS,
|
peerTLS: c.cfg.PeerTLS,
|
||||||
clientTLS: c.cfg.ClientTLS,
|
clientTLS: c.cfg.ClientTLS,
|
||||||
quotaBackendBytes: c.cfg.QuotaBackendBytes,
|
quotaBackendBytes: c.cfg.QuotaBackendBytes,
|
||||||
maxTxnOps: c.cfg.MaxTxnOps,
|
maxTxnOps: c.cfg.MaxTxnOps,
|
||||||
maxRequestBytes: c.cfg.MaxRequestBytes,
|
maxRequestBytes: c.cfg.MaxRequestBytes,
|
||||||
grpcKeepAliveMinTime: c.cfg.GRPCKeepAliveMinTime,
|
grpcKeepAliveMinTime: c.cfg.GRPCKeepAliveMinTime,
|
||||||
grpcKeepAliveInterval: c.cfg.GRPCKeepAliveInterval,
|
grpcKeepAliveInterval: c.cfg.GRPCKeepAliveInterval,
|
||||||
grpcKeepAliveTimeout: c.cfg.GRPCKeepAliveTimeout,
|
grpcKeepAliveTimeout: c.cfg.GRPCKeepAliveTimeout,
|
||||||
|
clientMaxCallSendMsgSize: c.cfg.ClientMaxCallSendMsgSize,
|
||||||
|
clientMaxCallRecvMsgSize: c.cfg.ClientMaxCallRecvMsgSize,
|
||||||
})
|
})
|
||||||
m.DiscoveryURL = c.cfg.DiscoveryURL
|
m.DiscoveryURL = c.cfg.DiscoveryURL
|
||||||
if c.cfg.UseGRPC {
|
if c.cfg.UseGRPC {
|
||||||
@ -501,21 +506,25 @@ type member struct {
|
|||||||
// serverClient is a clientv3 that directly calls the etcdserver.
|
// serverClient is a clientv3 that directly calls the etcdserver.
|
||||||
serverClient *clientv3.Client
|
serverClient *clientv3.Client
|
||||||
|
|
||||||
keepDataDirTerminate bool
|
keepDataDirTerminate bool
|
||||||
|
clientMaxCallSendMsgSize int
|
||||||
|
clientMaxCallRecvMsgSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *member) GRPCAddr() string { return m.grpcAddr }
|
func (m *member) GRPCAddr() string { return m.grpcAddr }
|
||||||
|
|
||||||
type memberConfig struct {
|
type memberConfig struct {
|
||||||
name string
|
name string
|
||||||
peerTLS *transport.TLSInfo
|
peerTLS *transport.TLSInfo
|
||||||
clientTLS *transport.TLSInfo
|
clientTLS *transport.TLSInfo
|
||||||
quotaBackendBytes int64
|
quotaBackendBytes int64
|
||||||
maxTxnOps uint
|
maxTxnOps uint
|
||||||
maxRequestBytes uint
|
maxRequestBytes uint
|
||||||
grpcKeepAliveMinTime time.Duration
|
grpcKeepAliveMinTime time.Duration
|
||||||
grpcKeepAliveInterval time.Duration
|
grpcKeepAliveInterval time.Duration
|
||||||
grpcKeepAliveTimeout time.Duration
|
grpcKeepAliveTimeout time.Duration
|
||||||
|
clientMaxCallSendMsgSize int
|
||||||
|
clientMaxCallRecvMsgSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
// mustNewMember return an inited member with the given name. If peerTLS is
|
// mustNewMember return an inited member with the given name. If peerTLS is
|
||||||
@ -587,6 +596,8 @@ func mustNewMember(t *testing.T, mcfg memberConfig) *member {
|
|||||||
Timeout: mcfg.grpcKeepAliveTimeout,
|
Timeout: mcfg.grpcKeepAliveTimeout,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
m.clientMaxCallSendMsgSize = mcfg.clientMaxCallSendMsgSize
|
||||||
|
m.clientMaxCallRecvMsgSize = mcfg.clientMaxCallRecvMsgSize
|
||||||
|
|
||||||
m.InitialCorruptCheck = true
|
m.InitialCorruptCheck = true
|
||||||
|
|
||||||
@ -630,8 +641,10 @@ func NewClientV3(m *member) (*clientv3.Client, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg := clientv3.Config{
|
cfg := clientv3.Config{
|
||||||
Endpoints: []string{m.grpcAddr},
|
Endpoints: []string{m.grpcAddr},
|
||||||
DialTimeout: 5 * time.Second,
|
DialTimeout: 5 * time.Second,
|
||||||
|
MaxCallSendMsgSize: m.clientMaxCallSendMsgSize,
|
||||||
|
MaxCallRecvMsgSize: m.clientMaxCallRecvMsgSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.ClientTLSInfo != nil {
|
if m.ClientTLSInfo != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user