2016-10-21 21:02:54 +03:00
// Copyright 2016 The etcd Authors
//
// 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 integration
import (
2017-09-07 00:57:25 +03:00
"context"
2017-04-14 21:11:06 +03:00
"sync"
2016-10-21 21:02:54 +03:00
"testing"
"time"
2020-04-27 00:03:37 +03:00
"go.etcd.io/etcd/v3/etcdserver/api/v3rpc/rpctypes"
pb "go.etcd.io/etcd/v3/etcdserver/etcdserverpb"
"go.etcd.io/etcd/v3/pkg/testutil"
2017-04-14 21:11:06 +03:00
"google.golang.org/grpc"
2018-07-18 23:09:27 +03:00
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
2016-10-21 21:02:54 +03:00
)
2017-04-14 21:11:06 +03:00
// TestV3MaintenanceDefragmentInflightRange ensures inflight range requests
// does not panic the mvcc backend while defragment is running.
func TestV3MaintenanceDefragmentInflightRange ( t * testing . T ) {
2016-10-21 21:02:54 +03:00
defer testutil . AfterTest ( t )
clus := NewClusterV3 ( t , & ClusterConfig { Size : 1 } )
defer clus . Terminate ( t )
cli := clus . RandClient ( )
2017-04-14 21:11:06 +03:00
kvc := toGRPC ( cli ) . KV
if _ , err := kvc . Put ( context . Background ( ) , & pb . PutRequest { Key : [ ] byte ( "foo" ) , Value : [ ] byte ( "bar" ) } ) ; err != nil {
t . Fatal ( err )
}
2016-10-21 21:02:54 +03:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , time . Second )
donec := make ( chan struct { } )
go func ( ) {
defer close ( donec )
2017-04-14 21:11:06 +03:00
kvc . Range ( ctx , & pb . RangeRequest { Key : [ ] byte ( "foo" ) } )
2016-10-21 21:02:54 +03:00
} ( )
2017-04-14 21:11:06 +03:00
mvc := toGRPC ( cli ) . Maintenance
mvc . Defragment ( context . Background ( ) , & pb . DefragmentRequest { } )
2016-10-21 21:02:54 +03:00
cancel ( )
<- donec
}
2017-03-23 19:47:13 +03:00
2017-04-14 21:11:06 +03:00
// TestV3KVInflightRangeRequests ensures that inflight requests
// (sent before server shutdown) are gracefully handled by server-side.
// They are either finished or canceled, but never crash the backend.
2018-11-10 05:10:12 +03:00
// See https://github.com/etcd-io/etcd/issues/7322 for more detail.
2017-04-14 21:11:06 +03:00
func TestV3KVInflightRangeRequests ( t * testing . T ) {
2017-03-23 19:47:13 +03:00
defer testutil . AfterTest ( t )
clus := NewClusterV3 ( t , & ClusterConfig { Size : 1 } )
defer clus . Terminate ( t )
cli := clus . RandClient ( )
kvc := toGRPC ( cli ) . KV
2017-04-14 21:11:06 +03:00
2017-03-23 19:47:13 +03:00
if _ , err := kvc . Put ( context . Background ( ) , & pb . PutRequest { Key : [ ] byte ( "foo" ) , Value : [ ] byte ( "bar" ) } ) ; err != nil {
t . Fatal ( err )
}
2017-04-14 21:11:06 +03:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , 2 * time . Second )
2017-03-23 19:47:13 +03:00
2017-04-14 21:11:06 +03:00
reqN := 10 // use 500+ for fast machine
var wg sync . WaitGroup
wg . Add ( reqN )
for i := 0 ; i < reqN ; i ++ {
go func ( ) {
defer wg . Done ( )
_ , err := kvc . Range ( ctx , & pb . RangeRequest { Key : [ ] byte ( "foo" ) , Serializable : true } , grpc . FailFast ( false ) )
2017-09-08 21:50:57 +03:00
if err != nil {
2018-07-18 23:09:27 +03:00
errCode := status . Convert ( err ) . Code ( )
2018-04-20 20:43:44 +03:00
errDesc := rpctypes . ErrorDesc ( err )
2019-07-23 18:36:54 +03:00
if err != nil && ! ( errDesc == context . Canceled . Error ( ) || errCode == codes . Canceled || errCode == codes . Unavailable ) {
t . Errorf ( "inflight request should be canceled with '%v' or code Canceled or Unavailable, got '%v' with code '%s'" , context . Canceled . Error ( ) , errDesc , errCode )
2017-09-08 21:50:57 +03:00
}
2017-04-14 21:11:06 +03:00
}
} ( )
}
2017-03-23 19:47:13 +03:00
2017-04-14 21:11:06 +03:00
clus . Members [ 0 ] . Stop ( t )
2017-03-23 19:47:13 +03:00
cancel ( )
2017-04-14 21:11:06 +03:00
wg . Wait ( )
2017-03-23 19:47:13 +03:00
}