(t *testing.T)
| 109 | } |
| 110 | |
| 111 | func (s) TestRetryThrottling(t *testing.T) { |
| 112 | serverMu := sync.Mutex{} |
| 113 | i := -1 |
| 114 | |
| 115 | ss := &stubserver.StubServer{ |
| 116 | EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) { |
| 117 | serverMu.Lock() |
| 118 | defer serverMu.Unlock() |
| 119 | i++ |
| 120 | switch i { |
| 121 | case 0, 3, 6, 10, 11, 12, 13, 14, 16, 18: |
| 122 | return &testpb.Empty{}, nil |
| 123 | } |
| 124 | return nil, status.New(codes.Unavailable, "retryable error").Err() |
| 125 | }, |
| 126 | } |
| 127 | if err := ss.Start([]grpc.ServerOption{}, |
| 128 | grpc.WithDefaultServiceConfig(`{ |
| 129 | "methodConfig": [{ |
| 130 | "name": [{"service": "grpc.testing.TestService"}], |
| 131 | "waitForReady": true, |
| 132 | "retryPolicy": { |
| 133 | "MaxAttempts": 4, |
| 134 | "InitialBackoff": ".01s", |
| 135 | "MaxBackoff": ".01s", |
| 136 | "BackoffMultiplier": 1.0, |
| 137 | "RetryableStatusCodes": [ "UNAVAILABLE" ] |
| 138 | } |
| 139 | }], |
| 140 | "retryThrottling": { |
| 141 | "maxTokens": 10, |
| 142 | "tokenRatio": 0.5 |
| 143 | } |
| 144 | }`)); err != nil { |
| 145 | t.Fatalf("Error starting endpoint server: %v", err) |
| 146 | } |
| 147 | defer ss.Stop() |
| 148 | |
| 149 | testCases := []struct { |
| 150 | wantCode codes.Code |
| 151 | wantCount int |
| 152 | }{ |
| 153 | {codes.OK, 0}, // tokens = 10 |
| 154 | {codes.OK, 3}, // tokens = 8.5 (10 - 2 failures + 0.5 success) |
| 155 | {codes.OK, 6}, // tokens = 6 |
| 156 | {codes.Unavailable, 8}, // tokens = 5 -- first attempt is retried; second aborted. |
| 157 | {codes.Unavailable, 9}, // tokens = 4 |
| 158 | {codes.OK, 10}, // tokens = 4.5 |
| 159 | {codes.OK, 11}, // tokens = 5 |
| 160 | {codes.OK, 12}, // tokens = 5.5 |
| 161 | {codes.OK, 13}, // tokens = 6 |
| 162 | {codes.OK, 14}, // tokens = 6.5 |
| 163 | {codes.OK, 16}, // tokens = 5.5 |
| 164 | {codes.Unavailable, 17}, // tokens = 4.5 |
| 165 | } |
| 166 | for _, tc := range testCases { |
| 167 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 168 | _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}) |
nothing calls this directly
no test coverage detected