Add performance E2E test

Signed-off-by: Ming Qiu <mqiu@vmware.com>
pull/6569/head
Ming Qiu 2023-07-31 10:25:48 +08:00 committed by Ming
parent a6d79fc272
commit 3b45830012
104 changed files with 1661 additions and 127 deletions

View File

@ -359,5 +359,9 @@ gen-docs:
test-e2e: local
$(MAKE) -e VERSION=$(VERSION) -C test/e2e run
.PHONY: test-perf
test-perf: local
$(MAKE) -e VERSION=$(VERSION) -C test/perf run
go-generate:
go generate ./pkg/...

View File

@ -0,0 +1 @@
Add performance E2E test

1
go.mod
View File

@ -51,6 +51,7 @@ require (
k8s.io/client-go v0.25.6
k8s.io/klog/v2 v2.70.1
k8s.io/kube-aggregator v0.19.12
k8s.io/metrics v0.25.6
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
sigs.k8s.io/controller-runtime v0.12.2
sigs.k8s.io/yaml v1.3.0

2
go.sum
View File

@ -1360,6 +1360,8 @@ k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2R
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
k8s.io/metrics v0.25.6 h1:EezfQTfTsSW/Cs9oHJXAftRlbL0fnHfDh02ObTOs/34=
k8s.io/metrics v0.25.6/go.mod h1:LGcsjMsQQvt/4vrvQzqOIHv9/sIVov1ZE7HtQxc8d9w=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=

View File

@ -19,7 +19,7 @@ run:
# "/" will be replaced by current OS file path separator to properly work
# on Windows.
skip-dirs:
- test/e2e/*
- test/*
- pkg/plugin/generated/*
# - autogenerated_by_my_lib

View File

@ -24,10 +24,10 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
func BackupRestoreWithSnapshots() {

View File

@ -26,11 +26,11 @@ import (
. "github.com/onsi/gomega"
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
const deletionTest = "deletion-workload"

View File

@ -30,10 +30,10 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type SyncBackups struct {

View File

@ -30,12 +30,12 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type TTL struct {

View File

@ -24,9 +24,9 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
func APIExtensionsVersionsTest() {

View File

@ -36,9 +36,9 @@ import (
"github.com/vmware-tanzu/velero/pkg/builder"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
var veleroCfg VeleroConfig

View File

@ -9,10 +9,10 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
)
type NamespaceMapping struct {

View File

@ -13,10 +13,10 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type NodePort struct {

View File

@ -10,10 +10,10 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type PVCSelectedNodeChanging struct {

View File

@ -25,9 +25,9 @@ import (
"github.com/pkg/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
type MultiNSBackup struct {

View File

@ -24,9 +24,9 @@ import (
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
type NSAnnotationCase struct {

View File

@ -40,9 +40,9 @@ import (
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
type RBACCase struct {

View File

@ -10,10 +10,10 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type StorageClasssChanging struct {
@ -70,7 +70,7 @@ func (s *StorageClasssChanging) Init() error {
func (s *StorageClasssChanging) CreateResources() error {
s.Ctx, s.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
By(fmt.Sprintf("Create a storage class %s", s.desStorageClass), func() {
Expect(InstallStorageClass(s.Ctx, fmt.Sprintf("testdata/storage-class/%s.yaml",
Expect(InstallStorageClass(s.Ctx, fmt.Sprintf("../testdata/storage-class/%s.yaml",
s.VeleroCfg.CloudProvider))).To(Succeed())
})
By(fmt.Sprintf("Create namespace %s", s.namespace), func() {

View File

@ -27,12 +27,12 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
const (

View File

@ -27,7 +27,7 @@ import (
"github.com/onsi/ginkgo/reporters"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/backup"
. "github.com/vmware-tanzu/velero/test/e2e/backups"
. "github.com/vmware-tanzu/velero/test/e2e/basic"
@ -42,8 +42,8 @@ import (
. "github.com/vmware-tanzu/velero/test/e2e/scale"
. "github.com/vmware-tanzu/velero/test/e2e/schedule"
. "github.com/vmware-tanzu/velero/test/e2e/upgrade"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
func init() {

View File

@ -26,11 +26,11 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
var migrationNamespace string
@ -291,7 +291,7 @@ func MigrationTest(useVolumeSnapshots bool, veleroCLI2Version VeleroCLI2Version)
By(fmt.Sprintf("Restore %s", migrationNamespace), func() {
if OriginVeleroCfg.SnapshotMoveData {
By(fmt.Sprintf("Create a storage class %s for restore PV provisioned by storage class %s on different cloud provider", StorageClassName, KibishiiStorageClassName), func() {
Expect(InstallStorageClass(context.Background(), fmt.Sprintf("testdata/storage-class/%s.yaml", veleroCfg.StandbyClusterCloudProvider))).To(Succeed())
Expect(InstallStorageClass(context.Background(), fmt.Sprintf("../testdata/storage-class/%s.yaml", veleroCfg.StandbyClusterCloudProvider))).To(Succeed())
})
configmaptName := "datamover-storage-class-config"
labels := map[string]string{"velero.io/change-storage-class": "RestoreItemAction",

View File

@ -29,9 +29,9 @@ import (
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
func SSRTest() {

View File

@ -10,9 +10,9 @@ import (
. "github.com/onsi/gomega"
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
type PVBackupFiltering struct {
@ -67,7 +67,7 @@ func (p *PVBackupFiltering) Init() error {
func (p *PVBackupFiltering) CreateResources() error {
p.Ctx, p.CtxCancel = context.WithTimeout(context.Background(), 30*time.Minute)
err := InstallStorageClass(p.Ctx, fmt.Sprintf("testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))
err := InstallStorageClass(p.Ctx, fmt.Sprintf("../testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))
if err != nil {
return errors.Wrapf(err, "failed to install storage class for pv backup filtering test")
}

View File

@ -24,9 +24,9 @@ import (
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
type FilteringCase struct {

View File

@ -27,9 +27,9 @@ import (
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -25,9 +25,9 @@ import (
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -24,9 +24,9 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -25,9 +25,9 @@ import (
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -24,9 +24,9 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -26,9 +26,9 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
/*

View File

@ -30,9 +30,9 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
const FileName = "test-data.txt"
@ -110,7 +110,7 @@ func (r *ResourcePoliciesCase) CreateResources() error {
r.Ctx, r.CtxCancel = context.WithTimeout(context.Background(), 10*time.Minute)
By(("Installing storage class..."), func() {
Expect(r.installTestStorageClasses(fmt.Sprintf("testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))).To(Succeed(), "Failed to install storage class")
Expect(r.installTestStorageClasses(fmt.Sprintf("../testdata/storage-class/%s.yaml", VeleroCfg.CloudProvider))).To(Succeed(), "Failed to install storage class")
})
By(fmt.Sprintf("Create configmap %s in namespaces %s for workload\n", r.cmName, r.VeleroCfg.VeleroNamespace), func() {

View File

@ -30,10 +30,10 @@ import (
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
var ScheduleOrderedResources func() = TestFunc(&OrderedResources{})

View File

@ -10,10 +10,10 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type ScheduleBackupCreation struct {

View File

@ -10,10 +10,10 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/e2e/test"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type ScheduleBackup struct {

View File

@ -30,10 +30,9 @@ import (
"github.com/pkg/errors"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
/*
@ -84,7 +83,7 @@ func TestFunc(test VeleroBackupRestoreTest) func() {
BeforeEach(func() {
flag.Parse()
// Using the global velero config which covered the installation for most common cases
veleroCfg := e2e.VeleroCfg
veleroCfg := VeleroCfg
// TODO: Skip nodeport test until issue https://github.com/kubernetes/kubernetes/issues/114384 fixed
// TODO: Although this issue is closed, but it's not fixed.
// TODO: After bump up k8s version in AWS pipeline, this issue also apply for AWS pipeline.
@ -103,7 +102,7 @@ func TestFunc(test VeleroBackupRestoreTest) func() {
func TestFuncWithMultiIt(tests []VeleroBackupRestoreTest) func() {
return func() {
veleroCfg := e2e.VeleroCfg
veleroCfg := VeleroCfg
for k := range tests {
Expect(tests[k].Init()).To(Succeed(), fmt.Sprintf("Failed to instantiate test %s case", tests[k].GetTestMsg().Desc))
defer tests[k].GetTestCase().CtxCancel()
@ -212,7 +211,9 @@ func RunTestCase(test VeleroBackupRestoreTest) error {
if test == nil {
return errors.New("No case should be tested")
}
defer test.Clean()
fmt.Printf("CreateResources %s\n", time.Now().Format("2006-01-02 15:04:05"))
err := test.CreateResources()
if err != nil {

View File

@ -26,12 +26,12 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/kibishii"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/kibishii"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
const (

117
test/perf/Makefile Normal file
View File

@ -0,0 +1,117 @@
# Copyright 2020 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# If you update this file, please follow:
# https://suva.sh/posts/well-documented-makefiles/
# Use GOPROXY environment variable if set
.DEFAULT_GOAL:=help
ARCH ?= $(shell go env GOOS)-$(shell go env GOARCH)
platform_temp = $(subst -, ,$(ARCH))
GOOS = $(word 1, $(platform_temp))
GOARCH = $(word 2, $(platform_temp))
GOPROXY := $(shell go env GOPROXY)
ifeq ($(GOPROXY),)
GOPROXY := https://proxy.golang.org
endif
export GOPROXY
REPO_ROOT := $(shell git rev-parse --show-toplevel)
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
## --------------------------------------
## Binaries
## --------------------------------------
TOOLS_DIR := $(REPO_ROOT)/hack/tools
BIN_DIR := bin
TOOLS_BIN_DIR := $(TOOLS_DIR)/$(BIN_DIR)
GINKGO := $(GOPATH)/bin/ginkgo
KUSTOMIZE := $(TOOLS_BIN_DIR)/kustomize
OUTPUT_DIR := _output/$(GOOS)/$(GOARCH)/bin
GINKGO_FOCUS ?=
GINKGO_SKIP ?=
SKIP_STR := $(foreach var, $(subst ., ,$(GINKGO_SKIP)),-skip "$(var)")
FOCUS_STR := $(foreach var, $(subst ., ,$(GINKGO_FOCUS)),-focus "$(var)")
VELERO_CLI ?=$$(pwd)/../../_output/bin/$(GOOS)/$(GOARCH)/velero
VELERO_IMAGE ?= velero/velero:main
VELERO_VERSION ?= $(VERSION)
PLUGINS ?=
RESTORE_HELPER_IMAGE ?=
VELERO_NAMESPACE ?= velero
CREDS_FILE ?=
BSL_BUCKET ?=
BSL_PREFIX ?=
BSL_CONFIG ?=
VSL_CONFIG ?=
CLOUD_PROVIDER ?=
OBJECT_STORE_PROVIDER ?=
INSTALL_VELERO ?= true
REGISTRY_CREDENTIAL_FILE ?=
FEATURES ?=
DEBUG_E2E_TEST ?= false
VELERO_SERVER_DEBUG_MODE ?= false
NFS_SERVER_PATH ?=
# Parameters to run migration tests along with all other E2E tests, and both of them should
# be provided or left them all empty to skip migration tests with no influence to other
# E2E tests.
UPLOADER_TYPE ?=
TEST_CASE_DESCRIBE ?= 'velero performance test'
BACKUP_FOR_RESTORE ?=
.PHONY:ginkgo
ginkgo: # Make sure ginkgo is in $GOPATH/bin
go install github.com/onsi/ginkgo/ginkgo@v1.16.5
.PHONY: run
run: ginkgo
@[ "${CREDS_FILE}" ] && echo "Using credentials from ${CREDS_FILE}" || \
( echo "A credentials file is required to run E2E tests, please re-run the make target with CREDS_FILE=<PathToCredentialsFile>"; exit 1 )
@[ "${BSL_BUCKET}" ] && echo "Using bucket ${BSL_BUCKET} to store backups from E2E tests" || \
(echo "Bucket to store the backups from E2E tests is required, please re-run with BSL_BUCKET=<BucketName>"; exit 1 )
@[ "${CLOUD_PROVIDER}" ] && echo "Using cloud provider ${CLOUD_PROVIDER}" || \
(echo "Cloud provider for target cloud/plugin provider is required, please rerun with CLOUD_PROVIDER=<aws,azure,kind,vsphere>"; exit 1)
@$(GINKGO) -v $(FOCUS_STR) $(SKIP_STR) . -- -velerocli=$(VELERO_CLI) \
-velero-image=$(VELERO_IMAGE) \
-plugins=$(PLUGINS) \
-velero-version=$(VELERO_VERSION) \
-restore-helper-image=$(RESTORE_HELPER_IMAGE) \
-velero-namespace=$(VELERO_NAMESPACE) \
-credentials-file=$(CREDS_FILE) \
-bucket=$(BSL_BUCKET) \
-prefix=$(BSL_PREFIX) \
-bsl-config=$(BSL_CONFIG) \
-vsl-config=$(VSL_CONFIG) \
-cloud-provider=$(CLOUD_PROVIDER) \
-object-store-provider="$(OBJECT_STORE_PROVIDER)" \
-features=$(FEATURES) \
-install-velero=$(INSTALL_VELERO) \
-registry-credential-file=$(REGISTRY_CREDENTIAL_FILE) \
-debug-e2e-test=$(DEBUG_E2E_TEST) \
-velero-server-debug-mode=$(VELERO_SERVER_DEBUG_MODE) \
-uploader-type=$(UPLOADER_TYPE) \
-nfs-server-path=$(NFS_SERVER_PATH) \
-test-case-describe=$(TEST_CASE_DESCRIBE) \
-backup-for-restore=$(BACKUP_FOR_RESTORE)
build: ginkgo
mkdir -p $(OUTPUT_DIR)
$(GINKGO) build .

5
test/perf/README.md Normal file
View File

@ -0,0 +1,5 @@
# End-to-end tests
Document for running Velero end-to-end performance test suite.
And the data generate tool for performance test could be found in [here](https://github.com/vmware-tanzu/velero-performance-test)

View File

@ -0,0 +1,54 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package backup
import (
"context"
"fmt"
"strings"
"time"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/perf/test"
)
type BackupTest struct {
TestCase
}
func (b *BackupTest) Init() error {
b.TestCase.Init()
b.Ctx, b.CtxCancel = context.WithTimeout(context.Background(), 1*time.Hour)
b.CaseBaseName = "backup"
b.BackupName = "backup-" + b.CaseBaseName + "-" + b.UUIDgen
b.NSExcluded = &[]string{"kube-system", "velero", "default", "kube-public", "kube-node-lease"}
b.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", b.BackupName,
"--exclude-namespaces", strings.Join(*b.NSExcluded, ","),
"--default-volumes-to-fs-backup",
"--snapshot-volumes=false", "--wait",
}
b.TestMsg = &TestMSG{
Desc: "Do backup resources for performance test",
FailedMSG: "Failed to backup resources",
Text: fmt.Sprintf("Should backup resources success"),
}
return nil
}

58
test/perf/basic/basic.go Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright 2021 the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package basic
import (
"context"
"fmt"
"strings"
"time"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/perf/test"
)
type BasicTest struct {
TestCase
}
func (b *BasicTest) Init() error {
b.TestCase.Init()
b.Ctx, b.CtxCancel = context.WithTimeout(context.Background(), 1*time.Hour)
b.CaseBaseName = "backuprestore"
b.BackupName = "backup-" + b.CaseBaseName + "-" + b.UUIDgen
b.RestoreName = "restore-" + b.CaseBaseName + "-" + b.UUIDgen
b.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", b.BackupName,
"--exclude-namespaces", strings.Join(*b.NSExcluded, ","),
"--default-volumes-to-fs-backup",
"--snapshot-volumes=false", "--wait",
}
b.RestoreArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore", b.RestoreName,
"--from-backup", b.BackupName, "--wait",
}
b.TestMsg = &TestMSG{
Desc: "Do backup and restore resources for performance test",
FailedMSG: "Failed to backup and restore resources",
Text: fmt.Sprintf("Should backup and restore resources success"),
}
return nil
}

121
test/perf/e2e_suite_test.go Normal file
View File

@ -0,0 +1,121 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package perf_test
import (
"context"
"flag"
"fmt"
"testing"
. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/reporters"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test"
"github.com/vmware-tanzu/velero/test/perf/backup"
"github.com/vmware-tanzu/velero/test/perf/basic"
"github.com/vmware-tanzu/velero/test/perf/restore"
"github.com/vmware-tanzu/velero/test/perf/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
"github.com/vmware-tanzu/velero/test/util/report"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
func init() {
flag.StringVar(&VeleroCfg.CloudProvider, "cloud-provider", "", "cloud that Velero will be installed into. Required.")
flag.StringVar(&VeleroCfg.ObjectStoreProvider, "object-store-provider", "", "provider of object store plugin. Required if cloud-provider is kind, otherwise ignored.")
flag.StringVar(&VeleroCfg.BSLBucket, "bucket", "", "name of the object storage bucket where backups from e2e tests should be stored. Required.")
flag.StringVar(&VeleroCfg.CloudCredentialsFile, "credentials-file", "", "file containing credentials for backup and volume provider. Required.")
flag.StringVar(&VeleroCfg.VeleroCLI, "velerocli", "velero", "path to the velero application to use.")
flag.StringVar(&VeleroCfg.VeleroImage, "velero-image", "velero/velero:main", "image for the velero server to be tested.")
flag.StringVar(&VeleroCfg.Plugins, "plugins", "", "provider plugins to be tested.")
flag.StringVar(&VeleroCfg.AddBSLPlugins, "additional-bsl-plugins", "", "additional plugins to be tested.")
flag.StringVar(&VeleroCfg.VeleroVersion, "velero-version", "main", "image version for the velero server to be tested with.")
flag.StringVar(&VeleroCfg.RestoreHelperImage, "restore-helper-image", "", "image for the velero restore helper to be tested.")
flag.StringVar(&VeleroCfg.BSLConfig, "bsl-config", "", "configuration to use for the backup storage location. Format is key1=value1,key2=value2")
flag.StringVar(&VeleroCfg.BSLPrefix, "prefix", "", "prefix under which all Velero data should be stored within the bucket. Optional.")
flag.StringVar(&VeleroCfg.VSLConfig, "vsl-config", "", "configuration to use for the volume snapshot location. Format is key1=value1,key2=value2")
flag.StringVar(&VeleroCfg.VeleroNamespace, "velero-namespace", "velero", "namespace to install Velero into")
flag.BoolVar(&VeleroCfg.InstallVelero, "install-velero", true, "install/uninstall velero during the test. Optional.")
flag.BoolVar(&VeleroCfg.UseNodeAgent, "use-node-agent", true, "whether deploy node agent daemonset velero during the test. Optional.")
flag.StringVar(&VeleroCfg.RegistryCredentialFile, "registry-credential-file", "", "file containing credential for the image registry, follows the same format rules as the ~/.docker/config.json file. Optional.")
//vmware-tanzu-experiments
flag.StringVar(&VeleroCfg.Features, "features", "", "Comma-separated list of features to enable for this Velero process.")
flag.StringVar(&VeleroCfg.DefaultCluster, "default-cluster-context", "", "Default cluster context for migration test.")
flag.BoolVar(&VeleroCfg.Debug, "debug-e2e-test", true, "Switch to control namespace cleaning.")
flag.StringVar(&VeleroCfg.UploaderType, "uploader-type", "kopia", "Identify persistent volume backup uploader.")
flag.BoolVar(&VeleroCfg.VeleroServerDebugMode, "velero-server-debug-mode", false, "Identify persistent volume backup uploader.")
flag.StringVar(&VeleroCfg.NFSServerPath, "nfs-server-path", "", "the path of nfs server")
flag.StringVar(&VeleroCfg.TestCaseDescribe, "test-case-describe", "velero performance test", "the description for the current test")
flag.StringVar(&VeleroCfg.BackupForRestore, "backup-for-restore", "", "the name of backup for restore")
}
func initConfig() error {
cli, err := NewTestClient("")
if err != nil {
return errors.WithStack(err)
}
VeleroCfg.DefaultClient = &cli
ReportData = &Report{
TestDescription: VeleroCfg.TestCaseDescribe,
OtherFields: make(map[string]interface{}),
}
return nil
}
var _ = Describe("[PerformanceTest][BackupAndRestore] Velero test on both backup and restore resources", test.TestFunc(&basic.BasicTest{}))
var _ = Describe("[PerformanceTest][Backup] Velero test on only backup resources", test.TestFunc(&backup.BackupTest{}))
var _ = Describe("[PerformanceTest][Restore] Velero test on only restore resources", test.TestFunc(&restore.RestoreTest{}))
func TestE2e(t *testing.T) {
flag.Parse()
By("Install test resources before testing TestE2e")
// Skip running E2E tests when running only "short" tests because:
// 1. E2E tests are long running tests involving installation of Velero and performing backup and restore operations.
// 2. E2E tests require a Kubernetes cluster to install and run velero which further requires more configuration. See above referenced command line flags.
if err := initConfig(); err != nil {
fmt.Println(err)
t.FailNow()
}
RegisterFailHandler(Fail)
junitReporter := reporters.NewJUnitReporter("report.xml")
RunSpecsWithDefaultAndCustomReporters(t, "E2e Suite", []Reporter{junitReporter})
}
var _ = BeforeSuite(func() {
if VeleroCfg.InstallVelero {
By("Install test resources before testing BeforeSuite")
Expect(PrepareVelero(context.Background(), "install resource before testing")).To(Succeed())
}
})
var _ = AfterSuite(func() {
Expect(report.GenerateYamlReport()).To(Succeed())
if VeleroCfg.InstallVelero && !VeleroCfg.Debug {
By("release test resources after testing")
Expect(VeleroUninstall(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace)).To(Succeed())
}
})

View File

@ -0,0 +1,51 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/test/util/metrics"
)
const MinioDesc = "Minio disk usage"
type MinioMetrics struct {
Metrics map[string]string
CloudCredentialsFile string
BslBucket string
BslPrefix string
BslConfig string
}
func (m *MinioMetrics) Update() error {
if bucketSize, err := metrics.GetMinioDiskUsage(m.CloudCredentialsFile,
m.BslBucket, m.BslPrefix, m.BslConfig); err != nil {
return errors.WithStack(err)
} else {
m.Metrics["minio"] = formatMemoryDiskValue(bucketSize)
}
return nil
}
func (m *MinioMetrics) GetMetrics() map[string]string {
return m.Metrics
}
func (m *MinioMetrics) GetMetricsName() string {
return MinioDesc
}

View File

@ -0,0 +1,132 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"fmt"
"strings"
"sync"
"time"
)
// Metric is an interface for metrics that test needs.
type Metric interface {
Update() error
GetMetricsName() string
GetMetrics() map[string]string
}
// MetricsCollector is a singleton struct for collecting metrics.
type MetricsCollector struct {
Metrics []Metric // metrics need update periodically
OneTimeMetrics []Metric // OneTimeMetrics just update one time
Mu sync.Mutex // mutex for protecting shared resources
}
// GetMetricsCollector returns the singleton instance of MetricsCollector
func GetMetricsCollector() *MetricsCollector {
return &MetricsCollector{
Metrics: []Metric{},
OneTimeMetrics: []Metric{},
}
}
// RegisterMetric adds a metric to the MetricsCollector
func (m *MetricsCollector) RegisterMetric(metric Metric) {
m.Metrics = append(m.Metrics, metric)
}
// RegisterOneTimeMetric adds a one-time metric to the MetricsCollector
func (m *MetricsCollector) RegisterOneTimeMetric(metric Metric) {
m.OneTimeMetrics = append(m.OneTimeMetrics, metric)
}
// UpdateMetrics periodically updates the metrics for all metrics
func (m *MetricsCollector) UpdateMetrics() {
for {
m.Mu.Lock() // Acquire the lock before accessing shared resources
for _, metric := range m.Metrics {
if err := metric.Update(); err != nil {
fmt.Printf("Failed to update metrics: %v\n", err)
continue
}
}
m.Mu.Unlock() // Release the lock after accessing shared resources
time.Sleep(15 * time.Second) // Adjust the interval as per your requirement.
}
}
// UpdateMetrics periodically updates the one-time metrics for all metrics
func (m *MetricsCollector) UpdateOneTimeMetrics() {
// NotifyOneTimeMonitors notifies the one-time metrics about the metric
for _, metric := range m.OneTimeMetrics {
if err := metric.Update(); err != nil {
fmt.Printf("Failed to update one-time metrics: %v\n", err)
continue
}
}
}
// GetMetrics returns the metrics from all metrics
func (m *MetricsCollector) GetMetrics() map[string]interface{} {
m.Mu.Lock() // Acquire the lock before accessing shared resources
defer m.Mu.Unlock() // Release the lock after the function returns
dataMap := make(map[string]interface{})
resData := make(map[string]([]map[string]map[string]string))
for _, metric := range m.Metrics {
monitorMetrics := metric.GetMetrics()
res := getResourceConsumption(monitorMetrics)
if _, ok := resData[metric.GetMetricsName()]; !ok {
resData[metric.GetMetricsName()] = make([]map[string]map[string]string, 0)
}
resData[metric.GetMetricsName()] = append(resData[metric.GetMetricsName()], res)
}
for metricsName, metrics := range resData {
dataMap[metricsName] = metrics
}
for _, metric := range m.OneTimeMetrics {
oneTimeMetricsMap := make(map[string]interface{})
monitorMetrics := metric.GetMetrics()
for key, value := range monitorMetrics {
oneTimeMetricsMap[key] = value
}
dataMap[metric.GetMetricsName()] = oneTimeMetricsMap
}
return dataMap
}
// Helper function to process Resource Consumption data
func getResourceConsumption(resourceMap map[string]string) map[string]map[string]string {
result := map[string]map[string]string{}
resourcePrefix := map[string]string{"MaxCPU": "Max CPU", "MaxMemory": "MaxMemory", "AverageCPU": "Average CPU", "AverageMemory": "Average Memory"}
for key, value := range resourceMap {
parts := strings.Split(key, ":")
resourceName := parts[0]
resourceType := parts[1]
if _, ok := resourcePrefix[resourceType]; ok {
if result[resourceName] == nil {
result[resourceName] = map[string]string{}
}
result[resourceName][resourcePrefix[resourceType]] = value
}
}
return result
}

51
test/perf/metrics/nfs.go Normal file
View File

@ -0,0 +1,51 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"context"
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/test/util/metrics"
)
const NFSDesc = "NFS disk usage"
type NFSMetrics struct {
Metrics map[string]string
NFSServerPath string
Ctx context.Context
}
func (n *NFSMetrics) Update() error {
if usedSpace, err := metrics.GetNFSPathDiskUsage(n.Ctx, n.NFSServerPath); err != nil {
return errors.WithStack(err)
} else {
n.Metrics["nfs"] = usedSpace
}
return nil
}
func (n *NFSMetrics) GetMetrics() map[string]string {
return n.Metrics
}
func (n *NFSMetrics) GetMetricsName() string {
return NFSDesc
}

109
test/perf/metrics/pod.go Normal file
View File

@ -0,0 +1,109 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"context"
"fmt"
"strings"
"github.com/pkg/errors"
metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
"github.com/vmware-tanzu/velero/test/util/metrics"
)
const PodResourceDesc = "Resource consumption"
type PodMetrics struct {
Client *metricsclientset.Clientset
Metrics map[string]int64
count int64
PodName, Namespace string
Ctx context.Context
}
func (p *PodMetrics) Update() error {
cpu, mem, err := metrics.GetPodUsageMetrics(p.Ctx, p.Client, p.PodName, p.Namespace)
if err != nil {
return errors.WithStack(err)
} else {
keyMaxCPU := p.PodName + ":MaxCPU"
curCPU := cpu.MilliValue()
if curCPU > p.Metrics[keyMaxCPU] {
p.Metrics[keyMaxCPU] = curCPU
}
keyMaxMem := p.PodName + ":MaxMemory"
curMem := mem.MilliValue()
if curMem > p.Metrics[keyMaxMem] {
p.Metrics[keyMaxMem] = curMem
}
keyAvgCPU := p.PodName + ":AverageCPU"
preAvgCPU := p.Metrics[keyAvgCPU]
p.Metrics[keyAvgCPU] = (preAvgCPU*p.count + curCPU) / (p.count + 1)
keyAvgMem := p.PodName + ":AverageMemory"
preAvgMem := p.Metrics[keyAvgMem]
p.Metrics[keyAvgMem] = (preAvgMem*p.count + curMem) / (p.count + 1)
p.count++
}
return nil
}
func (p *PodMetrics) GetMetrics() map[string]string {
tmpMetrics := make(map[string]string)
for k := range p.Metrics {
if strings.Contains(k, "CPU") {
tmpMetrics[k] = formatCPUValue(p.Metrics[k])
} else if strings.Contains(k, "Memory") {
tmpMetrics[k] = formatMemoryDiskValue(p.Metrics[k] / 1024)
}
}
return tmpMetrics
}
func (p *PodMetrics) GetMetricsName() string {
return PodResourceDesc
}
func formatCPUValue(milliValue int64) string {
if milliValue < 1000 {
return fmt.Sprintf("%d mili core", milliValue)
}
coreValue := float64(milliValue) / 1000.0
return fmt.Sprintf("%.2f core", coreValue)
}
func formatMemoryDiskValue(memoryValue int64) string {
units := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
if memoryValue == 0 {
return "0 B"
}
base := int64(1024)
exp := int64(0)
for memoryValue >= base && exp < int64(len(units)-1) {
memoryValue /= base
exp++
}
return fmt.Sprintf("%d %s", memoryValue, units[exp])
}

58
test/perf/metrics/time.go Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import "time"
const TimeCaseDesc = "Time cost"
type TimeMetrics struct {
Name string
TimeInfo map[string]time.Time // metric name : start timestamp
Metrics map[string]float64 // metric name : time duration
}
func (t *TimeMetrics) GetMetrics() map[string]string {
tmpMetrics := make(map[string]string)
for k, v := range t.Metrics {
duration := time.Duration(v) * time.Second
tmpMetrics[k] = duration.String()
}
return tmpMetrics
}
func (t *TimeMetrics) Start(name string) {
t.TimeInfo[name] = time.Now()
}
func (t *TimeMetrics) End(name string) {
t.Metrics[name] = time.Now().Sub(t.TimeInfo[name]).Seconds()
if t.Metrics[name] < 1 {
// For those too shoter time difference we should ignored
// as it may not really execute the logic
delete(t.Metrics, name)
}
}
func (t *TimeMetrics) Update() error {
t.Metrics[t.Name] = time.Now().Sub(t.TimeInfo[t.Name]).Seconds()
return nil
}
func (t *TimeMetrics) GetMetricsName() string {
return TimeCaseDesc
}

View File

@ -0,0 +1,78 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package restore
import (
"context"
"fmt"
"time"
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/perf/test"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
type RestoreTest struct {
TestCase
}
func (r *RestoreTest) Init() error {
r.TestCase.Init()
r.Ctx, r.CtxCancel = context.WithTimeout(context.Background(), 1*time.Hour)
r.CaseBaseName = "restore"
r.RestoreName = "restore-" + r.CaseBaseName + "-" + r.UUIDgen
r.TestMsg = &TestMSG{
Desc: "Do restore resources for performance test",
FailedMSG: "Failed to restore resources",
Text: fmt.Sprintf("Should restore resources success"),
}
return r.clearUpResourcesBeforRestore()
}
func (r *RestoreTest) clearUpResourcesBeforRestore() error {
// we need to clear up all resources before do the restore test
return r.TestCase.Destroy()
}
func (r *RestoreTest) Restore() error {
var backupName string
if VeleroCfg.BackupForRestore != "" {
backupName = VeleroCfg.BackupForRestore
} else {
// put partial parameters initialization here because we could not get latest backups in init periods for
// velero may not ready
var err error
backupName, err = GetLatestSuccessBackupsFromBSL(r.Ctx, VeleroCfg.VeleroCLI, "default")
if err != nil {
return errors.Wrapf(err, "failed to get backup to do the restore test")
}
}
r.BackupName = backupName
r.RestoreArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore", r.RestoreName,
"--from-backup", r.BackupName, "--wait",
}
return r.TestCase.Restore()
}
func (r *RestoreTest) Destroy() error {
return nil
}

292
test/perf/test/test.go Normal file
View File

@ -0,0 +1,292 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package test
import (
"context"
"fmt"
"math/rand"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/test/util/report"
"github.com/vmware-tanzu/velero/test/util/velero"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
. "github.com/vmware-tanzu/velero/test"
"github.com/vmware-tanzu/velero/test/perf/metrics"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
/*
The VeleroBackupRestoreTest interface is just could be suit for the cases that follow the test flow of
create resources, backup, delete test resource, restore and verify.
And the cases have similar execute function and similar data. it's both fine for you to use it or not which
depends on your test patterns.
*/
type VeleroBackupRestoreTest interface {
Init() error
CreateResources() error
Backup() error
Destroy() error
Restore() error
Verify() error
Clean() error
GetTestMsg() *TestMSG
GetTestCase() *TestCase
}
type TestMSG struct {
Desc string
Text string
FailedMSG string
}
type TestCase struct {
BackupName string
RestoreName string
CaseBaseName string
BackupArgs []string
RestoreArgs []string
NamespacesTotal int
TestMsg *TestMSG
Client TestClient
NSIncluded *[]string
NSExcluded *[]string
UseVolumeSnapshots bool
RestorePhaseExpect velerov1api.RestorePhase
Ctx context.Context
CtxCancel context.CancelFunc
UUIDgen string
timer *metrics.TimeMetrics
}
func TestFunc(test VeleroBackupRestoreTest) func() {
return func() {
Expect(test.Init()).To(Succeed(), "Failed to instantiate test cases")
By(fmt.Sprintf("Run test %s ...... \n", test.GetTestCase().CaseBaseName))
BeforeEach(func() {
// Using the global velero config which covered the installation for most common cases
if VeleroCfg.InstallVelero {
Expect(PrepareVelero(context.Background(), test.GetTestCase().CaseBaseName)).To(Succeed())
}
})
It(test.GetTestMsg().Text, func() {
Expect(RunTestCase(test)).To(Succeed(), test.GetTestMsg().FailedMSG)
})
}
}
func (t *TestCase) Init() error {
t.Ctx, t.CtxCancel = context.WithTimeout(context.Background(), 1*time.Hour)
t.NSExcluded = &[]string{"kube-system", "velero", "default", "kube-public", "kube-node-lease"}
t.UUIDgen = t.GenerateUUID()
t.Client = *VeleroCfg.DefaultClient
t.timer = &metrics.TimeMetrics{
Name: "Total time cost",
TimeInfo: map[string]time.Time{"Total time cost": time.Now()},
Metrics: make(map[string]float64),
}
return nil
}
func (t *TestCase) GenerateUUID() string {
rand.Seed(time.Now().UnixNano())
return fmt.Sprintf("%08d", rand.Intn(100000000))
}
func (t *TestCase) CreateResources() error {
return nil
}
func (t *TestCase) Backup() error {
if len(t.BackupArgs) == 0 {
return nil
}
if err := VeleroBackupExec(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName, t.BackupArgs); err != nil {
RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName, "")
return errors.Wrap(err, "Failed to backup resources")
}
return nil
}
func (t *TestCase) Destroy() error {
By(fmt.Sprintf("Start to destroy namespace %s......", t.CaseBaseName), func() {
Expect(CleanupNamespacesFiterdByExcludes(t.GetTestCase().Ctx, t.Client, *t.NSExcluded)).To(Succeed(), "Could cleanup retrieve namespaces")
Expect(ClearClaimRefForFailedPVs(t.Ctx, t.Client)).To(Succeed(), "Failed to make PV status become to available")
})
return nil
}
func (t *TestCase) Restore() error {
if len(t.RestoreArgs) == 0 {
return nil
}
By("Start to restore ......", func() {
if t.RestorePhaseExpect == "" {
t.RestorePhaseExpect = velerov1api.RestorePhaseCompleted
}
Expect(VeleroRestoreExec(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.RestoreName, t.RestoreArgs, t.RestorePhaseExpect)).To(Succeed(), func() string {
RunDebug(context.Background(), VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, "", t.RestoreName)
return "Fail to restore workload"
})
})
return nil
}
func (t *TestCase) Verify() error {
return nil
}
func (t *TestCase) Clean() error {
if !VeleroCfg.Debug {
By("Clean backups and restore after test", func() {
if len(t.BackupArgs) != 0 {
if err := VeleroBackupDelete(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.BackupName); err != nil {
fmt.Printf("Failed to delete backup %s with err %v\n", t.BackupName, err)
}
}
if len(t.RestoreArgs) != 0 {
if err := VeleroRestoreDelete(t.Ctx, VeleroCfg.VeleroCLI, VeleroCfg.VeleroNamespace, t.RestoreName); err != nil {
fmt.Printf("Failed to delete restore %s with err %v\n", t.RestoreName, err)
}
}
})
Expect(ClearClaimRefForFailedPVs(t.Ctx, t.Client)).To(Succeed(), "Failed to make PV status become to available")
}
return nil
}
func (t *TestCase) GetTestMsg() *TestMSG {
return t.TestMsg
}
func (t *TestCase) GetTestCase() *TestCase {
return t
}
func RunTestCase(test VeleroBackupRestoreTest) error {
collectors := new(metrics.MetricsCollector)
test.GetTestCase().MonitorMetircs(test.GetTestCase().Ctx, collectors)
timer := test.GetTestCase().timer
collectors.RegisterOneTimeMetric(timer)
go collectors.UpdateMetrics()
By(fmt.Sprintf("Running test case %s %s\n", test.GetTestMsg().Desc, time.Now().Format("2006-01-02 15:04:05")))
if test == nil {
return errors.New("No case should be tested")
}
defer func() {
collectors.UpdateOneTimeMetrics()
metrics := collectors.GetMetrics()
report.AddTestSuitData(metrics, test.GetTestMsg().Desc)
test.Clean()
fmt.Printf("OutPut metrics %v for case %s", metrics, test.GetTestCase().CaseBaseName)
}()
fmt.Printf("CreateResources %s\n", time.Now().Format("2006-01-02 15:04:05"))
timer.Start("Create Resources Time Cost")
err := test.CreateResources()
if err != nil {
return err
}
timer.End("Create Resources Time Cost")
timer.Start("Backup Time Cost")
fmt.Printf("Backup %s\n", time.Now().Format("2006-01-02 15:04:05"))
err = test.Backup()
if err != nil {
return err
}
timer.End("Backup Time Cost")
fmt.Printf("Destroy %s\n", time.Now().Format("2006-01-02 15:04:05"))
timer.Start("Destroy Resources Time Cost")
err = test.Destroy()
if err != nil {
return err
}
timer.End("Destroy Resources Time Cost")
fmt.Printf("Restore %s\n", time.Now().Format("2006-01-02 15:04:05"))
timer.Start("Restore Time Cost")
err = test.Restore()
if err != nil {
return err
}
timer.End("Restore Time Cost")
fmt.Printf("Verify %s\n", time.Now().Format("2006-01-02 15:04:05"))
timer.Start("Verify Resource Time Cost")
err = test.Verify()
if err != nil {
return err
}
timer.End("Verify Resource Time Cost")
fmt.Printf("Finish run test %s\n", time.Now().Format("2006-01-02 15:04:05"))
return nil
}
func (t *TestCase) MonitorMetircs(ctx context.Context, collectors *metrics.MetricsCollector) {
if VeleroCfg.NFSServerPath == "" {
fmt.Println("couldn't monitor nfs server disk usage for nfs server path is not configured")
} else {
nfsMetrics := &metrics.NFSMetrics{NFSServerPath: VeleroCfg.NFSServerPath, Metrics: make(map[string]string), Ctx: ctx}
collectors.RegisterOneTimeMetric(nfsMetrics)
}
minioMetrics := &metrics.MinioMetrics{
CloudCredentialsFile: VeleroCfg.CloudCredentialsFile,
BslPrefix: VeleroCfg.BSLPrefix,
BslConfig: VeleroCfg.BSLConfig,
Metrics: make(map[string]string),
BslBucket: VeleroCfg.BSLBucket}
collectors.RegisterOneTimeMetric(minioMetrics)
timeMetrics := &metrics.TimeMetrics{
Name: t.CaseBaseName,
TimeInfo: make(map[string]time.Time),
Metrics: make(map[string]float64),
}
collectors.RegisterOneTimeMetric(timeMetrics)
veleroPodList, err := velero.ListVeleroPods(ctx, VeleroCfg.VeleroNamespace)
if err != nil {
fmt.Printf("couldn't monitor velero pod metrics for failed to get velero pod with err %v\n", err)
} else {
for _, pod := range veleroPodList {
podMetrics := &metrics.PodMetrics{
Ctx: ctx,
Client: VeleroCfg.DefaultClient.MetricsClient,
Metrics: make(map[string]int64),
PodName: pod,
Namespace: VeleroCfg.VeleroNamespace,
}
collectors.RegisterMetric(podMetrics)
}
}
}

