debian-forge-composer/internal/worker/client_test.go
Tomas Hozza a4e6531565 worker: define job types as constants
Define supported job type names as constants and use them in all places,
instead of string literals.

There are multiple benefits of this approach. Using constants removed
the room for typos in the string literals. One can use autocompletion in
IDE for job types. Using constant makes it easier to find all references
where it is used and thus all places that are handling a specific job
type.
2022-06-10 14:48:18 +01:00

138 lines
3.8 KiB
Go

package worker_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/osbuild/osbuild-composer/internal/jobqueue/fsjobqueue"
"github.com/osbuild/osbuild-composer/internal/worker"
)
// newTestWorkerServer returns 3 strings:
// - base URL of the worker server
// - base URL of the OAuth server
// - offline token for OAuth
//
// The worker server has one pending osbuild job of arch "arch" ready to be dequeued.
func newTestWorkerServer(t *testing.T) (string, string, string) {
tempdir := t.TempDir()
q, err := fsjobqueue.New(tempdir)
require.NoError(t, err)
config := worker.Config{
ArtifactsDir: tempdir,
BasePath: "/api/image-builder-worker/v1",
}
workerServer := worker.NewServer(nil, q, config)
_, err = workerServer.EnqueueOSBuild("arch", &worker.OSBuildJob{}, "")
require.NoError(t, err)
handler := workerServer.Handler()
workSrv := httptest.NewServer(handler)
t.Cleanup(workSrv.Close)
offlineToken := "someOfflineToken"
accessToken := "accessToken!"
/* Check that the worker supplies the access token */
calls := 0
proxySrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if calls == 0 {
require.Equal(t, "Bearer", r.Header.Get("Authorization"))
w.WriteHeader(http.StatusUnauthorized)
return
}
require.Equal(t, "Bearer "+accessToken, r.Header.Get("Authorization"))
handler.ServeHTTP(w, r)
}))
t.Cleanup(proxySrv.Close)
/* Start oauth srv supplying the bearer token */
oauthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
calls += 1
require.Equal(t, "POST", r.Method)
err := r.ParseForm()
require.NoError(t, err)
require.Equal(t, "refresh_token", r.FormValue("grant_type"))
require.Equal(t, "rhsm-api", r.FormValue("client_id"))
require.Equal(t, offlineToken, r.FormValue("refresh_token"))
bt := struct {
AccessToken string `json:"access_token"`
}{
accessToken,
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(bt)
require.NoError(t, err)
}))
t.Cleanup(oauthSrv.Close)
return proxySrv.URL, oauthSrv.URL, offlineToken
}
func TestOAuth(t *testing.T) {
workerURL, oauthURL, offlineToken := newTestWorkerServer(t)
client, err := worker.NewClient(worker.ClientConfig{
BaseURL: workerURL,
TlsConfig: nil,
ClientId: "rhsm-api",
OfflineToken: offlineToken,
OAuthURL: oauthURL,
BasePath: "/api/image-builder-worker/v1",
})
require.NoError(t, err)
job, err := client.RequestJob([]string{worker.JobTypeOSBuild}, "arch")
require.NoError(t, err)
r := strings.NewReader("artifact contents")
require.NoError(t, job.UploadArtifact("some-artifact", r))
c, err := job.Canceled()
require.False(t, c)
require.NoError(t, err)
}
func TestProxy(t *testing.T) {
workerURL, oauthURL, offlineToken := newTestWorkerServer(t)
// initialize a test proxy server
proxy := &proxy{}
proxySrv := httptest.NewServer(proxy)
t.Cleanup(proxySrv.Close)
client, err := worker.NewClient(worker.ClientConfig{
BaseURL: workerURL,
TlsConfig: nil,
ClientId: "rhsm-api",
OfflineToken: offlineToken,
OAuthURL: oauthURL,
BasePath: "/api/image-builder-worker/v1",
ProxyURL: proxySrv.URL,
})
require.NoError(t, err)
job, err := client.RequestJob([]string{worker.JobTypeOSBuild}, "arch")
require.NoError(t, err)
r := strings.NewReader("artifact contents")
require.NoError(t, job.UploadArtifact("some-artifact", r))
c, err := job.Canceled()
require.False(t, c)
require.NoError(t, err)
// we expect 5 calls to go through the proxy:
// - request job (fails, no oauth token)
// - oauth call
// - request job (succeeds)
// - upload artifact
// - cancel
require.Equal(t, 5, proxy.calls)
}