diff --git a/README.md b/README.md index a61b0452f..7b35c847e 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,7 @@ docker run --rm -v "${PWD}:/workspace" ghcr.io/pl-strflt/junit-xml-to-html:lates ```bash docker run --network host -w "/workspace" -v "${PWD}:/workspace" ghcr.io/ipfs/gateway-conformance merge-fixtures /workspace/[output-car] ``` + +## Working on the Test Suite + +Set the environment variable `GOLOG_LOG_LEVEL="conformance=debug"` to toggle debug logging. diff --git a/tests/t0114_gateway_subdomains_test.go b/tests/t0114_gateway_subdomains_test.go index 4d899c32e..a1d83414e 100644 --- a/tests/t0114_gateway_subdomains_test.go +++ b/tests/t0114_gateway_subdomains_test.go @@ -13,44 +13,28 @@ import ( func TestGatewaySubdomains(t *testing.T) { // fixture := car.MustOpenUnixfsCar("t0114-gateway_subdomains") - - CID_VAL := "hello" CIDv1 := "bafkreicysg23kiwv34eg2d7qweipxwosdo2py4ldv42nbauguluen5v6am" - // CIDv0 := "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" - // // CIDv0to1 is necessary because raw-leaves are enabled by default during - // // "ipfs add" with CIDv1 and disabled with CIDv0 - // CIDv0to1 := "bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4" - // CIDv1_TOO_LONG := "bafkrgqhhyivzstcz3hhswshfjgy6ertgmnqeleynhwt4dlfsthi4hn7zgh4uvlsb5xncykzapi3ocd4lzogukir6ksdy6wzrnz6ohnv4aglcs" - DIR_CID := "bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe" // ./testdirlisting + DIR_CID := "bafybeiht6dtwk3les7vqm6ibpvz6qpohidvlshsfyr7l5mpysdw2vmbbhe" tests := []CTest{ { - Name: "request for 127.0.0.1/ipfs/{CID} stays on path", - Request: CRequest{ - Url: fmt.Sprintf("ipfs/%s", CIDv1), - }, - Response: CResponse{ - StatusCode: 200, - Body: Contains(CID_VAL), - }, - }, - { - Name: "request for localhost/ipfs/{CIDv1} returns HTTP 301 Moved Permanently", + Name: "request for {gateway}/ipfs/{CIDv1} returns HTTP 301 Moved Permanently", Request: CRequest{ DoNotFollowRedirects: true, - Url: fmt.Sprintf("/ipfs/%s", CIDv1), + RawURL: fmt.Sprintf("http://%s/ipfs/%s", SubdomainGatewayHost, CIDv1), + // Url: fmt.Sprintf("ipfs/%s", CIDv1), }, Response: CResponse{ StatusCode: 301, Headers: map[string]interface{}{ - "Location": Contains("http://%s.ipfs.localhost:8080", CIDv1), + "Location": Contains("http://%s.ipfs.%s", CIDv1, SubdomainGatewayHost), }, }, }, { Name: "request for {cid}.ipfs.localhost/api returns data if present on the content root", Request: CRequest{ - RawURL: fmt.Sprintf("http://%s.ipfs.localhost:8080/api/file.txt", DIR_CID), + RawURL: fmt.Sprintf("http://%s.ipfs.%s/api/file.txt", DIR_CID, SubdomainGatewayHost), }, Response: CResponse{ Body: Contains("I am a txt file"), diff --git a/tooling/test/config.go b/tooling/test/config.go new file mode 100644 index 000000000..1ec80fc77 --- /dev/null +++ b/tooling/test/config.go @@ -0,0 +1,86 @@ +package test + +import ( + "context" + "net" + "net/http" + "net/url" + "os" + "strings" + "time" + + logging "github.com/ipfs/go-log" +) + +var log = logging.Logger("conformance") + +func GetEnv(key string, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + +var GatewayUrl = strings.TrimRight( + GetEnv("GATEWAY_URL", "http://localhost:8080"), + "/") + +var SubdomainGatewayUrl = strings.TrimRight( + GetEnv("SUBDOMAIN_GATEWAY_URL", "http://example.com:8080"), + "/") + +var GatewayHost = "" +var SubdomainGatewayHost = "" + +func init() { + parse, err := url.Parse(GatewayUrl) + if err != nil { + panic(err) + } + + GatewayHost = parse.Host + + parse, err = url.Parse(SubdomainGatewayUrl) + if err != nil { + panic(err) + } + + SubdomainGatewayHost = parse.Host + log.Debugf("SubdomainGatewayHost: %s", SubdomainGatewayHost) +} + +func NewDialer() *net.Dialer { + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + Resolver: &net.Resolver{ + PreferGo: true, + Dial: func(ctx context.Context, network, address string) (net.Conn, error) { + log.Debugf("Custom Resolver dialing into network: %s, address: %s", network, address) + + d := net.Dialer{ + Timeout: 30 * time.Second, + } + + return d.DialContext(ctx, network, address) + }, + }, + } + + http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + log.Debugf("Custom Dialer dialing into network: %s, address: %s", network, addr) + + // If we call into a subdomain `somethingsomething.example.com`, + // actually dial the gateway url on its base address (probably localhost:8080) + if strings.HasSuffix(addr, SubdomainGatewayHost) { + addr = GatewayHost + } + + log.Debugf("Custom Dialer dialing into (effective) network: %s, address: %s", network, addr) + conn, err := dialer.DialContext(ctx, network, addr) + return conn, err + } + + return dialer +} diff --git a/tooling/test/test.go b/tooling/test/test.go index 8249af099..20b02a7b7 100644 --- a/tooling/test/test.go +++ b/tooling/test/test.go @@ -5,24 +5,11 @@ import ( "fmt" "io" "net/http" - "os" - "strings" "testing" "github.com/ipfs/gateway-conformance/tooling/check" ) -func GetEnv(key string, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - -var GatewayUrl = strings.TrimRight( - GetEnv("GATEWAY_URL", "http://127.0.0.1:8080"), - "/") - type CRequest struct { Method string RawURL string @@ -44,7 +31,10 @@ type CTest struct { Response CResponse } + func Run(t *testing.T, tests []CTest) { + NewDialer() + for _, test := range tests { t.Run(test.Name, func(t *testing.T) { method := test.Request.Method