View File

@ -30,6 +30,7 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
@ -53,6 +54,9 @@ type Factory interface {
// types to its scheme. It uses the following priority to specify the cluster
// configuration: --kubeconfig flag, KUBECONFIG environment variable, in-cluster configuration.
KubebuilderClient() (kbclient.Client, error)
MetricsClient() (*metricsclientset.Clientset, error)
// SetBasename changes the basename for an already-constructed client.
// This is useful for generating clients that require a different user-agent string below the root `velero`
// command, such as the server subcommand.
@ -170,6 +174,19 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) {
return kubebuilderClient, nil
}
func (f *factory) MetricsClient() (*metricsclientset.Clientset, error) {
clientConfig, err := f.ClientConfig()
if err != nil {
return nil, err
}
metricsClient, err := metricsclientset.NewForConfig(clientConfig)
if err != nil {
return nil, errors.WithStack(err)
}
return metricsClient, nil
}
func (f *factory) SetBasename(name string) {
f.baseName = name
}

View File

@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package e2e
package test
import (
"time"
"github.com/google/uuid"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
const StorageClassName = "e2e-storage-class"
@ -30,7 +30,15 @@ var UUIDgen uuid.UUID
var VeleroCfg VeleroConfig
type Report struct {
TestDescription string `yaml:"Test Description"`
OtherFields map[string]interface{} `yaml:",inline"`
}
var ReportData *Report
type VeleroConfig struct {
VeleroCfgInPerf
VeleroCLI string
VeleroImage string
VeleroVersion string
@ -77,6 +85,12 @@ type VeleroConfig struct {
StandbyClusterCloudProvider string
}
type VeleroCfgInPerf struct {
NFSServerPath string
TestCaseDescribe string
BackupForRestore string
}
type SnapshotCheckPoint struct {
NamespaceBackedUp string
// SnapshotIDList is for Azure CSI Verification

View File

@ -29,7 +29,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/k8s"
)
func GetClients() (*kubernetes.Clientset, *snapshotterClientSet.Clientset, error) {

View File

@ -18,9 +18,10 @@ package k8s
import (
"k8s.io/client-go/kubernetes"
metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/vmware-tanzu/velero/test/e2e/pkg/client"
"github.com/vmware-tanzu/velero/test/pkg/client"
)
// TestClient contains different API clients that are in use throughout
@ -43,6 +44,8 @@ type TestClient struct {
// controller runtime framework by v2.0, it is the intent to remove all
// client-go API clients. Please use the controller runtime to make API calls for tests.
dynamicFactory client.DynamicFactory
MetricsClient *metricsclientset.Clientset
}
var (
@ -80,9 +83,16 @@ func InitTestClient(kubecontext string) (TestClient, error) {
factory := client.NewDynamicFactory(dynamicClient)
return TestClient{
metricsClient, err := f.MetricsClient()
if err != nil {
return TestClient{}, err
}
testClient := TestClient{
Kubebuilder: kb,
ClientGo: clientGo,
dynamicFactory: factory,
}, nil
MetricsClient: metricsClient,
}
return testClient, nil
}

View File

@ -30,7 +30,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/builder"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
"github.com/vmware-tanzu/velero/test/e2e/util/common"
"github.com/vmware-tanzu/velero/test/util/common"
)
// ensureClusterExists returns whether or not a Kubernetes cluster exists for tests to be run on.

View File

@ -126,6 +126,30 @@ func CleanupNamespacesWithPoll(ctx context.Context, client TestClient, CaseBaseN
return nil
}
func CleanupNamespacesFiterdByExcludes(ctx context.Context, client TestClient, excludeNS []string) error {
namespaces, err := client.ClientGo.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
return errors.Wrap(err, "Could not retrieve namespaces")
}
for _, checkNamespace := range namespaces.Items {
isExclude := false
for k := range excludeNS {
if checkNamespace.Name == excludeNS[k] {
isExclude = true
}
}
if !isExclude {
err := DeleteNamespace(ctx, client, checkNamespace.Name, true)
if err != nil {
return errors.Wrapf(err, "Could not delete namespace %s", checkNamespace.Name)
}
fmt.Printf("Namespace %s was deleted\n", checkNamespace.Name)
}
}
return nil
}
func CleanupNamespaces(ctx context.Context, client TestClient, CaseBaseName string) error {
namespaces, err := client.ClientGo.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {

View File

@ -8,7 +8,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
common "github.com/vmware-tanzu/velero/test/e2e/util/common"
common "github.com/vmware-tanzu/velero/test/util/common"
)
func GetWorkerNodes(ctx context.Context) ([]string, error) {

View File

@ -22,6 +22,7 @@ import (
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/util/retry"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -64,3 +65,31 @@ func AddAnnotationToPersistentVolume(ctx context.Context, client TestClient, nam
return client.ClientGo.CoreV1().PersistentVolumes().Update(ctx, newPV, metav1.UpdateOptions{})
}
func ClearClaimRefForFailedPVs(ctx context.Context, client TestClient) error {
pvList, err := client.ClientGo.CoreV1().PersistentVolumes().List(ctx, metav1.ListOptions{})
if err != nil {
return fmt.Errorf("failed to list PVs: %v", err)
}
for _, pv := range pvList.Items {
pvName := pv.Name
if pv.Status.Phase != corev1.VolumeAvailable {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
pv, getErr := client.ClientGo.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{})
if getErr != nil {
return fmt.Errorf("failed to get PV %s: %v", pvName, getErr)
}
pv.Spec.ClaimRef = nil
_, updateErr := client.ClientGo.CoreV1().PersistentVolumes().Update(ctx, pv, metav1.UpdateOptions{})
return updateErr
})
if retryErr != nil {
return fmt.Errorf("failed to clear claimRef for PV %s: %v", pvName, retryErr)
}
}
}
return nil
}

View File

@ -28,10 +28,10 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test/e2e/util/k8s"
. "github.com/vmware-tanzu/velero/test/e2e/util/providers"
. "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
. "github.com/vmware-tanzu/velero/test/util/k8s"
. "github.com/vmware-tanzu/velero/test/util/providers"
. "github.com/vmware-tanzu/velero/test/util/velero"
)
const (

View File

@ -0,0 +1,33 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/test/util/providers"
)
func GetMinioDiskUsage(cloudCredentialsFile string, bslBucket string, bslPrefix string, bslConfig string) (int64, error) {
var aws providers.AWSStorage
toatalSize, err := aws.GetMinioBucketSize(cloudCredentialsFile, bslBucket, bslPrefix, bslConfig)
if err != nil {
return 0, errors.Errorf("a Failed to get minio bucket size with err %v", err)
} else {
return toatalSize, nil
}
}

