h2non / gock

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

Home Page:https://pkg.go.dev/github.com/h2non/gock

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

gock issue while mocking Prometheus with URL escaped query parameters

Ahmad-Faizan opened this issue · comments

It seems there is an issue while mocking Prometheus URLs with gock.
Prometheus URLs contain a query which is written in PromQL. The resulting URLs look similar to http://localhost:9090/api/v1/query?query=scalar(anyMetric)

This test fails as long as the MatchParam() is present in Line 18 in main_test.go

// file : main.go

package main

import (
	"log"
	"net/http"
	"net/url"
)

func main() {

	err := fetchMetrics()
	log.Println(err)
}

func fetchMetrics() error {
	promURL := &url.URL{
		Scheme: "http",
		Host:   "prometheus-k8s.monitoring:9090",
		Path:   "/api/v1/query",
	}
	q := promURL.Query()
	q.Set("query", "scalar(testMetric)")
	promURL.RawQuery = q.Encode()

	resp, err := http.Get(promURL.String())
	if err != nil || resp.StatusCode != http.StatusOK {
		return err
	}

	return nil
}
// file : main_test.go

package main

import (
	"log"
	"net/url"
	"testing"

	"gopkg.in/h2non/gock.v1"
)

func TestFetchMetrics(t *testing.T) {
	defer gock.Off()

	promQuery := "scalar(testMetric)"

	gock.New("http://prometheus-k8s.monitoring:9090").
		Get("/api/v1/query").
		MatchParam("query", url.QueryEscape(promQuery)).
		// MatchParam("query", promQuery).
		Reply(200)

	err := fetchMetrics()
	if err != nil {
		log.Println(err)
		t.Fail()
	}

}

I tried passing promQuery variable as a normal string as well as a URL encoded string but the test fails in both the scenarios.
Test command -

go test -count 1 -v .

Is this a issue due to gock ?

Same happened when I try to match param of date type.
Encoded value: 2023-09-23T01%3A28%3A16%2B02%3A00
String value: 2023-09-23T01:28:16+02:00

Hello @Ahmad-Faizan @denizgursoy

gock uses regexp.MatchString() to match query parameters (code).

Any chars that have a special meaning in a regular expression, like (, ) or +, need to be escaped:

// ...
MatchParam("query", `scalar\(testMetric\)`)
// ...

I just learnt that regexp.QuoteMeta method can be used escape special characters in a reqular expression