Skip to content

Commit

Permalink
Schema version validation changes (#174)
Browse files Browse the repository at this point in the history
* schema version validation changes:

* schema version validation error response code changed from 500 to 400
* optional bugfix version allowed

Signed-off-by: Michael Valdron <mvaldron@redhat.com>

* schema version error status message updated to show that the version must be 2.x or higher.

Signed-off-by: Michael Valdron <mvaldron@redhat.com>

* minSchemaVersion and maxSchemaVersion query parameter test cases added

Signed-off-by: Michael Valdron <mvaldron@redhat.com>

* integration test case added for change done for minSchemaVersion and maxSchemaVersion.

Signed-off-by: Michael Valdron <mvaldron@redhat.com>

---------

Signed-off-by: Michael Valdron <mvaldron@redhat.com>
  • Loading branch information
michael-valdron committed Jun 20, 2023
1 parent 200b4f0 commit bdfb830
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 22 deletions.
28 changes: 14 additions & 14 deletions index/server/pkg/server/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,21 +428,21 @@ func buildIndexAPIResponse(c *gin.Context, wantV1Index bool) {
maxSchemaVersion := c.Query("maxSchemaVersion")
if maxSchemaVersion != "" || minSchemaVersion != "" {
// check if schema version filters are in valid format.
// should only include major and minor version. e.g. 2.1
// should include major and minor versions as well as an optional bugfix version. e.g. 2.1 or 2.1.0
if minSchemaVersion != "" {
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)$`, minSchemaVersion)
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)(\.[0-9]+)?$`, minSchemaVersion)
if !matched || err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": fmt.Sprintf("minSchemaVersion %s is not valid, should only include major and minor version. %v", minSchemaVersion, err),
c.JSON(http.StatusBadRequest, gin.H{
"status": fmt.Sprintf("minSchemaVersion %s is not valid, version format should be '+2.x' or '+2.x.x'. %v", minSchemaVersion, err),
})
return
}
}
if maxSchemaVersion != "" {
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)$`, maxSchemaVersion)
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)(\.[0-9]+)?$`, maxSchemaVersion)
if !matched || err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": fmt.Sprintf("maxSchemaVersion %s is not valid, should only include major and minor version. %v", maxSchemaVersion, err),
c.JSON(http.StatusBadRequest, gin.H{
"status": fmt.Sprintf("maxSchemaVersion %s is not valid, version format should be '+2.x' or '+2.x.x'. %v", maxSchemaVersion, err),
})
return
}
Expand Down Expand Up @@ -538,21 +538,21 @@ func fetchDevfile(c *gin.Context, name string, version string) ([]byte, indexSch
minSchemaVersion := c.Query("minSchemaVersion")
maxSchemaVersion := c.Query("maxSchemaVersion")
// check if schema version filters are in valid format.
// should only include major and minor version. e.g. 2.1
// should include major and minor versions as well as an optional bugfix version. e.g. 2.1 or 2.1.0
if minSchemaVersion != "" {
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)$`, minSchemaVersion)
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)(\.[0-9]+)?$`, minSchemaVersion)
if !matched || err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": fmt.Sprintf("minSchemaVersion %s is not valid, should only include major and minor version. %v", minSchemaVersion, err),
c.JSON(http.StatusBadRequest, gin.H{
"status": fmt.Sprintf("minSchemaVersion %s is not valid, version format should be '+2.x' or '+2.x.x'. %v", minSchemaVersion, err),
})
return []byte{}, indexSchema.Schema{}
}
}
if maxSchemaVersion != "" {
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)$`, maxSchemaVersion)
matched, err := regexp.MatchString(`^([2-9])\.([0-9]+)(\.[0-9]+)?$`, maxSchemaVersion)
if !matched || err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": fmt.Sprintf("maxSchemaVersion %s is not valid, should only include major and minor version. %v", maxSchemaVersion, err),
c.JSON(http.StatusBadRequest, gin.H{
"status": fmt.Sprintf("maxSchemaVersion %s is not valid, version format should be '+2.x' or '+2.x.x'. %v", maxSchemaVersion, err),
})
return []byte{}, indexSchema.Schema{}
}
Expand Down
111 changes: 105 additions & 6 deletions index/server/pkg/server/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"log"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -508,6 +509,7 @@ func TestServeDevfileIndexV2WithType(t *testing.T) {
tests := []struct {
name string
params gin.Params
query url.Values
wantCode int
}{
{
Expand All @@ -531,6 +533,50 @@ func TestServeDevfileIndexV2WithType(t *testing.T) {
},
wantCode: http.StatusOK,
},
{
name: "GET /v2index/all?minSchemaVersion=2.1.0&maxSChemaVersion=2.2 - Successful Response Test",
params: gin.Params{
gin.Param{Key: "type", Value: "all"},
},
query: url.Values{
"minSchemaVersion": []string{"2.1.0"},
"maxSchemaVersion": []string{"2.2"},
},
wantCode: http.StatusOK,
},
{
name: "GET /v2index/all?minSchemaVersion=1.0&maxSChemaVersion=2.2 - Bad Request Response Test",
params: gin.Params{
gin.Param{Key: "type", Value: "all"},
},
query: url.Values{
"minSchemaVersion": []string{"1.0"},
"maxSchemaVersion": []string{"2.2"},
},
wantCode: http.StatusBadRequest,
},
{
name: "GET /v2index/all?minSchemaVersion=2.0.0.0&maxSChemaVersion=2.2 - Bad Request Response Test",
params: gin.Params{
gin.Param{Key: "type", Value: "all"},
},
query: url.Values{
"minSchemaVersion": []string{"2.0.0.0"},
"maxSchemaVersion": []string{"2.2"},
},
wantCode: http.StatusBadRequest,
},
{
name: "GET /v2index/all?minSchemaVersion=2.0.0&maxSChemaVersion=test - Bad Request Response Test",
params: gin.Params{
gin.Param{Key: "type", Value: "all"},
},
query: url.Values{
"minSchemaVersion": []string{"2.0.0"},
"maxSchemaVersion": []string{"test"},
},
wantCode: http.StatusBadRequest,
},
{
name: "GET /v2index/notatype - Type Not Found Response Test",
params: gin.Params{
Expand All @@ -547,7 +593,9 @@ func TestServeDevfileIndexV2WithType(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)

c.Request = httptest.NewRequest(http.MethodGet, "/v2index", nil)
c.Params = append(c.Params, test.params...)
c.Request.URL.RawQuery = test.query.Encode()

serveDevfileIndexV2WithType(c)

Expand Down Expand Up @@ -623,7 +671,7 @@ func TestServeDevfile(t *testing.T) {
}

if gotSchemaVersion := content.Data.GetSchemaVersion(); !reflect.DeepEqual(gotSchemaVersion, test.wantSchemaVersion) {
t.Errorf("Did not get expected status code, Got: %v, Expected: %v", gotSchemaVersion, test.wantSchemaVersion)
t.Errorf("Did not get expected schema version, Got: %v, Expected: %v", gotSchemaVersion, test.wantSchemaVersion)
}
}
})
Expand All @@ -635,12 +683,13 @@ func TestServeDevfileWithVersion(t *testing.T) {
tests := []struct {
name string
params gin.Params
query url.Values
wantCode int
wantSchemaVersion string
wantError bool
}{
{
name: "GET /devfiles/go/default - Fetch Go Devfile With Default Version",
name: "GET /devfiles/go/default - Fetch Go Devfile With Default Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "default"},
Expand All @@ -649,14 +698,62 @@ func TestServeDevfileWithVersion(t *testing.T) {
wantSchemaVersion: "2.0.0",
},
{
name: "GET /devfiles/go/latest - Fetch Go Devfile With Latest Version",
name: "GET /devfiles/go/latest - Fetch Go Devfile With Latest Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "latest"},
},
wantCode: http.StatusOK,
wantSchemaVersion: "2.1.0",
},
{
name: "GET /devfiles/go/latest?minSchemaVersion=2.1 - Fetch Go Devfile With Latest Devfile 2.1.0 Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "latest"},
},
query: url.Values{
"minSchemaVersion": []string{"2.1"},
},
wantCode: http.StatusOK,
wantSchemaVersion: "2.1.0",
},
{
name: "GET /devfiles/go/latest?maxSchemaVersion=2.0.0 - Fetch Go Devfile With Latest Devfile 2.0.0 Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "latest"},
},
query: url.Values{
"maxSchemaVersion": []string{"2.0.0"},
},
wantCode: http.StatusOK,
wantSchemaVersion: "2.0.0",
},
{
name: "GET /devfiles/go/latest?maxSchemaVersion=1.0 - Invalid Schema Version Fetch Go Devfile With Latest Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "latest"},
},
query: url.Values{
"maxSchemaVersion": []string{"1.0"},
},
wantCode: http.StatusBadRequest,
wantError: true,
},
{
name: "GET /devfiles/go/latest?minSchemaVersion=test - Invalid Schema Version Fetch Go Devfile With Latest Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "go"},
gin.Param{Key: "version", Value: "latest"},
},
query: url.Values{
"minSchemaVersion": []string{"test"},
},
wantCode: http.StatusBadRequest,
wantError: true,
},
{
name: "GET /devfiles/go/1.2.0 - Fetch Go Devfile With Specific Version",
params: gin.Params{
Expand All @@ -667,7 +764,7 @@ func TestServeDevfileWithVersion(t *testing.T) {
wantSchemaVersion: "2.1.0",
},
{
name: "GET /devfiles/not-exist/latest - Fetch Non-Existent Devfile With Latest Version",
name: "GET /devfiles/not-exist/latest - Fetch Non-Existent Devfile With Latest Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "not-exist"},
gin.Param{Key: "version", Value: "latest"},
Expand All @@ -676,7 +773,7 @@ func TestServeDevfileWithVersion(t *testing.T) {
wantError: true,
},
{
name: "GET /devfiles/java-maven/not-exist - Fetch Java Maven Devfile With Non-Existent Version",
name: "GET /devfiles/java-maven/not-exist - Fetch Java Maven Devfile With Non-Existent Stack Version",
params: gin.Params{
gin.Param{Key: "name", Value: "java-maven"},
gin.Param{Key: "version", Value: "non-exist"},
Expand All @@ -701,7 +798,9 @@ func TestServeDevfileWithVersion(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)

c.Request = httptest.NewRequest(http.MethodGet, "/devfiles", nil)
c.Params = append(c.Params, test.params...)
c.Request.URL.RawQuery = test.query.Encode()

serveDevfileWithVersion(c)

Expand All @@ -715,7 +814,7 @@ func TestServeDevfileWithVersion(t *testing.T) {
}

if gotSchemaVersion := content.Data.GetSchemaVersion(); !reflect.DeepEqual(gotSchemaVersion, test.wantSchemaVersion) {
t.Errorf("Did not get expected status code, Got: %v, Expected: %v", gotSchemaVersion, test.wantSchemaVersion)
t.Errorf("Did not get expected schema version, Got: %v, Expected: %v", gotSchemaVersion, test.wantSchemaVersion)
}
}
})
Expand Down
16 changes: 14 additions & 2 deletions tests/integration/pkg/tests/indexserver_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,25 @@ var _ = ginkgo.Describe("[Verify index server is working properly]", func() {
}
})

ginkgo.It("/v2index?arch=amd64&arch=arm64 endpoint should return stacks for devfile schema version 2.1.x", func() {
ginkgo.It("/v2index?minSchemaVersion=2.1&maxSchemaVersion=2.1 endpoint should return stacks for devfile schema version 2.1.0", func() {
registryIndex := util.GetRegistryIndex(config.Registry + "/v2index/all?minSchemaVersion=2.1&maxSchemaVersion=2.1")

for _, index := range registryIndex {
if len(index.Versions) != 0 {
for _, version := range index.Versions {
gomega.Expect(version.SchemaVersion).Should(gomega.HavePrefix("2.1"))
gomega.Expect(version.SchemaVersion).Should(gomega.Equal("2.1.0"))
}
}
}
})

ginkgo.It("/v2index?minSchemaVersion=2.1.0&maxSchemaVersion=2.1.0 endpoint should return stacks for devfile schema version 2.1.0", func() {
registryIndex := util.GetRegistryIndex(config.Registry + "/v2index/all?minSchemaVersion=2.1.0&maxSchemaVersion=2.1.0")

for _, index := range registryIndex {
if len(index.Versions) != 0 {
for _, version := range index.Versions {
gomega.Expect(version.SchemaVersion).Should(gomega.Equal("2.1.0"))
}
}
}
Expand Down

0 comments on commit bdfb830

Please sign in to comment.