MCPcopy
hub / github.com/keploy/keploy / PerformFuzzyMatch

Method PerformFuzzyMatch

pkg/agent/proxy/integrations/http/match.go:828–890  ·  view source on GitHub ↗

PerformFuzzyMatch performs fuzzy matching on the request body. Noisy (obfuscated) values are stripped from mock bodies before computing similarity so that redacted padding doesn't skew the score.

(tcsMocks []*models.Mock, reqBuff []byte)

Source from the content-addressed store, hash-verified

826// Noisy (obfuscated) values are stripped from mock bodies before computing
827// similarity so that redacted padding doesn't skew the score.
828func (h *HTTP) PerformFuzzyMatch(tcsMocks []*models.Mock, reqBuff []byte) (bool, *models.Mock) {
829 // Log all mock names in a single line for better readability
830 mockNames := make([]string, len(tcsMocks))
831 for i, mock := range tcsMocks {
832 mockNames[i] = mock.Name
833 }
834 h.Logger.Debug("mocks under consideration for performfuzzyMatch function", zap.Strings("mock names", mockNames))
835
836 encodedReq := encode(reqBuff)
837 for _, mock := range tcsMocks {
838 encodedMock, _ := decode(mock.Spec.HTTPReq.Body)
839 if string(encodedMock) == string(reqBuff) || mock.Spec.HTTPReq.Body == encodedReq {
840 h.Logger.Debug("http mock matched",
841 zap.String("mock", mock.Name),
842 zap.Float64("match_percentage", 100.0),
843 zap.String("match_type", "fuzzy_exact"))
844 return true, mock
845 }
846 }
847
848 // Build mock body strings, stripping noisy values for fair comparison
849 mockStrings := make([]string, len(tcsMocks))
850 for i := range tcsMocks {
851 nc := util.NewNoiseChecker(tcsMocks[i].Noise)
852 mockStrings[i] = util.StripNoisyJSON(tcsMocks[i].Spec.HTTPReq.Body, nc)
853 }
854
855 // String-based fuzzy matching (Levenshtein distance)
856 reqStr := string(reqBuff)
857 if util.IsASCII(reqStr) {
858 idx, dist := h.findStringMatch(reqStr, mockStrings)
859 if idx != -1 {
860 maxLen := len(reqStr)
861 if len(mockStrings[idx]) > maxLen {
862 maxLen = len(mockStrings[idx])
863 }
864 pct := 0.0
865 if maxLen > 0 {
866 pct = (1.0 - float64(dist)/float64(maxLen)) * 100
867 }
868 h.Logger.Debug("http mock matched",
869 zap.String("mock", tcsMocks[idx].Name),
870 zap.Float64("match_percentage", pct),
871 zap.String("match_type", "fuzzy_levenshtein"))
872 return true, tcsMocks[idx]
873 }
874 }
875
876 // Binary fuzzy matching (Jaccard similarity) with stripped mock bodies
877 mockBodies := make([][]byte, len(mockStrings))
878 for i := range mockStrings {
879 mockBodies[i] = []byte(mockStrings[i])
880 }
881 mxIdx, mxSim := h.jaccardBestMatch(mockBodies, reqBuff)
882 if mxIdx != -1 {
883 h.Logger.Debug("http mock matched",
884 zap.String("mock", tcsMocks[mxIdx].Name),
885 zap.Float64("match_percentage", mxSim*100),

Callers 1

matchMethod · 0.95

Calls 9

findStringMatchMethod · 0.95
jaccardBestMatchMethod · 0.95
NewNoiseCheckerFunction · 0.92
StripNoisyJSONFunction · 0.92
IsASCIIFunction · 0.92
encodeFunction · 0.85
decodeFunction · 0.85
DebugMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected