diff --git a/index/server/pkg/server/endpoint.go b/index/server/pkg/server/endpoint.go index acdfb1f1..b4f426ea 100644 --- a/index/server/pkg/server/endpoint.go +++ b/index/server/pkg/server/endpoint.go @@ -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 } @@ -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{} } diff --git a/index/server/pkg/server/endpoint_test.go b/index/server/pkg/server/endpoint_test.go index 7a277f81..89c8c1ce 100644 --- a/index/server/pkg/server/endpoint_test.go +++ b/index/server/pkg/server/endpoint_test.go @@ -26,6 +26,7 @@ import ( "log" "net/http" "net/http/httptest" + "net/url" "os" "path/filepath" "reflect" @@ -508,6 +509,7 @@ func TestServeDevfileIndexV2WithType(t *testing.T) { tests := []struct { name string params gin.Params + query url.Values wantCode int }{ { @@ -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{ @@ -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) @@ -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) } } }) @@ -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"}, @@ -649,7 +698,7 @@ 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"}, @@ -657,6 +706,54 @@ func TestServeDevfileWithVersion(t *testing.T) { 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{ @@ -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"}, @@ -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"}, @@ -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) @@ -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) } } }) diff --git a/tests/integration/pkg/tests/indexserver_tests.go b/tests/integration/pkg/tests/indexserver_tests.go index 0f579975..1f80245b 100644 --- a/tests/integration/pkg/tests/indexserver_tests.go +++ b/tests/integration/pkg/tests/indexserver_tests.go @@ -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")) } } }