store, weldr: Add support for fake composes

Yes. This goes against my desire not to change code to accommodate
tests. But there is no other good way to test compose results without
long running, and possibly fragile, composes. And this matches lorax's
behavior.

The change adds support for the ?test=1|2 query parameter to the compose
POST, and a new store function - PushTestCompose that handles creating
the fake compose results.

Passing ?test=1 will create a failed compose. Passing ?test=2 will
create a successful compose, but one without any files.

The purpose of these is to be able to test the compose result API
responses like compose/failed, etc.
This commit is contained in:
Brian C. Lane 2020-04-09 13:49:06 -07:00 committed by Tom Gundersen
parent ebeecfaf33
commit 2860398c2a
2 changed files with 90 additions and 1 deletions

View file

@ -554,6 +554,73 @@ func (s *Store) PushCompose(imageType distro.ImageType, bp *blueprint.Blueprint,
return composeID, nil
}
// PushTestCompose is used for testing
// Set testSuccess to create a fake successful compose, otherwise it will create a failed compose
// It does not actually run a compose job
func (s *Store) PushTestCompose(imageType distro.ImageType, bp *blueprint.Blueprint, repos []rpmmd.RepoConfig, packages, buildPackages []rpmmd.PackageSpec, size uint64, targets []*target.Target, testSuccess bool) (uuid.UUID, error) {
if targets == nil {
targets = []*target.Target{}
}
composeID := uuid.New()
// Compatibility layer for image types in Weldr API v0
imageTypeCommon, exists := common.ImageTypeFromCompatString(imageType.Name())
if !exists {
panic("fatal error, compose type does not exist")
}
if s.stateDir != nil {
outputDir := s.getImageBuildDirectory(composeID, 0)
err := os.MkdirAll(outputDir, 0755)
if err != nil {
return uuid.Nil, fmt.Errorf("cannot create output directory for job %v: %#v", composeID, err)
}
}
manifestStruct, err := imageType.Manifest(bp.Customizations, repos, packages, buildPackages, imageType.Size(size))
if err != nil {
return uuid.Nil, err
}
// FIXME: handle or comment this possible error
_ = s.change(func() error {
s.Composes[composeID] = compose.Compose{
Blueprint: bp,
ImageBuilds: []compose.ImageBuild{
{
QueueStatus: common.IBRunning,
Manifest: manifestStruct,
ImageType: imageTypeCommon,
Targets: targets,
JobCreated: time.Now(),
JobStarted: time.Now(),
Size: size,
},
},
}
return nil
})
var status common.ImageBuildState
var result common.ComposeResult
if testSuccess {
status = common.IBFinished
result = common.ComposeResult{Success: true}
} else {
status = common.IBFailed
result = common.ComposeResult{}
}
// Instead of starting the job, immediately set a final status
err = s.UpdateImageBuildInCompose(composeID, 0, status, &result)
if err != nil {
return uuid.Nil, err
}
return composeID, nil
}
// DeleteCompose deletes the compose from the state file and also removes all files on disk that are
// associated with this compose
func (s *Store) DeleteCompose(id uuid.UUID) error {

View file

@ -1467,7 +1467,29 @@ func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request
return
}
composeID, err := api.store.PushCompose(imageType, bp, api.allRepositories(), packages, buildPackages, cr.Size, targets)
var composeID uuid.UUID
// Check for test parameter
q, err := url.ParseQuery(request.URL.RawQuery)
if err != nil {
errors := responseError{
ID: "InvalidChars",
Msg: fmt.Sprintf("invalid query string: %v", err),
}
statusResponseError(writer, http.StatusBadRequest, errors)
return
}
testMode := q.Get("test")
if testMode == "1" {
// Create a failed compose
composeID, err = api.store.PushTestCompose(imageType, bp, api.allRepositories(), packages, buildPackages, cr.Size, targets, false)
} else if testMode == "2" {
// Create a successful compose
composeID, err = api.store.PushTestCompose(imageType, bp, api.allRepositories(), packages, buildPackages, cr.Size, targets, true)
} else {
composeID, err = api.store.PushCompose(imageType, bp, api.allRepositories(), packages, buildPackages, cr.Size, targets)
}
// TODO: we should probably do some kind of blueprint validation in future
// for now, let's just 500 and bail out