Skip to content

Commit

Permalink
feat: add Spec(s) operations
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentsenta committed Sep 7, 2023
1 parent bdeb1a9 commit 3c0faab
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 14 deletions.
13 changes: 12 additions & 1 deletion tests/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ import (
"testing"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/test"
)

func logGatewayURL(t *testing.T) {
tooling.LogMetadata(t, struct {
GatewayURL string `json:"gateway_url"`
SubdomainGatewayURL string `json:"subdomain_gateway_url"`
}{
GatewayURL: test.GatewayURL,
SubdomainGatewayURL: test.SubdomainGatewayURL,
})
}

func TestMetadata(t *testing.T) {
tooling.LogVersion(t)
tooling.LogJobURL(t)
tooling.LogGatewayURL(t)
logGatewayURL(t)
}
4 changes: 3 additions & 1 deletion tests/path_gateway_dag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestGatewayJsonCbor(t *testing.T) {
},
{
Name: "GET UnixFS file with JSON bytes is returned with application/json Content-Type - with headers",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#accept-request-header",
Hint: `
## Quick regression check for JSON stored on UnixFS:
## it has nothing to do with DAG-JSON and JSON codecs,
Expand Down Expand Up @@ -467,7 +468,7 @@ func TestNativeDag(t *testing.T) {
Response: Expect().
Headers(
Header("Content-Type").Hint("expected Content-Type").Equals("application/vnd.ipld.dag-{{format}}", row.Format),
Header("Content-Length").Hint("includes Content-Length").Equals("{{length}}", len(dagTraversal.RawData())),
Header("Content-Length").Spec("specs.ipfs.tech/http-gateways/path-gateway/#content-disposition-response-header").Hint("includes Content-Length").Equals("{{length}}", len(dagTraversal.RawData())),
Header("Content-Disposition").Hint("includes Content-Disposition").Contains(`{{disposition}}; filename="{{cid}}.{{format}}"`, row.Disposition, dagTraversalCID, row.Format),
Header("X-Content-Type-Options").Hint("includes nosniff hint").Contains("nosniff"),
),
Expand Down Expand Up @@ -541,6 +542,7 @@ func TestNativeDag(t *testing.T) {
},
{
Name: Fmt("HEAD {{name}} with only-if-cached for missing block returns HTTP 412 Precondition Failed", row.Name),
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#only-if-cached",
Request: Request().
Path("/ipfs/{{cid}}", missingCID).
Header("Cache-Control", "only-if-cached").
Expand Down
1 change: 1 addition & 0 deletions tests/path_gateway_tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func TestTar(t *testing.T) {
},
{
Name: "GET TAR with explicit ?filename= succeeds with modified Content-Disposition header",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#content-disposition-response-header",
Request: Request().
Path("/ipfs/{{cid}}", dirCID).
Query("filename", "testтест.tar").
Expand Down
6 changes: 6 additions & 0 deletions tests/path_gateway_unixfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ func TestGatewayCache(t *testing.T) {
// ==========
{
Name: "GET for /ipfs/ file with matching Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/root4/index.html", fixture.MustGetCid()).
Headers(
Expand All @@ -209,6 +210,7 @@ func TestGatewayCache(t *testing.T) {
},
{
Name: "GET for /ipfs/ dir with index.html file with matching Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/root4/", fixture.MustGetCid()).
Headers(
Expand All @@ -219,6 +221,7 @@ func TestGatewayCache(t *testing.T) {
},
{
Name: "GET for /ipfs/ file with matching third Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/root4/index.html", fixture.MustGetCid()).
Headers(
Expand All @@ -229,6 +232,7 @@ func TestGatewayCache(t *testing.T) {
},
{
Name: "GET for /ipfs/ file with matching weak Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/root4/index.html", fixture.MustGetCid()).
Headers(
Expand All @@ -239,6 +243,7 @@ func TestGatewayCache(t *testing.T) {
},
{
Name: "GET for /ipfs/ file with wildcard Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/root4/index.html", fixture.MustGetCid()).
Headers(
Expand All @@ -249,6 +254,7 @@ func TestGatewayCache(t *testing.T) {
},
{
Name: "GET for /ipfs/ dir listing with matching weak Etag in If-None-Match returns 304 Not Modified",
Spec: "specs.ipfs.tech/http-gateways/path-gateway/#if-none-match-request-header",
Request: Request().
Path("/ipfs/{{cid}}/root2/root3/", fixture.MustGetCid()).
Headers(
Expand Down
6 changes: 5 additions & 1 deletion tests/redirects_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/url"
"testing"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/car"
. "github.com/ipfs/gateway-conformance/tooling/check"
"github.com/ipfs/gateway-conformance/tooling/dnslink"
Expand All @@ -14,6 +15,7 @@ import (
)

func TestRedirectsFileSupport(t *testing.T) {
tooling.LogSpecs(t, "specs.ipfs.tech/http-gateways/web-redirects-file/")
fixture := car.MustOpenUnixfsCar("redirects_file/redirects.car")
redirectDir := fixture.MustGetNode("examples")
redirectDirCID := redirectDir.Base32Cid()
Expand Down Expand Up @@ -164,7 +166,8 @@ func TestRedirectsFileSupport(t *testing.T) {
Contains("could not parse _redirects:"),
Contains(`forced redirects (or "shadowing") are not supported`),
),
),
).Spec("specs.ipfs.tech/http-gateways/web-redirects-file/#no-forced-redirects"),
Spec: "specs.ipfs.tech/http-gateways/web-redirects-file/#error-handling",
},
{
Name: "invalid file: request for $TOO_LARGE_REDIRECTS_DIR_HOSTNAME/not-found returns error about too large redirects file",
Expand All @@ -179,6 +182,7 @@ func TestRedirectsFileSupport(t *testing.T) {
Contains("redirects file size cannot exceed"),
),
),
Spec: "specs.ipfs.tech/http-gateways/web-redirects-file/#max-file-size",
},
}...)

Expand Down
3 changes: 3 additions & 0 deletions tests/trustless_gateway_car_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tests
import (
"testing"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/car"
. "github.com/ipfs/gateway-conformance/tooling/check"
"github.com/ipfs/gateway-conformance/tooling/helpers"
Expand Down Expand Up @@ -398,6 +399,8 @@ func TestTrustlessCarDagScopeAll(t *testing.T) {
}

func TestTrustlessCarEntityBytes(t *testing.T) {
tooling.LogSpecs(t, "specs.ipfs.tech/http-gateways/trustless-gateway/#entity-bytes-request-query-parameter")

singleLayerHamtMultiBlockFilesFixture := car.MustOpenUnixfsCar("trustless_gateway_car/single-layer-hamt-with-multi-block-files.car")
subdirWithMixedBlockFiles := car.MustOpenUnixfsCar("trustless_gateway_car/subdir-with-mixed-block-files.car")
missingBlockFixture := car.MustOpenUnixfsCar("trustless_gateway_car/file-3k-and-3-blocks-missing-block.car")
Expand Down
6 changes: 5 additions & 1 deletion tests/trustless_gateway_raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"strings"
"testing"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/car"
. "github.com/ipfs/gateway-conformance/tooling/check"
"github.com/ipfs/gateway-conformance/tooling/specs"
. "github.com/ipfs/gateway-conformance/tooling/test"
)

func TestTrustlessRaw(t *testing.T) {
tooling.LogSpecs(t, "specs.ipfs.tech/http-gateways/trustless-gateway/#block-responses-application-vnd-ipld-raw")
fixture := car.MustOpenUnixfsCar("gateway-raw-block.car")

tests := SugarTests{
Expand Down Expand Up @@ -128,6 +130,8 @@ func TestTrustlessRaw(t *testing.T) {
}

func TestTrustlessRawRanges(t *testing.T) {
// @lidel: "The optional entity-bytes=from:to parameter is available only for CAR requests."

// Multi-range requests MUST conform to the HTTP semantics. The server does not
// need to be able to support returning multiple ranges. However, it must respond
// correctly.
Expand All @@ -140,7 +144,7 @@ func TestTrustlessRawRanges(t *testing.T) {

RunWithSpecs(t, SugarTests{
{
Name: "GETaa with application/vnd.ipld.raw with single range request includes correct bytes",
Name: "GET with application/vnd.ipld.raw with single range request includes correct bytes",
Request: Request().
Path("/ipfs/{{cid}}", fixture.MustGetCid("dir", "ascii.txt")).
Headers(
Expand Down
14 changes: 7 additions & 7 deletions tooling/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package tooling
import (
"encoding/json"
"testing"

"github.com/ipfs/gateway-conformance/tooling/test"
)

func LogMetadata(t *testing.T, value interface{}) {
Expand Down Expand Up @@ -34,12 +32,14 @@ func LogJobURL(t *testing.T) {
})
}

func LogGatewayURL(t *testing.T) {
func LogSpecs(t *testing.T, specs ...string) {
if len(specs) == 0 {
return
}

Check warning on line 38 in tooling/metadata.go

View check run for this annotation

Codecov / codecov/patch

tooling/metadata.go#L35-L38

Added lines #L35 - L38 were not covered by tests

LogMetadata(t, struct {
GatewayURL string `json:"gateway_url"`
SubdomainGatewayURL string `json:"subdomain_gateway_url"`
Specs []string `json:"specs"`

Check warning on line 41 in tooling/metadata.go

View check run for this annotation

Codecov / codecov/patch

tooling/metadata.go#L41

Added line #L41 was not covered by tests
}{
GatewayURL: test.GatewayURL,
SubdomainGatewayURL: test.SubdomainGatewayURL,
Specs: specs,

Check warning on line 43 in tooling/metadata.go

View check run for this annotation

Codecov / codecov/patch

tooling/metadata.go#L43

Added line #L43 was not covered by tests
})
}
22 changes: 22 additions & 0 deletions tooling/test/sugar.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ type ExpectBuilder struct {
StatusCode_ int `json:"statusCode,omitempty"`
Headers_ []HeaderBuilder `json:"headers,omitempty"`
Body_ interface{} `json:"body,omitempty"`
Specs_ []string `json:"specs,omitempty"`
}

func Expect() ExpectBuilder {
Expand All @@ -157,6 +158,16 @@ func (e ExpectBuilder) Header(h HeaderBuilder) ExpectBuilder {
return e
}

func (e ExpectBuilder) Spec(spec string) ExpectBuilder {
e.Specs_ = []string{spec}
return e
}

func (e ExpectBuilder) Specs(specs ...string) ExpectBuilder {
e.Specs_ = specs
return e
}

func (e ExpectBuilder) Bytes(body string) ExpectBuilder {
e.Body_ = []byte(body)
return e
Expand Down Expand Up @@ -213,6 +224,7 @@ type HeaderBuilder struct {
Value_ string `json:"value,omitempty"`
Check_ check.Check[[]string] `json:"check,omitempty"`
Hint_ string `json:"hint,omitempty"`
Specs_ []string `json:"specs,omitempty"`
Not_ bool `json:"not,omitempty"`
}

Expand Down Expand Up @@ -245,6 +257,16 @@ func (h HeaderBuilder) Hint(hint string) HeaderBuilder {
return h
}

func (h HeaderBuilder) Specs(specs ...string) HeaderBuilder {
h.Specs_ = specs
return h
}

func (h HeaderBuilder) Spec(spec string) HeaderBuilder {
h.Specs_ = []string{spec}
return h
}

func (h HeaderBuilder) Equals(value string, args ...any) HeaderBuilder {
h.Check_ = check.IsUniqAnd(check.IsEqual(value, args...))
return h
Expand Down
21 changes: 21 additions & 0 deletions tooling/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import (
"testing"
"time"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/specs"
)

type SugarTest struct {
Name string
Hint string
Spec string
Specs []string
Request RequestBuilder
Requests []RequestBuilder
Response ExpectBuilder
Expand All @@ -20,6 +23,22 @@ type SugarTest struct {

type SugarTests []SugarTest

func (s *SugarTest) AllSpecs() []string {
if len(s.Specs) > 0 && s.Spec != "" {
panic("cannot have both Spec and Specs")
}

if len(s.Specs) > 0 {
return s.Specs
}

if s.Spec != "" {
return []string{s.Spec}
}

return []string{}
}

func RunWithSpecs(
t *testing.T,
tests SugarTests,
Expand Down Expand Up @@ -51,6 +70,7 @@ func run(t *testing.T, tests SugarTests) {

if len(test.Requests) > 0 {
t.Run(test.Name, func(t *testing.T) {
tooling.LogSpecs(t, test.AllSpecs()...)
responses := make([]*http.Response, 0, len(test.Requests))

for _, req := range test.Requests {
Expand All @@ -63,6 +83,7 @@ func run(t *testing.T, tests SugarTests) {
})
} else {
t.Run(test.Name, func(t *testing.T) {
tooling.LogSpecs(t, test.AllSpecs()...)
_, res, localReport := runRequest(timeout, t, test, test.Request)
validateResponse(t, test.Response, res, localReport)
})
Expand Down
11 changes: 8 additions & 3 deletions tooling/test/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"testing"

"github.com/ipfs/gateway-conformance/tooling"
"github.com/ipfs/gateway-conformance/tooling/check"
)

Expand All @@ -16,15 +17,19 @@ func validateResponse(
localReport Reporter,
) {
t.Helper()
tooling.LogSpecs(t, expected.Specs_...)

if expected.StatusCode_ != 0 {
if res.StatusCode != expected.StatusCode_ {
localReport(t, "Status code is not %d. It is %d", expected.StatusCode_, res.StatusCode)
}
t.Run("Status code", func(t *testing.T) {
if res.StatusCode != expected.StatusCode_ {
localReport(t, "Status code is not %d. It is %d", expected.StatusCode_, res.StatusCode)
}
})
}

for _, header := range expected.Headers_ {
t.Run(fmt.Sprintf("Header %s", header.Key_), func(t *testing.T) {
tooling.LogSpecs(t, header.Specs_...)
actual := res.Header.Values(header.Key_)

c := header.Check_
Expand Down

0 comments on commit 3c0faab

Please sign in to comment.