Skip to content

Commit

Permalink
Merge pull request #539 from codingben/CNV-43604
Browse files Browse the repository at this point in the history
test(CNV-43604): add disk-uploader unit tests
  • Loading branch information
kubevirt-bot authored Nov 7, 2024
2 parents 7acd856 + 57be0f8 commit 4129a54
Show file tree
Hide file tree
Showing 79 changed files with 5,974 additions and 74 deletions.
14 changes: 8 additions & 6 deletions cmd/disk-uploader/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"os"

"github.com/kubevirt/kubevirt-tekton-tasks/modules/disk-uploader/pkg/certificate"
"github.com/kubevirt/kubevirt-tekton-tasks/modules/disk-uploader/pkg/disk"
"github.com/kubevirt/kubevirt-tekton-tasks/modules/disk-uploader/pkg/image"
Expand All @@ -10,7 +12,7 @@ import (
"github.com/kubevirt/kubevirt-tekton-tasks/modules/shared/pkg/exit"
"github.com/kubevirt/kubevirt-tekton-tasks/modules/shared/pkg/log"

k8sv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"

goarg "github.com/alexflint/go-arg"
Expand All @@ -28,7 +30,7 @@ const (
kvExportTokenHeader string = "x-kubevirt-export-token"
)

func run(opts parse.CLIOptions, k8sClient *k8sv1.CoreV1Client, virtClient kubecli.KubevirtClient) error {
func run(opts parse.CLIOptions, k8sClient kubernetes.Interface, virtClient kubecli.KubevirtClient) error {
kind := opts.GetExportSourceKind()
name := opts.GetExportSourceName()
namespace := opts.GetExportSourceNamespace()
Expand All @@ -38,13 +40,13 @@ func run(opts parse.CLIOptions, k8sClient *k8sv1.CoreV1Client, virtClient kubecl

log.Logger().Info("Creating a new Secret object...", zap.String("namespace", namespace), zap.String("name", name))

if err := secrets.CreateVirtualMachineExportSecret(k8sClient, virtClient, namespace, name); err != nil {
if err := secrets.CreateVirtualMachineExportSecret(k8sClient, namespace, name); err != nil {
return err
}

log.Logger().Info("Creating a new VirtualMachineExport object...", zap.String("namespace", namespace), zap.String("name", name))

if err := vmexport.CreateVirtualMachineExport(k8sClient, virtClient, kind, namespace, name); err != nil {
if err := vmexport.CreateVirtualMachineExport(virtClient, kind, namespace, name); err != nil {
return err
}

Expand All @@ -68,7 +70,7 @@ func run(opts parse.CLIOptions, k8sClient *k8sv1.CoreV1Client, virtClient kubecl
return err
}

if err := certificate.CreateCertificateFile(certificatePath, certificateData); err != nil {
if err := os.WriteFile(certificatePath, []byte(certificateData), 0644); err != nil {
return err
}

Expand Down Expand Up @@ -121,7 +123,7 @@ func main() {
exit.ExitOrDieFromError(genericExitCode, err)
}

k8sClient, err := k8sv1.NewForConfig(config)
k8sClient, err := kubernetes.NewForConfig(config)
if err != nil {
exit.ExitOrDieFromError(genericExitCode, err)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ replace (

require (
github.com/alexflint/go-arg v1.5.1
github.com/golang/mock v1.6.0
github.com/google/go-containerregistry v0.20.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/onsi/ginkgo/v2 v2.20.1
Expand Down Expand Up @@ -78,7 +79,6 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
Expand Down
6 changes: 3 additions & 3 deletions modules/copy-template/pkg/templates/template-provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/yaml"
k8sv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

Expand Down Expand Up @@ -50,7 +50,7 @@ func (t *templateProvider) Update(template *templatev1.Template) (*templatev1.Te
type TemplateCreator struct {
cliOptions *parse.CLIOptions
templateProvider TemplateProvider
k8sClient *k8sv1.CoreV1Client
k8sClient kubernetes.Interface
}

func NewTemplateCreator(cliOptions *parse.CLIOptions) (*TemplateCreator, error) {
Expand All @@ -61,7 +61,7 @@ func NewTemplateCreator(cliOptions *parse.CLIOptions) (*TemplateCreator, error)
return nil, err
}

k8sclient := k8sv1.NewForConfigOrDie(config)
k8sclient := kubernetes.NewForConfigOrDie(config)

return &TemplateCreator{
cliOptions: cliOptions,
Expand Down
6 changes: 3 additions & 3 deletions modules/create-vm/pkg/vmcreator/vm-creator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/kubevirt/kubevirt-tekton-tasks/modules/shared/pkg/zerrors"
"github.com/kubevirt/kubevirt-tekton-tasks/modules/shared/pkg/zutils"
templatev1 "github.com/openshift/client-go/template/clientset/versioned/typed/template/v1"
k8sv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/kubernetes"

"github.com/spf13/cobra"
"go.uber.org/zap"
Expand All @@ -33,7 +33,7 @@ type VMCreator struct {
config *rest.Config
templateProvider templates.TemplateProvider
virtualMachineProvider virtualMachine.VirtualMachineProvider
k8sClient *k8sv1.CoreV1Client
k8sClient kubernetes.Interface
}

func NewVMCreator(cliOptions *parse.CLIOptions) (*VMCreator, error) {
Expand All @@ -51,7 +51,7 @@ func NewVMCreator(cliOptions *parse.CLIOptions) (*VMCreator, error) {
return nil, fmt.Errorf("cannot create kubevirt client: %v", err.Error())
}

k8sclient := k8sv1.NewForConfigOrDie(config)
k8sclient := kubernetes.NewForConfigOrDie(config)

var templateProvider templates.TemplateProvider
virtualMachineProvider := virtualMachine.NewVirtualMachineProvider(kubevirtClient)
Expand Down
17 changes: 1 addition & 16 deletions modules/disk-uploader/pkg/certificate/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package certificate
import (
"context"
"fmt"
"os"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubecli "kubevirt.io/client-go/kubecli"
Expand All @@ -15,7 +14,7 @@ func GetCertificateFromVirtualMachineExport(client kubecli.KubevirtClient, names
return "", err
}

if vmExport.Status.Links == nil && vmExport.Status.Links.Internal == nil {
if vmExport.Status.Links == nil || vmExport.Status.Links.Internal == nil {
return "", fmt.Errorf("no links found in VirtualMachineExport status")
}

Expand All @@ -25,17 +24,3 @@ func GetCertificateFromVirtualMachineExport(client kubecli.KubevirtClient, names
}
return content, nil
}

func CreateCertificateFile(path, data string) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return fmt.Errorf("failed to create file: %w", err)
}
defer file.Close()

_, err = file.WriteString(data)
if err != nil {
return fmt.Errorf("failed to write content to file: %w", err)
}
return nil
}
13 changes: 13 additions & 0 deletions modules/disk-uploader/pkg/certificate/certificate_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package certificate_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestCertificate(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Certificate Suite")
}
117 changes: 117 additions & 0 deletions modules/disk-uploader/pkg/certificate/certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package certificate_test

import (
"context"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/golang/mock/gomock"

"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

v1beta1 "kubevirt.io/api/export/v1beta1"
kubevirtfake "kubevirt.io/client-go/generated/kubevirt/clientset/versioned/fake"
"kubevirt.io/client-go/kubecli"

"github.com/kubevirt/kubevirt-tekton-tasks/modules/disk-uploader/pkg/certificate"
)

var _ = Describe("Certificate", func() {
const (
namespace = "test-namespace"
name = "test-vmexport"
)

var (
vmExportClient *kubevirtfake.Clientset
virtClient kubecli.KubevirtClient
)

BeforeEach(func() {
ctrl := gomock.NewController(GinkgoT())
vmExportClient = kubevirtfake.NewSimpleClientset()

kubecli.GetKubevirtClientFromClientConfig = kubecli.GetMockKubevirtClientFromClientConfig
kubecli.MockKubevirtClientInstance = kubecli.NewMockKubevirtClient(ctrl)
kubecli.MockKubevirtClientInstance.EXPECT().VirtualMachineExport(namespace).Return(vmExportClient.ExportV1beta1().VirtualMachineExports(namespace)).AnyTimes()

virtClient, _ = kubecli.GetKubevirtClientFromClientConfig(nil)
})

Describe("GetCertificateFromVirtualMachineExport", func() {
It("should return the certificate content", func() {
_, err := vmExportClient.ExportV1beta1().VirtualMachineExports(namespace).Create(context.Background(),
&v1beta1.VirtualMachineExport{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Status: &v1beta1.VirtualMachineExportStatus{
Links: &v1beta1.VirtualMachineExportLinks{
Internal: &v1beta1.VirtualMachineExportLink{
Cert: "test-cert-content",
},
},
},
},
metav1.CreateOptions{},
)
Expect(err).NotTo(HaveOccurred())

cert, err := certificate.GetCertificateFromVirtualMachineExport(virtClient, namespace, name)
Expect(err).NotTo(HaveOccurred())
Expect(cert).To(Equal("test-cert-content"))
})

It("should return not found error", func() {
_, err := certificate.GetCertificateFromVirtualMachineExport(virtClient, namespace, "test")
Expect(err).To(MatchError(errors.IsNotFound, "errors.IsNotFound"))
})

It("should return an error when no links found", func() {
_, err := vmExportClient.ExportV1beta1().VirtualMachineExports(namespace).Create(context.Background(),
&v1beta1.VirtualMachineExport{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Status: &v1beta1.VirtualMachineExportStatus{
Links: nil,
},
},
metav1.CreateOptions{},
)
Expect(err).NotTo(HaveOccurred())

cert, err := certificate.GetCertificateFromVirtualMachineExport(virtClient, namespace, name)
Expect(err).To(MatchError("no links found in VirtualMachineExport status"))
Expect(cert).To(BeEmpty())
})

It("should return an error when no certificate found", func() {
_, err := vmExportClient.ExportV1beta1().VirtualMachineExports(namespace).Create(context.Background(),
&v1beta1.VirtualMachineExport{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Status: &v1beta1.VirtualMachineExportStatus{
Links: &v1beta1.VirtualMachineExportLinks{
Internal: &v1beta1.VirtualMachineExportLink{
Cert: "",
},
},
},
},
metav1.CreateOptions{},
)
Expect(err).NotTo(HaveOccurred())

cert, err := certificate.GetCertificateFromVirtualMachineExport(virtClient, namespace, name)
Expect(err).To(MatchError("no certificate found in VirtualMachineExport status"))
Expect(cert).To(BeEmpty())
})
})
})
8 changes: 4 additions & 4 deletions modules/disk-uploader/pkg/parse/clioptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ func (c *CLIOptions) trimSpaces() {

func (c *CLIOptions) assertValidParams() error {
if c.ExportSourceKind == "" {
return zerrors.NewMissingRequiredError("%s param has to be specified", c.ExportSourceKind)
return zerrors.NewMissingRequiredError("%s param has to be specified", "export-source-kind")
}

if c.ExportSourceName == "" {
return zerrors.NewMissingRequiredError("%s param has to be specified", c.ExportSourceName)
return zerrors.NewMissingRequiredError("%s param has to be specified", "export-source-name")
}

if c.VolumeName == "" {
return zerrors.NewMissingRequiredError("%s param has to be specified", c.VolumeName)
return zerrors.NewMissingRequiredError("%s param has to be specified", "volume-name")
}

if c.ImageDestination == "" {
return zerrors.NewMissingRequiredError("%s param has to be specified", c.ImageDestination)
return zerrors.NewMissingRequiredError("%s param has to be specified", "image-destination")
}
return nil
}
Expand Down
77 changes: 77 additions & 0 deletions modules/disk-uploader/pkg/parse/clioptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package parse_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"go.uber.org/zap/zapcore"

"github.com/kubevirt/kubevirt-tekton-tasks/modules/disk-uploader/pkg/parse"
)

var _ = Describe("CLIOptions", func() {
const (
expectedExportSourceKind = "vm"
expectedExportSourceNamespace = "test-namespace"
expectedExportSourceName = "test-vmexport"
expectedVolumeName = "test-volume"
expectedImageDestination = "quay.io/kubevirt/example"
)

DescribeTable("Init return correct assertion errors", func(expectedErrMessage string, options *parse.CLIOptions) {
Expect(options.Init()).To(MatchError(expectedErrMessage))
},
Entry("no export-source-kind", "export-source-kind param has to be specified",
&parse.CLIOptions{}),
Entry("no export-source-name", "export-source-name param has to be specified",
&parse.CLIOptions{ExportSourceKind: expectedExportSourceKind}),
Entry("no volume-name", "volume-name param has to be specified",
&parse.CLIOptions{ExportSourceKind: expectedExportSourceKind, ExportSourceName: expectedExportSourceName}),
Entry("no image-destination", "image-destination param has to be specified",
&parse.CLIOptions{ExportSourceKind: expectedExportSourceKind, ExportSourceName: expectedExportSourceName, VolumeName: expectedVolumeName}),
)

Context("valid cli options", func() {
It("should succeed with yaml output", func() {
options := &parse.CLIOptions{
ExportSourceKind: expectedExportSourceKind,
ExportSourceNamespace: expectedExportSourceNamespace,
ExportSourceName: expectedExportSourceName,
VolumeName: expectedVolumeName,
ImageDestination: expectedImageDestination,
PushTimeout: 60,
Debug: true,
}
Expect(options.Init()).To(Succeed())
})

It("Init should trim spaces", func() {
options := &parse.CLIOptions{
ExportSourceKind: " " + expectedExportSourceKind + " ",
ExportSourceNamespace: " " + expectedExportSourceNamespace + " ",
ExportSourceName: " " + expectedExportSourceName + " ",
VolumeName: " " + expectedVolumeName + " ",
ImageDestination: " " + expectedImageDestination + " ",
PushTimeout: 60,
Debug: true,
}

Expect(options.Init()).To(Succeed())
Expect(options.ExportSourceKind).To(Equal(expectedExportSourceKind), "ExportSourceKind should equal")
Expect(options.ExportSourceNamespace).To(Equal(expectedExportSourceNamespace), "ExportSourceNamespace should equal")
Expect(options.ExportSourceName).To(Equal(expectedExportSourceName), "ExportSourceName should equal")
Expect(options.VolumeName).To(Equal(expectedVolumeName), "VolumeName should equal")
Expect(options.ImageDestination).To(Equal(expectedImageDestination), "ImageDestination should equal")
})

It("GetDebugLevel should return correct debug level when Debug is true", func() {
options := &parse.CLIOptions{Debug: true}
Expect(options.GetDebugLevel()).To(Equal(zapcore.DebugLevel), "level should equal")
})

It("GetDebugLevel should return correct info level when Debug is false", func() {
options := &parse.CLIOptions{Debug: false}
Expect(options.GetDebugLevel()).To(Equal(zapcore.InfoLevel), "level should equal")
})
})
})
Loading

0 comments on commit 4129a54

Please sign in to comment.