MCPcopy
hub / github.com/keploy/keploy / SimulateGRPC

Function SimulateGRPC

pkg/http2.go:561–766  ·  view source on GitHub ↗
(ctx context.Context, tc *models.TestCase, testSetID string, logger *zap.Logger, cfg SimulationConfig)

Source from the content-addressed store, hash-verified

559}
560
561func 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
563 decoded, err := url.QueryUnescape(tc.HTTPReq.URL)
564 if err == nil {
565 tc.HTTPReq.URL = decoded
566 }
567 }
568 // Render any template values in the test case before simulation
569 templateData := buildTemplateDataSnapshot()
570 if len(templateData) > 0 {
571 testCaseBytes, err := json.Marshal(tc)
572 if err != nil {
573 utils.LogError(logger, err, "failed to marshal the testcase for templating")
574 return nil, err
575 }
576
577 // Render only real Keploy placeholders ({{ .x }}, {{ string .y }}, etc.),
578 // ignoring LaTeX/HTML like {{\pi}}.
579 renderedStr, rerr := utils.RenderTemplatesInString(logger, string(testCaseBytes), templateData)
580 if rerr != nil {
581 logger.Debug("template rendering had recoverable errors", zap.Error(rerr))
582 }
583
584 err = json.Unmarshal([]byte(renderedStr), &tc)
585 if err != nil {
586 utils.LogError(logger, err, "failed to unmarshal the rendered testcase")
587 return nil, err
588 }
589 }
590
591 grpcReq := tc.GrpcReq
592
593 logger.Info("starting test for", zap.String("test case", models.HighlightString(tc.Name)), zap.String("test set", models.HighlightString(testSetID)))
594
595 // Extract target address from headers
596 authority, ok := grpcReq.Headers.PseudoHeaders[":authority"]
597 if !ok {
598 return nil, fmt.Errorf("missing :authority header")
599 }
600
601 // Determine which port to use for test execution.
602 var err error
603 authority, err = ResolveTestTarget(authority, cfg.URLReplacements, cfg.PortMappings, cfg.ConfigHost, tc.AppPort, cfg.ConfigPort, false, logger)
604 if err != nil {
605 return nil, err
606 }
607
608 // Extract method path
609 path, ok := grpcReq.Headers.PseudoHeaders[":path"]
610 if !ok {
611 return nil, fmt.Errorf("missing :path header")
612 }
613
614 // Create a TCP connection, retrying a pure connection-refused. A slow-starting
615 // gRPC app (especially a docker app under CI load) can briefly refuse
616 // connections while still coming up; a refused dial sent zero bytes and
617 // consumed zero mocks, so the re-dial is safe. Mirrors the HTTP replay path's
618 // doRequestWithConnRefusedRetry — a genuinely-down app still fails fast after

Callers 1

SimulateRequestMethod · 0.92

Calls 13

LogErrorFunction · 0.92
RenderTemplatesInStringFunction · 0.92
ResolveTestTargetFunction · 0.85
MarshalMethod · 0.80
UnmarshalMethod · 0.80
DebugMethod · 0.65
CloseMethod · 0.65
NewMethod · 0.65
ErrorMethod · 0.45

Tested by

no test coverage detected