debian-forge-composer/internal/worker/server_test.go
Tom Gundersen 0417c6d8bb distro: make the osbuild package internal to the distros
Rather than Manifest() returning an osbuild.Manifest object, introduce a
new distro.Manifest object which represents it as an opaque, JSON
serializable object. This new type has the following properties:

1) its serialization is compatible with the input to osbuild,
2) any valid osbuild input can be deserialized into it, and
3) marshalling and unmarshaling to and from JSON is lossless.

This means that even as we change the subset of valid osbulid manifests
that we support, we can still load any previous state from disk, and it
will continue to work just as before, even though we can no longer
deserialize it into our internal notion of osbuild.Manifest.

This fixes the underlying problem of which #685 was a symptom.

Signed-off-by: Tom Gundersen <teg@jklm.no>
2020-06-03 00:30:01 +02:00

138 lines
4.6 KiB
Go

package worker_test
import (
"net/http"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/distro/fedoratest"
"github.com/osbuild/osbuild-composer/internal/jobqueue/testjobqueue"
"github.com/osbuild/osbuild-composer/internal/test"
"github.com/osbuild/osbuild-composer/internal/worker"
)
// Ensure that the status request returns OK.
func TestStatus(t *testing.T) {
server := worker.NewServer(nil, testjobqueue.New(), "")
test.TestRoute(t, server, false, "GET", "/status", ``, http.StatusOK, `{"status":"OK"}`, "message")
}
func TestErrors(t *testing.T) {
var cases = []struct {
Method string
Path string
Body string
ExpectedStatus int
}{
// Bogus path
{"GET", "/foo", ``, http.StatusNotFound},
// Create job with invalid body
{"POST", "/job-queue/v1/jobs", ``, http.StatusBadRequest},
// Wrong method
{"GET", "/job-queue/v1/jobs", ``, http.StatusMethodNotAllowed},
// Update job with invalid ID
{"PATCH", "/job-queue/v1/jobs/foo", `{"status":"FINISHED"}`, http.StatusBadRequest},
// Update job that does not exist, with invalid body
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", ``, http.StatusBadRequest},
// Update job that does not exist
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", `{"status":"FINISHED"}`, http.StatusNotFound},
}
for _, c := range cases {
server := worker.NewServer(nil, testjobqueue.New(), "")
test.TestRoute(t, server, false, c.Method, c.Path, c.Body, c.ExpectedStatus, "{}", "message")
}
}
func TestCreate(t *testing.T) {
distroStruct := fedoratest.New()
arch, err := distroStruct.GetArch("x86_64")
if err != nil {
t.Fatalf("error getting arch from distro")
}
imageType, err := arch.GetImageType("qcow2")
if err != nil {
t.Fatalf("error getting image type from arch")
}
manifest, err := imageType.Manifest(nil, distro.ImageOptions{Size: imageType.Size(0)}, nil, nil, nil)
if err != nil {
t.Fatalf("error creating osbuild manifest")
}
server := worker.NewServer(nil, testjobqueue.New(), "")
id, err := server.Enqueue(manifest, nil)
require.NoError(t, err)
test.TestRoute(t, server, false, "POST", "/job-queue/v1/jobs", `{}`, http.StatusCreated,
`{"id":"`+id.String()+`","manifest":{"sources":{},"pipeline":{}}}`, "created")
}
func testUpdateTransition(t *testing.T, from, to string, expectedStatus int) {
distroStruct := fedoratest.New()
arch, err := distroStruct.GetArch("x86_64")
if err != nil {
t.Fatalf("error getting arch from distro")
}
imageType, err := arch.GetImageType("qcow2")
if err != nil {
t.Fatalf("error getting image type from arch")
}
server := worker.NewServer(nil, testjobqueue.New(), "")
id := uuid.Nil
if from != "VOID" {
manifest, err := imageType.Manifest(nil, distro.ImageOptions{Size: imageType.Size(0)}, nil, nil, nil)
if err != nil {
t.Fatalf("error creating osbuild manifest")
}
id, err = server.Enqueue(manifest, nil)
require.NoError(t, err)
if from != "WAITING" {
test.SendHTTP(server, false, "POST", "/job-queue/v1/jobs", `{}`)
if from != "RUNNING" {
test.SendHTTP(server, false, "PATCH", "/job-queue/v1/jobs/"+id.String(), `{"status":"`+from+`"}`)
}
}
}
test.TestRoute(t, server, false, "PATCH", "/job-queue/v1/jobs/"+id.String(), `{"status":"`+to+`"}`, expectedStatus, "{}", "message")
}
func TestUpdate(t *testing.T) {
var cases = []struct {
From string
To string
ExpectedStatus int
}{
{"VOID", "WAITING", http.StatusBadRequest},
{"VOID", "RUNNING", http.StatusBadRequest},
{"VOID", "FINISHED", http.StatusNotFound},
{"VOID", "FAILED", http.StatusNotFound},
{"WAITING", "WAITING", http.StatusBadRequest},
{"WAITING", "RUNNING", http.StatusBadRequest},
{"WAITING", "FINISHED", http.StatusBadRequest},
{"WAITING", "FAILED", http.StatusBadRequest},
{"RUNNING", "WAITING", http.StatusBadRequest},
{"RUNNING", "RUNNING", http.StatusBadRequest},
{"RUNNING", "FINISHED", http.StatusOK},
{"RUNNING", "FAILED", http.StatusOK},
{"FINISHED", "WAITING", http.StatusBadRequest},
{"FINISHED", "RUNNING", http.StatusBadRequest},
{"FINISHED", "FINISHED", http.StatusBadRequest},
{"FINISHED", "FAILED", http.StatusBadRequest},
{"FAILED", "WAITING", http.StatusBadRequest},
{"FAILED", "RUNNING", http.StatusBadRequest},
{"FAILED", "FINISHED", http.StatusBadRequest},
{"FAILED", "FAILED", http.StatusBadRequest},
}
for _, c := range cases {
t.Log(c)
testUpdateTransition(t, c.From, c.To, c.ExpectedStatus)
}
}