debian-forge-composer/internal/jobqueue/api_test.go
Lars Karlitski 1b7cb6c11b store/jobqueue: remove distro field from jobs
A job's purpose is to build an osbuild manifest and upload the results
somewhere. It should not know about which distro was used to generate
the pipeline.

Workers depended on the distro package in two ways:

1. To set an osbuild `--build-env`. This is not necessary anymore in new
   versions of osbuild. More importantly, it was wrong: it passed the
   runner from the distro that is being built, instead of one that
   matches the host.

   This patch simply removes that logic.

2. To fetch the output filename with `Distro.FilenameFromType()`. While
   that is useful, I don't think it warrants the dependency.

   This patch uses the fact that all current pipelines output exactly
   one file and uploads that. This should probably be extended in the
   future to upload all output files, or to name them explicitly in the
   upload target.

The worker should now compile to a smaller binary and do less
unnecessary work on startup (like reading repository files).
2020-03-18 12:24:20 +01:00

124 lines
5.4 KiB
Go

package jobqueue_test
import (
"net/http"
"testing"
distro_mock "github.com/osbuild/osbuild-composer/internal/mocks/distro"
"github.com/osbuild/osbuild-composer/internal/blueprint"
test_distro "github.com/osbuild/osbuild-composer/internal/distro/fedoratest"
"github.com/osbuild/osbuild-composer/internal/jobqueue"
"github.com/osbuild/osbuild-composer/internal/store"
"github.com/osbuild/osbuild-composer/internal/test"
"github.com/google/uuid"
)
func TestBasic(t *testing.T) {
var cases = []struct {
Method string
Path string
Body string
ExpectedStatus int
ExpectedResponse string
}{
// Create job with invalid body
{"POST", "/job-queue/v1/jobs", ``, http.StatusBadRequest, `invalid request: EOF`},
// Update job with invalid ID
{"PATCH", "/job-queue/v1/jobs/foo/builds/0", `{"status":"RUNNING"}`, http.StatusBadRequest, `invalid compose id: invalid UUID length: 3`},
// Update job that does not exist, with invalid body
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/builds/0", ``, http.StatusBadRequest, `invalid status: EOF`},
// Update job that does not exist
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/builds/0", `{"status":"RUNNING"}`, http.StatusNotFound, `compose does not exist`},
}
for _, c := range cases {
registry, err := distro_mock.NewDefaultRegistry()
if err != nil {
t.Fatal(err)
}
api := jobqueue.New(nil, store.New(nil, *registry))
test.TestNonJsonRoute(t, api, false, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedResponse)
}
}
func TestCreate(t *testing.T) {
id, _ := uuid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff")
distroStruct := test_distro.New()
registry, err := distro_mock.NewDefaultRegistry()
if err != nil {
t.Fatal(err)
}
store := store.New(nil, *registry)
api := jobqueue.New(nil, store)
err = store.PushCompose(distroStruct, id, &blueprint.Blueprint{}, nil, nil, "x86_64", "qcow2", 0, nil)
if err != nil {
t.Fatalf("error pushing compose: %v", err)
}
test.TestRoute(t, api, false, "POST", "/job-queue/v1/jobs", `{}`, http.StatusCreated,
`{"id":"ffffffff-ffff-ffff-ffff-ffffffffffff","image_build_id":0,"manifest":{"sources":{},"pipeline":{}},"targets":[],"output_type":"qcow2"}`, "created", "uuid")
}
func testUpdateTransition(t *testing.T, from, to string, expectedStatus int, expectedResponse string) {
id, _ := uuid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff")
distroStruct := test_distro.New()
registry, err := distro_mock.NewDefaultRegistry()
if err != nil {
t.Fatal(err)
}
store := store.New(nil, *registry)
api := jobqueue.New(nil, store)
if from != "VOID" {
err := store.PushCompose(distroStruct, id, &blueprint.Blueprint{}, nil, nil, "x86_64", "qcow2", 0, nil)
if err != nil {
t.Fatalf("error pushing compose: %v", err)
}
if from != "WAITING" {
test.SendHTTP(api, false, "POST", "/job-queue/v1/jobs", `{}`)
if from != "RUNNING" {
test.SendHTTP(api, false, "PATCH", "/job-queue/v1/jobs/ffffffff-ffff-ffff-ffff-ffffffffffff/builds/0", `{"status":"`+from+`"}`)
}
}
}
test.TestNonJsonRoute(t, api, false, "PATCH", "/job-queue/v1/jobs/ffffffff-ffff-ffff-ffff-ffffffffffff/builds/0", `{"status":"`+to+`"}`, expectedStatus, expectedResponse)
}
func TestUpdate(t *testing.T) {
var cases = []struct {
From string
To string
ExpectedStatus int
ExpectedResponse string
}{
{"VOID", "WAITING", http.StatusNotFound, "compose does not exist"},
{"VOID", "RUNNING", http.StatusNotFound, "compose does not exist"},
{"VOID", "FINISHED", http.StatusNotFound, "compose does not exist"},
{"VOID", "FAILED", http.StatusNotFound, "compose does not exist"},
{"WAITING", "WAITING", http.StatusNotFound, "compose has not been popped"},
{"WAITING", "RUNNING", http.StatusNotFound, "compose has not been popped"},
{"WAITING", "FINISHED", http.StatusNotFound, "compose has not been popped"},
{"WAITING", "FAILED", http.StatusNotFound, "compose has not been popped"},
{"RUNNING", "WAITING", http.StatusBadRequest, "invalid state transition: image build cannot be moved into waiting state"},
{"RUNNING", "RUNNING", http.StatusOK, ""},
{"RUNNING", "FINISHED", http.StatusOK, ""},
{"RUNNING", "FAILED", http.StatusOK, ""},
{"FINISHED", "WAITING", http.StatusBadRequest, "invalid state transition: image build cannot be moved into waiting state"},
{"FINISHED", "RUNNING", http.StatusBadRequest, "invalid state transition: only waiting image build can be transitioned into running state"},
{"FINISHED", "FINISHED", http.StatusBadRequest, "invalid state transition: only running image build can be transitioned into finished or failed state"},
{"FINISHED", "FAILED", http.StatusBadRequest, "invalid state transition: only running image build can be transitioned into finished or failed state"},
{"FAILED", "WAITING", http.StatusBadRequest, "invalid state transition: image build cannot be moved into waiting state"},
{"FAILED", "RUNNING", http.StatusBadRequest, "invalid state transition: only waiting image build can be transitioned into running state"},
{"FAILED", "FINISHED", http.StatusBadRequest, "invalid state transition: only running image build can be transitioned into finished or failed state"},
{"FAILED", "FAILED", http.StatusBadRequest, "invalid state transition: only running image build can be transitioned into finished or failed state"},
}
for _, c := range cases {
testUpdateTransition(t, c.From, c.To, c.ExpectedStatus, c.ExpectedResponse)
}
}