go.etcd.io/etcd@v3.3.27+incompatible/etcdserver/api/v3rpc/watch_test.go (about) 1 // Copyright 2018 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package v3rpc 16 17 import ( 18 "bytes" 19 "math" 20 "testing" 21 22 pb "github.com/coreos/etcd/etcdserver/etcdserverpb" 23 "github.com/coreos/etcd/mvcc/mvccpb" 24 ) 25 26 func TestSendFragment(t *testing.T) { 27 tt := []struct { 28 wr *pb.WatchResponse 29 maxRequestBytes int 30 fragments int 31 werr error 32 }{ 33 { // large limit should not fragment 34 wr: createResponse(100, 1), 35 maxRequestBytes: math.MaxInt32, 36 fragments: 1, 37 }, 38 { // large limit for two messages, expect no fragment 39 wr: createResponse(10, 2), 40 maxRequestBytes: 50, 41 fragments: 1, 42 }, 43 { // limit is small but only one message, expect no fragment 44 wr: createResponse(1024, 1), 45 maxRequestBytes: 1, 46 fragments: 1, 47 }, 48 { // exceed limit only when combined, expect fragments 49 wr: createResponse(11, 5), 50 maxRequestBytes: 20, 51 fragments: 5, 52 }, 53 { // 5 events with each event exceeding limits, expect fragments 54 wr: createResponse(15, 5), 55 maxRequestBytes: 10, 56 fragments: 5, 57 }, 58 { // 4 events with some combined events exceeding limits 59 wr: createResponse(10, 4), 60 maxRequestBytes: 35, 61 fragments: 2, 62 }, 63 } 64 65 for i := range tt { 66 fragmentedResp := make([]*pb.WatchResponse, 0) 67 testSend := func(wr *pb.WatchResponse) error { 68 fragmentedResp = append(fragmentedResp, wr) 69 return nil 70 } 71 err := sendFragments(tt[i].wr, tt[i].maxRequestBytes, testSend) 72 if err != tt[i].werr { 73 t.Errorf("#%d: expected error %v, got %v", i, tt[i].werr, err) 74 } 75 got := len(fragmentedResp) 76 if got != tt[i].fragments { 77 t.Errorf("#%d: expected response number %d, got %d", i, tt[i].fragments, got) 78 } 79 if got > 0 && fragmentedResp[got-1].Fragment { 80 t.Errorf("#%d: expected fragment=false in last response, got %+v", i, fragmentedResp[got-1]) 81 } 82 } 83 } 84 85 func createResponse(dataSize, events int) (resp *pb.WatchResponse) { 86 resp = &pb.WatchResponse{Events: make([]*mvccpb.Event, events)} 87 for i := range resp.Events { 88 resp.Events[i] = &mvccpb.Event{ 89 Kv: &mvccpb.KeyValue{ 90 Key: bytes.Repeat([]byte("a"), dataSize), 91 }, 92 } 93 } 94 return resp 95 }