SimulateGRPC simulates a gRPC call and returns the response This is a simplified version using gRPC client instead of manual HTTP/2 frame handling dialTCPWithConnRefusedRetry dials authority over TCP, retrying a pure connection-refused (the app is still coming up) up to maxConnRefusedRetries with th
(ctx context.Context, logger *zap.Logger, authority string)
| 540 | // zero mocks, so the re-dial is idempotent; any other dial error, exhaustion of |
| 541 | // the attempts, or a cancelled context returns immediately. |
| 542 | func dialTCPWithConnRefusedRetry(ctx context.Context, logger *zap.Logger, authority string) (net.Conn, error) { |
| 543 | for attempt := 0; ; attempt++ { |
| 544 | conn, err := net.Dial("tcp", authority) |
| 545 | if err == nil { |
| 546 | return conn, nil |
| 547 | } |
| 548 | if attempt >= maxConnRefusedRetries || !isPreResponseConnRefused(err) { |
| 549 | return nil, err |
| 550 | } |
| 551 | logger.Debug("gRPC dial refused; the app may still be coming up — retrying", |
| 552 | zap.Int("attempt", attempt+1), zap.Int("maxRetries", maxConnRefusedRetries), zap.Error(err)) |
| 553 | select { |
| 554 | case <-ctx.Done(): |
| 555 | return nil, ctx.Err() |
| 556 | case <-time.After(connRefusedRetryBackoff * time.Duration(attempt+1)): |
| 557 | } |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | func SimulateGRPC(ctx context.Context, tc *models.TestCase, testSetID string, logger *zap.Logger, cfg SimulationConfig) (*models.GrpcResp, error) { |
| 562 | if strings.Contains(tc.HTTPReq.URL, "%7B") { // case in which URL string has encoded template placeholders |