Add weldrcheck package to hold the integration tests
These tests build on the client functions to run integration tests on a running API server. It uses the reflect module to examine the methods attached to the checkBlueprintsV0 struct and run the ones with names that start with 'Check', also checking the type signature of the functions and failing the test if any of them don't match. This will make it easier to add more checks without needing to add boilerplate call/registration of the functions in the top level runner. Just add the new function with the right name and signature and it will be run when checkBlueprintsV0.Run() is called. Checks for other API routes should be added to their own modules. There will be some duplication of the Run function in each, but I think that it will help keep things more manageable by separating them instead of putting them all into a single giant Run() call.
This commit is contained in:
parent
ea1b633d3a
commit
f298fed16d
2 changed files with 1044 additions and 0 deletions
941
internal/weldrcheck/blueprints.go
Normal file
941
internal/weldrcheck/blueprints.go
Normal file
|
|
@ -0,0 +1,941 @@
|
|||
// Package weldrcheck - blueprints contains functions to check the blueprints API
|
||||
// Copyright (C) 2020 by Red Hat, Inc.
|
||||
package weldrcheck
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/client"
|
||||
)
|
||||
|
||||
type checkBlueprintsV0 struct {
|
||||
socket string
|
||||
}
|
||||
|
||||
// Run will execute the API V0 Blueprint check functions
|
||||
// This will call all of the methods that start with 'Check', passing them a pointer to a
|
||||
// checkBlueprintsV0 struct and expecting a bool to be returned to indicate whether or not the test
|
||||
// passed.
|
||||
// If any of the tests fail it will return false.
|
||||
func (c *checkBlueprintsV0) Run() bool {
|
||||
pass := true
|
||||
|
||||
// Construct a reflect.Type to use for checking method type signatures
|
||||
boolType := reflect.TypeOf(true)
|
||||
structType := reflect.TypeOf(c)
|
||||
funcType := reflect.FuncOf([]reflect.Type{structType}, []reflect.Type{boolType}, false)
|
||||
|
||||
structValue := reflect.ValueOf(c)
|
||||
// Get all the exported methods on this struct named 'Check*' and run them
|
||||
for i := 0; i < structType.NumMethod(); i++ {
|
||||
method := structType.Method(i)
|
||||
// Make sure it starts with Check and matches the type signature
|
||||
if strings.HasPrefix(method.Name, "Check") {
|
||||
if method.Type != funcType {
|
||||
log.Printf("ERROR: Check function '%s' has wrong type: %s", method.Name, method.Type)
|
||||
pass = false
|
||||
continue
|
||||
}
|
||||
|
||||
r := structValue.Method(i).Call(nil)
|
||||
if !r[0].Bool() {
|
||||
pass = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pass
|
||||
}
|
||||
|
||||
// POST a new TOML blueprint
|
||||
func (c *checkBlueprintsV0) CheckPostTOML() bool {
|
||||
name := "POST of a TOML blueprint"
|
||||
|
||||
bp := `
|
||||
name="test-toml-blueprint-v0"
|
||||
description="postTOMLBlueprintV0"
|
||||
version="0.0.1"
|
||||
[[packages]]
|
||||
name="bash"
|
||||
version="*"
|
||||
|
||||
[[modules]]
|
||||
name="util-linux"
|
||||
version="*"
|
||||
|
||||
[[customizations.user]]
|
||||
name="root"
|
||||
password="qweqweqwe"
|
||||
`
|
||||
resp := client.PostTOMLBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// POST a new JSON blueprint
|
||||
func (c *checkBlueprintsV0) CheckPostJSON() bool {
|
||||
name := "POST of a JSON blueprint"
|
||||
|
||||
bp := `{
|
||||
"name": "test-json-blueprint-v0",
|
||||
"description": "postJSONBlueprintV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// POST a blueprint to the workspace as TOML
|
||||
func (c *checkBlueprintsV0) CheckPostTOMLWS() bool {
|
||||
name := "POST TOML blueprint to workspace"
|
||||
|
||||
bp := `
|
||||
name="test-toml-blueprint-ws-v0"
|
||||
description="postTOMLBlueprintWSV0"
|
||||
version="0.0.1"
|
||||
[[packages]]
|
||||
name="bash"
|
||||
version="*"
|
||||
|
||||
[[modules]]
|
||||
name="util-linux"
|
||||
version="*"
|
||||
|
||||
[[customizations.user]]
|
||||
name="root"
|
||||
password="qweqweqwe"
|
||||
`
|
||||
resp := client.PostTOMLWorkspaceV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// POST a blueprint to the workspace as JSON
|
||||
func (c *checkBlueprintsV0) CheckPostJSONWS() bool {
|
||||
name := "POST JSON blueprint to workspace"
|
||||
|
||||
bp := `{
|
||||
"name": "test-json-blueprint-ws-v0",
|
||||
"description": "postJSONBlueprintWSV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp := client.PostJSONWorkspaceV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// delete a blueprint
|
||||
func (c *checkBlueprintsV0) CheckDelete() bool {
|
||||
name := "DELETE blueprint"
|
||||
|
||||
// POST a blueprint to delete
|
||||
bp := `{
|
||||
"name": "test-delete-blueprint-v0",
|
||||
"description": "deleteBlueprintV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Delete the blueprint
|
||||
resp = client.DeleteBlueprintV0(c.socket, "test-delete-blueprint-v0")
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// delete a new blueprint from the workspace
|
||||
func (c *checkBlueprintsV0) CheckDeleteNewWS() bool {
|
||||
name := "DELETE new blueprint from workspace"
|
||||
|
||||
// POST a blueprint to delete
|
||||
bp := `{
|
||||
"name": "test-delete-new-blueprint-ws-v0",
|
||||
"description": "deleteNewBlueprintWSV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp := client.PostJSONWorkspaceV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Delete the blueprint
|
||||
resp = client.DeleteWorkspaceV0(c.socket, "test-delete-new-blueprint-ws-v0")
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// delete blueprint changes from the workspace
|
||||
func (c *checkBlueprintsV0) CheckDeleteChangesWS() bool {
|
||||
name := "DELETE blueprint changes from workspace"
|
||||
|
||||
// POST a blueprint first
|
||||
bp := `{
|
||||
"name": "test-delete-blueprint-changes-ws-v0",
|
||||
"description": "deleteBlueprintChangesWSV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Post blueprint changes to the workspace
|
||||
bp = `{
|
||||
"name": "test-delete-blueprint-changes-ws-v0",
|
||||
"description": "workspace copy",
|
||||
"version": "0.2.0",
|
||||
"packages": [{"name": "frobozz", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
resp = client.PostJSONWorkspaceV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint, make sure it is the modified one and that changes = true
|
||||
info, err := client.GetBlueprintsInfoJSONV0(c.socket, "test-delete-blueprint-changes-ws-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: No change states returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Name != "test-delete-blueprint-changes-ws-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong blueprint returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Name != "test-delete-blueprint-changes-ws-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong change state returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Changed != true {
|
||||
log.Printf("FAIL: %s failed: wrong change state returned (false)", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Description != "workspace copy" {
|
||||
log.Printf("FAIL: %s failed: workspace copy not returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Delete the blueprint from the workspace
|
||||
resp = client.DeleteWorkspaceV0(c.socket, "test-delete-blueprint-changes-ws-v0")
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint, make sure it is the un-modified one
|
||||
info, err = client.GetBlueprintsInfoJSONV0(c.socket, "test-delete-blueprint-changes-ws-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: No change states returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Name != "test-delete-blueprint-changes-ws-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong blueprint returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Name != "test-delete-blueprint-changes-ws-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong change state returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Changed != false {
|
||||
log.Printf("FAIL: %s failed: wrong change state returned (true)", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Description != "deleteBlueprintChangesWSV0" {
|
||||
log.Printf("FAIL: %s failed: original blueprint not returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// list blueprints
|
||||
func (c *checkBlueprintsV0) CheckList() bool {
|
||||
name := "List blueprints"
|
||||
// Post a couple of blueprints
|
||||
bps := []string{`{
|
||||
"name": "test-list-blueprint-1-v0",
|
||||
"description": "listBlueprintsV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`,
|
||||
`{
|
||||
"name": "test-list-blueprint-2-v0",
|
||||
"description": "listBlueprintsV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`}
|
||||
|
||||
for i := range bps {
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bps[i])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Get the list of blueprints
|
||||
list, err := client.ListBlueprintsV0(c.socket)
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Make sure the blueprints are in the list
|
||||
sorted := sort.StringSlice(list)
|
||||
if !isStringInSlice(sorted, "test-list-blueprint-1-v0") ||
|
||||
!isStringInSlice(sorted, "test-list-blueprint-2-v0") {
|
||||
log.Printf("FAIL: %s failed", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// get blueprint contents as TOML
|
||||
func (c *checkBlueprintsV0) CheckGetTOML() bool {
|
||||
name := "Get TOML Blueprint"
|
||||
bp := `{
|
||||
"name": "test-get-blueprint-1-v0",
|
||||
"description": "getTOMLBlueprintV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
// Post a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get it as TOML
|
||||
body, err := client.GetBlueprintInfoTOMLV0(c.socket, "test-get-blueprint-1-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
log.Printf("FAIL: %s failed: body of response is empty", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Can it be decoded as TOML?
|
||||
var decoded interface{}
|
||||
if _, err := toml.Decode(body, &decoded); err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// get blueprint contents as JSON
|
||||
func (c *checkBlueprintsV0) CheckGetJSON() bool {
|
||||
name := "Get JSON Blueprint"
|
||||
bp := `{
|
||||
"name": "test-get-blueprint-2-v0",
|
||||
"description": "getJSONBlueprintV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
// Post a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint and its changed state
|
||||
info, err := client.GetBlueprintsInfoJSONV0(c.socket, "test-get-blueprint-2-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: No change states returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Name != "test-get-blueprint-2-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong blueprint returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Name != "test-get-blueprint-2-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong change state returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Changes[0].Changed != false {
|
||||
log.Printf("FAIL: %s failed: unexpected changes", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// pushing the same blueprint bumps the version number returned by show
|
||||
func (c *checkBlueprintsV0) CheckBumpVersion() bool {
|
||||
name := "Bump Blueprint Version number"
|
||||
bp := `{
|
||||
"name": "test-bump-blueprint-1-v0",
|
||||
"description": "bumpBlueprintVersionV0",
|
||||
"version": "2.1.2",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`
|
||||
|
||||
// List blueprints
|
||||
list, err := client.ListBlueprintsV0(c.socket)
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// If the blueprint already exists it needs to be deleted to start from a known state
|
||||
sorted := sort.StringSlice(list)
|
||||
if isStringInSlice(sorted, "test-bump-blueprint-1-v0") {
|
||||
// Delete this blueprint if it already exists
|
||||
resp := client.DeleteBlueprintV0(c.socket, "test-bump-blueprint-1-v0")
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Post a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Post a blueprint again to bump verion to 2.1.3
|
||||
resp = client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint and its changed state
|
||||
info, err := client.GetBlueprintsInfoJSONV0(c.socket, "test-bump-blueprint-1-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Name != "test-bump-blueprint-1-v0" {
|
||||
log.Printf("FAIL: %s failed: wrong blueprint returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Version != "2.1.3" {
|
||||
log.Printf("FAIL: %s failed: wrong blueprint version", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// Make several changes to a blueprint and list the changes
|
||||
func (c *checkBlueprintsV0) CheckBlueprintChangesV0() bool {
|
||||
name := "List blueprint changes"
|
||||
|
||||
bps := []string{`{
|
||||
"name": "test-blueprint-changes-v0",
|
||||
"description": "CheckBlueprintChangesV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}]
|
||||
}`,
|
||||
`{
|
||||
"name": "test-blueprint-changes-v0",
|
||||
"description": "CheckBlueprintChangesV0",
|
||||
"version": "0.1.0",
|
||||
"packages": [{"name": "bash", "version": "*"}, {"name": "tmux", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`,
|
||||
`{
|
||||
"name": "test-blueprint-changes-v0",
|
||||
"description": "CheckBlueprintChangesV0",
|
||||
"version": "0.1.1",
|
||||
"packages": [{"name": "bash", "version": "*"}, {"name": "tmux", "version": "*"}],
|
||||
"modules": [],
|
||||
"customizations": {"user": [{"name": "root", "password": "asdasdasd"}]}
|
||||
}`}
|
||||
|
||||
// Push 3 changes to the blueprint
|
||||
for i := range bps {
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bps[i])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// List the changes
|
||||
changes, err := client.GetBlueprintsChangesV0(c.socket, []string{"test-blueprint-changes-v0"})
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges) != 1 {
|
||||
log.Printf("FAIL: %s failed: No changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if changes.BlueprintsChanges[0].Name != "test-blueprint-changes-v0" {
|
||||
log.Printf("FAIL: %s failed: Wrong blueprint changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges[0].Changes) < 3 {
|
||||
log.Printf("FAIL: %s failed: Wrong number of changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// Undo blueprint changes
|
||||
func (c *checkBlueprintsV0) CheckUndoBlueprintV0() bool {
|
||||
name := "Undo blueprint changes"
|
||||
|
||||
bps := []string{`{
|
||||
"name": "test-undo-blueprint-v0",
|
||||
"description": "CheckUndoBlueprintV0",
|
||||
"version": "0.0.5",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`,
|
||||
`{
|
||||
"name": "test-undo-blueprint-v0",
|
||||
"description": "CheckUndoBlueprintv0",
|
||||
"version": "0.0.6",
|
||||
"packages": [{"name": "bash", "version": "0.5.*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`}
|
||||
|
||||
// Push original version of the blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bps[0])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the commit hash
|
||||
changes, err := client.GetBlueprintsChangesV0(c.socket, []string{"test-undo-blueprint-v0"})
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges) != 1 {
|
||||
log.Printf("FAIL: %s failed: No changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges[0].Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: Wrong number of changes returned", name)
|
||||
return false
|
||||
}
|
||||
commit := changes.BlueprintsChanges[0].Changes[0].Commit
|
||||
|
||||
if len(commit) == 0 {
|
||||
log.Printf("FAIL: %s failed: First commit is empty", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Push the new version with wrong bash version
|
||||
resp = client.PostJSONBlueprintV0(c.socket, bps[1])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint, confirm bash version is '0.5.*'
|
||||
info, err := client.GetBlueprintsInfoJSONV0(c.socket, "test-undo-blueprint-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints[0].Packages) < 1 {
|
||||
log.Printf("FAIL: %s failed: No packages in the blueprint", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Packages[0].Name != "bash" ||
|
||||
info.Blueprints[0].Packages[0].Version != "0.5.*" {
|
||||
log.Printf("FAIL: %s failed to push change: Wrong package in the blueprint: %s", name, info.Blueprints[0].Packages[0])
|
||||
log.Printf("%#v", info)
|
||||
return false
|
||||
}
|
||||
|
||||
// Revert the blueprint to the original version
|
||||
resp = client.UndoBlueprintChangeV0(c.socket, "test-undo-blueprint-v0", commit)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the blueprint, confirm bash version is '*'
|
||||
info, err = client.GetBlueprintsInfoJSONV0(c.socket, "test-undo-blueprint-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(info.Blueprints[0].Packages) < 1 {
|
||||
log.Printf("FAIL: %s failed: No packages in the blueprint", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if info.Blueprints[0].Packages[0].Name != "bash" ||
|
||||
info.Blueprints[0].Packages[0].Version != "*" {
|
||||
log.Printf("FAIL: %s failed to undo change: Wrong package in the blueprint: %s", name, info.Blueprints[0].Packages[0])
|
||||
log.Printf("%#v", info)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// Tag a blueprint with a new revision
|
||||
// The blueprint revision tag cannot be reset, it always increments by one, and cannot be deleted.
|
||||
// So to test tagging we tag two blueprint changes and make sure the second is first +1
|
||||
func (c *checkBlueprintsV0) CheckBlueprintTagV0() bool {
|
||||
name := "Tag a blueprint"
|
||||
|
||||
bps := []string{`{
|
||||
"name": "test-tag-blueprint-v0",
|
||||
"description": "CheckBlueprintTagV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "0.1.*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`,
|
||||
`{
|
||||
"name": "test-tag-blueprint-v0",
|
||||
"description": "CheckBlueprintTagV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "0.5.*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}],
|
||||
"customizations": {"user": [{"name": "root", "password": "qweqweqwe"}]}
|
||||
}`}
|
||||
|
||||
// Push a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bps[0])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s POST failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Tag the blueprint
|
||||
tagResp := client.TagBlueprintV0(c.socket, "test-tag-blueprint-v0")
|
||||
if tagResp.Status != true {
|
||||
log.Printf("FAIL: %s Tag failed: %s", name, tagResp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get changes, get the blueprint's revision
|
||||
changes, err := client.GetBlueprintsChangesV0(c.socket, []string{"test-tag-blueprint-v0"})
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s GET changes failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges) != 1 {
|
||||
log.Printf("FAIL: %s failed: No changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges[0].Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: Wrong number of changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
revision := changes.BlueprintsChanges[0].Changes[0].Revision
|
||||
if revision == nil || *revision == 0 {
|
||||
log.Printf("FAIL: %s failed: Revision is zero", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// Push a new version of the blueprint
|
||||
resp = client.PostJSONBlueprintV0(c.socket, bps[1])
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s POST failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Tag the blueprint
|
||||
tagResp = client.TagBlueprintV0(c.socket, "test-tag-blueprint-v0")
|
||||
if tagResp.Status != true {
|
||||
log.Printf("FAIL: %s Tag failed: %s", name, tagResp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Get changes, confirm that Revision is revision +1
|
||||
changes, err = client.GetBlueprintsChangesV0(c.socket, []string{"test-tag-blueprint-v0"})
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges) != 1 {
|
||||
log.Printf("FAIL: %s failed: No changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(changes.BlueprintsChanges[0].Changes) < 1 {
|
||||
log.Printf("FAIL: %s failed: Wrong number of changes returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
newRevision := changes.BlueprintsChanges[0].Changes[0].Revision
|
||||
if newRevision == nil || *newRevision != *revision+1 {
|
||||
log.Printf("FAIL: %s failed: Revision is not %d", name, *revision+1)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// depsolve a blueprint with packages and modules
|
||||
func (c *checkBlueprintsV0) CheckBlueprintDepsolveV0() bool {
|
||||
name := "Depsolve a blueprint"
|
||||
|
||||
bp := `{
|
||||
"name": "test-deps-blueprint-v0",
|
||||
"description": "CheckBlueprintDepsolveV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}]
|
||||
}`
|
||||
|
||||
// Push a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s POST failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Depsolve the blueprint
|
||||
deps, err := client.DepsolveBlueprintV0(c.socket, "test-deps-blueprint-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
if len(deps.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No blueprint dependencies returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(deps.Blueprints[0].Dependencies) < 3 {
|
||||
log.Printf("FAIL: %s failed: Not enough dependencies returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Get the bash and util-linux dependencies and make sure their versions are not *
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// freeze a blueprint
|
||||
func (c *checkBlueprintsV0) CheckBlueprintFreezeV0() bool {
|
||||
name := "Freeze a blueprint"
|
||||
|
||||
bp := `{
|
||||
"name": "test-freeze-blueprint-v0",
|
||||
"description": "CheckBlueprintFreezeV0",
|
||||
"version": "0.0.1",
|
||||
"packages": [{"name": "bash", "version": "*"}],
|
||||
"modules": [{"name": "util-linux", "version": "*"}]
|
||||
}`
|
||||
|
||||
// Push a blueprint
|
||||
resp := client.PostJSONBlueprintV0(c.socket, bp)
|
||||
if resp.Status != true {
|
||||
log.Printf("FAIL: %s POST failed: %s", name, resp.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// Freeze the blueprint
|
||||
frozen, err := client.FreezeBlueprintV0(c.socket, "test-freeze-blueprint-v0")
|
||||
if err != nil {
|
||||
log.Printf("FAIL: %s failed: %s", name, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
if len(frozen.Blueprints) < 1 {
|
||||
log.Printf("FAIL: %s failed: No frozen blueprints returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(frozen.Blueprints[0].Blueprint.Packages) < 1 {
|
||||
log.Printf("FAIL: %s failed: No frozen packages returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if frozen.Blueprints[0].Blueprint.Packages[0].Name != "bash" ||
|
||||
frozen.Blueprints[0].Blueprint.Packages[0].Version == "*" {
|
||||
log.Printf("FAIL: %s failed: Incorrect frozen packages", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(frozen.Blueprints[0].Blueprint.Modules) < 1 {
|
||||
log.Printf("FAIL: %s failed: No frozen modules returned", name)
|
||||
return false
|
||||
}
|
||||
|
||||
if frozen.Blueprints[0].Blueprint.Modules[0].Name != "util-linux" ||
|
||||
frozen.Blueprints[0].Blueprint.Modules[0].Version == "*" {
|
||||
log.Printf("FAIL: %s failed: Incorrect frozen modules", name)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Printf("OK: %s was successful", name)
|
||||
return true
|
||||
}
|
||||
|
||||
// diff of blueprint changes
|
||||
func (c *checkBlueprintsV0) CheckBlueprintDiffV0() bool {
|
||||
name := "Diff of blueprint changes"
|
||||
log.Printf("SKIP: %s was skipped, needs to be implemented", name)
|
||||
return true
|
||||
}
|
||||
103
internal/weldrcheck/check.go
Normal file
103
internal/weldrcheck/check.go
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// Package weldrcheck contains functions used to run integration tests on a running API server
|
||||
// Copyright (C) 2020 by Red Hat, Inc.
|
||||
package weldrcheck
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/client"
|
||||
)
|
||||
|
||||
// Checks should be self-contained and not depend on the state of the server
|
||||
// They should use their own blueprints, not the default blueprints
|
||||
// They should not assume version numbers for packages will match
|
||||
// They should run checks that depend on previous results from the same function
|
||||
// not from other functions.
|
||||
// The blueprint version number may get bumped if the server has had tests run before
|
||||
// do not assume the bp version will match unless first deleting the old one.
|
||||
|
||||
// isStringInSlice returns true if the string is present, false if not
|
||||
// slice must be sorted
|
||||
// TODO decide if this belongs in a more widely useful package location
|
||||
func isStringInSlice(slice []string, s string) bool {
|
||||
i := sort.SearchStrings(slice, s)
|
||||
if i < len(slice) && slice[i] == s {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Run the API V0 checks against the server
|
||||
// Return true if all the checks pass
|
||||
func runV0Checks(socket string) (pass bool) {
|
||||
pass = true
|
||||
|
||||
bpv0 := checkBlueprintsV0{socket}
|
||||
pass = bpv0.Run()
|
||||
|
||||
if pass {
|
||||
log.Println("OK: ALL V0 API checks were successful")
|
||||
} else {
|
||||
log.Println("FAIL: One or more V0 API checks failed")
|
||||
}
|
||||
return pass
|
||||
}
|
||||
|
||||
// Run the V1 checks against the server
|
||||
func runV1Checks(socket string) (pass bool) {
|
||||
pass = true
|
||||
|
||||
if pass {
|
||||
log.Println("OK: ALL V1 API checks were successful")
|
||||
} else {
|
||||
log.Println("FAIL: One or more V1 API checks failed")
|
||||
}
|
||||
return pass
|
||||
}
|
||||
|
||||
// Run executes all of the weldr API checks against a running API server
|
||||
// This is designed to run against any WELDR API server, not just osbuild-composer
|
||||
func Run(socket string) {
|
||||
log.Printf("Running API check on %s", socket)
|
||||
|
||||
// Does the socket exist?
|
||||
if _, err := os.Stat(socket); os.IsNotExist(err) {
|
||||
log.Printf("ERROR: API socket %s is missing", socket)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Does the server respond to /api/status?
|
||||
status, err := client.GetStatusV0(socket)
|
||||
if err != nil {
|
||||
log.Printf("ERROR: status request failed: %s", err)
|
||||
// If status check fails there is no point in continuing
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Print("OK: status request")
|
||||
apiVersion, e := strconv.Atoi(status.API)
|
||||
if e != nil {
|
||||
log.Printf("ERROR: status API version error: %s", e)
|
||||
log.Println("ERROR: Only running V0 checks")
|
||||
apiVersion = 0
|
||||
}
|
||||
log.Printf("INFO: Running tests against: %s %s server using V%d API", status.Backend, status.Build, apiVersion)
|
||||
|
||||
// Run the V0 checks
|
||||
log.Println("INFO: Running API V0 checks")
|
||||
pass := runV0Checks(socket)
|
||||
|
||||
// Run the V1 checks if the server claims to support it
|
||||
if apiVersion > 0 {
|
||||
log.Println("INFO: Running API V1 checks")
|
||||
passV1 := runV1Checks(socket)
|
||||
|
||||
pass = pass && passV1
|
||||
}
|
||||
|
||||
if !pass {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue