Blame internal/distro/distro_test_common/distro_test_common.go

Packit 63bb0d
package distro_test_common
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"encoding/json"
Packit 63bb0d
	"fmt"
Packit 63bb0d
	"io/ioutil"
Packit 63bb0d
	"path"
Packit 63bb0d
	"path/filepath"
Packit 63bb0d
	"testing"
Packit 63bb0d
Packit Service 509fd4
	"github.com/google/go-cmp/cmp"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/blueprint"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/distro"
Packit 63bb0d
	"github.com/osbuild/osbuild-composer/internal/rpmmd"
Packit 63bb0d
	"github.com/stretchr/testify/assert"
Packit 63bb0d
	"github.com/stretchr/testify/require"
Packit 63bb0d
)
Packit 63bb0d
Packit Service 509fd4
const RandomTestSeed = 0
Packit Service 509fd4
Packit 63bb0d
func TestDistro_Manifest(t *testing.T, pipelinePath string, prefix string, distros ...distro.Distro) {
Packit 63bb0d
	assert := assert.New(t)
Packit 63bb0d
	fileNames, err := filepath.Glob(filepath.Join(pipelinePath, prefix))
Packit 63bb0d
	assert.NoErrorf(err, "Could not read pipelines directory '%s': %v", pipelinePath, err)
Packit 63bb0d
	require.Greaterf(t, len(fileNames), 0, "No pipelines found in %s for %s", pipelinePath, prefix)
Packit 63bb0d
	for _, fileName := range fileNames {
Packit 63bb0d
		type repository struct {
Packit 63bb0d
			BaseURL    string `json:"baseurl,omitempty"`
Packit 63bb0d
			Metalink   string `json:"metalink,omitempty"`
Packit 63bb0d
			MirrorList string `json:"mirrorlist,omitempty"`
Packit 63bb0d
			GPGKey     string `json:"gpgkey,omitempty"`
Packit 63bb0d
			CheckGPG   bool   `json:"check_gpg,omitempty"`
Packit 63bb0d
		}
Packit 63bb0d
		type composeRequest struct {
Packit 63bb0d
			Distro       string               `json:"distro"`
Packit 63bb0d
			Arch         string               `json:"arch"`
Packit 63bb0d
			ImageType    string               `json:"image-type"`
Packit 63bb0d
			Repositories []repository         `json:"repositories"`
Packit 63bb0d
			Blueprint    *blueprint.Blueprint `json:"blueprint"`
Packit 63bb0d
		}
Packit 63bb0d
		var tt struct {
Packit Service 15f37d
			ComposeRequest *composeRequest                `json:"compose-request"`
Packit Service 15f37d
			PackageSets    map[string][]rpmmd.PackageSpec `json:"rpmmd"`
Packit Service 15f37d
			Manifest       distro.Manifest                `json:"manifest,omitempty"`
Packit 63bb0d
		}
Packit 63bb0d
		file, err := ioutil.ReadFile(fileName)
Packit 63bb0d
		assert.NoErrorf(err, "Could not read test-case '%s': %v", fileName, err)
Packit 63bb0d
		err = json.Unmarshal([]byte(file), &tt)
Packit 63bb0d
		assert.NoErrorf(err, "Could not parse test-case '%s': %v", fileName, err)
Packit 63bb0d
		if tt.ComposeRequest == nil || tt.ComposeRequest.Blueprint == nil {
Packit 63bb0d
			t.Logf("Skipping '%s'.", fileName)
Packit 63bb0d
			continue
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		repos := make([]rpmmd.RepoConfig, len(tt.ComposeRequest.Repositories))
Packit 63bb0d
		for i, repo := range tt.ComposeRequest.Repositories {
Packit 63bb0d
			repos[i] = rpmmd.RepoConfig{
Packit 63bb0d
				Name:       fmt.Sprintf("repo-%d", i),
Packit 63bb0d
				BaseURL:    repo.BaseURL,
Packit 63bb0d
				Metalink:   repo.Metalink,
Packit 63bb0d
				MirrorList: repo.MirrorList,
Packit 63bb0d
				GPGKey:     repo.GPGKey,
Packit 63bb0d
				CheckGPG:   repo.CheckGPG,
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		t.Run(path.Base(fileName), func(t *testing.T) {
Packit 63bb0d
			distros, err := distro.NewRegistry(distros...)
Packit 63bb0d
			require.NoError(t, err)
Packit 63bb0d
			d := distros.GetDistro(tt.ComposeRequest.Distro)
Packit 63bb0d
			if d == nil {
Packit 63bb0d
				t.Errorf("unknown distro: %v", tt.ComposeRequest.Distro)
Packit 63bb0d
				return
Packit 63bb0d
			}
Packit 63bb0d
			arch, err := d.GetArch(tt.ComposeRequest.Arch)
Packit 63bb0d
			if err != nil {
Packit 63bb0d
				t.Errorf("unknown arch: %v", tt.ComposeRequest.Arch)
Packit 63bb0d
				return
Packit 63bb0d
			}
Packit 63bb0d
			imageType, err := arch.GetImageType(tt.ComposeRequest.ImageType)
Packit 63bb0d
			if err != nil {
Packit 63bb0d
				t.Errorf("unknown image type: %v", tt.ComposeRequest.ImageType)
Packit 63bb0d
				return
Packit 63bb0d
			}
Packit 63bb0d
			got, err := imageType.Manifest(tt.ComposeRequest.Blueprint.Customizations,
Packit 63bb0d
				distro.ImageOptions{
Packit 63bb0d
					Size: imageType.Size(0),
Packit Service bcdfb1
					OSTree: distro.OSTreeImageOptions{
Packit Service bcdfb1
						Ref: imageType.OSTreeRef(),
Packit Service bcdfb1
					},
Packit 63bb0d
				},
Packit 63bb0d
				repos,
Packit Service 15f37d
				tt.PackageSets,
Packit Service 509fd4
				RandomTestSeed)
Packit 63bb0d
Packit 63bb0d
			if (err == nil && tt.Manifest == nil) || (err != nil && tt.Manifest != nil) {
Packit 63bb0d
				t.Errorf("distro.Manifest() error = %v", err)
Packit 63bb0d
				return
Packit 63bb0d
			}
Packit 63bb0d
			if tt.Manifest != nil {
Packit Service 509fd4
				var expected, actual interface{}
Packit Service 509fd4
				err = json.Unmarshal(tt.Manifest, &expected)
Packit Service 509fd4
				require.NoError(t, err)
Packit Service 509fd4
				err = json.Unmarshal(got, &actual)
Packit Service 509fd4
				require.NoError(t, err)
Packit Service 509fd4
Packit Service 509fd4
				diff := cmp.Diff(expected, actual)
Packit Service 509fd4
				require.Emptyf(t, diff, "Distro: %s\nArch: %s\nImage type: %s\nTest case file: %s\n", d.Name(), arch.Name(), imageType.Name(), fileName)
Packit 63bb0d
			}
Packit 63bb0d
		})
Packit 63bb0d
	}
Packit 63bb0d
}
Packit Service bcdfb1
Packit Service bcdfb1
func isOSTree(imgType distro.ImageType) bool {
Packit Service 15f37d
	packageSets := imgType.PackageSets(blueprint.Blueprint{})
Packit Service 15f37d
	for _, pkg := range packageSets["build-packages"].Include {
Packit Service bcdfb1
		if pkg == "rpm-ostree" {
Packit Service bcdfb1
			return true
Packit Service bcdfb1
		}
Packit Service bcdfb1
	}
Packit Service bcdfb1
	return false
Packit Service bcdfb1
}
Packit Service bcdfb1
Packit Service bcdfb1
var knownKernels = []string{"kernel", "kernel-debug", "kernel-rt"}
Packit Service bcdfb1
Packit Service bcdfb1
// Returns the number of known kernels in the package list
Packit Service bcdfb1
func kernelCount(imgType distro.ImageType) int {
Packit Service 15f37d
	pkgs := imgType.PackageSets(blueprint.Blueprint{})["packages"].Include
Packit Service bcdfb1
	n := 0
Packit Service bcdfb1
	for _, pkg := range pkgs {
Packit Service bcdfb1
		for _, kernel := range knownKernels {
Packit Service bcdfb1
			if kernel == pkg {
Packit Service bcdfb1
				n++
Packit Service bcdfb1
			}
Packit Service bcdfb1
		}
Packit Service bcdfb1
	}
Packit Service bcdfb1
	return n
Packit Service bcdfb1
}
Packit Service bcdfb1
Packit Service bcdfb1
func TestDistro_KernelOption(t *testing.T, d distro.Distro) {
Packit Service bcdfb1
	for _, archName := range d.ListArches() {
Packit Service bcdfb1
		arch, err := d.GetArch(archName)
Packit Service bcdfb1
		assert.NoError(t, err)
Packit Service bcdfb1
		for _, typeName := range arch.ListImageTypes() {
Packit Service bcdfb1
			imgType, err := arch.GetImageType(typeName)
Packit Service bcdfb1
			assert.NoError(t, err)
Packit Service bcdfb1
			nk := kernelCount(imgType)
Packit Service bcdfb1
			// at least one kernel for general image types
Packit Service bcdfb1
			// exactly one kernel for OSTree commits
Packit Service bcdfb1
			if nk < 1 || (isOSTree(imgType) && nk != 1) {
Packit Service bcdfb1
				assert.Fail(t, fmt.Sprintf("%s Kernel count", d.Name()),
Packit Service bcdfb1
					"Image type %s (arch %s) specifies %d Kernel packages", typeName, archName, nk)
Packit Service bcdfb1
			}
Packit Service bcdfb1
		}
Packit Service bcdfb1
	}
Packit Service bcdfb1
}