This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-infra-e2e.git


The following commit(s) were added to refs/heads/main by this push:
     new aa5115f  Implement the verification of query (#10)
aa5115f is described below

commit aa5115f4279164d5b0a83b19f4750c03cdf69e74
Author: Hoshea Jiang <[email protected]>
AuthorDate: Thu Mar 4 22:18:34 2021 +0800

    Implement the verification of query (#10)
---
 commands/root.go                              |  6 ++-
 commands/verify/verify.go                     | 63 +++++++++++++++++++++++++--
 examples/simple/e2e.yaml                      | 12 +++++
 internal/components/verifier/verifier.go      | 57 ++++++------------------
 internal/components/verifier/verifier_test.go |  4 +-
 internal/config/globalConfig.go               |  6 ++-
 internal/util/utils.go                        | 16 +++++++
 test/verify/3.expected.yaml                   | 22 ++++++++++
 8 files changed, 133 insertions(+), 53 deletions(-)

diff --git a/commands/root.go b/commands/root.go
index 8493e0d..d378f0c 100644
--- a/commands/root.go
+++ b/commands/root.go
@@ -29,6 +29,8 @@ import (
        "github.com/apache/skywalking-infra-e2e/internal/constant"
 )
 
+var cfg string
+
 // Root represents the base command when called without any subcommands
 var Root = &cobra.Command{
        Use:           "e2e command [flags]",
@@ -37,7 +39,7 @@ var Root = &cobra.Command{
        SilenceErrors: true,
        SilenceUsage:  true,
        PersistentPreRun: func(cmd *cobra.Command, args []string) {
-               config.ReadGlobalConfigFile(constant.E2EDefaultFile)
+               config.ReadGlobalConfigFile(cfg)
        },
 }
 
@@ -50,5 +52,7 @@ func Execute() error {
        Root.AddCommand(verify.Verify)
        Root.AddCommand(cleanup.Cleanup)
 
+       Root.PersistentFlags().StringVarP(&cfg, "config", "c", 
constant.E2EDefaultFile, "the config file")
+
        return Root.Execute()
 }
diff --git a/commands/verify/verify.go b/commands/verify/verify.go
index 91f37bf..05ccbe0 100644
--- a/commands/verify/verify.go
+++ b/commands/verify/verify.go
@@ -21,6 +21,9 @@ import (
        "fmt"
 
        "github.com/apache/skywalking-infra-e2e/internal/components/verifier"
+       "github.com/apache/skywalking-infra-e2e/internal/config"
+       "github.com/apache/skywalking-infra-e2e/internal/logger"
+       "github.com/apache/skywalking-infra-e2e/internal/util"
 
        "github.com/spf13/cobra"
 )
@@ -41,10 +44,62 @@ var Verify = &cobra.Command{
        Use:   "verify",
        Short: "verify if the actual data match the expected data",
        RunE: func(cmd *cobra.Command, args []string) error {
-               if actual != "" && expected != "" {
-                       return verifier.VerifyDataFile(actual, expected)
+               if expected != "" {
+                       return verifySingleCase(expected, actual, query)
                }
-               fmt.Println("Not implemented.")
-               return nil
+               // If there is no given flags.
+               return verifyAccordingConfig()
        },
 }
+
+func verifySingleCase(expectedFile, actualFile, query string) error {
+       expectedData, err := util.ReadFileContent(expectedFile)
+       if err != nil {
+               return fmt.Errorf("failed to read the expected data file: %v", 
err)
+       }
+
+       var actualData, sourceName string
+       if actualFile != "" {
+               sourceName = actualFile
+               actualData, err = util.ReadFileContent(actualFile)
+               if err != nil {
+                       return fmt.Errorf("failed to read the actual data file: 
%v", err)
+               }
+       } else if query != "" {
+               sourceName = query
+               actualData, err = util.ExecuteCommand(query)
+               if err != nil {
+                       return fmt.Errorf("failed to execute the query: %v", 
err)
+               }
+       }
+
+       if err = verifier.Verify(actualData, expectedData); err != nil {
+               logger.Log.Warnf("failed to verify the output: %s\n", 
sourceName)
+               if me, ok := err.(*verifier.MismatchError); ok {
+                       fmt.Println(me.Error())
+               }
+       } else {
+               logger.Log.Infof("verified the output: %s\n", sourceName)
+       }
+       return nil
+}
+
+// verifyAccordingConfig reads cases from the config file and verifies them.
+func verifyAccordingConfig() error {
+       if config.GlobalConfig.Error != nil {
+               return config.GlobalConfig.Error
+       }
+
+       e2eConfig := config.GlobalConfig.E2EConfig
+
+       for _, v := range e2eConfig.Verify {
+               if v.Expected != "" {
+                       if err := verifySingleCase(v.Expected, v.Actual, 
v.Query); err != nil {
+                               logger.Log.Errorf("%v", err)
+                       }
+               } else {
+                       logger.Log.Error("the expected data file is not 
specified")
+               }
+       }
+       return nil
+}
diff --git a/examples/simple/e2e.yaml b/examples/simple/e2e.yaml
index 181cd9c..721d446 100644
--- a/examples/simple/e2e.yaml
+++ b/examples/simple/e2e.yaml
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# This file is used to show how to write configuration files and can be used 
to test.
+
 setup:
   env: kind
   file: kind.yaml
@@ -32,3 +34,13 @@ setup:
           resource: pod
           for: condition=Ready
   timeout: 600
+
+verify:
+  - actual: ../../test/verify/1.actual.yaml
+    expected: ../../test/verify/1.expected.yaml
+  - actual: ../../test/verify/2.actual.yaml
+    expected: ../../test/verify/2.expected.yaml
+  - actual: ../../test/verify/1.actual.yaml
+    expected: ../../test/verify/2.expected.yaml
+  - query: swctl --display yaml service ls
+    expected: ../../test/verify/3.expected.yaml
diff --git a/internal/components/verifier/verifier.go 
b/internal/components/verifier/verifier.go
index 2f4675a..866b063 100644
--- a/internal/components/verifier/verifier.go
+++ b/internal/components/verifier/verifier.go
@@ -14,25 +14,24 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
+
 package verifier
 
 import (
        "bytes"
-       "errors"
        "fmt"
 
-       "github.com/apache/skywalking-infra-e2e/internal/logger"
-       "github.com/apache/skywalking-infra-e2e/internal/util"
        "github.com/apache/skywalking-infra-e2e/third-party/go/template"
 
        "github.com/google/go-cmp/cmp"
        "gopkg.in/yaml.v2"
 )
 
-// MismatchError is the error type returned by the verify functions.
-// Then the caller will know if there is a mismatch.
+// MismatchError is the error type returned by the Verify functions.
+// It contains the diff content.
 type MismatchError struct {
-       Err error
+       Err  error
+       diff string
 }
 
 func (e *MismatchError) Unwrap() error { return e.Err }
@@ -41,65 +40,35 @@ func (e *MismatchError) Error() string {
        if e == nil {
                return "<nil>"
        }
-       return "the actual data does not match the expected data"
-}
-
-// VerifyDataFile reads the actual data from the file and verifies.
-func VerifyDataFile(actualFile, expectedFile string) error {
-       actualData, err := util.ReadFileContent(actualFile)
-       if err != nil {
-               logger.Log.Error("failed to read the actual data file")
-               return err
-       }
-
-       expectedTemplate, err := util.ReadFileContent(expectedFile)
-       if err != nil {
-               logger.Log.Error("failed to read the expected data file")
-               return err
-       }
-
-       return verify(actualData, expectedTemplate)
+       return e.diff
 }
 
-// VerifyQuery gets the actual data from the query and then verifies.
-func VerifyQuery(query, expectedFile string) error {
-       return errors.New("not implemented")
-}
-
-// verify checks if the actual data match the expected template.
-// It will print the diff if the actual data does not match.
-func verify(actualData, expectedTemplate string) error {
+// Verify checks if the actual data match the expected template.
+func Verify(actualData, expectedTemplate string) error {
        var actual interface{}
        if err := yaml.Unmarshal([]byte(actualData), &actual); err != nil {
-               logger.Log.Error("failed to unmarshal actual data")
-               return err
+               return fmt.Errorf("failed to unmarshal actual data: %v", err)
        }
 
        tmpl, err := 
template.New("test").Funcs(funcMap()).Parse(expectedTemplate)
        if err != nil {
-               logger.Log.Error("failed to parse template")
-               return err
+               return fmt.Errorf("failed to parse template: %v", err)
        }
 
        var b bytes.Buffer
        if err := tmpl.Execute(&b, actual); err != nil {
-               logger.Log.Error("failed to execute template")
-               return err
+               return fmt.Errorf("failed to execute template: %v", err)
        }
 
        var expected interface{}
        if err := yaml.Unmarshal(b.Bytes(), &expected); err != nil {
-               logger.Log.Error("failed to unmarshal expected data")
-               return err
+               return fmt.Errorf("failed to unmarshal expected data: %v", err)
        }
 
        if !cmp.Equal(expected, actual) {
                // TODO: use a custom Reporter (suggested by the comment of 
cmp.Diff)
                diff := cmp.Diff(expected, actual)
-               fmt.Println(diff)
-               return &MismatchError{}
+               return &MismatchError{diff: diff}
        }
-
-       logger.Log.Info("the actual data matches the expected data")
        return nil
 }
diff --git a/internal/components/verifier/verifier_test.go 
b/internal/components/verifier/verifier_test.go
index f7d073a..0d6b7e7 100644
--- a/internal/components/verifier/verifier_test.go
+++ b/internal/components/verifier/verifier_test.go
@@ -142,8 +142,8 @@ metrics:
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
-                       if err := verify(tt.args.actualData, 
tt.args.expectedTemplate); (err != nil) != tt.wantErr {
-                               t.Errorf("verify() error = %v, wantErr %v", 
err, tt.wantErr)
+                       if err := Verify(tt.args.actualData, 
tt.args.expectedTemplate); (err != nil) != tt.wantErr {
+                               t.Errorf("Verify() error = %v, wantErr %v", 
err, tt.wantErr)
                        }
                })
        }
diff --git a/internal/config/globalConfig.go b/internal/config/globalConfig.go
index f8c1334..c796962 100644
--- a/internal/config/globalConfig.go
+++ b/internal/config/globalConfig.go
@@ -22,9 +22,10 @@ import (
        "fmt"
        "io/ioutil"
 
-       "gopkg.in/yaml.v2"
-
+       "github.com/apache/skywalking-infra-e2e/internal/logger"
        "github.com/apache/skywalking-infra-e2e/internal/util"
+
+       "gopkg.in/yaml.v2"
 )
 
 // GlobalE2EConfig store E2EConfig which can be used globally.
@@ -57,4 +58,5 @@ func ReadGlobalConfigFile(configFilePath string) {
 
        GlobalConfig.E2EConfig = e2eConfigObject
        GlobalConfig.Error = nil
+       logger.Log.Info("load the e2e config successfully")
 }
diff --git a/internal/util/utils.go b/internal/util/utils.go
index 0c2a2f0..fc5bda4 100644
--- a/internal/util/utils.go
+++ b/internal/util/utils.go
@@ -19,6 +19,7 @@
 package util
 
 import (
+       "bytes"
        "errors"
        "io/ioutil"
        "os"
@@ -52,3 +53,18 @@ func ReadFileContent(filename string) (string, error) {
        }
        return "", errors.New("the file does not exist")
 }
+
+// ExecuteCommand executes the given command and returns the result.
+func ExecuteCommand(cmd string) (string, error) {
+       command := exec.Command("bash", "-c", cmd)
+       outinfo := bytes.Buffer{}
+       command.Stdout = &outinfo
+
+       if err := command.Start(); err != nil {
+               return "", err
+       }
+       if err := command.Wait(); err != nil {
+               return "", err
+       }
+       return outinfo.String(), nil
+}
diff --git a/test/verify/3.expected.yaml b/test/verify/3.expected.yaml
new file mode 100644
index 0000000..40f5133
--- /dev/null
+++ b/test/verify/3.expected.yaml
@@ -0,0 +1,22 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- contains . }}
+- id: {{ notEmpty .id }}
+  name: {{ notEmpty .name }}
+  group: ""
+{{- end }}

Reply via email to