v2 tests: Make it easier to add mock handlers to newV2Server

This refactors the server setup, splitting the depsolve and ostree
resolve goroutine creation into helper functions. It also removes the
use of channels, which was always set to "" (and in the case of the
multi-tenancy test an empty list, which acts the same).

Related: RHEL-60136
This commit is contained in:
Brian C. Lane 2025-01-27 13:58:52 -08:00 committed by Tomáš Hozza
parent 532f1b0396
commit 17bebb547c
3 changed files with 73 additions and 55 deletions

View file

@ -25,7 +25,7 @@ type jobResult struct {
} }
func TestKojiCompose(t *testing.T) { func TestKojiCompose(t *testing.T) {
kojiServer, workerServer, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) kojiServer, workerServer, _, cancel := newV2Server(t, t.TempDir(), false, false)
handler := kojiServer.Handler("/api/image-builder-composer/v2") handler := kojiServer.Handler("/api/image-builder-composer/v2")
workerHandler := workerServer.Handler() workerHandler := workerServer.Handler()
defer cancel() defer cancel()
@ -557,7 +557,7 @@ func TestKojiCompose(t *testing.T) {
} }
func TestKojiJobTypeValidation(t *testing.T) { func TestKojiJobTypeValidation(t *testing.T) {
server, workers, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) server, workers, _, cancel := newV2Server(t, t.TempDir(), false, false)
handler := server.Handler("/api/image-builder-composer/v2") handler := server.Handler("/api/image-builder-composer/v2")
defer cancel() defer cancel()

View file

@ -196,9 +196,7 @@ func runNextJob(t *testing.T, jobs []uuid.UUID, workerHandler http.Handler, orgI
// that all jobs are assigned to the correct channel, therefore we need also // that all jobs are assigned to the correct channel, therefore we need also
// this test. // this test.
func TestMultitenancy(t *testing.T) { func TestMultitenancy(t *testing.T) {
// Passing an empty list as depsolving channels, we want to do depsolves apiServer, workerServer, q, cancel := newV2Server(t, t.TempDir(), true, false)
// ourselvess
apiServer, workerServer, q, cancel := newV2Server(t, t.TempDir(), []string{}, true, false)
handler := apiServer.Handler("/api/image-builder-composer/v2") handler := apiServer.Handler("/api/image-builder-composer/v2")
defer cancel() defer cancel()

View file

@ -69,37 +69,18 @@ var sbomDoc = json.RawMessage(`{
] ]
}`) }`)
func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT bool, failDepsolve bool) (*v2.Server, *worker.Server, jobqueue.JobQueue, context.CancelFunc) { // mockDepsolve starts a routine which just completes depsolve jobs
q, err := fsjobqueue.New(dir) // It requires some of the test framework to operate
require.NoError(t, err) // And the optional fail parameter will cause it to return an error as if the depsolve failed
workerServer := worker.NewServer(nil, q, worker.Config{BasePath: "/api/worker/v1", JWTEnabled: enableJWT, TenantProviderFields: []string{"rh-org-id", "account_id"}}) func mockDepsolve(t *testing.T, workerServer *worker.Server, wg *sync.WaitGroup, fail bool) func() {
ctx, cancel := context.WithCancel(context.Background())
distros := distrofactory.NewTestDefault()
require.NotNil(t, distros)
repos, err := reporegistry.New([]string{"../../../test/data"})
require.Nil(t, err)
require.NotNil(t, repos)
require.Greater(t, len(repos.ListDistros()), 0)
config := v2.ServerConfig{
JWTEnabled: enableJWT,
TenantProviderFields: []string{"rh-org-id", "account_id"},
}
v2Server := v2.NewServer(workerServer, distros, repos, 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) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
for { for {
_, token, _, _, _, err := workerServer.RequestJob(depsolveContext, test_distro.TestArchName, []string{worker.JobTypeDepsolve}, depsolveChannels, uuid.Nil) _, token, _, _, _, err := workerServer.RequestJob(ctx, test_distro.TestArchName, []string{worker.JobTypeDepsolve}, []string{""}, uuid.Nil)
select { select {
case <-depsolveContext.Done(): case <-ctx.Done():
return return
default: default:
} }
@ -147,7 +128,7 @@ func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT
ErrorType: worker.ErrorType(""), ErrorType: worker.ErrorType(""),
} }
if failDepsolve { if fail {
dJR.JobResult.JobError = clienterrors.New(clienterrors.ErrorDNFOtherError, "DNF Error", nil) dJR.JobResult.JobError = clienterrors.New(clienterrors.ErrorDNFOtherError, "DNF Error", nil)
} }
@ -160,15 +141,21 @@ func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT
} }
}() }()
return cancel
}
ostreeResolveContext, cancelOstree := context.WithCancel(context.Background()) // mockOSTreeResolve starts a routine which completes a dummy ostree job
// It requires some of the test framework to operate
// And the optional fail parameter will cause it to return an error as if the ostree job failed
func mockOSTreeResolve(t *testing.T, workerServer *worker.Server, wg *sync.WaitGroup, fail bool) func() {
ctx, cancel := context.WithCancel(context.Background())
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
for { for {
_, token, _, _, _, err := workerServer.RequestJob(ostreeResolveContext, test_distro.TestDistro1Name, []string{worker.JobTypeOSTreeResolve}, depsolveChannels, uuid.Nil) _, token, _, _, _, err := workerServer.RequestJob(ctx, test_distro.TestDistro1Name, []string{worker.JobTypeOSTreeResolve}, []string{""}, uuid.Nil)
select { select {
case <-ostreeResolveContext.Done(): case <-ctx.Done():
return return
default: default:
} }
@ -186,7 +173,7 @@ func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT
}, },
} }
if failDepsolve { if fail {
oJR.JobResult.JobError = clienterrors.New(clienterrors.ErrorOSTreeParamsInvalid, "ostree error", nil) oJR.JobResult.JobError = clienterrors.New(clienterrors.ErrorOSTreeParamsInvalid, "ostree error", nil)
} }
@ -199,9 +186,42 @@ func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT
} }
}() }()
return cancel
}
func newV2Server(t *testing.T, dir string, enableJWT bool, fail 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 := distrofactory.NewTestDefault()
require.NotNil(t, distros)
repos, err := reporegistry.New([]string{"../../../test/data"})
require.Nil(t, err)
require.NotNil(t, repos)
require.Greater(t, len(repos.ListDistros()), 0)
config := v2.ServerConfig{
JWTEnabled: enableJWT,
TenantProviderFields: []string{"rh-org-id", "account_id"},
}
v2Server := v2.NewServer(workerServer, distros, repos, config)
require.NotNil(t, v2Server)
t.Cleanup(v2Server.Shutdown)
// Setup the depsolve and ostree resolve job handlers
// These are mocked functions that return a static set of results for testing
var wg sync.WaitGroup
var cancelFuncs []context.CancelFunc
cancelFuncs = append(cancelFuncs, mockDepsolve(t, workerServer, &wg, fail))
cancelFuncs = append(cancelFuncs, mockOSTreeResolve(t, workerServer, &wg, fail))
cancelWithWait := func() { cancelWithWait := func() {
cancel() for _, cancel := range cancelFuncs {
cancelOstree() cancel()
}
wg.Wait() wg.Wait()
} }
@ -209,7 +229,7 @@ func newV2Server(t *testing.T, dir string, depsolveChannels []string, enableJWT
} }
func TestUnknownRoute(t *testing.T) { func TestUnknownRoute(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/badroute", ``, http.StatusNotFound, ` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/badroute", ``, http.StatusNotFound, `
@ -223,7 +243,7 @@ func TestUnknownRoute(t *testing.T) {
} }
func TestGetError(t *testing.T) { func TestGetError(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors/4", ``, http.StatusOK, ` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors/4", ``, http.StatusOK, `
@ -246,7 +266,7 @@ func TestGetError(t *testing.T) {
} }
func TestGetErrorList(t *testing.T) { func TestGetErrorList(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() 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, ` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/errors?page=3&size=1", ``, http.StatusOK, `
@ -265,7 +285,7 @@ func TestGetErrorList(t *testing.T) {
} }
func TestCompose(t *testing.T) { func TestCompose(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
testDistro := test_distro.DistroFactory(test_distro.TestDistro1Name) testDistro := test_distro.DistroFactory(test_distro.TestDistro1Name)
@ -656,7 +676,7 @@ func TestCompose(t *testing.T) {
} }
func TestComposeStatusSuccess(t *testing.T) { func TestComposeStatusSuccess(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -790,7 +810,7 @@ func TestComposeStatusSuccess(t *testing.T) {
} }
func TestComposeStatusFailure(t *testing.T) { func TestComposeStatusFailure(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -845,7 +865,7 @@ func TestComposeStatusFailure(t *testing.T) {
} }
func TestComposeStatusInvalidUUID(t *testing.T) { func TestComposeStatusInvalidUUID(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/composes/abcdef", ``, http.StatusBadRequest, ` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/composes/abcdef", ``, http.StatusBadRequest, `
@ -861,7 +881,7 @@ func TestComposeStatusInvalidUUID(t *testing.T) {
} }
func TestComposeJobError(t *testing.T) { func TestComposeJobError(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -922,7 +942,7 @@ func TestComposeJobError(t *testing.T) {
} }
func TestComposeDependencyError(t *testing.T) { func TestComposeDependencyError(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, true) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, true)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -999,7 +1019,7 @@ func TestComposeDependencyError(t *testing.T) {
} }
func TestComposeTargetErrors(t *testing.T) { func TestComposeTargetErrors(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -1091,7 +1111,7 @@ func TestComposeTargetErrors(t *testing.T) {
} }
func TestComposeCustomizations(t *testing.T) { func TestComposeCustomizations(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -1197,7 +1217,7 @@ func TestComposeCustomizations(t *testing.T) {
} }
func TestComposeRhcSubscription(t *testing.T) { func TestComposeRhcSubscription(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -1233,7 +1253,7 @@ func TestComposeRhcSubscription(t *testing.T) {
} }
func TestImageTypes(t *testing.T) { func TestImageTypes(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -1420,7 +1440,7 @@ func TestImageTypes(t *testing.T) {
} }
func TestImageFromCompose(t *testing.T) { func TestImageFromCompose(t *testing.T) {
srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, wrksrv, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(` test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
@ -1560,7 +1580,7 @@ func TestImageFromCompose(t *testing.T) {
} }
func TestDepsolveBlueprint(t *testing.T) { func TestDepsolveBlueprint(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST",
@ -1592,7 +1612,7 @@ func TestDepsolveBlueprint(t *testing.T) {
} }
func TestDepsolveDistroErrors(t *testing.T) { func TestDepsolveDistroErrors(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
// matching distros, but not supported // matching distros, but not supported
@ -1665,7 +1685,7 @@ func TestDepsolveDistroErrors(t *testing.T) {
} }
func TestDepsolveArchErrors(t *testing.T) { func TestDepsolveArchErrors(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), []string{""}, false, false) srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel() defer cancel()
// Unsupported architecture // Unsupported architecture