weldr: add support for toml format in /blueprints/freeze

This is needed for lorax parity. When multiple blueprints are being frozen in
toml mode, the API returns an error. This is the same behaviour as in the
/blueprints/info route.

Fixes #667
This commit is contained in:
Ondřej Budai 2020-06-04 15:56:19 +02:00 committed by Tom Gundersen
parent 1f580738db
commit d65057e164
3 changed files with 114 additions and 22 deletions

View file

@ -14,6 +14,7 @@ import (
"testing"
"time"
"github.com/BurntSushi/toml"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/distro"
@ -135,6 +136,40 @@ func TestRoute(t *testing.T, api API, external bool, method, path, body string,
require.Equal(t, expected, reply)
}
func TestTOMLRoute(t *testing.T, api API, external bool, method, path, body string, expectedStatus int, expectedTOML string, ignoreFields ...string) {
t.Helper()
resp := SendHTTP(api, external, method, path, body)
if resp == nil {
t.Skip("This test is for internal testing only")
}
replyTOML, err := ioutil.ReadAll(resp.Body)
require.NoErrorf(t, err, "%s: could not read response body", path)
assert.Equalf(t, expectedStatus, resp.StatusCode, "SendHTTP failed for path %s: %v", path, string(replyTOML))
if expectedTOML == "" {
require.Lenf(t, replyTOML, 0, "%s: expected no response body, but got:\n%s", path, replyTOML)
}
var reply, expected interface{}
err = toml.Unmarshal(replyTOML, &reply)
require.NoErrorf(t, err, "%s: json.Unmarshal failed for\n%s", path, string(replyTOML))
if expectedTOML == "*" {
return
}
err = toml.Unmarshal([]byte(expectedTOML), &expected)
require.NoErrorf(t, err, "%s: expected TOML is invalid", path)
dropFields(reply, ignoreFields...)
dropFields(expected, ignoreFields...)
require.Equal(t, expected, reply)
}
func TestNonJsonRoute(t *testing.T, api API, external bool, method, path, body string, expectedStatus int, expectedResponse string) {
response := SendHTTP(api, external, method, path, body)
assert.Equalf(t, expectedStatus, response.StatusCode, "%s: status mismatch", path)

View file

@ -1240,11 +1240,32 @@ func (api *API) blueprintsFreezeHandler(writer http.ResponseWriter, request *htt
blueprints = append(blueprints, blueprintFrozen{blueprint})
}
err := json.NewEncoder(writer).Encode(reply{
Blueprints: blueprints,
Errors: errors,
})
common.PanicOnError(err)
format := request.URL.Query().Get("format")
if format == "toml" {
// lorax concatenates multiple blueprints with `\n\n` here,
// which is never useful. Deviate by only returning the first
// blueprint.
if len(blueprints) > 1 {
errors := responseError{
ID: "HTTPError",
Msg: "toml format only supported when requesting one blueprint",
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
encoder := toml.NewEncoder(writer)
encoder.Indent = ""
err := encoder.Encode(blueprints[0].Blueprint)
common.PanicOnError(err)
} else {
err := json.NewEncoder(writer).Encode(reply{
Blueprints: blueprints,
Errors: errors,
})
common.PanicOnError(err)
}
}
func (api *API) blueprintsDiffHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {

View file

@ -12,15 +12,14 @@ import (
"testing"
"time"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/target"
"github.com/osbuild/osbuild-composer/internal/blueprint"
test_distro "github.com/osbuild/osbuild-composer/internal/distro/fedoratest"
rpmmd_mock "github.com/osbuild/osbuild-composer/internal/mocks/rpmmd"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/store"
"github.com/osbuild/osbuild-composer/internal/target"
"github.com/osbuild/osbuild-composer/internal/test"
"github.com/BurntSushi/toml"
@ -326,21 +325,58 @@ func TestSetPkgEVRA(t *testing.T) {
}
func TestBlueprintsFreeze(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator
Path string
ExpectedStatus int
ExpectedJSON string
}{
{rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test", http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}}],"errors":[]}`},
}
t.Run("json", func(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator
Path string
ExpectedStatus int
ExpectedJSON string
}{
{rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test,test2", http.StatusOK, `{"blueprints":[{"blueprint":{"name":"test","description":"Test","version":"0.0.1","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}},{"blueprint":{"name":"test2","description":"Test","version":"0.0.0","packages":[{"name":"dep-package1","version":"1.33-2.fc30.x86_64"},{"name":"dep-package3","version":"7:3.0.3-1.fc30.x86_64"}],"modules":[{"name":"dep-package2","version":"2.9-1.fc30.x86_64"}],"groups":[]}}],"errors":[]}`},
}
for _, c := range cases {
api, _ := createWeldrAPI(c.Fixture)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.TestRoute(t, api, false, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedJSON)
test.SendHTTP(api, false, "DELETE", "/api/v0/blueprints/delete/test", ``)
}
for _, c := range cases {
api, _ := createWeldrAPI(c.Fixture)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test2","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.TestRoute(t, api, false, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedJSON)
}
})
t.Run("toml", func(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator
Path string
ExpectedStatus int
ExpectedTOML string
}{
{rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test?format=toml", http.StatusOK, "name=\"test\"\n description=\"Test\"\n version=\"0.0.1\"\n groups = []\n [[packages]]\n name=\"dep-package1\"\n version=\"1.33-2.fc30.x86_64\"\n [[packages]]\n name=\"dep-package3\"\n version=\"7:3.0.3-1.fc30.x86_64\"\n [[modules]]\n name=\"dep-package2\"\n version=\"2.9-1.fc30.x86_64\""},
}
for _, c := range cases {
api, _ := createWeldrAPI(c.Fixture)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.TestTOMLRoute(t, api, false, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedTOML)
}
})
t.Run("toml-multiple", func(t *testing.T) {
var cases = []struct {
Fixture rpmmd_mock.FixtureGenerator
Path string
ExpectedStatus int
ExpectedJSON string
}{
{rpmmd_mock.BaseFixture, "/api/v0/blueprints/freeze/test,test2?format=toml", http.StatusBadRequest, "{\"status\":false,\"errors\":[{\"id\":\"HTTPError\",\"msg\":\"toml format only supported when requesting one blueprint\"}]}"},
}
for _, c := range cases {
api, _ := createWeldrAPI(c.Fixture)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.SendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test2","description":"Test","packages":[{"name":"dep-package1","version":"*"},{"name":"dep-package3","version":"*"}], "modules":[{"name":"dep-package2","version":"*"}],"version":"0.0.0"}`)
test.TestRoute(t, api, false, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedJSON)
}
})
}
func TestBlueprintsDiff(t *testing.T) {