github.com/cloudwego/kitex@v0.9.0/pkg/remote/trans/nphttp2/grpc/flowcontrol_test.go (about) 1 /* 2 * Copyright 2022 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package grpc 18 19 import ( 20 "math" 21 "testing" 22 "time" 23 24 "github.com/cloudwego/kitex/internal/test" 25 ) 26 27 func TestWriteQuota(t *testing.T) { 28 // init 29 quotaLimit := int32(100) 30 done := make(chan struct{}) 31 32 // test newWriteQuota() 33 wq := newWriteQuota(quotaLimit, done) 34 35 // test get() and less than quotaLimit 36 err := wq.get(80) 37 test.Assert(t, err == nil, err) 38 39 // test realReplenish() to refresh quotaLimit 40 wq.realReplenish(80) 41 test.Assert(t, wq.quota == quotaLimit) 42 43 // test get() in block situation 44 go func() { 45 time.Sleep(time.Millisecond * 50) 46 wq.replenish(40) 47 }() 48 err = wq.get(120) 49 test.Assert(t, err == nil, err) 50 51 // test get() after block and replenish 52 err = wq.get(20) 53 test.Assert(t, err == nil, err) 54 55 // test stop writeQuota by channel 56 go func() { 57 time.Sleep(time.Millisecond * 50) 58 var s struct{} 59 done <- s 60 }() 61 err = wq.get(20) 62 test.Assert(t, err == errStreamDone) 63 } 64 65 func TestTrInFlow(t *testing.T) { 66 // init 67 oldLimit := uint32(100) 68 trInFlow := &trInFlow{limit: oldLimit} 69 limit := 2 * oldLimit 70 71 // test newLimit() 72 delta := trInFlow.newLimit(limit) 73 test.Assert(t, delta == oldLimit) 74 75 // test onData() but unacked is less than 1/4 limit 76 increase := trInFlow.onData(limit / 10) 77 test.Assert(t, increase == 0) 78 79 // test onData() and unacked is more than 1/4 limit 80 increase = trInFlow.onData(limit / 2) 81 test.Assert(t, increase == limit/2+limit/10) 82 83 // test reset() 84 increase = trInFlow.onData(limit / 5) 85 test.Assert(t, increase == 0) 86 increase = trInFlow.reset() 87 test.Assert(t, increase == limit/5) 88 } 89 90 func TestInFlow(t *testing.T) { 91 // init 92 oldLimit := uint32(100) 93 inFlow := &inFlow{limit: oldLimit} 94 limit := oldLimit * 2 95 96 // test newLimit() 97 inFlow.newLimit(limit) 98 test.Assert(t, inFlow.limit == limit) 99 100 // test empty onData() 101 err := inFlow.onData(0) 102 test.Assert(t, err == nil, err) 103 104 // test empty onRead() 105 increase := inFlow.onRead(0) 106 test.Assert(t, increase == 0) 107 108 // test onData() 109 err = inFlow.onData(limit) 110 test.Assert(t, err == nil, err) 111 112 // test onRead() 113 size := inFlow.onRead(limit) 114 test.Assert(t, size == limit) 115 116 // test onData() illegal situation 117 err = inFlow.onData(limit * 2) 118 test.Assert(t, err != nil) 119 120 // test maybeAdjust() no adjust 121 adjustNum := inFlow.maybeAdjust(0) 122 test.Assert(t, adjustNum == 0) 123 124 // test maybeAdjust() do adjust 125 adjustNum = inFlow.maybeAdjust(limit * 2) 126 test.Assert(t, adjustNum == limit*2) 127 128 // test maybeAdjust() maxSize adjust (f.delta - limit) 129 adjustNum = inFlow.maybeAdjust(math.MaxInt32 + 1) 130 test.Assert(t, adjustNum == math.MaxInt32-limit) 131 }