api: add blueprints changes route
For each blueprint name passed to the route, a list of the changes to that blueprint will be returned. weldr/tests: add blueprint changes test In order to test blueprint changes a blueprint must be created with a unique id. Blueprint changes are not deleted when the blueprint is deleted so in order to test this against lorax the blueprint must have not been used/tested before. This id is created from a random int. The test creates and deletes the same blueprint twice to check that each creation updates the list of changes.
This commit is contained in:
parent
080bd4968c
commit
9970150ed5
2 changed files with 86 additions and 0 deletions
|
|
@ -64,6 +64,7 @@ func New(repo rpmmd.RepoConfig, packages rpmmd.PackageList, logger *log.Logger,
|
||||||
api.router.GET("/api/v0/blueprints/info/*blueprints", api.blueprintsInfoHandler)
|
api.router.GET("/api/v0/blueprints/info/*blueprints", api.blueprintsInfoHandler)
|
||||||
api.router.GET("/api/v0/blueprints/depsolve/*blueprints", api.blueprintsDepsolveHandler)
|
api.router.GET("/api/v0/blueprints/depsolve/*blueprints", api.blueprintsDepsolveHandler)
|
||||||
api.router.GET("/api/v0/blueprints/diff/:blueprint/:from/:to", api.blueprintsDiffHandler)
|
api.router.GET("/api/v0/blueprints/diff/:blueprint/:from/:to", api.blueprintsDiffHandler)
|
||||||
|
api.router.GET("/api/v0/blueprints/changes/*blueprints", api.blueprintsChangesHandler)
|
||||||
api.router.POST("/api/v0/blueprints/new", api.blueprintsNewHandler)
|
api.router.POST("/api/v0/blueprints/new", api.blueprintsNewHandler)
|
||||||
api.router.POST("/api/v0/blueprints/workspace", api.blueprintsWorkspaceHandler)
|
api.router.POST("/api/v0/blueprints/workspace", api.blueprintsWorkspaceHandler)
|
||||||
api.router.DELETE("/api/v0/blueprints/delete/:blueprint", api.blueprintDeleteHandler)
|
api.router.DELETE("/api/v0/blueprints/delete/:blueprint", api.blueprintDeleteHandler)
|
||||||
|
|
@ -706,6 +707,73 @@ func (api *API) blueprintsDiffHandler(writer http.ResponseWriter, request *http.
|
||||||
json.NewEncoder(writer).Encode(reply{diffs})
|
json.NewEncoder(writer).Encode(reply{diffs})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) blueprintsChangesHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
|
||||||
|
type change struct {
|
||||||
|
Changes []blueprint.Change `json:"changes"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type reply struct {
|
||||||
|
BlueprintsChanges []change `json:"blueprints"`
|
||||||
|
Errors []responseError `json:"errors"`
|
||||||
|
Limit uint `json:"limit"`
|
||||||
|
Offset uint `json:"offset"`
|
||||||
|
}
|
||||||
|
|
||||||
|
names := strings.Split(params.ByName("blueprints"), ",")
|
||||||
|
if names[0] == "/" {
|
||||||
|
errors := responseError{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
ID: "HTTPError",
|
||||||
|
Msg: "Not Found",
|
||||||
|
}
|
||||||
|
statusResponseError(writer, http.StatusNotFound, errors)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
offset, limit, err := parseOffsetAndLimit(request.URL.Query())
|
||||||
|
if err != nil {
|
||||||
|
errors := responseError{
|
||||||
|
ID: "BadLimitOrOffset",
|
||||||
|
Msg: fmt.Sprintf("BadRequest: %s", err.Error()),
|
||||||
|
}
|
||||||
|
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
allChanges := []change{}
|
||||||
|
errors := []responseError{}
|
||||||
|
for i, name := range names {
|
||||||
|
// remove leading / from first name
|
||||||
|
if i == 0 {
|
||||||
|
name = name[1:]
|
||||||
|
}
|
||||||
|
bpChanges := api.store.GetBlueprintChanges(name)
|
||||||
|
if bpChanges != nil {
|
||||||
|
change := change{
|
||||||
|
Changes: bpChanges,
|
||||||
|
Name: name,
|
||||||
|
Total: len(bpChanges),
|
||||||
|
}
|
||||||
|
allChanges = append(allChanges, change)
|
||||||
|
} else {
|
||||||
|
error := responseError{
|
||||||
|
ID: "UnknownBlueprint",
|
||||||
|
Msg: name,
|
||||||
|
}
|
||||||
|
errors = append(errors, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json.NewEncoder(writer).Encode(reply{
|
||||||
|
BlueprintsChanges: allChanges,
|
||||||
|
Errors: errors,
|
||||||
|
Offset: offset,
|
||||||
|
Limit: limit,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (api *API) blueprintsNewHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
|
func (api *API) blueprintsNewHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
|
||||||
contentType := request.Header["Content-Type"]
|
contentType := request.Header["Content-Type"]
|
||||||
if len(contentType) != 1 || contentType[0] != "application/json" {
|
if len(contentType) != 1 || contentType[0] != "application/json" {
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,16 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||||
"github.com/osbuild/osbuild-composer/internal/store"
|
"github.com/osbuild/osbuild-composer/internal/store"
|
||||||
|
|
@ -298,6 +301,21 @@ func TestBlueprintsDelete(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBlueprintsChanges(t *testing.T) {
|
||||||
|
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
id := strconv.Itoa(rand.Int())
|
||||||
|
ignoreFields := []string{"commit", "timestamp"}
|
||||||
|
|
||||||
|
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"`+id+`","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||||
|
testRoute(t, api, true, "GET", "/api/v0/blueprints/changes/failing"+id, ``, http.StatusOK, `{"blueprints":[],"errors":[{"id":"UnknownBlueprint","msg":"failing`+id+`"}],"limit":20,"offset":0}`, ignoreFields...)
|
||||||
|
testRoute(t, api, true, "GET", "/api/v0/blueprints/changes/"+id, ``, http.StatusOK, `{"blueprints":[{"changes":[{"commit":"","message":"Recipe `+id+`, version 0.0.0 saved.","revision":null,"timestamp":""}],"name":"`+id+`","total":1}],"errors":[],"limit":20,"offset":0}`, ignoreFields...)
|
||||||
|
sendHTTP(api, true, "DELETE", "/api/v0/blueprints/delete/"+id, ``)
|
||||||
|
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"`+id+`","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||||
|
testRoute(t, api, true, "GET", "/api/v0/blueprints/changes/"+id, ``, http.StatusOK, `{"blueprints":[{"changes":[{"commit":"","message":"Recipe `+id+`, version 0.0.0 saved.","revision":null,"timestamp":""},{"commit":"","message":"Recipe `+id+`, version 0.0.0 saved.","revision":null,"timestamp":""}],"name":"`+id+`","total":2}],"errors":[],"limit":20,"offset":0}`, ignoreFields...)
|
||||||
|
sendHTTP(api, true, "DELETE", "/api/v0/blueprints/delete/"+id, ``)
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompose(t *testing.T) {
|
func TestCompose(t *testing.T) {
|
||||||
var cases = []struct {
|
var cases = []struct {
|
||||||
External bool
|
External bool
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue