From 5821098c29e786d621e5fb02566fbc7af7db0905 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 3 Aug 2023 15:17:14 -0700 Subject: [PATCH] cloudapi: Add tests for refactored handler code Add tests for GetBlueprintWithCustomizations, GetPayloadRepositories, GetSubscription, and GetOstreeOptions methods. --- internal/cloudapi/v2/compose_test.go | 222 ++++++++++++++++++++++ internal/cloudapi/v2/imagerequest_test.go | 43 +++++ 2 files changed, 265 insertions(+) create mode 100644 internal/cloudapi/v2/compose_test.go diff --git a/internal/cloudapi/v2/compose_test.go b/internal/cloudapi/v2/compose_test.go new file mode 100644 index 000000000..febc1e15a --- /dev/null +++ b/internal/cloudapi/v2/compose_test.go @@ -0,0 +1,222 @@ +package v2 + +import ( + "testing" + + "github.com/osbuild/images/pkg/subscription" + "github.com/osbuild/osbuild-composer/internal/blueprint" + "github.com/osbuild/osbuild-composer/internal/common" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetBlueprintWithCustomizations(t *testing.T) { + // Empty request should return empty blueprint + cr := ComposeRequest{} + bp, err := cr.GetBlueprintWithCustomizations() + require.Nil(t, err) + assert.Equal(t, "empty blueprint", bp.Name) + assert.Equal(t, "0.0.0", bp.Version) + assert.Nil(t, bp.Customizations) + + // Test with customizations + expected := blueprint.Blueprint{Name: "empty blueprint"} + err = expected.Initialize() + require.Nil(t, err) + + // interface{} is a terrible idea. Work around it... + var rootStr interface{} = "root" + + // anonymous structs buried in a data type are almost as bad. + services := struct { + Disabled *[]string `json:"disabled,omitempty"` + Enabled *[]string `json:"enabled,omitempty"` + }{ + Disabled: &[]string{"cleanup"}, + Enabled: &[]string{"sshd"}, + } + + // Construct the compose request with customizations + cr = ComposeRequest{Customizations: &Customizations{ + Users: &[]User{ + User{ + Name: "admin", + Key: common.ToPtr("dummy ssh-key"), + Groups: &[]string{"users", "wheel"}, + }}, + Packages: &[]string{"bash", "tmux"}, + Containers: &[]Container{ + Container{ + Name: common.ToPtr("container-name"), + Source: "http://some.path.to/a/container/source", + }, + }, + Directories: &[]Directory{ + Directory{ + Path: "/opt/extra", + EnsureParents: common.ToPtr(true), + User: &rootStr, + Group: &rootStr, + Mode: common.ToPtr("0755"), + }, + }, + Files: &[]File{ + File{ + Path: "/etc/mad.conf", + Data: common.ToPtr("Alfred E. Neuman was here.\n"), + EnsureParents: common.ToPtr(true), + User: &rootStr, + Group: &rootStr, + Mode: common.ToPtr("0644"), + }, + }, + Filesystem: &[]Filesystem{ + Filesystem{ + Mountpoint: "/var/lib/wopr/", + MinSize: 1099511627776, + }, + }, + Services: &services, + Openscap: &OpenSCAP{ProfileId: "B 263-59"}, + CustomRepositories: &[]CustomRepository{ + CustomRepository{ + Id: "custom repo", + Metalink: common.ToPtr("http://example.org/metalink"), + CheckGpg: common.ToPtr(true), + Enabled: common.ToPtr(true), + }, + }, + }} + + // Construct the expected blueprint result + // Packages + expected.Packages = []blueprint.Package{ + {Name: "bash"}, + {Name: "tmux"}, + } + + // Containers + expected.Containers = []blueprint.Container{ + blueprint.Container{ + Name: "container-name", + Source: "http://some.path.to/a/container/source", + }, + } + + // Customizations + expected.Customizations = &blueprint.Customizations{ + User: []blueprint.UserCustomization{ + blueprint.UserCustomization{ + Name: "admin", + Key: common.ToPtr("dummy ssh-key"), + Groups: []string{"users", "wheel"}, + }, + }, + Directories: []blueprint.DirectoryCustomization{ + blueprint.DirectoryCustomization{ + Path: "/opt/extra", + User: "root", + Group: "root", + Mode: "0755", + EnsureParents: true, + }, + }, + Files: []blueprint.FileCustomization{ + blueprint.FileCustomization{ + Path: "/etc/mad.conf", + User: "root", + Group: "root", + Mode: "0644", + Data: "Alfred E. Neuman was here.\n", + }, + }, + Filesystem: []blueprint.FilesystemCustomization{ + blueprint.FilesystemCustomization{ + Mountpoint: "/var/lib/wopr/", + MinSize: 1099511627776, + }, + }, + Services: &blueprint.ServicesCustomization{ + Enabled: []string{"sshd"}, + Disabled: []string{"cleanup"}, + }, + OpenSCAP: &blueprint.OpenSCAPCustomization{ + ProfileID: "B 263-59", + }, + Repositories: []blueprint.RepositoryCustomization{ + blueprint.RepositoryCustomization{ + Id: "custom repo", + Metalink: "http://example.org/metalink", + Enabled: common.ToPtr(true), + GPGCheck: common.ToPtr(true), + }, + }, + } + + bp, err = cr.GetBlueprintWithCustomizations() + require.Nil(t, err) + assert.Equal(t, bp, expected) +} + +func TestGetPayloadRepositories(t *testing.T) { + + // Empty PayloadRepositories + cr := ComposeRequest{} + repos := cr.GetPayloadRepositories() + assert.Len(t, repos, 0) + assert.Equal(t, []Repository(nil), repos) + + // Populated PayloadRepositories + cr = ComposeRequest{Customizations: &Customizations{ + PayloadRepositories: &[]Repository{ + Repository{ + Baseurl: common.ToPtr("http://example.org/pub/linux/repo"), + CheckGpg: common.ToPtr(true), + PackageSets: &[]string{"build", "archive"}, + Rhsm: common.ToPtr(false), + }, + }, + }} + + expected := []Repository{ + Repository{ + Baseurl: common.ToPtr("http://example.org/pub/linux/repo"), + CheckGpg: common.ToPtr(true), + PackageSets: &[]string{"build", "archive"}, + Rhsm: common.ToPtr(false), + }, + } + repos = cr.GetPayloadRepositories() + assert.Len(t, repos, 1) + assert.Equal(t, expected, repos) +} + +func TestGetSubscriptions(t *testing.T) { + // Empty Subscription + cr := ComposeRequest{} + sub := cr.GetSubscription() + assert.Equal(t, (*subscription.ImageOptions)(nil), sub) + + // Populated Subscription + cr = ComposeRequest{Customizations: &Customizations{ + Subscription: common.ToPtr(Subscription{ + ActivationKey: "key", + BaseUrl: "http://example.org/baseurl", + Insights: false, + Organization: "Weyland-Yutani", + ServerUrl: "http://example.org/serverurl", + }), + }} + + expected := &subscription.ImageOptions{ + ActivationKey: "key", + BaseUrl: "http://example.org/baseurl", + Insights: false, + Organization: "Weyland-Yutani", + ServerUrl: "http://example.org/serverurl", + } + sub = cr.GetSubscription() + assert.Equal(t, expected, sub) + +} diff --git a/internal/cloudapi/v2/imagerequest_test.go b/internal/cloudapi/v2/imagerequest_test.go index ed9691303..2c257d409 100644 --- a/internal/cloudapi/v2/imagerequest_test.go +++ b/internal/cloudapi/v2/imagerequest_test.go @@ -8,6 +8,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/common" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestImageRequestSize(t *testing.T) { @@ -86,3 +87,45 @@ func TestImageRequestSize(t *testing.T) { // The test_distro default size is actually 5GiB assert.Equal(t, uint64(5368709120), imageOptions.Size) } + +func TestGetOstreeOptions(t *testing.T) { + // No Ostree settings + ir := ImageRequest{ + Architecture: test_distro.TestArchName, + ImageType: test_distro.TestImageTypeName, + } + options, err := ir.GetOSTreeOptions() + assert.Nil(t, options) + assert.Nil(t, err) + + // Populated Ostree settings + ir = ImageRequest{ + Architecture: test_distro.TestArchName, + ImageType: test_distro.TestImageTypeName, + Ostree: &OSTree{ + Contenturl: common.ToPtr("http://url.to.content/"), + Parent: common.ToPtr("02604b2da6e954bd34b8b82a835e5a77d2b60ffa"), + Ref: common.ToPtr("reference"), + Url: common.ToPtr("http://the.url/"), + }, + } + options, err = ir.GetOSTreeOptions() + assert.Nil(t, err) + require.NotNil(t, options) + assert.Equal(t, "http://url.to.content/", options.ContentURL) + assert.Equal(t, "02604b2da6e954bd34b8b82a835e5a77d2b60ffa", options.ParentRef) + assert.Equal(t, "reference", options.ImageRef) + assert.Equal(t, "http://the.url/", options.URL) + + // Populated Ostree settings with no url + ir = ImageRequest{ + Architecture: test_distro.TestArchName, + ImageType: test_distro.TestImageTypeName, + Ostree: &OSTree{ + Contenturl: common.ToPtr("http://url.to.content/"), + }, + } + _, err = ir.GetOSTreeOptions() + require.NotNil(t, err) + assert.Error(t, err) +}