ResolveTestTarget determines the final target (URL for HTTP, Authority for gRPC) by applying replacement logic and precedence rules. Priority logic (lowest → highest): 1. AppPort (recorded port). 2. ConfigPort (top-level port/grpcPort/ssePort combined with protocol overrides). 3. replaceWith URL re
(originalTarget string, urlReplacements map[string]string, portMappings map[uint32]uint32, configHost string, appPort uint16, configPort uint32, isHTTP bool, logger *zap.Logger)
| 3833 | // 3. replaceWith URL replacements – if replacement has explicit port, skip steps 1-2. |
| 3834 | // 4. replaceWith port mappings – always applied last, overrides everything. |
| 3835 | func ResolveTestTarget(originalTarget string, urlReplacements map[string]string, portMappings map[uint32]uint32, configHost string, appPort uint16, configPort uint32, isHTTP bool, logger *zap.Logger) (string, error) { |
| 3836 | finalTarget := originalTarget |
| 3837 | replacementHasPort := false |
| 3838 | replacementMatched := false |
| 3839 | |
| 3840 | // Step 1: Check replaceWith URL |
| 3841 | if len(urlReplacements) > 0 { |
| 3842 | for substr, replacement := range urlReplacements { |
| 3843 | if strings.Contains(finalTarget, substr) { |
| 3844 | replacementMatched = true |
| 3845 | finalTarget = strings.Replace(finalTarget, substr, replacement, 1) |
| 3846 | |
| 3847 | // Check if the replacement value explicitly defines a port. |
| 3848 | checkStr := replacement |
| 3849 | if isHTTP { |
| 3850 | if strings.HasPrefix(replacement, "http://") { |
| 3851 | checkStr = strings.TrimPrefix(replacement, "http://") |
| 3852 | } else if strings.HasPrefix(replacement, "https://") { |
| 3853 | checkStr = strings.TrimPrefix(replacement, "https://") |
| 3854 | } |
| 3855 | } |
| 3856 | |
| 3857 | if hasExplicitPort(checkStr) { |
| 3858 | replacementHasPort = true |
| 3859 | } |
| 3860 | |
| 3861 | logger.Debug("Applied replaceWith substitution", |
| 3862 | zap.String("find", substr), |
| 3863 | zap.String("replace", replacement), |
| 3864 | zap.String("result_target", finalTarget), |
| 3865 | zap.Bool("replacement_has_port", replacementHasPort)) |
| 3866 | break |
| 3867 | } |
| 3868 | } |
| 3869 | } |
| 3870 | |
| 3871 | // If URL replacement set a port and there are no port mappings, we are done |
| 3872 | if replacementHasPort && len(portMappings) == 0 { |
| 3873 | return finalTarget, nil |
| 3874 | } |
| 3875 | |
| 3876 | // Step 2: ConfigHost override (only if no URL replacement match) |
| 3877 | if !replacementMatched && !replacementHasPort && configHost != "" { |
| 3878 | var err error |
| 3879 | if isHTTP { |
| 3880 | finalTarget, err = utils.ReplaceHost(finalTarget, configHost) |
| 3881 | } else { |
| 3882 | finalTarget, err = utils.ReplaceGrpcHost(finalTarget, configHost) |
| 3883 | } |
| 3884 | if err != nil { |
| 3885 | utils.LogError(logger, err, "failed to replace host with config host") |
| 3886 | return "", err |
| 3887 | } |
| 3888 | logger.Debug("Replaced host with config host", zap.String("host", configHost), zap.String("target", finalTarget)) |
| 3889 | } |
| 3890 | |
| 3891 | // Parse host and port from finalTarget |
| 3892 | var host string |