mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #5222 from gyuho/error_interface
rpctypes: error interface
This commit is contained in:
commit
33968059e9
@ -19,6 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/auth/authpb"
|
||||
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
@ -87,37 +88,37 @@ func NewAuth(c *Client) Auth {
|
||||
|
||||
func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
|
||||
resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{})
|
||||
return (*AuthEnableResponse)(resp), err
|
||||
return (*AuthEnableResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) {
|
||||
resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password})
|
||||
return (*AuthenticateResponse)(resp), err
|
||||
return (*AuthenticateResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
|
||||
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password})
|
||||
return (*AuthUserAddResponse)(resp), err
|
||||
return (*AuthUserAddResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
|
||||
resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name})
|
||||
return (*AuthUserDeleteResponse)(resp), err
|
||||
return (*AuthUserDeleteResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
|
||||
resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password})
|
||||
return (*AuthUserChangePasswordResponse)(resp), err
|
||||
return (*AuthUserChangePasswordResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) UserGrant(ctx context.Context, user string, role string) (*AuthUserGrantResponse, error) {
|
||||
resp, err := auth.remote.UserGrant(ctx, &pb.AuthUserGrantRequest{User: user, Role: role})
|
||||
return (*AuthUserGrantResponse)(resp), err
|
||||
return (*AuthUserGrantResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
|
||||
resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name})
|
||||
return (*AuthRoleAddResponse)(resp), err
|
||||
return (*AuthRoleAddResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func (auth *auth) RoleGrant(ctx context.Context, name string, key string, permType PermissionType) (*AuthRoleGrantResponse, error) {
|
||||
@ -126,7 +127,7 @@ func (auth *auth) RoleGrant(ctx context.Context, name string, key string, permTy
|
||||
PermType: authpb.Permission_Type(permType),
|
||||
}
|
||||
resp, err := auth.remote.RoleGrant(ctx, &pb.AuthRoleGrantRequest{Name: name, Perm: perm})
|
||||
return (*AuthRoleGrantResponse)(resp), err
|
||||
return (*AuthRoleGrantResponse)(resp), rpctypes.Error(err)
|
||||
}
|
||||
|
||||
func StrToPermissionType(s string) (PermissionType, error) {
|
||||
|
@ -411,7 +411,7 @@ func TestKVCompact(t *testing.T) {
|
||||
}
|
||||
err = kv.Compact(ctx, 7)
|
||||
if err == nil || err != rpctypes.ErrCompacted {
|
||||
t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev)
|
||||
t.Fatalf("error got %v, want %v", err, rpctypes.ErrCompacted)
|
||||
}
|
||||
|
||||
wcli := clus.RandClient()
|
||||
|
@ -23,11 +23,9 @@ import (
|
||||
"github.com/coreos/etcd/integration"
|
||||
"github.com/coreos/etcd/pkg/testutil"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
func TestLeastNotFoundError(t *testing.T) {
|
||||
func TestLeaseNotFoundError(t *testing.T) {
|
||||
defer testutil.AfterTest(t)
|
||||
|
||||
clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
|
||||
@ -113,8 +111,8 @@ func TestLeaseKeepAliveOnce(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err = lapi.KeepAliveOnce(context.Background(), clientv3.LeaseID(0))
|
||||
if grpc.Code(err) != codes.NotFound {
|
||||
t.Errorf("invalid error returned %v", err)
|
||||
if err != rpctypes.ErrLeaseNotFound {
|
||||
t.Errorf("expected %v, got %v", rpctypes.ErrLeaseNotFound, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,7 +364,7 @@ func TestWatchCompactRevision(t *testing.T) {
|
||||
t.Fatalf("expected wresp, but got closed channel")
|
||||
}
|
||||
if wresp.Err() != rpctypes.ErrCompacted {
|
||||
t.Fatalf("wresp.Err() expected ErrCompacteed, but got %v", wresp.Err())
|
||||
t.Fatalf("wresp.Err() expected %v, but got %v", rpctypes.ErrCompacted, wresp.Err())
|
||||
}
|
||||
|
||||
// ensure the channel is closed
|
||||
|
@ -125,33 +125,33 @@ func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.Co
|
||||
|
||||
func checkRangeRequest(r *pb.RangeRequest) error {
|
||||
if len(r.Key) == 0 {
|
||||
return rpctypes.ErrEmptyKey
|
||||
return rpctypes.ErrGRPCEmptyKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPutRequest(r *pb.PutRequest) error {
|
||||
if len(r.Key) == 0 {
|
||||
return rpctypes.ErrEmptyKey
|
||||
return rpctypes.ErrGRPCEmptyKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkDeleteRequest(r *pb.DeleteRangeRequest) error {
|
||||
if len(r.Key) == 0 {
|
||||
return rpctypes.ErrEmptyKey
|
||||
return rpctypes.ErrGRPCEmptyKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkTxnRequest(r *pb.TxnRequest) error {
|
||||
if len(r.Compare) > MaxOpsPerTxn || len(r.Success) > MaxOpsPerTxn || len(r.Failure) > MaxOpsPerTxn {
|
||||
return rpctypes.ErrTooManyOps
|
||||
return rpctypes.ErrGRPCTooManyOps
|
||||
}
|
||||
|
||||
for _, c := range r.Compare {
|
||||
if len(c.Key) == 0 {
|
||||
return rpctypes.ErrEmptyKey
|
||||
return rpctypes.ErrGRPCEmptyKey
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ func checkTxnRequest(r *pb.TxnRequest) error {
|
||||
return checkRequestDupKeys(r.Failure)
|
||||
}
|
||||
|
||||
// checkRequestDupKeys gives rpctypes.ErrDuplicateKey if the same key is modified twice
|
||||
// checkRequestDupKeys gives rpctypes.ErrGRPCDuplicateKey if the same key is modified twice
|
||||
func checkRequestDupKeys(reqs []*pb.RequestUnion) error {
|
||||
// check put overlap
|
||||
keys := make(map[string]struct{})
|
||||
@ -186,7 +186,7 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error {
|
||||
continue
|
||||
}
|
||||
if _, ok := keys[string(preq.Key)]; ok {
|
||||
return rpctypes.ErrDuplicateKey
|
||||
return rpctypes.ErrGRPCDuplicateKey
|
||||
}
|
||||
keys[string(preq.Key)] = struct{}{}
|
||||
}
|
||||
@ -215,14 +215,14 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error {
|
||||
}
|
||||
if dreq.RangeEnd == nil {
|
||||
if _, found := keys[string(dreq.Key)]; found {
|
||||
return rpctypes.ErrDuplicateKey
|
||||
return rpctypes.ErrGRPCDuplicateKey
|
||||
}
|
||||
} else {
|
||||
lo := sort.SearchStrings(sortedKeys, string(dreq.Key))
|
||||
hi := sort.SearchStrings(sortedKeys, string(dreq.RangeEnd))
|
||||
if lo != hi {
|
||||
// element between lo and hi => overlap
|
||||
return rpctypes.ErrDuplicateKey
|
||||
return rpctypes.ErrGRPCDuplicateKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {
|
||||
func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
|
||||
resp, err := ls.le.LeaseGrant(ctx, cr)
|
||||
if err == lease.ErrLeaseExists {
|
||||
return nil, rpctypes.ErrLeaseExist
|
||||
return nil, rpctypes.ErrGRPCLeaseExist
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -48,7 +48,7 @@ func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest)
|
||||
func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
|
||||
resp, err := ls.le.LeaseRevoke(ctx, rr)
|
||||
if err != nil {
|
||||
return nil, rpctypes.ErrLeaseNotFound
|
||||
return nil, rpctypes.ErrGRPCLeaseNotFound
|
||||
}
|
||||
ls.hdr.fill(resp.Header)
|
||||
return resp, nil
|
||||
|
@ -45,7 +45,7 @@ func NewClusterServer(s *etcdserver.EtcdServer) *ClusterServer {
|
||||
func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) {
|
||||
urls, err := types.NewURLs(r.PeerURLs)
|
||||
if err != nil {
|
||||
return nil, rpctypes.ErrMemberBadURLs
|
||||
return nil, rpctypes.ErrGRPCMemberBadURLs
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@ -53,9 +53,9 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest)
|
||||
err = cs.server.AddMember(ctx, *m)
|
||||
switch {
|
||||
case err == membership.ErrIDExists:
|
||||
return nil, rpctypes.ErrMemberExist
|
||||
return nil, rpctypes.ErrGRPCMemberExist
|
||||
case err == membership.ErrPeerURLexists:
|
||||
return nil, rpctypes.ErrPeerURLExist
|
||||
return nil, rpctypes.ErrGRPCPeerURLExist
|
||||
case err != nil:
|
||||
return nil, grpc.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
@ -72,7 +72,7 @@ func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveReq
|
||||
case err == membership.ErrIDRemoved:
|
||||
fallthrough
|
||||
case err == membership.ErrIDNotFound:
|
||||
return nil, rpctypes.ErrMemberNotFound
|
||||
return nil, rpctypes.ErrGRPCMemberNotFound
|
||||
case err != nil:
|
||||
return nil, grpc.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
@ -88,9 +88,9 @@ func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateReq
|
||||
err := cs.server.UpdateMember(ctx, m)
|
||||
switch {
|
||||
case err == membership.ErrPeerURLexists:
|
||||
return nil, rpctypes.ErrPeerURLExist
|
||||
return nil, rpctypes.ErrGRPCPeerURLExist
|
||||
case err == membership.ErrIDNotFound:
|
||||
return nil, rpctypes.ErrMemberNotFound
|
||||
return nil, rpctypes.ErrGRPCMemberNotFound
|
||||
case err != nil:
|
||||
return nil, grpc.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error {
|
||||
Alarm: pb.AlarmType_NOSPACE,
|
||||
}
|
||||
qa.a.Alarm(ctx, req)
|
||||
return rpctypes.ErrNoSpace
|
||||
return rpctypes.ErrGRPCNoSpace
|
||||
}
|
||||
|
||||
func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer {
|
||||
|
@ -20,62 +20,104 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided")
|
||||
ErrTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request")
|
||||
ErrDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request")
|
||||
ErrCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted")
|
||||
ErrFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision")
|
||||
ErrNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded")
|
||||
// server-side error
|
||||
ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided")
|
||||
ErrGRPCTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request")
|
||||
ErrGRPCDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request")
|
||||
ErrGRPCCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted")
|
||||
ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision")
|
||||
ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded")
|
||||
|
||||
ErrLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found")
|
||||
ErrLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists")
|
||||
ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found")
|
||||
ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists")
|
||||
|
||||
ErrMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist")
|
||||
ErrPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists")
|
||||
ErrMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid")
|
||||
ErrMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found")
|
||||
ErrGRPCMemberExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: member ID already exist")
|
||||
ErrGRPCPeerURLExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: Peer URLs already exists")
|
||||
ErrGRPCMemberBadURLs = grpc.Errorf(codes.InvalidArgument, "etcdserver: given member URLs are invalid")
|
||||
ErrGRPCMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found")
|
||||
|
||||
ErrRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large")
|
||||
ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large")
|
||||
|
||||
ErrUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists")
|
||||
ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found")
|
||||
ErrRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists")
|
||||
ErrRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found")
|
||||
ErrAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password")
|
||||
ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists")
|
||||
ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found")
|
||||
ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists")
|
||||
ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found")
|
||||
ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password")
|
||||
|
||||
errStringToError = map[string]error{
|
||||
grpc.ErrorDesc(ErrEmptyKey): ErrEmptyKey,
|
||||
grpc.ErrorDesc(ErrTooManyOps): ErrTooManyOps,
|
||||
grpc.ErrorDesc(ErrDuplicateKey): ErrDuplicateKey,
|
||||
grpc.ErrorDesc(ErrCompacted): ErrCompacted,
|
||||
grpc.ErrorDesc(ErrFutureRev): ErrFutureRev,
|
||||
grpc.ErrorDesc(ErrNoSpace): ErrNoSpace,
|
||||
grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey,
|
||||
grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps,
|
||||
grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey,
|
||||
grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted,
|
||||
grpc.ErrorDesc(ErrGRPCFutureRev): ErrGRPCFutureRev,
|
||||
grpc.ErrorDesc(ErrGRPCNoSpace): ErrGRPCNoSpace,
|
||||
|
||||
grpc.ErrorDesc(ErrLeaseNotFound): ErrLeaseNotFound,
|
||||
grpc.ErrorDesc(ErrLeaseExist): ErrLeaseExist,
|
||||
grpc.ErrorDesc(ErrGRPCLeaseNotFound): ErrGRPCLeaseNotFound,
|
||||
grpc.ErrorDesc(ErrGRPCLeaseExist): ErrGRPCLeaseExist,
|
||||
|
||||
grpc.ErrorDesc(ErrMemberExist): ErrMemberExist,
|
||||
grpc.ErrorDesc(ErrPeerURLExist): ErrPeerURLExist,
|
||||
grpc.ErrorDesc(ErrMemberBadURLs): ErrMemberBadURLs,
|
||||
grpc.ErrorDesc(ErrMemberNotFound): ErrMemberNotFound,
|
||||
grpc.ErrorDesc(ErrGRPCMemberExist): ErrGRPCMemberExist,
|
||||
grpc.ErrorDesc(ErrGRPCPeerURLExist): ErrGRPCPeerURLExist,
|
||||
grpc.ErrorDesc(ErrGRPCMemberBadURLs): ErrGRPCMemberBadURLs,
|
||||
grpc.ErrorDesc(ErrGRPCMemberNotFound): ErrGRPCMemberNotFound,
|
||||
|
||||
grpc.ErrorDesc(ErrRequestTooLarge): ErrRequestTooLarge,
|
||||
grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge,
|
||||
|
||||
grpc.ErrorDesc(ErrUserAlreadyExist): ErrUserAlreadyExist,
|
||||
grpc.ErrorDesc(ErrUserNotFound): ErrUserNotFound,
|
||||
grpc.ErrorDesc(ErrRoleAlreadyExist): ErrRoleAlreadyExist,
|
||||
grpc.ErrorDesc(ErrRoleNotFound): ErrRoleNotFound,
|
||||
grpc.ErrorDesc(ErrAuthFailed): ErrAuthFailed,
|
||||
grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist,
|
||||
grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound,
|
||||
grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist,
|
||||
grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound,
|
||||
grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed,
|
||||
}
|
||||
|
||||
// client-side error
|
||||
ErrEmptyKey = Error(ErrGRPCEmptyKey)
|
||||
ErrTooManyOps = Error(ErrGRPCTooManyOps)
|
||||
ErrDuplicateKey = Error(ErrGRPCDuplicateKey)
|
||||
ErrCompacted = Error(ErrGRPCCompacted)
|
||||
ErrFutureRev = Error(ErrGRPCFutureRev)
|
||||
ErrNoSpace = Error(ErrGRPCNoSpace)
|
||||
|
||||
ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound)
|
||||
ErrLeaseExist = Error(ErrGRPCLeaseExist)
|
||||
|
||||
ErrMemberExist = Error(ErrGRPCMemberExist)
|
||||
ErrPeerURLExist = Error(ErrGRPCPeerURLExist)
|
||||
ErrMemberBadURLs = Error(ErrGRPCMemberBadURLs)
|
||||
ErrMemberNotFound = Error(ErrGRPCMemberNotFound)
|
||||
|
||||
ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge)
|
||||
|
||||
ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist)
|
||||
ErrUserNotFound = Error(ErrGRPCUserNotFound)
|
||||
ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist)
|
||||
ErrRoleNotFound = Error(ErrGRPCRoleNotFound)
|
||||
ErrAuthFailed = Error(ErrGRPCAuthFailed)
|
||||
)
|
||||
|
||||
// EtcdError defines gRPC server errors.
|
||||
// (https://github.com/grpc/grpc-go/blob/master/rpc_util.go#L319-L323)
|
||||
type EtcdError struct {
|
||||
code codes.Code
|
||||
desc string
|
||||
}
|
||||
|
||||
// Code returns grpc/codes.Code.
|
||||
// TODO: define clientv3/codes.Code.
|
||||
func (e EtcdError) Code() codes.Code {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e EtcdError) Error() string {
|
||||
return e.desc
|
||||
}
|
||||
|
||||
func Error(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
v, ok := errStringToError[err.Error()]
|
||||
if !ok {
|
||||
verr, ok := errStringToError[grpc.ErrorDesc(err)]
|
||||
if !ok { // not gRPC error
|
||||
return err
|
||||
}
|
||||
return v
|
||||
return EtcdError{code: grpc.Code(verr), desc: grpc.ErrorDesc(verr)}
|
||||
}
|
||||
|
42
etcdserver/api/v3rpc/rpctypes/error_test.go
Normal file
42
etcdserver/api/v3rpc/rpctypes/error_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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 rpctypes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
e1 := grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided")
|
||||
e2 := ErrGRPCEmptyKey
|
||||
e3 := ErrEmptyKey
|
||||
|
||||
if e1 != e2 {
|
||||
t.Fatalf("expected 'true', got %T != %T", e1, e2)
|
||||
}
|
||||
if grpc.Code(e1) != e3.(EtcdError).Code() {
|
||||
t.Fatalf("expected them to be equal, got %v / %v", grpc.Code(e1), e3.(EtcdError).Code())
|
||||
}
|
||||
|
||||
if e1 == e3 {
|
||||
t.Fatalf("expected 'false', got %T == %T", e1, e3)
|
||||
}
|
||||
if grpc.Code(e2) != e3.(EtcdError).Code() {
|
||||
t.Fatalf("expected them to be equal, got %v / %v", grpc.Code(e2), e3.(EtcdError).Code())
|
||||
}
|
||||
}
|
@ -27,26 +27,26 @@ import (
|
||||
func togRPCError(err error) error {
|
||||
switch err {
|
||||
case mvcc.ErrCompacted:
|
||||
return rpctypes.ErrCompacted
|
||||
return rpctypes.ErrGRPCCompacted
|
||||
case mvcc.ErrFutureRev:
|
||||
return rpctypes.ErrFutureRev
|
||||
return rpctypes.ErrGRPCFutureRev
|
||||
case lease.ErrLeaseNotFound:
|
||||
return rpctypes.ErrLeaseNotFound
|
||||
return rpctypes.ErrGRPCLeaseNotFound
|
||||
// TODO: handle error from raft and timeout
|
||||
case etcdserver.ErrRequestTooLarge:
|
||||
return rpctypes.ErrRequestTooLarge
|
||||
return rpctypes.ErrGRPCRequestTooLarge
|
||||
case etcdserver.ErrNoSpace:
|
||||
return rpctypes.ErrNoSpace
|
||||
return rpctypes.ErrGRPCNoSpace
|
||||
case auth.ErrUserAlreadyExist:
|
||||
return rpctypes.ErrUserAlreadyExist
|
||||
return rpctypes.ErrGRPCUserAlreadyExist
|
||||
case auth.ErrUserNotFound:
|
||||
return rpctypes.ErrUserNotFound
|
||||
return rpctypes.ErrGRPCUserNotFound
|
||||
case auth.ErrRoleAlreadyExist:
|
||||
return rpctypes.ErrRoleAlreadyExist
|
||||
return rpctypes.ErrGRPCRoleAlreadyExist
|
||||
case auth.ErrRoleNotFound:
|
||||
return rpctypes.ErrRoleNotFound
|
||||
return rpctypes.ErrGRPCRoleNotFound
|
||||
case auth.ErrAuthFailed:
|
||||
return rpctypes.ErrAuthFailed
|
||||
return rpctypes.ErrGRPCAuthFailed
|
||||
default:
|
||||
return grpc.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
@ -196,8 +196,13 @@ func (c *cluster) HTTPMembers() []client.Member {
|
||||
}
|
||||
|
||||
func (c *cluster) mustNewMember(t *testing.T) *member {
|
||||
name := c.name(rand.Int())
|
||||
m := mustNewMember(t, name, c.cfg.PeerTLS, c.cfg.ClientTLS, c.cfg.QuotaBackendBytes)
|
||||
m := mustNewMember(t,
|
||||
memberConfig{
|
||||
name: c.name(rand.Int()),
|
||||
peerTLS: c.cfg.PeerTLS,
|
||||
clientTLS: c.cfg.ClientTLS,
|
||||
quotaBackendBytes: c.cfg.QuotaBackendBytes,
|
||||
})
|
||||
m.DiscoveryURL = c.cfg.DiscoveryURL
|
||||
if c.cfg.UseGRPC {
|
||||
if err := m.listenGRPC(); err != nil {
|
||||
@ -416,17 +421,24 @@ type member struct {
|
||||
grpcAddr string
|
||||
}
|
||||
|
||||
type memberConfig struct {
|
||||
name string
|
||||
peerTLS *transport.TLSInfo
|
||||
clientTLS *transport.TLSInfo
|
||||
quotaBackendBytes int64
|
||||
}
|
||||
|
||||
// mustNewMember return an inited member with the given name. If peerTLS is
|
||||
// set, it will use https scheme to communicate between peers.
|
||||
func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, clientTLS *transport.TLSInfo, quotaBackendBytes int64) *member {
|
||||
func mustNewMember(t *testing.T, mcfg memberConfig) *member {
|
||||
var err error
|
||||
m := &member{}
|
||||
|
||||
peerScheme, clientScheme := "http", "http"
|
||||
if peerTLS != nil {
|
||||
if mcfg.peerTLS != nil {
|
||||
peerScheme = "https"
|
||||
}
|
||||
if clientTLS != nil {
|
||||
if mcfg.clientTLS != nil {
|
||||
clientScheme = "https"
|
||||
}
|
||||
|
||||
@ -436,7 +448,7 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m.PeerTLSInfo = peerTLS
|
||||
m.PeerTLSInfo = mcfg.peerTLS
|
||||
|
||||
cln := newLocalListener(t)
|
||||
m.ClientListeners = []net.Listener{cln}
|
||||
@ -444,15 +456,15 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m.ClientTLSInfo = clientTLS
|
||||
m.ClientTLSInfo = mcfg.clientTLS
|
||||
|
||||
m.Name = name
|
||||
m.Name = mcfg.name
|
||||
|
||||
m.DataDir, err = ioutil.TempDir(os.TempDir(), "etcd")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
clusterStr := fmt.Sprintf("%s=%s://%s", name, peerScheme, pln.Addr().String())
|
||||
clusterStr := fmt.Sprintf("%s=%s://%s", mcfg.name, peerScheme, pln.Addr().String())
|
||||
m.InitialPeerURLsMap, err = types.NewURLsMap(clusterStr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -465,7 +477,7 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client
|
||||
}
|
||||
m.ElectionTicks = electionTicks
|
||||
m.TickMs = uint(tickDuration / time.Millisecond)
|
||||
m.QuotaBackendBytes = quotaBackendBytes
|
||||
m.QuotaBackendBytes = mcfg.quotaBackendBytes
|
||||
return m
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ func TestLaunchDuplicateMemberShouldFail(t *testing.T) {
|
||||
|
||||
func TestSnapshotAndRestartMember(t *testing.T) {
|
||||
defer testutil.AfterTest(t)
|
||||
m := mustNewMember(t, "snapAndRestartTest", nil, nil)
|
||||
m := mustNewMember(t, memberConfig{name: "snapAndRestartTest"})
|
||||
m.SnapCount = 100
|
||||
m.Launch()
|
||||
defer m.Terminate(t)
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
func TestUpgradeMember(t *testing.T) {
|
||||
defer testutil.AfterTest(t)
|
||||
m := mustNewMember(t, "integration046", nil, nil)
|
||||
m := mustNewMember(t, memberConfig{name: "integration046"})
|
||||
cmd := exec.Command("cp", "-r", "testdata/integration046_data/conf", "testdata/integration046_data/log", "testdata/integration046_data/snapshot", m.DataDir)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
|
@ -193,8 +193,8 @@ func TestV3TxnTooManyOps(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err := kvc.Txn(context.Background(), txn)
|
||||
if err != rpctypes.ErrTooManyOps {
|
||||
t.Errorf("#%d: err = %v, want %v", i, err, rpctypes.ErrTooManyOps)
|
||||
if err != rpctypes.ErrGRPCTooManyOps {
|
||||
t.Errorf("#%d: err = %v, want %v", i, err, rpctypes.ErrGRPCTooManyOps)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,17 +233,17 @@ func TestV3TxnDuplicateKeys(t *testing.T) {
|
||||
{
|
||||
txnSuccess: []*pb.RequestUnion{putreq, putreq},
|
||||
|
||||
werr: rpctypes.ErrDuplicateKey,
|
||||
werr: rpctypes.ErrGRPCDuplicateKey,
|
||||
},
|
||||
{
|
||||
txnSuccess: []*pb.RequestUnion{putreq, delKeyReq},
|
||||
|
||||
werr: rpctypes.ErrDuplicateKey,
|
||||
werr: rpctypes.ErrGRPCDuplicateKey,
|
||||
},
|
||||
{
|
||||
txnSuccess: []*pb.RequestUnion{putreq, delInRangeReq},
|
||||
|
||||
werr: rpctypes.ErrDuplicateKey,
|
||||
werr: rpctypes.ErrGRPCDuplicateKey,
|
||||
},
|
||||
{
|
||||
txnSuccess: []*pb.RequestUnion{delKeyReq, delInRangeReq, delKeyReq, delInRangeReq},
|
||||
@ -502,15 +502,15 @@ func TestV3TxnInvaildRange(t *testing.T) {
|
||||
Request: &pb.RequestUnion_RequestRange{
|
||||
RequestRange: rreq}})
|
||||
|
||||
if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrFutureRev {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrFutureRev)
|
||||
if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrGRPCFutureRev {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCFutureRev)
|
||||
}
|
||||
|
||||
// compacted rev
|
||||
tv, _ := txn.Success[1].Request.(*pb.RequestUnion_RequestRange)
|
||||
tv.RequestRange.Revision = 1
|
||||
if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrCompacted {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrCompacted)
|
||||
if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrGRPCCompacted {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCCompacted)
|
||||
}
|
||||
}
|
||||
|
||||
@ -527,8 +527,8 @@ func TestV3TooLargeRequest(t *testing.T) {
|
||||
preq := &pb.PutRequest{Key: []byte("foo"), Value: largeV}
|
||||
|
||||
_, err := kvc.Put(context.Background(), preq)
|
||||
if err != rpctypes.ErrRequestTooLarge {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrRequestTooLarge)
|
||||
if err != rpctypes.ErrGRPCRequestTooLarge {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCRequestTooLarge)
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,8 +581,8 @@ func TestV3StorageQuotaAPI(t *testing.T) {
|
||||
// test big put
|
||||
bigbuf := make([]byte, 64*1024)
|
||||
_, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: key, Value: bigbuf})
|
||||
if err == nil || err != rpctypes.ErrNoSpace {
|
||||
t.Fatalf("big put got %v, expected %v", err, rpctypes.ErrNoSpace)
|
||||
if err == nil || err != rpctypes.ErrGRPCNoSpace {
|
||||
t.Fatalf("big put got %v, expected %v", err, rpctypes.ErrGRPCNoSpace)
|
||||
}
|
||||
|
||||
// test big txn
|
||||
@ -597,8 +597,8 @@ func TestV3StorageQuotaAPI(t *testing.T) {
|
||||
txnreq := &pb.TxnRequest{}
|
||||
txnreq.Success = append(txnreq.Success, puttxn)
|
||||
_, txnerr := kvc.Txn(context.TODO(), txnreq)
|
||||
if txnerr == nil || err != rpctypes.ErrNoSpace {
|
||||
t.Fatalf("big txn got %v, expected %v", err, rpctypes.ErrNoSpace)
|
||||
if txnerr == nil || err != rpctypes.ErrGRPCNoSpace {
|
||||
t.Fatalf("big txn got %v, expected %v", err, rpctypes.ErrGRPCNoSpace)
|
||||
}
|
||||
}
|
||||
|
||||
@ -696,8 +696,8 @@ func TestV3AlarmDeactivate(t *testing.T) {
|
||||
key := []byte("abc")
|
||||
smallbuf := make([]byte, 512)
|
||||
_, err := kvc.Put(context.TODO(), &pb.PutRequest{Key: key, Value: smallbuf})
|
||||
if err == nil && err != rpctypes.ErrNoSpace {
|
||||
t.Fatalf("put got %v, expected %v", err, rpctypes.ErrNoSpace)
|
||||
if err == nil && err != rpctypes.ErrGRPCNoSpace {
|
||||
t.Fatalf("put got %v, expected %v", err, rpctypes.ErrGRPCNoSpace)
|
||||
}
|
||||
|
||||
alarmReq.Action = pb.AlarmRequest_DEACTIVATE
|
||||
|
@ -106,7 +106,7 @@ func TestV3LeaseGrantByID(t *testing.T) {
|
||||
lresp, err = toGRPC(clus.RandClient()).Lease.LeaseGrant(
|
||||
context.TODO(),
|
||||
&pb.LeaseGrantRequest{ID: 1, TTL: 1})
|
||||
if err != rpctypes.ErrLeaseExist {
|
||||
if err != rpctypes.ErrGRPCLeaseExist {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@ -242,8 +242,8 @@ func TestV3PutOnNonExistLease(t *testing.T) {
|
||||
badLeaseID := int64(0x12345678)
|
||||
putr := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar"), Lease: badLeaseID}
|
||||
_, err := toGRPC(clus.RandClient()).KV.Put(ctx, putr)
|
||||
if err != rpctypes.ErrLeaseNotFound {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrCompacted)
|
||||
if err != rpctypes.ErrGRPCLeaseNotFound {
|
||||
t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCCompacted)
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,7 +424,7 @@ func leaseExist(t *testing.T, clus *ClusterV3, leaseID int64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if err == rpctypes.ErrLeaseExist {
|
||||
if err == rpctypes.ErrGRPCLeaseExist {
|
||||
return true
|
||||
}
|
||||
t.Fatalf("unexpecter error %v", err)
|
||||
|
2
test
2
test
@ -28,7 +28,7 @@ ln -s ${PWD}/cmd/vendor $GOPATH/src
|
||||
|
||||
# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt.
|
||||
PKGS=`ls pkg/*/*go | cut -f1,2 -d/ | sort | uniq`
|
||||
TESTABLE_AND_FORMATTABLE="auth client clientv3 discovery error etcdctl/ctlv2 etcdctl/ctlv3 etcdmain etcdserver etcdserver/auth etcdserver/api/v2http etcdserver/api/v2http/httptypes $PKGS proxy/httpproxy proxy/tcpproxy raft snap mvcc mvcc/backend store version wal rafthttp"
|
||||
TESTABLE_AND_FORMATTABLE="auth client clientv3 discovery error etcdctl/ctlv2 etcdctl/ctlv3 etcdmain etcdserver etcdserver/auth etcdserver/api/v2http etcdserver/api/v2http/httptypes etcdserver/api/v3rpc etcdserver/api/v3rpc/rpctypes $PKGS proxy/httpproxy proxy/tcpproxy raft snap mvcc mvcc/backend store version wal rafthttp"
|
||||
FORMATTABLE="$TESTABLE_AND_FORMATTABLE *.go etcdctl/ integration clientv3/integration e2e alarm"
|
||||
|
||||
# user has not provided PKG override
|
||||
|
Loading…
x
Reference in New Issue
Block a user