From 101d25e154365a3b08c8a76d2f994f32875b350a Mon Sep 17 00:00:00 2001 From: Vee Zhang Date: Thu, 12 Oct 2023 04:51:54 -0500 Subject: [PATCH] feat: e2e add version test (#330) --- go.mod | 9 +- go.sum | 18 +- hack/e2e.sh | 2 +- tests/e2e/e2evalidator/e2evalidator.go | 58 ++++++ .../envfuncsext/nebulacluster-ready-func.go | 175 ++++++++++++++++++ tests/e2e/envfuncsext/nebulacluster.go | 171 ----------------- tests/e2e/nebulacluster_basic_test.go | 150 ++++++++++++++- 7 files changed, 398 insertions(+), 185 deletions(-) create mode 100644 tests/e2e/e2evalidator/e2evalidator.go create mode 100644 tests/e2e/envfuncsext/nebulacluster-ready-func.go diff --git a/go.mod b/go.mod index d9bfaaab..9019d69a 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( github.com/caarlos0/env/v8 v8.0.0 + github.com/go-playground/validator/v10 v10.15.5 github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.5.1 github.com/onsi/gomega v1.27.7 @@ -11,7 +12,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/vesoft-inc/fbthrift v0.0.0-20230214024353-fa2f34755b28 github.com/vesoft-inc/nebula-agent/v3 v3.6.0 github.com/vesoft-inc/nebula-go/v3 v3.6.0 @@ -62,12 +63,15 @@ require ( github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect @@ -98,6 +102,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/juju/ratelimit v1.0.1 // indirect github.com/kr/fs v0.1.0 // indirect + github.com/leodido/go-urn v1.2.4 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -143,7 +148,7 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.5.0 // indirect + golang.org/x/crypto v0.7.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect diff --git a/go.sum b/go.sum index 4cd23a3d..cab23830 100644 --- a/go.sum +++ b/go.sum @@ -128,6 +128,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= @@ -148,6 +150,13 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -300,6 +309,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -385,8 +396,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -467,8 +479,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= diff --git a/hack/e2e.sh b/hack/e2e.sh index 581b59d9..6c75a227 100755 --- a/hack/e2e.sh +++ b/hack/e2e.sh @@ -28,4 +28,4 @@ env | grep '^E2E_' | sort echo -e "\nstarting e2e tests\n" -go test -v ./tests/e2e -args -test.timeout 1h -test.v -v 4 "${@}" +go test -timeout 1h -v ./tests/e2e -args -test.timeout 1h -test.v -v 4 "${@}" diff --git a/tests/e2e/e2evalidator/e2evalidator.go b/tests/e2e/e2evalidator/e2evalidator.go new file mode 100644 index 00000000..41806489 --- /dev/null +++ b/tests/e2e/e2evalidator/e2evalidator.go @@ -0,0 +1,58 @@ +package e2evalidator + +import ( + "fmt" + "reflect" + "strings" + + "github.com/go-playground/validator/v10" +) + +type Rule string + +func StructWithRules(actual any, rulesMapping map[string]Rule) (errMessages []string) { + for field, rule := range rulesMapping { + actualVal := reflect.ValueOf(actual) + + isValid := true + for _, name := range strings.Split(field, ".") { + if actualVal.Kind() == reflect.Ptr { + actualVal = actualVal.Elem() + } + actualVal = actualVal.FieldByName(name) + if !actualVal.IsValid() { + isValid = false + errMessages = append(errMessages, fmt.Sprintf("field %q is invalid at %q\n", field, name)) + break + } + } + + if isValid { + if actualVal.Kind() == reflect.Ptr { + actualVal = actualVal.Elem() + } + val := actualVal.Interface() + if err := validator.New().Var(val, string(rule)); err != nil { + errMessages = append(errMessages, fmt.Sprintf("field %q(%v) does not match %q\n", field, val, rule)) + } + } + } + + return errMessages +} + +func RuleAnd(rs ...Rule) Rule { + ss := make([]string, len(rs)) + for i, r := range rs { + ss[i] = string(r) + } + return Rule(strings.Join(ss, ",")) +} + +func Eq(v any) Rule { + return Rule(fmt.Sprintf("eq=%v", v)) +} + +func Ne(v any) Rule { + return Rule(fmt.Sprintf("ne=%v", v)) +} diff --git a/tests/e2e/envfuncsext/nebulacluster-ready-func.go b/tests/e2e/envfuncsext/nebulacluster-ready-func.go new file mode 100644 index 00000000..d2a36dbb --- /dev/null +++ b/tests/e2e/envfuncsext/nebulacluster-ready-func.go @@ -0,0 +1,175 @@ +/* +Copyright 2023 Vesoft Inc. + +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 envfuncsext + +import ( + "context" + stderrors "errors" + + "k8s.io/klog/v2" + "sigs.k8s.io/e2e-framework/pkg/envconf" + + appsv1alpha1 "github.com/vesoft-inc/nebula-operator/apis/apps/v1alpha1" + "github.com/vesoft-inc/nebula-operator/tests/e2e/e2evalidator" +) + +var defaultNebulaClusterReadyFuncs = []NebulaClusterReadyFunc{ + defaultNebulaClusterReadyFuncForStatus, + defaultNebulaClusterReadyFuncForGraphd, + defaultNebulaClusterReadyFuncForMetad, + defaultNebulaClusterReadyFuncForStoraged, + defaultNebulaClusterReadyFuncForAgent, + defaultNebulaClusterReadyFuncForExporter, + defaultNebulaClusterReadyFuncForConsole, +} + +func DefaultNebulaClusterReadyFunc(ctx context.Context, cfg *envconf.Config, nc *appsv1alpha1.NebulaCluster) (bool, error) { + for _, fn := range defaultNebulaClusterReadyFuncs { + if isReady, err := fn(ctx, cfg, nc); !isReady || err != nil { + return isReady, err + } + } + return true, nil +} + +func NebulaClusterReadyFuncForFields(ignoreValidationErrors bool, rulesMapping map[string]e2evalidator.Rule) NebulaClusterReadyFunc { + return func(_ context.Context, _ *envconf.Config, nc *appsv1alpha1.NebulaCluster) (isReady bool, err error) { + if errMessages := e2evalidator.StructWithRules(nc, rulesMapping); len(errMessages) > 0 { + if ignoreValidationErrors { + klog.InfoS("Waiting for NebulaCluster to be ready but not expected", "errMessages", errMessages) + return false, nil + } + + klog.Error(nil, "Waiting for NebulaCluster to be ready but not expected", "errMessages", errMessages) + return false, stderrors.New("check NebulaCluster") + } + return true, nil + } +} + +func defaultNebulaClusterReadyFuncForStatus(_ context.Context, _ *envconf.Config, nc *appsv1alpha1.NebulaCluster) (bool, error) { + isReady := nc.IsReady() + if isReady { + // TODO: Add more checks + + { // Graphd status checks + if !isComponentStatusExpected( + &nc.Status.Graphd, + &nc.Spec.Graphd.ComponentSpec, + "namespace", nc.Namespace, + "name", nc.Name, + "component", appsv1alpha1.GraphdComponentType, + ) { + isReady = false + } + } + + { // Metad status checks + if !isComponentStatusExpected( + &nc.Status.Metad, + &nc.Spec.Metad.ComponentSpec, + "namespace", nc.Namespace, + "name", nc.Name, + "component", appsv1alpha1.MetadComponentType, + ) { + isReady = false + } + } + + { // Storaged status checks + if !isComponentStatusExpected( + &nc.Status.Storaged.ComponentStatus, + &nc.Spec.Storaged.ComponentSpec, + "namespace", nc.Namespace, + "name", nc.Name, + "component", appsv1alpha1.StoragedComponentType, + ) { + isReady = false + } + + if !nc.Status.Storaged.HostsAdded { + klog.InfoS("Waiting for NebulaCluster to be ready but HostsAdded is false", + "graphdReplicas", int(*nc.Spec.Graphd.Replicas), + "namespace", nc.Namespace, + "name", nc.Name, + "component", appsv1alpha1.StoragedComponentType, + ) + } + } + } + + return isReady, nil +} + +func defaultNebulaClusterReadyFuncForGraphd(_ context.Context, _ *envconf.Config, _ *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func defaultNebulaClusterReadyFuncForMetad(_ context.Context, _ *envconf.Config, _ *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func defaultNebulaClusterReadyFuncForStoraged(_ context.Context, _ *envconf.Config, _ *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func defaultNebulaClusterReadyFuncForAgent(_ context.Context, _ *envconf.Config, nc *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func defaultNebulaClusterReadyFuncForExporter(_ context.Context, _ *envconf.Config, _ *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func defaultNebulaClusterReadyFuncForConsole(_ context.Context, _ *envconf.Config, _ *appsv1alpha1.NebulaCluster) (bool, error) { + // TODO + return true, nil +} + +func isComponentStatusExpected( + componentStatus *appsv1alpha1.ComponentStatus, + componentSpec *appsv1alpha1.ComponentSpec, + logKeysAndValues ...any, +) bool { + if errMessages := e2evalidator.StructWithRules( + componentStatus, + map[string]e2evalidator.Rule{ + "Version": e2evalidator.Eq(componentSpec.Version), + "Phase": e2evalidator.Eq(appsv1alpha1.RunningPhase), + "Workload.ReadyReplicas": e2evalidator.Eq(*componentSpec.Replicas), + "Workload.UpdatedReplicas": e2evalidator.Eq(*componentSpec.Replicas), + "Workload.CurrentReplicas": e2evalidator.Eq(*componentSpec.Replicas), + "Workload.AvailableReplicas": e2evalidator.Eq(*componentSpec.Replicas), + "Workload.CurrentRevision": e2evalidator.Eq(componentStatus.Workload.UpdateRevision), + }, + ); len(errMessages) > 0 { + klog.InfoS("Waiting for NebulaCluster to be ready but componentStatus not expected", + append( + logKeysAndValues, + "errMessages", errMessages, + )..., + ) + return false + } + + return true +} diff --git a/tests/e2e/envfuncsext/nebulacluster.go b/tests/e2e/envfuncsext/nebulacluster.go index 979c63ac..db07dc67 100644 --- a/tests/e2e/envfuncsext/nebulacluster.go +++ b/tests/e2e/envfuncsext/nebulacluster.go @@ -209,174 +209,3 @@ func UninstallNebulaCluster(opts ...NebulaClusterOption) env.Func { }), nil } } - -func DefaultNebulaClusterReadyFunc(_ context.Context, _ *envconf.Config, nc *appsv1alpha1.NebulaCluster) (bool, error) { - isReady := nc.IsReady() - if isReady { - // TODO: Add more checks - - { // Graphd status checks - if !isComponentStatusExpected( - &nc.Status.Graphd, - &nc.Spec.Graphd.ComponentSpec, - "namespace", nc.Namespace, - "name", nc.Name, - "component", appsv1alpha1.GraphdComponentType, - ) { - isReady = false - } - } - - { // Metad status checks - if !isComponentStatusExpected( - &nc.Status.Metad, - &nc.Spec.Metad.ComponentSpec, - "namespace", nc.Namespace, - "name", nc.Name, - "component", appsv1alpha1.MetadComponentType, - ) { - isReady = false - } - } - - { // Storaged status checks - if !isComponentStatusExpected( - &nc.Status.Storaged.ComponentStatus, - &nc.Spec.Storaged.ComponentSpec, - "namespace", nc.Namespace, - "name", nc.Name, - "component", appsv1alpha1.StoragedComponentType, - ) { - isReady = false - } - - if !nc.Status.Storaged.HostsAdded { - klog.InfoS("Waiting for NebulaCluster to be ready but HostsAdded is false", - "graphdReplicas", int(*nc.Spec.Graphd.Replicas), - "namespace", nc.Namespace, - "name", nc.Name, - "component", appsv1alpha1.StoragedComponentType, - ) - } - } - } - - return isReady, nil -} - -func NebulaClusterReadyFuncForReplicas(graphdReplicas, metadReplicas, storagedReplicas int) NebulaClusterReadyFunc { - return func(_ context.Context, _ *envconf.Config, nc *appsv1alpha1.NebulaCluster) (isReady bool, err error) { - defer func() { - if !isReady { - klog.InfoS("Waiting for NebulaCluster to be ready but replicas not expected", - "graphdReplicas", int(*nc.Spec.Graphd.Replicas), - "graphdReplicasExpected", graphdReplicas, - "metadReplicas", *nc.Spec.Metad.Replicas, - "metadReplicasExpected", metadReplicas, - "storagedReplicas", *nc.Spec.Storaged.Replicas, - "storagedReplicasExpected", storagedReplicas, - ) - } - }() - - return int(*nc.Spec.Graphd.Replicas) == graphdReplicas && - int(*nc.Spec.Metad.Replicas) == metadReplicas && - int(*nc.Spec.Storaged.Replicas) == storagedReplicas, nil - } -} - -func isComponentStatusExpected( - componentStatus *appsv1alpha1.ComponentStatus, - componentSpec *appsv1alpha1.ComponentSpec, - logKeysAndValues ...any, -) bool { - isExpected := true - if componentStatus.Version != componentSpec.Version { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Version not expected", - append( - logKeysAndValues, - "expected", componentSpec.Version, - "current", componentStatus.Version, - )..., - ) - } - - if componentStatus.Phase != appsv1alpha1.RunningPhase { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Phase is not Running", - append( - logKeysAndValues, - "current", componentStatus.Phase, - )..., - ) - } - - if componentStatus.Workload.ReadyReplicas != *componentSpec.Replicas { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.ReadyReplicas not expected", - append( - logKeysAndValues, - "expected", componentStatus.Workload.ReadyReplicas, - "current", *componentSpec.Replicas, - )..., - ) - } - - if componentStatus.Workload.Replicas != *componentSpec.Replicas { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.Replicas not expected", - append( - logKeysAndValues, - "expected", componentStatus.Workload.Replicas, - "current", *componentSpec.Replicas, - )..., - ) - } - - if componentStatus.Workload.UpdatedReplicas != *componentSpec.Replicas { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.UpdatedReplicas not expected", - append( - logKeysAndValues, - "expected", componentStatus.Workload.UpdatedReplicas, - "current", *componentSpec.Replicas, - )..., - ) - } - - if componentStatus.Workload.CurrentReplicas != *componentSpec.Replicas { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.CurrentReplicas not expected", - append( - logKeysAndValues, - "expected", componentStatus.Workload.CurrentReplicas, - "current", *componentSpec.Replicas, - )..., - ) - } - - if componentStatus.Workload.AvailableReplicas != *componentSpec.Replicas { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.AvailableReplicas not expected", - append( - logKeysAndValues, - "expected", componentStatus.Workload.AvailableReplicas, - "current", *componentSpec.Replicas, - )..., - ) - } - - if componentStatus.Workload.UpdateRevision != componentStatus.Workload.CurrentRevision { - isExpected = false - klog.InfoS("Waiting for NebulaCluster to be ready but Workload.CurrentRevision not equal Workload.UpdateRevision", - append( - logKeysAndValues, - "UpdateRevision", componentStatus.Workload.UpdateRevision, - "CurrentRevision", componentStatus.Workload.CurrentRevision, - )..., - ) - } - - return isExpected -} diff --git a/tests/e2e/nebulacluster_basic_test.go b/tests/e2e/nebulacluster_basic_test.go index 97706862..e807d004 100644 --- a/tests/e2e/nebulacluster_basic_test.go +++ b/tests/e2e/nebulacluster_basic_test.go @@ -1,6 +1,7 @@ package e2e import ( + "github.com/vesoft-inc/nebula-operator/tests/e2e/e2evalidator" "github.com/vesoft-inc/nebula-operator/tests/e2e/envfuncsext" "sigs.k8s.io/e2e-framework/third_party/helm" ) @@ -8,6 +9,7 @@ import ( const ( LabelCategoryBasic = "basic" LabelGroupScale = "scale" + LabelGroupVersion = "version" ) var testCasesBasic []ncTestCase @@ -30,7 +32,11 @@ var testCasesBasicScale = []ncTestCase{ }, InstallWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(2, 3, 3), + envfuncsext.NebulaClusterReadyFuncForFields(false, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(2), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -50,7 +56,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(4, 3, 4), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(4), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(4), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -69,7 +79,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(5, 3, 4), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(5), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(4), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -88,7 +102,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(5, 3, 5), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(5), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(5), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -106,7 +124,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(3, 3, 4), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(3), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(4), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -124,7 +146,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(3, 3, 3), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(3), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -142,7 +168,11 @@ var testCasesBasicScale = []ncTestCase{ }, UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ envfuncsext.WithNebulaClusterReadyFuncs( - envfuncsext.NebulaClusterReadyFuncForReplicas(2, 3, 3), + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(2), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + }), envfuncsext.DefaultNebulaClusterReadyFunc, ), }, @@ -153,7 +183,111 @@ var testCasesBasicScale = []ncTestCase{ // test cases about version of graphd|metad|storaged var testCasesBasicVersion = []ncTestCase{ - // TODO + { + Name: "update version", + Labels: map[string]string{ + LabelKeyCategory: LabelCategoryBasic, + LabelKeyGroup: LabelGroupVersion, + }, + InstallWaitNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterReadyFuncs( + envfuncsext.NebulaClusterReadyFuncForFields(false, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(2), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + "Spec.Graphd.Version": e2evalidator.Ne("latest"), + "Spec.Metad.Version": e2evalidator.Ne("latest"), + "Spec.Storaged.Version": e2evalidator.Ne("latest"), + "Spec.Storaged.EnableForceUpdate": e2evalidator.Eq(false), + }), + envfuncsext.DefaultNebulaClusterReadyFunc, + ), + }, + LoadLDBC: true, + UpgradeCases: []ncTestUpgradeCase{ + { + Name: "update version", + UpgradeFunc: nil, + UpgradeNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterHelmRawOptions( + helm.WithArgs( + "--set", "nebula.version=latest", + ), + ), + }, + UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterReadyFuncs( + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(2), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + "Spec.Graphd.Version": e2evalidator.Eq("latest"), + "Spec.Metad.Version": e2evalidator.Eq("latest"), + "Spec.Storaged.Version": e2evalidator.Eq("latest"), + "Spec.Storaged.EnableForceUpdate": e2evalidator.Eq(false), + }), + envfuncsext.DefaultNebulaClusterReadyFunc, + ), + }, + }, + { + Name: "update version with scale", + UpgradeFunc: nil, + UpgradeNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterHelmRawOptions( + helm.WithArgs( + "--set", "nebula.graphd.replicas=4", + "--set", "nebula.metad.replicas=3", + "--set", "nebula.storaged.replicas=4", + ), + ), + }, + UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterReadyFuncs( + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(4), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(4), + "Spec.Graphd.Version": e2evalidator.Ne("latest"), + "Spec.Metad.Version": e2evalidator.Ne("latest"), + "Spec.Storaged.Version": e2evalidator.Ne("latest"), + "Spec.Storaged.EnableForceUpdate": e2evalidator.Eq(false), + }), + envfuncsext.DefaultNebulaClusterReadyFunc, + ), + }, + }, + { + Name: "update version with scale and enableForceUpdate", + UpgradeFunc: nil, + UpgradeNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterHelmRawOptions( + helm.WithArgs( + "--set", "nebula.version=latest", + "--set", "nebula.graphd.replicas=2", + "--set", "nebula.metad.replicas=3", + "--set", "nebula.storaged.replicas=3", + "--set", "nebula.enableForceUpdate=true", + ), + ), + }, + UpgradeWaitNCOptions: []envfuncsext.NebulaClusterOption{ + envfuncsext.WithNebulaClusterReadyFuncs( + envfuncsext.NebulaClusterReadyFuncForFields(true, map[string]e2evalidator.Rule{ + "Spec.Graphd.Replicas": e2evalidator.Eq(2), + "Spec.Metad.Replicas": e2evalidator.Eq(3), + "Spec.Storaged.Replicas": e2evalidator.Eq(3), + "Spec.Graphd.Version": e2evalidator.Eq("latest"), + "Spec.Metad.Version": e2evalidator.Eq("latest"), + "Spec.Storaged.Version": e2evalidator.Eq("latest"), + "Spec.Storaged.EnableForceUpdate": e2evalidator.Eq(true), + }), + envfuncsext.DefaultNebulaClusterReadyFunc, + ), + }, + }, + }, + }, } // test cases about resources of graphd|metad|storaged