48
test/util/metrics/nfs.go Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"context"
"os/exec"
"strings"
"github.com/pkg/errors"
)
func GetNFSPathDiskUsage(ctx context.Context, nfsServerPath string) (string, error) {
cmd := exec.CommandContext(ctx, "df", "-h", nfsServerPath)
output, err := cmd.Output()
if err != nil {
return "0B", errors.WithStack(err)
}
strOutput := string(output)
// parse command output
lines := strings.Split(strOutput, "\n")
if len(lines) < 2 {
return "0B", errors.Errorf("Failed to get disk usage for nfs server path %s with command output %s", nfsServerPath, strOutput)
}
fields := strings.Fields(lines[1])
if len(fields) < 5 {
return "0B", errors.Errorf("Failed to parse disk usage for nfs server path %s with command output %s", nfsServerPath, strOutput)
}
usedSpaceStr := fields[2]
return usedSpaceStr, nil
}

45
test/util/metrics/pod.go Normal file
View File

@ -0,0 +1,45 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package metrics
import (
"context"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/metrics/pkg/apis/metrics/v1beta1"
metricsclientset "k8s.io/metrics/pkg/client/clientset/versioned"
)
func GetPodUsageMetrics(ctx context.Context, metricsClient *metricsclientset.Clientset, podName, namespace string) (cpuUsage, memoryUsage resource.Quantity, err error) {
var podMetrics *v1beta1.PodMetrics
podMetrics, err = metricsClient.MetricsV1beta1().PodMetricses(namespace).Get(ctx, podName, metav1.GetOptions{})
if err != nil {
return
}
// Variables to store the max and sum of CPU and memory usage
// For velero pod we only return the main container
for _, container := range podMetrics.Containers {
cpuUsage = container.Usage[corev1.ResourceCPU]
memoryUsage = container.Usage[corev1.ResourceMemory]
return
}
return
}

