debian-forge-composer/internal/cloudapi/v2/v2_test.go
Ondřej Budai 058edd3d76 cloudapi: remove a confusing test
This test tested two things:

1) Invalid route - this is already covered by TestUnknownRoute
2) Invalid UUID in the compose status route - this is now covered by
   TestComposeStatusInvalidUUID

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2022-07-19 16:00:52 +02:00

1105 lines
33 KiB
Go

package v2_test
import (
"context"
"encoding/json"
"fmt"
"net/http"
"sync"
"testing"
"github.com/stretchr/testify/require"
"github.com/osbuild/osbuild-composer/pkg/jobqueue"
v2 "github.com/osbuild/osbuild-composer/internal/cloudapi/v2"
"github.com/osbuild/osbuild-composer/internal/distro/test_distro"
"github.com/osbuild/osbuild-composer/internal/jobqueue/fsjobqueue"
distro_mock "github.com/osbuild/osbuild-composer/internal/mocks/distro"
"github.com/osbuild/osbuild-composer/internal/osbuild"
"github.com/osbuild/osbuild-composer/internal/ostree/mock_ostree_repo"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/test"
"github.com/osbuild/osbuild-composer/internal/worker"
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
)
func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT bool) (*v2.Server, *worker.Server, jobqueue.JobQueue, context.CancelFunc) {
q, err := fsjobqueue.New(dir)
require.NoError(t, err)
workerServer := worker.NewServer(nil, q, worker.Config{BasePath: "/api/worker/v1", JWTEnabled: enableJWT, TenantProviderFields: []string{"rh-org-id", "account_id"}})
distros, err := distro_mock.NewDefaultRegistry()
require.NoError(t, err)
require.NotNil(t, distros)
config := v2.ServerConfig{
JWTEnabled: enableJWT,
TenantProviderFields: []string{"rh-org-id", "account_id"},
}
v2Server := v2.NewServer(workerServer, distros, config)
require.NotNil(t, v2Server)
t.Cleanup(v2Server.Shutdown)
// start a routine which just completes depsolve jobs
depsolveContext, cancel := context.WithCancel(context.Background())
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for {
_, token, _, _, _, err := workerServer.RequestJob(depsolveContext, test_distro.TestDistroName, []string{worker.JobTypeDepsolve}, depsolveChannels)
select {
case <-depsolveContext.Done():
return
default:
}
if err != nil {
continue
}
rawMsg, err := json.Marshal(&worker.DepsolveJobResult{PackageSpecs: map[string][]rpmmd.PackageSpec{"build": []rpmmd.PackageSpec{rpmmd.PackageSpec{Name: "pkg1"}}}, Error: "", ErrorType: worker.ErrorType("")})
require.NoError(t, err)
err = workerServer.FinishJob(token, rawMsg)
if err != nil {
return
}
}
}()
cancelWithWait := func() {
cancel()
wg.Wait()
}
return v2Server, workerServer, q, cancelWithWait
}
func TestUnknownRoute(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/badroute", ``, http.StatusNotFound, `
{
"href": "/api/image-builder-composer/v2/errors/21",
"id": "21",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-21",
"reason": "Requested resource doesn't exist"
}`, "operation_id", "details")
}
func TestGetError(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors/4", ``, http.StatusOK, `
{
"href": "/api/image-builder-composer/v2/errors/4",
"id": "4",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-4",
"reason": "Unsupported distribution"
}`, "operation_id", "details")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors/3000", ``, http.StatusNotFound, `
{
"href": "/api/image-builder-composer/v2/errors/17",
"id": "17",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-17",
"reason": "Error with given id not found"
}`, "operation_id", "details")
}
func TestGetErrorList(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors?page=3&size=1", ``, http.StatusOK, `
{
"kind": "ErrorList",
"page": 3,
"size": 1,
"items": [{
"href": "/api/image-builder-composer/v2/errors/4",
"id": "4",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-4",
"reason": "Unsupported distribution"
}]
}`, "operation_id", "total", "details")
}
func TestCompose(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
// create two ostree repos, one to serve the default test_distro ref (for fallback tests) and one to serve a custom ref
ostreeRepoDefault := mock_ostree_repo.Setup(test_distro.New().OSTreeRef())
defer ostreeRepoDefault.TearDown()
ostreeRepoOther := mock_ostree_repo.Setup("some/other/ref")
defer ostreeRepoOther.TearDown()
// unsupported distribution
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "unsupported_distro",
"image_request":{
"architecture": "%s",
"image_type": "aws.ec2",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1",
"share_with_accounts": ["123456789012"]
}
}
}`, test_distro.TestArch3Name), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/30",
"id": "30",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-30",
"reason": "Request could not be validated"
}`, "operation_id", "details")
// unsupported architecture
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "unsupported_arch",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/5",
"id": "5",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-5",
"reason": "Unsupported architecture"
}`, "operation_id", "details")
// unsupported imagetype
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "unsupported_image_type",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/30",
"id": "30",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-30",
"reason": "Request could not be validated"
}`, "operation_id", "details")
// Returns 404, but should be 405; see https://github.com/labstack/echo/issues/1981
// test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
// {
// "distribution": "%s",
// "image_requests":[{
// "architecture": "%s",
// "image_type": "%s",
// "repositories": [{
// "baseurl": "somerepo.org",
// "rhsm": false
// }],
// "upload_options": {
// "region": "eu-central-1"
// }
// }]
// }`, test_distro.TestDistroName, test_distro.TestArch3Name, test_distro.TestImageTypeName), http.StatusMethodNotAllowed, `
// {
// "href": "/api/image-builder-composer/v2/errors/22",
// "id": "22",
// "kind": "Error",
// "code": "IMAGE-BUILDER-COMPOSER-22",
// "reason": "Requested method isn't supported for resource"
// }`, "operation_id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"koji":{
"name": "name",
"version": "version",
"release": "release",
"server": "https://koji.example.com",
"task_id": 42
},
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}]
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// ostree parameters (success)
// ref only
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"ref": "rhel/10/x86_64/edge"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// url only (must use ostreeRepoDefault for default ref)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"url": "%s"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoDefault.Server.URL), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// ref + url
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"ref": "%s",
"url": "%s"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoDefault.OSTreeRef, ostreeRepoDefault.Server.URL), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// parent + url
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"parent": "%s",
"url": "%s"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoDefault.OSTreeRef, ostreeRepoDefault.Server.URL), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// ref + parent + url
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"parent": "%s",
"url": "%s",
"ref": "a/new/ref"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoOther.OSTreeRef, ostreeRepoOther.Server.URL), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// ostree errors
// bad url
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"ref": "rhel/10/x86_64/edge",
"url": "not-a-URL"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/10",
"id": "10",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-10",
"reason": "Error resolving OSTree repo"
}`, "operation_id", "details")
// bad ref
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"ref": "/bad/ref"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/9",
"id": "9",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-9",
"reason": "Invalid OSTree ref"
}`, "operation_id", "details")
// bad parent ref
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"ref": "%s",
"url": "%s",
"parent": "/bad/ref/number/2"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoDefault.OSTreeRef, ostreeRepoDefault.Server.URL), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/9",
"id": "9",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-9",
"reason": "Invalid OSTree ref"
}`, "operation_id", "details")
// incorrect ref for URL
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"url": "%s",
"parent": "incorrect/ref"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, ostreeRepoOther.Server.URL), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/10",
"id": "10",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-10",
"reason": "Error resolving OSTree repo"
}`, "operation_id", "details")
// parent ref without URL
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "edge-commit",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
},
"ostree": {
"parent": "some/ref"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusBadRequest, `
{
"href": "/api/image-builder-composer/v2/errors/27",
"id": "27",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-27",
"reason": "Invalid OSTree parameters or parameter combination"
}`, "operation_id", "details")
}
func TestComposeStatusSuccess(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
jobId, token, jobType, args, dynArgs, err := wrksrv.RequestJob(context.Background(), test_distro.TestArch3Name, []string{worker.JobTypeOSBuild}, []string{""})
require.NoError(t, err)
require.Equal(t, worker.JobTypeOSBuild, jobType)
var osbuildJob worker.OSBuildJob
err = json.Unmarshal(args, &osbuildJob)
require.NoError(t, err)
require.Equal(t, 0, len(osbuildJob.Manifest))
require.NotEqual(t, 0, len(dynArgs[0]))
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {"status": "building"},
"status": "pending"
}`, jobId, jobId))
res, err := json.Marshal(&worker.OSBuildJobResult{
Success: true,
OSBuildOutput: &osbuild.Result{Success: true},
})
require.NoError(t, err)
err = wrksrv.FinishJob(token, res)
require.NoError(t, err)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {"status": "success"},
"status": "success"
}`, jobId, jobId))
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/metadata", jobId), ``, http.StatusInternalServerError, `
{
"href": "/api/image-builder-composer/v2/errors/1012",
"id": "1012",
"kind": "Error",
"code": "IMAGE-BUILDER-COMPOSER-1012",
"reason": "OSBuildJobResult does not have expected fields set"
}`, "operation_id", "details")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/logs", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v/logs",
"id": "%v",
"kind": "ComposeLogs",
"image_builds": [
{
"arch": "",
"host_os": "",
"osbuild_output": {
"log": null,
"metadata": null,
"success": true,
"type": ""
},
"pipeline_names": {
"build": [
"build"
],
"payload": [
"os",
"assembler"
]
},
"success": true,
"upload_status": ""
}
]
}`, jobId, jobId))
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/manifests", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v/manifests",
"id": "%v",
"kind": "ComposeManifests",
"manifests": [
{
"version": "",
"pipelines": [],
"sources": {}
}
]
}`, jobId, jobId), "details")
}
func TestComposeStatusFailure(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
jobId, token, jobType, _, _, err := wrksrv.RequestJob(context.Background(), test_distro.TestArch3Name, []string{worker.JobTypeOSBuild}, []string{""})
require.NoError(t, err)
require.Equal(t, worker.JobTypeOSBuild, jobType)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {"status": "building"},
"status": "pending"
}`, jobId, jobId))
err = wrksrv.FinishJob(token, nil)
require.NoError(t, err)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {
"error": {
"id": 10,
"details": null,
"reason": "osbuild build failed"
},
"status": "failure"
},
"status": "failure"
}`, jobId, jobId))
}
func TestComposeStatusInvalidUUID(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/composes/abcdef", ``, http.StatusBadRequest, `
{
"code": "IMAGE-BUILDER-COMPOSER-14",
"details": "",
"href": "/api/image-builder-composer/v2/errors/14",
"id": "14",
"kind": "Error",
"reason": "Invalid format for compose id"
}
`, "operation_id")
}
func TestComposeJobError(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
jobId, token, jobType, _, _, err := wrksrv.RequestJob(context.Background(), test_distro.TestArch3Name, []string{worker.JobTypeOSBuild}, []string{""})
require.NoError(t, err)
require.Equal(t, worker.JobTypeOSBuild, jobType)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {"status": "building"},
"status": "pending"
}`, jobId, jobId))
jobErr := worker.JobResult{
JobError: clienterrors.WorkerClientError(clienterrors.ErrorBuildJob, "Error building image"),
}
jobResult, err := json.Marshal(worker.OSBuildJobResult{JobResult: jobErr})
require.NoError(t, err)
err = wrksrv.FinishJob(token, jobResult)
require.NoError(t, err)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {
"error": {
"id": 10,
"details": null,
"reason": "Error building image"
},
"status": "failure"
},
"status": "failure"
}`, jobId, jobId))
}
func TestComposeDependencyError(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
jobId, token, jobType, _, _, err := wrksrv.RequestJob(context.Background(), test_distro.TestArch3Name, []string{worker.JobTypeOSBuild}, []string{""})
require.NoError(t, err)
require.Equal(t, worker.JobTypeOSBuild, jobType)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {"status": "building"},
"status": "pending"
}`, jobId, jobId))
jobErr := worker.JobResult{
JobError: clienterrors.WorkerClientError(clienterrors.ErrorManifestDependency, "Manifest dependency failed"),
}
jobErr.JobError.Details = clienterrors.WorkerClientError(clienterrors.ErrorDNFOtherError, "DNF Error")
jobResult, err := json.Marshal(worker.OSBuildJobResult{JobResult: jobErr})
require.NoError(t, err)
err = wrksrv.FinishJob(token, jobResult)
require.NoError(t, err)
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v",
"kind": "ComposeStatus",
"id": "%v",
"image_status": {
"error": {
"details": {
"details": null,
"id": 22,
"reason": "DNF Error"
},
"id": 9,
"reason": "Manifest dependency failed"
},
"status": "failure"
},
"status": "failure"
}`, jobId, jobId))
}
func TestComposeCustomizations(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"customizations": {
"subscription": {
"organization": "2040324",
"activation_key": "my-secret-key",
"server_url": "subscription.rhsm.redhat.com",
"base_url": "http://cdn.redhat.com/",
"insights": true
},
"packages": [ "pkg1", "pkg2" ],
"users": [{
"name": "user1",
"groups": [ "wheel" ],
"key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrGKErMYi+MMUwuHaRAJmRLoIzRf2qD2dD5z0BTx/6x"
}],
"payload_repositories": [{
"baseurl": "some-custom-repo.org",
"check_gpg": false,
"ignore_ssl": false,
"gpg_key": "some-gpg-key"
}],
"services": {
"enabled": [
"nftables"
],
"disabled": [
"firewalld"
]
}
},
"image_request":{
"architecture": "%s",
"image_type": "aws",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
}
func TestImageTypes(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false)
defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1",
"snapshot_name": "name",
"share_with_accounts": ["123456789012","234567890123"]
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesAws)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1",
"snapshot_name": "name",
"share_with_accounts": ["123456789012","234567890123"]
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesAws)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesEdgeCommit)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesEdgeInstaller)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"subscription_id": "4e5d8b2c-ab24-4413-90c5-612306e809e2",
"tenant_id": "5c7ef5b6-1c3f-4da0-a622-0b060239d7d7",
"resource_group": "ToucanResourceGroup",
"location": "westeurope"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesAzure)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu",
"bucket": "some-eu-bucket",
"share_with_accounts": ["user:alice@example.com"]
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesGcp)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesImageInstaller)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesGuestImage)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1"
}
}
}`, test_distro.TestDistroName, test_distro.TestArch3Name, string(v2.ImageTypesVsphere)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
}