Skip to content

Commit

Permalink
Registry index server endpoint testing added (#130)
Browse files Browse the repository at this point in the history
* devfile registry index server README added.

* Squashed commit of the following:

commit e3b6365
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Aug 16 13:32:01 2022 -0400

    oci server spec links added to godocs in ocitest.go

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

commit e09a610
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Aug 16 13:13:31 2022 -0400

    godocs added to endpoint_test.go and tag error detail changed to match ResponseError.Detail type signature

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

commit 737544b
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Aug 16 12:58:37 2022 -0400

    godocs added to ocitest.go and Detail field under ResponseError type signature changed

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

commit 36e9223
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 29 19:01:15 2022 -0400

    TestOCIServerProxy test function and test cases added.

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

commit 7163dfb
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 29 19:00:01 2022 -0400

    ProxyRecorder struct with inheritance to httptest.ResponseRecorder, ProxyRecorder adds CloseNotify receiver function from http.CloseNotifier which is needed for testing the oci proxy route and missing from httptest.ResponseRecorder

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

commit 52d94f6
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 17:20:55 2022 -0400

    java-wildfly manifest test data and test cases under TestServeDevfileStarterProject added.

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

commit b3c4891
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 16:54:41 2022 -0400

    TestServeDevfileStarterProjectWithVersion test function and test cases added.

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

commit 9cf79f8
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 16:43:09 2022 -0400

    java-quarkus manifest test data and test case under TestServeDevfileStarterProject added.

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

commit aebbedc
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 16:03:43 2022 -0400

    TestServeDevfileStarterProject test function and test cases added.

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

commit a2f464f
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 14:56:27 2022 -0400

    TestServeDevfileWithVersion test function and test cases added.

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

commit 4e4749a
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 28 13:43:53 2022 -0400

    when fetching a blob, mock oci server handler now walks specified stack's directory rather than iterate through immediate children.

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

commit a415a06
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 27 17:13:27 2022 -0400

    go-digest updated to direct dependency for digest handling in the mock OCI server.

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

commit 1742b06
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 27 17:10:52 2022 -0400

    go stack manifest testing data and TestServeDevfile test case added.

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

commit ab7505d
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 27 17:09:05 2022 -0400

    first success mock testing with OCI server, TestServeDevfile testing updated including fail case.

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

commit c8196db
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Jul 26 18:35:16 2022 -0400

    test data for manifests added, handlers for mock OCI server progress.

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

commit 323393c
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Jul 26 18:33:54 2022 -0400

    Fixups: 'blob' corrected to 'blobs' in routes and the 'detail' field under ResponseError type changed from string to ResponseErrorDetails.

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

commit 6e0a403
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 19:43:31 2022 -0400

    added missing error logging after pullStackFromRegistry

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

commit 044de92
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 19:14:40 2022 -0400

    mock OCI server package created.

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

commit d4aed3d
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 15:41:52 2022 -0400

    remove unused arraylist source.

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

commit f3af869
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 15:36:17 2022 -0400

    removed unused validateMethods function

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

commit 6868622
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 15:35:03 2022 -0400

    writeErrors changed to use gin.H and json marshal

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

commit 5fe00bf
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Jul 22 15:31:31 2022 -0400

    routing changed to use gin framework, ping test for mock OCI server.

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

commit e11d9fb
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 21 18:23:47 2022 -0400

    mock OCI server routes corrected, e.g. '/v2/:name/manifests/:ref' corrected to '/v2/devfile-catalog/:name/manifests/:ref'

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

commit db8cb4e
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Thu Jul 21 18:21:34 2022 -0400

    TestServeDevfile test function added with base source.

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

commit a5fc352
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Jul 19 18:38:12 2022 -0400

    mock oci server setup code added.

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

commit 2978667
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Tue Jul 19 18:31:55 2022 -0400

    arraylist util functions and testing added.

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

commit eb51b6d
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 13 23:02:48 2022 -0400

    serve devfile index with type testing seperated from base serve devfile index testing.

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

commit a62e5ff
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 13 22:50:03 2022 -0400

    endpoint function exporting reverted due to changing test source file package to the same as the endpoint functions.

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

commit 74366e7
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 13 22:46:16 2022 -0400

    setupVar fixture function added. testing for serve devfile index endpoints added.

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

commit a7e426c
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Wed Jul 13 22:44:10 2022 -0400

    test registry for index/server mock testing added.

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

commit 17b0c7d
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Mon Jul 11 16:13:59 2022 -0400

    fixed up TestServeHealthCheck

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

commit eb6d6f8
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri May 6 17:03:38 2022 -0400

    ServeDevfileIndexV1 testing added.

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

commit 38b468a
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Mon May 2 17:45:11 2022 -0400

    endpoint_test.go added:

    - Mock testing for ServeHealthCheck created
    - Base source for ServeDevfileIndexV1 with TODOs created

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

commit 766511a
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Mon May 2 11:32:16 2022 -0400

    endpoint handlers exported from package for use in mock testing

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

commit dfd1b91
Author: Michael Valdron <mvaldron@redhat.com>
Date:   Fri Apr 29 16:52:31 2022 -0400

    CreateIndexServer generator function added.

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

* bug which records status code 200 for HEAD request despite response returning 404 fixed.

* environment variables section added to testing docs in index server README

* additional oci proxy test cases for fetching blobs added.

* starterProjectMediaType constant added.

* revert to original router creation source for registry index server.

Signed-off-by: Michael Valdron <mvaldron@redhat.com>
  • Loading branch information
michael-valdron authored Aug 19, 2022
1 parent 888ae9b commit e70843d
Show file tree
Hide file tree
Showing 30 changed files with 3,455 additions and 21 deletions.
26 changes: 26 additions & 0 deletions index/server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Devfile registry index server

## Overview

Provides REST API support for devfile registries and serves [devfile registry viewer](https://github.com/devfile/registry-viewer) client.

For more information on REST API docs: [registry-REST-API.adoc](registry-REST-API.adoc)

## Testing

Endpoint unit testing is defined under `pkg/server/endpoint_test.go` and can be performed by running the following:

```sh
go test pkg/server/endpoint_test.go
```

or by running all tests:

```sh
go test ./...
```

**Environment Variables**

- `DEVFILE_REGISTRY`: Optional environment variable for specifying testing registry path
- default: `../../tests/registry`
2 changes: 1 addition & 1 deletion index/server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/gin-gonic/gin v1.7.7
github.com/hashicorp/go-version v1.4.0
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.1
github.com/prometheus/client_golang v1.11.0
golang.org/x/text v0.3.6
Expand Down Expand Up @@ -64,7 +65,6 @@ require (
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions index/server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ github.com/devfile/api/v2 v2.0.0-20220117162434-6e6e6a8bc14c h1:sjghKUov/WT71dBr
github.com/devfile/api/v2 v2.0.0-20220117162434-6e6e6a8bc14c/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de h1:jImHtiAxjyul1UkPmf6C3EMS5wqNz+k84LKkCXkeqws=
github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de/go.mod h1:GSPfJaBg0+bBjBHbwBE5aerJLH6tWGQu2q2rHYd9czM=
github.com/devfile/registry-support/index/generator v0.0.0-20220316161530-f06d84c42b54 h1:k7F4Hc4svkA+qHerBTZzcU1iVrQAJHOh8KurPnL4uYk=
github.com/devfile/registry-support/index/generator v0.0.0-20220316161530-f06d84c42b54/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc=
github.com/devfile/registry-support/index/generator v0.0.0-20220624203950-e7282a4695b6 h1:bTbZxKSjF9xfiUuOKpoyX7P/ZcnIRy993+JBvkQ91hw=
github.com/devfile/registry-support/index/generator v0.0.0-20220624203950-e7282a4695b6/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
Expand Down
127 changes: 127 additions & 0 deletions index/server/pkg/ocitest/ocitest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package ocitest

import (
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"net/http/httptest"

"github.com/gin-gonic/gin"
)

// ResponseError repersents an error returned in an errors response by an OCI server,
// see https://github.com/opencontainers/distribution-spec/blob/main/spec.md#error-codes
type ResponseError struct {
Code string `json:"code"` // Error code
Message string `json:"message"` // Error Message
Detail map[string]interface{} `json:"detail"` // Additional detail on the error (optional)
}

// MockOCIServer is an entity for mocking an OCI server
// for testing. At the moment, this is only needed for
// the devfile registry index server endpoint testing,
// however, this entity could be used in a testing scenario
// where an OCI server is needed.
//
// More on the OCI server specification, see https://github.com/opencontainers/distribution-spec/blob/main/spec.md
type MockOCIServer struct {
httpserver *httptest.Server // Test server entity
router *gin.Engine // Router engine for route management
ServeManifest func(c *gin.Context) // Handler for serving a manifest for a blob
ServeBlob func(c *gin.Context) // Handler for serving a blob from the OCI server
}

// servePing is a custom handler to test if
// MockOCIServer is listening for requests
func servePing(c *gin.Context) {
data, err := json.Marshal(gin.H{
"message": "ok",
})
if err != nil {
log.Fatal(err)
}

c.JSON(http.StatusOK, data)
}

// WriteErrors writes error response object for OCI server
// errors
func WriteErrors(errors []ResponseError) map[string]interface{} {
return gin.H{
"errors": errors,
}
}

// NewMockOCIServer creates a MockOCIServer entity
func NewMockOCIServer() *MockOCIServer {
gin.SetMode(gin.TestMode)

mockOCIServer := &MockOCIServer{
// Create router engine of mock OCI server
router: gin.Default(),
}

// Create mock OCI server using the router engine
mockOCIServer.httpserver = httptest.NewUnstartedServer(mockOCIServer.router)

return mockOCIServer
}

// Start listening on listenAddr for requests to the MockOCIServer
func (server *MockOCIServer) Start(listenAddr string) error {
// Testing Route for checking mock OCI server
server.router.GET("/v2/ping", servePing)

// Pull Routes, see https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pull
// Fetch manifest routes
if server.ServeManifest != nil {
server.router.GET("/v2/devfile-catalog/:name/manifests/:ref", server.ServeManifest)
server.router.HEAD("/v2/devfile-catalog/:name/manifests/:ref", server.ServeManifest)
}

// Fetch blob routes
if server.ServeBlob != nil {
server.router.GET("/v2/devfile-catalog/:name/blobs/:digest", server.ServeBlob)
server.router.HEAD("/v2/devfile-catalog/:name/blobs/:digest", server.ServeBlob)
}

l, err := net.Listen("tcp", listenAddr)
if err != nil {
return fmt.Errorf("unexpected error while creating listener: %v", err)
}

server.httpserver.Listener.Close()
server.httpserver.Listener = l

server.httpserver.Start()

return nil
}

// Close the MockOCIServer connection
func (server *MockOCIServer) Close() {
server.httpserver.Close()
}

// ProxyRecorder is an extension of the ResponseRecorder
// struct within httptest with an additional receiver CloseNotifier
// which is needed for testing the proxy route to the OCI server
type ProxyRecorder struct {
*httptest.ResponseRecorder
http.CloseNotifier
}

// NewProxyRecorder creates a new ProxyRecorder entity
func NewProxyRecorder() *ProxyRecorder {
return &ProxyRecorder{
ResponseRecorder: httptest.NewRecorder(),
}
}

// CloseNotify creates a bool channel for notifying a
// closure of a request
func (rec *ProxyRecorder) CloseNotify() <-chan bool {
return make(<-chan bool)
}
25 changes: 13 additions & 12 deletions index/server/pkg/server/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ import (

const (
// Constants for resource names and media types
archiveMediaType = "application/x-tar"
archiveName = "archive.tar"
devfileName = "devfile.yaml"
devfileNameHidden = ".devfile.yaml"
devfileConfigMediaType = "application/vnd.devfileio.devfile.config.v2+json"
devfileMediaType = "application/vnd.devfileio.devfile.layer.v1"
pngLogoMediaType = "image/png"
pngLogoName = "logo.png"
svgLogoMediaType = "image/svg+xml"
svgLogoName = "logo.svg"
vsxMediaType = "application/vnd.devfileio.vsx.layer.v1.tar"
vsxName = "vsx"
archiveMediaType = "application/x-tar"
archiveName = "archive.tar"
starterProjectMediaType = "application/zip"
devfileName = "devfile.yaml"
devfileNameHidden = ".devfile.yaml"
devfileConfigMediaType = "application/vnd.devfileio.devfile.config.v2+json"
devfileMediaType = "application/vnd.devfileio.devfile.layer.v1"
pngLogoMediaType = "image/png"
pngLogoName = "logo.png"
svgLogoMediaType = "image/svg+xml"
svgLogoName = "logo.svg"
vsxMediaType = "application/vnd.devfileio.vsx.layer.v1.tar"
vsxName = "vsx"

scheme = "http"
registryService = "localhost:5000"
Expand Down
3 changes: 2 additions & 1 deletion index/server/pkg/server/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func serveDevfileStarterProjectWithVersion(c *gin.Context) {
}

c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.zip\"", starterProjectName))
c.Data(http.StatusAccepted, "application/zip", downloadBytes)
c.Data(http.StatusAccepted, starterProjectMediaType, downloadBytes)
}
}

Expand Down Expand Up @@ -521,6 +521,7 @@ func fetchDevfile(c *gin.Context, name string, version string) ([]byte, indexSch
if devfileIndex.Type == indexSchema.StackDevfileType {
bytes, err = pullStackFromRegistry(foundVersion)
if err != nil {
log.Print(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
"status": fmt.Sprintf("Problem pulling version %s from OCI Registry", foundVersion.Version),
Expand Down
Loading

0 comments on commit e70843d

Please sign in to comment.