View File

@ -29,7 +29,7 @@ import (
"github.com/pkg/errors"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
e2e "github.com/vmware-tanzu/velero/test/e2e"
"github.com/vmware-tanzu/velero/test"
)
type AWSStorage string
@ -145,7 +145,7 @@ func (s AWSStorage) DeleteObjectsInBucket(cloudCredentialsFile, bslBucket, bslPr
return nil
}
func (s AWSStorage) IsSnapshotExisted(cloudCredentialsFile, bslConfig, backupObject string, snapshotCheck e2e.SnapshotCheckPoint) error {
func (s AWSStorage) IsSnapshotExisted(cloudCredentialsFile, bslConfig, backupObject string, snapshotCheck test.SnapshotCheckPoint) error {
config := flag.NewMap()
config.Set(bslConfig)
@ -197,3 +197,57 @@ func (s AWSStorage) IsSnapshotExisted(cloudCredentialsFile, bslConfig, backupObj
return nil
}
}
func (s AWSStorage) GetMinioBucketSize(cloudCredentialsFile, bslBucket, bslPrefix, bslConfig string) (int64, error) {
config := flag.NewMap()
config.Set(bslConfig)
region := config.Data()["region"]
s3url := config.Data()["s3Url"]
s3Config := &aws.Config{
Credentials: credentials.NewSharedCredentials(cloudCredentialsFile, ""),
Endpoint: aws.String(s3url),
Region: aws.String(region),
DisableSSL: aws.Bool(true),
S3ForcePathStyle: aws.Bool(true),
}
if region != "minio" {
return 0, errors.New("it only supported by minio")
}
sess, err := session.NewSession(s3Config)
if err != nil {
return 0, errors.Wrapf(err, "Error create config session")
}
svc := s3.New(sess)
var totalSize int64
var continuationToken *string
// Paginate through objects in the bucket
objectsInput := &s3.ListObjectsV2Input{
Bucket: aws.String(bslBucket),
ContinuationToken: continuationToken,
}
if bslPrefix != "" {
objectsInput.Prefix = aws.String(bslPrefix)
}
for {
resp, err := svc.ListObjectsV2(objectsInput)
if err != nil {
return 0, errors.Wrapf(err, "Error list objects")
}
// Process objects in the current response
for _, obj := range resp.Contents {
totalSize += *obj.Size
}
// Check if there are more objects to retrieve
if !*resp.IsTruncated {
break
}
// Set the continuation token for the next page
continuationToken = resp.NextContinuationToken
}
return totalSize, nil
}

View File

@ -37,7 +37,7 @@ import (
"golang.org/x/net/context"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
. "github.com/vmware-tanzu/velero/test/e2e"
. "github.com/vmware-tanzu/velero/test"
)
type AzureStorage string

View File

@ -24,8 +24,8 @@ import (
"github.com/pkg/errors"
. "github.com/vmware-tanzu/velero/test/e2e"
velero "github.com/vmware-tanzu/velero/test/e2e/util/velero"
. "github.com/vmware-tanzu/velero/test"
velero "github.com/vmware-tanzu/velero/test/util/velero"
)
type ObjectsInStorage interface {

Some files were not shown because too many files have changed in this diff Show More