From 6f858df5839a6d358706d2a187feac43c37a28ae Mon Sep 17 00:00:00 2001 From: "Badr, Nesma" Date: Thu, 11 Jul 2024 13:57:26 +0200 Subject: [PATCH] Add integration test --- .../oci/associated-resources.yaml | 3 + pkg/testutils/manifest.go | 50 ------- pkg/testutils/utils.go | 52 +++++++ .../controller/kyma/manifest_test.go | 131 ++++++++++++++++-- .../custom_resource_check/manifest_test.go | 2 +- .../manifest/manifest_controller_test.go | 4 +- .../controller/manifest/ready_check_test.go | 2 +- 7 files changed, 181 insertions(+), 63 deletions(-) create mode 100644 pkg/test_samples/oci/associated-resources.yaml diff --git a/pkg/test_samples/oci/associated-resources.yaml b/pkg/test_samples/oci/associated-resources.yaml new file mode 100644 index 00000000000..9ca90eea422 --- /dev/null +++ b/pkg/test_samples/oci/associated-resources.yaml @@ -0,0 +1,3 @@ +associatedResources: + - serverless.kyma-project.io/v1alpha2/functions + - operator.kyma-project.io/v1alpha1/serverlesses diff --git a/pkg/testutils/manifest.go b/pkg/testutils/manifest.go index 7f6f2c7d091..0cecf34eeca 100644 --- a/pkg/testutils/manifest.go +++ b/pkg/testutils/manifest.go @@ -6,16 +6,11 @@ import ( "errors" "fmt" "io" - "net/http/httptest" - "net/url" "os" "strconv" "strings" - "github.com/google/go-containerregistry/pkg/name" containerregistryv1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/partial" - "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/types" templatev1alpha1 "github.com/kyma-project/template-operator/api/v1alpha1" apimetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -378,51 +373,6 @@ func (m mockLayer) DiffID() (containerregistryv1.Hash, error) { return containerregistryv1.Hash{Algorithm: "fake", Hex: "diff id"}, nil } -func CreateImageSpecLayer(manifestFilePath string) (containerregistryv1.Layer, error) { - return partial.UncompressedToLayer(mockLayer{filePath: manifestFilePath}) -} - -func PushToRemoteOCIRegistry(server *httptest.Server, manifestFilePath, layerName string) error { - layer, err := CreateImageSpecLayer(manifestFilePath) - if err != nil { - return err - } - digest, err := layer.Digest() - if err != nil { - return err - } - - // Set up a fake registry and write what we pulled to it. - u, err := url.Parse(server.URL) - if err != nil { - return err - } - - dst := fmt.Sprintf("%s/%s@%s", u.Host, layerName, digest) - ref, err := name.NewDigest(dst) - if err != nil { - return err - } - - err = remote.WriteLayer(ref.Context(), layer) - if err != nil { - return err - } - - got, err := remote.Layer(ref) - if err != nil { - return err - } - gotHash, err := got.Digest() - if err != nil { - return err - } - if gotHash != digest { - return errors.New("has not equal to digest") - } - return nil -} - func CreateOCIImageSpec(name, repo, manifestFilePath string, enableCredSecretSelector bool) (v1beta2.ImageSpec, error) { imageSpec := v1beta2.ImageSpec{ Name: name, diff --git a/pkg/testutils/utils.go b/pkg/testutils/utils.go index 34134839f6f..4eea6536cde 100644 --- a/pkg/testutils/utils.go +++ b/pkg/testutils/utils.go @@ -21,9 +21,15 @@ import ( machineryaml "k8s.io/apimachinery/pkg/util/yaml" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/google/go-containerregistry/pkg/name" + containerregistryv1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/partial" + "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/kyma-project/lifecycle-manager/pkg/testutils/random" + "net/http/httptest" + "net/url" ) const ( @@ -170,3 +176,49 @@ func parseResourcesFromYAML(yamlFilePath string, clnt client.Client) ([]*unstruc } return resources, nil } + +func CreateImageSpecLayer(filePath string) (containerregistryv1.Layer, error) { + return partial.UncompressedToLayer(mockLayer{filePath: filePath}) +} + +func PushToRemoteOCIRegistry(server *httptest.Server, filePath, layerName string) (string, error) { + layer, err := CreateImageSpecLayer(filePath) + if err != nil { + return "", err + } + digest, err := layer.Digest() + if err != nil { + return "", err + } + + // Set up a fake registry and write what we pulled to it. + u, err := url.Parse(server.URL) + if err != nil { + return "", err + } + + dst := fmt.Sprintf("%s/%s@%s", u.Host, layerName, digest) + ref, err := name.NewDigest(dst) + if err != nil { + return "", err + } + + err = remote.WriteLayer(ref.Context(), layer) + if err != nil { + return "", err + } + + got, err := remote.Layer(ref) + if err != nil { + return "", err + } + gotHash, err := got.Digest() + if err != nil { + return "", err + } + if gotHash != digest { + return "", errors.New("has not equal to digest") + } + + return digest.String(), nil +} diff --git a/tests/integration/controller/kyma/manifest_test.go b/tests/integration/controller/kyma/manifest_test.go index ea29f0d661c..f3ec89a31d6 100644 --- a/tests/integration/controller/kyma/manifest_test.go +++ b/tests/integration/controller/kyma/manifest_test.go @@ -4,26 +4,35 @@ import ( "encoding/json" "errors" "fmt" - "reflect" - "strings" - + "github.com/google/go-containerregistry/pkg/registry" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + compdescv2 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/versions/v2" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/genericocireg" "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/genericocireg/componentmapping" "github.com/open-component-model/ocm/pkg/runtime" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" + "k8s.io/utils/strings/slices" + "net/http/httptest" + "os" + "path/filepath" + "reflect" + "sigs.k8s.io/yaml" + "strings" "github.com/kyma-project/lifecycle-manager/api/shared" "github.com/kyma-project/lifecycle-manager/api/v1beta2" "github.com/kyma-project/lifecycle-manager/internal/pkg/flags" + "github.com/kyma-project/lifecycle-manager/pkg/testutils/builder" + "github.com/kyma-project/lifecycle-manager/tests/integration" + + "github.com/kyma-project/lifecycle-manager/pkg/module/parse" . "github.com/kyma-project/lifecycle-manager/pkg/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ) const ( @@ -40,9 +49,10 @@ const ( ) var ( - ErrEmptyModuleTemplateData = errors.New("module template spec.data is empty") - ErrVersionMismatch = errors.New("manifest spec.version mismatch with module template") - ErrInvalidManifest = errors.New("invalid ManifestResource") + ErrEmptyModuleTemplateData = errors.New("module template spec.data is empty") + ErrVersionMismatch = errors.New("manifest spec.version mismatch with module template") + ErrInvalidManifest = errors.New("invalid ManifestResource") + ErrIncorrectAssociatedResources = errors.New("incorrect associated resources") ) var _ = Describe("Manifest.Spec.Remote in default mode", Ordered, func() { @@ -189,6 +199,90 @@ var _ = Describe("Manifest.Spec is rendered correctly", Ordered, func() { }) }) +var _ = Describe("Manifest.Spec.AssociatedResources is rendered correctly", Ordered, func() { + kyma := NewTestKyma("kyma") + module := NewTestModule("test-associated-resources", v1beta2.DefaultChannel) + kyma.Spec.Modules = append(kyma.Spec.Modules, module) + var serverAddress string + var template *v1beta2.ModuleTemplate + associatedResourcesFilePath := filepath.Join(integration.GetProjectRoot(), "pkg", "test_samples", "oci", + "associated-resources.yaml") + BeforeAll(func() { + newReg := registry.New() + server := httptest.NewServer(newReg) + serverAddress = fmt.Sprintf("%s/%s", server.Listener.Addr().String(), "component-descriptors") + digest, err := PushToRemoteOCIRegistry(server, associatedResourcesFilePath, "associated-resources") + Expect(err).NotTo(HaveOccurred()) + + descriptor := &v1beta2.Descriptor{ + ComponentDescriptor: &compdesc.ComponentDescriptor{ + Metadata: compdesc.Metadata{ + ConfiguredVersion: compdescv2.SchemaVersion, + }, + ComponentSpec: compdesc.ComponentSpec{ + ObjectMeta: compdesc.ObjectMeta{ + Name: "associated-resources", + Version: "1.0.0-new-ocm", + }, + RepositoryContexts: []*runtime.UnstructuredTypedObject{ + { + Object: runtime.UnstructuredMap{ + "baseUrl": serverAddress, + "componentNameMapping": "urlPath", + "type": "OCIRegistry", + }, + }, + }, + Resources: []compdesc.Resource{ + { + ResourceMeta: compdesc.ResourceMeta{ + ElementMeta: compdesc.ElementMeta{ + Name: "associated-resources", + Version: "1.0.0", + }, + }, + Access: localblob.New(digest, "test1", "application/octet-stream", nil), + }, + { + ResourceMeta: compdesc.ResourceMeta{ + ElementMeta: compdesc.ElementMeta{ + Name: "raw-manifest", + Version: "1.0.0", + }, + }, + Access: localblob.New(digest, "test1", "application/octet-stream", nil), + }, + }, + }, + }, + } + + rawDescriptor, err := compdesc.Encode(descriptor.ComponentDescriptor, compdesc.DefaultJSONCodec) + Expect(err).ToNot(HaveOccurred()) + + template = builder.NewModuleTemplateBuilder(). + WithModuleName(module.Name). + WithChannel(v1beta2.DefaultChannel).WithDescriptor(descriptor).WithRawDescriptor(rawDescriptor).Build() + }) + + RegisterDefaultLifecycleForKymaWithoutTemplate(kyma) + + It("Deploy ModuleTemplate", func() { + Expect(kcpClient.Create(ctx, template)).To(Succeed()) + }) + + It("validate Manifest", func() { + expectManifest := expectManifestFor(kyma) + + By("checking Spec.AssociatedResources") + hasValidSpecAssociatedResources := func(manifest *v1beta2.Manifest) error { + return validateManifestSpecAssociatedResources(manifest.Spec.AssociatedResources, + associatedResourcesFilePath) + } + Eventually(expectManifest(hasValidSpecAssociatedResources), Timeout, Interval).Should(Succeed()) + }) +}) + var _ = Describe("Manifest.Spec is reset after manual update", Ordered, func() { const updateRepositoryURL = "registry.docker.io/kyma-project/component-descriptors" @@ -368,6 +462,25 @@ func validateManifestSpecInstallSource(manifestImageSpec *v1beta2.ImageSpec, return validateManifestSpecInstallSourceType(manifestImageSpec) } +func validateManifestSpecAssociatedResources(associatedResources []string, associatedResourcesFilePath string) error { + associatedResourcesBytes, err := os.ReadFile(associatedResourcesFilePath) + if err != nil { + return fmt.Errorf("failed to read associated resources file: %w", err) + } + + var expectedAssociatedResourcesList parse.AssociatedResourcesContent + err = yaml.Unmarshal(associatedResourcesBytes, &expectedAssociatedResourcesList) + if err != nil { + return fmt.Errorf("failed to unmarshal associated resources: %w", err) + } + + if !slices.Equal(expectedAssociatedResourcesList.AssociatedResources, associatedResources) { + return ErrIncorrectAssociatedResources + } + + return nil +} + func validateManifestSpecInstallSourceName(manifestImageSpec *v1beta2.ImageSpec, moduleTemplateDescriptor *v1beta2.Descriptor, ) error { diff --git a/tests/integration/controller/manifest/custom_resource_check/manifest_test.go b/tests/integration/controller/manifest/custom_resource_check/manifest_test.go index 8d722bd92f8..ea884f022ce 100644 --- a/tests/integration/controller/manifest/custom_resource_check/manifest_test.go +++ b/tests/integration/controller/manifest/custom_resource_check/manifest_test.go @@ -29,7 +29,7 @@ var _ = Describe("Warning state propagation test", Ordered, func() { It( "setup OCI", func() { - err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) + _, err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) Expect(err).NotTo(HaveOccurred()) }, ) diff --git a/tests/integration/controller/manifest/manifest_controller_test.go b/tests/integration/controller/manifest/manifest_controller_test.go index 8942819c033..d87f2f178e7 100644 --- a/tests/integration/controller/manifest/manifest_controller_test.go +++ b/tests/integration/controller/manifest/manifest_controller_test.go @@ -16,7 +16,7 @@ import ( func setupTestEnvironment(ociTempDir, installName string) { It("setup OCI", func() { - err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) + _, err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) Expect(err).NotTo(HaveOccurred()) }) BeforeEach( @@ -162,7 +162,7 @@ var _ = Describe( It( "setup remote oci Registry", func() { - err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) + _, err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) Expect(err).NotTo(HaveOccurred()) }, ) diff --git a/tests/integration/controller/manifest/ready_check_test.go b/tests/integration/controller/manifest/ready_check_test.go index 3a406e6b461..09b18377428 100644 --- a/tests/integration/controller/manifest/ready_check_test.go +++ b/tests/integration/controller/manifest/ready_check_test.go @@ -29,7 +29,7 @@ var _ = Describe("Manifest readiness check", Ordered, func() { installName := filepath.Join(customDir, "installs") It( "setup OCI", func() { - err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) + _, err := testutils.PushToRemoteOCIRegistry(server, manifestFilePath, installName) Expect(err).NotTo(HaveOccurred()) }, )