diff --git a/.gitignore b/.gitignore index c28eddd..2949c00 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ .tool-versions .vscode/ dsm-perf-tool +*.env +*.log # If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore diff --git a/cmd/common.go b/cmd/common.go index 12d4475..88ed6d8 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -9,6 +9,8 @@ package cmd import ( "context" "crypto/tls" + "encoding/csv" + "encoding/json" "fmt" "log" "math" @@ -16,6 +18,8 @@ import ( "net/http" "os" "os/signal" + "reflect" + "strconv" "strings" "syscall" "time" @@ -184,3 +188,104 @@ func GetSobject(kid *string) *sdkms.Sobject { } return key } + +func summarizeProfilingData(dataArr profilingDataArr) { + var inQueueData stats.Float64Data + var parseRequestData stats.Float64Data + var sessionLookupData stats.Float64Data + var validateInputData stats.Float64Data + var checkAccessData stats.Float64Data + var operateData stats.Float64Data + var dbFlushData stats.Float64Data + var totalData stats.Float64Data + additionalDataArr := make(map[string]stats.Float64Data) + actionNameMaxLen := len("SessionLookup") + for _, data := range dataArr { + inQueueData = append(inQueueData, float64(data.InQueue)) + parseRequestData = append(parseRequestData, float64(data.ParseRequest)) + sessionLookupData = append(sessionLookupData, float64(data.SessionLookup)) + validateInputData = append(validateInputData, float64(data.ValidateInput)) + checkAccessData = append(checkAccessData, float64(data.CheckAccess)) + operateData = append(operateData, float64(data.Operate)) + dbFlushData = append(dbFlushData, float64(data.DbFlush)) + totalData = append(totalData, float64(data.Total)) + actionNameMaxLen = Max(actionNameMaxLen, processAdditionalProfilingData(&data.AdditionalProfilingData, &additionalDataArr, actionNameMaxLen, "")) + } + fmt.Printf("%s: %s\n", StrPad("InQueue", actionNameMaxLen, " ", "LEFT"), summarizeData(inQueueData)) + fmt.Printf("%s: %s\n", StrPad("ParseRequest", actionNameMaxLen, " ", "LEFT"), summarizeData(parseRequestData)) + fmt.Printf("%s: %s\n", StrPad("SessionLookup", actionNameMaxLen, " ", "LEFT"), summarizeData(sessionLookupData)) + fmt.Printf("%s: %s\n", StrPad("ValidateInput", actionNameMaxLen, " ", "LEFT"), summarizeData(validateInputData)) + fmt.Printf("%s: %s\n", StrPad("CheckAccess", actionNameMaxLen, " ", "LEFT"), summarizeData(checkAccessData)) + fmt.Printf("%s: %s\n", StrPad("Operate", actionNameMaxLen, " ", "LEFT"), summarizeData(operateData)) + fmt.Printf("%s: %s\n", StrPad("DbFlush", actionNameMaxLen, " ", "LEFT"), summarizeData(dbFlushData)) + fmt.Printf("%s: %s\n", StrPad("Total", actionNameMaxLen, " ", "LEFT"), summarizeData(totalData)) + for actionName, timeArr := range additionalDataArr { + fmt.Printf("%s: %s\n", StrPad(actionName, actionNameMaxLen, " ", "LEFT"), summarizeData(timeArr)) + } +} + +func processAdditionalProfilingData(dataArr *[]additionalProfilingData, additionalDataArr *map[string]stats.Float64Data, actionNameMaxLen int, parentActionName string) int { + for _, customProfilingData := range *dataArr { + actionName := parentActionName + "/" + customProfilingData.Action + (*additionalDataArr)[actionName] = append((*additionalDataArr)[actionName], float64(customProfilingData.TookNs)) + actionNameMaxLen = Max(actionNameMaxLen, len(actionName)) + actionNameMaxLen = Max(actionNameMaxLen, processAdditionalProfilingData(&customProfilingData.SubActions, additionalDataArr, actionNameMaxLen, actionName)) + } + return actionNameMaxLen +} + +func (dataArr profilingDataArr) getCSVHeaders() (header []string) { + e := reflect.ValueOf(&dataArr[0]).Elem() + for i := 0; i < e.NumField(); i++ { + varName := e.Type().Field(i).Name + header = append(header, varName) + } + return header +} + +func (dataArr profilingDataArr) getCSVValues() (values [][]string) { + for _, data := range dataArr { + values = append(values, []string{ + strconv.FormatUint(data.InQueue, 10), + strconv.FormatUint(data.ParseRequest, 10), + strconv.FormatUint(data.SessionLookup, 10), + strconv.FormatUint(data.ValidateInput, 10), + strconv.FormatUint(data.CheckAccess, 10), + strconv.FormatUint(data.Operate, 10), + strconv.FormatUint(data.DbFlush, 10), + strconv.FormatUint(data.Total, 10), + }) + } + return values +} + +func saveProfilingDataToCSV(dataArr profilingDataArr) { + csvFile, err := os.CreateTemp(".", "profilingData.*.csv") + if err != nil { + log.Fatalf("Fatal error: %v\n", err) + } + w := csv.NewWriter(csvFile) + headers := dataArr.getCSVHeaders() + values := dataArr.getCSVValues() + if err := w.Write(headers); err != nil { + log.Fatalf("Fatal error: %v\n", err) + } + if err := w.WriteAll(values); err != nil { + log.Fatalf("Fatal error: %v\n", err) + } + + fmt.Println("Saved profiling data to:", csvFile.Name()) +} + +func parseProfilingDataStrArr(profilingDataStrArr []profilingDataStr) profilingDataArr { + var dataArr profilingDataArr + for _, profilingDataStr := range profilingDataStrArr { + var profilingData profilingData + err := json.Unmarshal([]byte(string(profilingDataStr)), &profilingData) + if err != nil { + log.Fatalf("Fatal error: %v\n", err) + } + dataArr = append(dataArr, profilingData) + } + return dataArr +} diff --git a/cmd/getVersion_test.go b/cmd/getVersion_test.go new file mode 100644 index 0000000..0811819 --- /dev/null +++ b/cmd/getVersion_test.go @@ -0,0 +1,61 @@ +/* Copyright (c) Fortanix, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package cmd + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/fortanix/sdkms-client-go/sdkms" + "github.com/stretchr/testify/assert" +) + +func TestTestSetupCmd(t *testing.T) { + resetRootCmdStatus() + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/sys/v1/version" { + t.Errorf("Expected to request '/sys/v1/version', got: %s", r.URL.Path) + } + w.WriteHeader(http.StatusOK) + resp := sdkms.VersionResponse{ + Version: "1234", + APIVersion: "1234", + ServerMode: "httptest", + } + respBytes, err := json.Marshal(resp) + if err != nil { + t.Fatal("Error encoding fake version response:", err) + } + w.Write(respBytes) + })) + defer server.Close() + // Parse the URL + parsedServerURL, err := url.Parse(server.URL) + if err != nil { + t.Fatal("Error parsing test server URL:", err) + } + testServerHost := parsedServerURL.Hostname() + testServerPort := parsedServerURL.Port() + if testServerPort == "" { + testServerPort = "443" + } + + args := []string{ + "--server", testServerHost, + "--port", testServerPort, + "--insecure", + "version", + "--count", "1", + } + + rootCmd.SetArgs(args) + err = ExecuteCmd() + assert.NoError(t, err) +} diff --git a/cmd/loadTest.go b/cmd/loadTest.go index b274733..61c9630 100644 --- a/cmd/loadTest.go +++ b/cmd/loadTest.go @@ -7,18 +7,12 @@ package cmd import ( - "encoding/csv" - "encoding/json" "fmt" - "io/ioutil" "log" - "reflect" - "strconv" "sync" "time" "github.com/fortanix/sdkms-client-go/sdkms" - "github.com/montanaflynn/stats" "github.com/spf13/cobra" ) @@ -211,104 +205,3 @@ func loadTest(name string, setup setupFunc, test testFunc, cleanup cleanupFunc) } fmt.Print("\n\n") } - -func summarizeProfilingData(dataArr profilingDataArr) { - var inQueueData stats.Float64Data - var parseRequestData stats.Float64Data - var sessionLookupData stats.Float64Data - var validateInputData stats.Float64Data - var checkAccessData stats.Float64Data - var operateData stats.Float64Data - var dbFlushData stats.Float64Data - var totalData stats.Float64Data - additionalDataArr := make(map[string]stats.Float64Data) - actionNameMaxLen := len("SessionLookup") - for _, data := range dataArr { - inQueueData = append(inQueueData, float64(data.InQueue)) - parseRequestData = append(parseRequestData, float64(data.ParseRequest)) - sessionLookupData = append(sessionLookupData, float64(data.SessionLookup)) - validateInputData = append(validateInputData, float64(data.ValidateInput)) - checkAccessData = append(checkAccessData, float64(data.CheckAccess)) - operateData = append(operateData, float64(data.Operate)) - dbFlushData = append(dbFlushData, float64(data.DbFlush)) - totalData = append(totalData, float64(data.Total)) - actionNameMaxLen = Max(actionNameMaxLen, processAdditionalProfilingData(&data.AdditionalProfilingData, &additionalDataArr, actionNameMaxLen, "")) - } - fmt.Printf("%s: %s\n", StrPad("InQueue", actionNameMaxLen, " ", "LEFT"), summarizeData(inQueueData)) - fmt.Printf("%s: %s\n", StrPad("ParseRequest", actionNameMaxLen, " ", "LEFT"), summarizeData(parseRequestData)) - fmt.Printf("%s: %s\n", StrPad("SessionLookup", actionNameMaxLen, " ", "LEFT"), summarizeData(sessionLookupData)) - fmt.Printf("%s: %s\n", StrPad("ValidateInput", actionNameMaxLen, " ", "LEFT"), summarizeData(validateInputData)) - fmt.Printf("%s: %s\n", StrPad("CheckAccess", actionNameMaxLen, " ", "LEFT"), summarizeData(checkAccessData)) - fmt.Printf("%s: %s\n", StrPad("Operate", actionNameMaxLen, " ", "LEFT"), summarizeData(operateData)) - fmt.Printf("%s: %s\n", StrPad("DbFlush", actionNameMaxLen, " ", "LEFT"), summarizeData(dbFlushData)) - fmt.Printf("%s: %s\n", StrPad("Total", actionNameMaxLen, " ", "LEFT"), summarizeData(totalData)) - for actionName, timeArr := range additionalDataArr { - fmt.Printf("%s: %s\n", StrPad(actionName, actionNameMaxLen, " ", "LEFT"), summarizeData(timeArr)) - } -} - -func processAdditionalProfilingData(dataArr *[]additionalProfilingData, additionalDataArr *map[string]stats.Float64Data, actionNameMaxLen int, parentActionName string) int { - for _, customProfilingData := range *dataArr { - actionName := parentActionName + "/" + customProfilingData.Action - (*additionalDataArr)[actionName] = append((*additionalDataArr)[actionName], float64(customProfilingData.TookNs)) - actionNameMaxLen = Max(actionNameMaxLen, len(actionName)) - actionNameMaxLen = Max(actionNameMaxLen, processAdditionalProfilingData(&customProfilingData.SubActions, additionalDataArr, actionNameMaxLen, actionName)) - } - return actionNameMaxLen -} - -func (dataArr profilingDataArr) getCSVHeaders() (header []string) { - e := reflect.ValueOf(&dataArr[0]).Elem() - for i := 0; i < e.NumField(); i++ { - varName := e.Type().Field(i).Name - header = append(header, varName) - } - return header -} - -func (dataArr profilingDataArr) getCSVValues() (values [][]string) { - for _, data := range dataArr { - values = append(values, []string{ - strconv.FormatUint(data.InQueue, 10), - strconv.FormatUint(data.ParseRequest, 10), - strconv.FormatUint(data.SessionLookup, 10), - strconv.FormatUint(data.ValidateInput, 10), - strconv.FormatUint(data.CheckAccess, 10), - strconv.FormatUint(data.Operate, 10), - strconv.FormatUint(data.DbFlush, 10), - strconv.FormatUint(data.Total, 10), - }) - } - return values -} - -func saveProfilingDataToCSV(dataArr profilingDataArr) { - csvFile, err := ioutil.TempFile(".", "profilingData.*.csv") - if err != nil { - log.Fatalf("Fatal error: %v\n", err) - } - w := csv.NewWriter(csvFile) - headers := dataArr.getCSVHeaders() - values := dataArr.getCSVValues() - if err := w.Write(headers); err != nil { - log.Fatalf("Fatal error: %v\n", err) - } - if err := w.WriteAll(values); err != nil { - log.Fatalf("Fatal error: %v\n", err) - } - - fmt.Println("Saved profiling data to:", csvFile.Name()) -} - -func parseProfilingDataStrArr(profilingDataStrArr []profilingDataStr) profilingDataArr { - var dataArr profilingDataArr - for _, profilingDataStr := range profilingDataStrArr { - var profilingData profilingData - err := json.Unmarshal([]byte(string(profilingDataStr)), &profilingData) - if err != nil { - log.Fatalf("Fatal error: %v\n", err) - } - dataArr = append(dataArr, profilingData) - } - return dataArr -} diff --git a/cmd/root.go b/cmd/root.go index af2ccdc..4854454 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,13 +7,17 @@ package cmd import ( - "fmt" - "os" "time" "github.com/spf13/cobra" ) +const defaultServerName = "sdkms.test.fortanix.com" +const defaultServerPort = uint16(443) +const defaultTlsNotVerify = false +const defaultRequestTimeout = 60 * time.Second +const defaultIdleConnectionTimeout = 0 * time.Second + var serverName string var serverPort uint16 var insecureTLS bool @@ -26,18 +30,15 @@ var rootCmd = &cobra.Command{ Long: `DSM performance tool`, } -func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } +func ExecuteCmd() error { + return rootCmd.Execute() } func init() { - rootCmd.PersistentFlags().StringVarP(&serverName, "server", "s", "sdkms.test.fortanix.com", "DSM server host name") - rootCmd.PersistentFlags().Uint16VarP(&serverPort, "port", "p", 443, "DSM server port") - rootCmd.PersistentFlags().BoolVar(&insecureTLS, "insecure", false, "Do not validate server's TLS certificate") - rootCmd.PersistentFlags().DurationVar(&requestTimeout, "request-timeout", 60*time.Second, "HTTP request timeout, 0 means no timeout") - rootCmd.PersistentFlags().DurationVar(&idleConnectionTimeout, "idle-connection-timeout", 0, "Idle connection timeout, 0 means no timeout (default behavior)") + rootCmd.PersistentFlags().StringVarP(&serverName, "server", "s", defaultServerName, "DSM server host name") + rootCmd.PersistentFlags().Uint16VarP(&serverPort, "port", "p", defaultServerPort, "DSM server port") + rootCmd.PersistentFlags().BoolVar(&insecureTLS, "insecure", defaultTlsNotVerify, "Do not validate server's TLS certificate") + rootCmd.PersistentFlags().DurationVar(&requestTimeout, "request-timeout", defaultRequestTimeout, "HTTP request timeout, 0 means no timeout") + rootCmd.PersistentFlags().DurationVar(&idleConnectionTimeout, "idle-connection-timeout", defaultIdleConnectionTimeout, "Idle connection timeout, 0 means no timeout (default behavior)") } diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..9c2e7ac --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,114 @@ +/* Copyright (c) Fortanix, Inc. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package cmd + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func resetRootCmdStatus() { + rootCmd.SetArgs([]string{}) + serverName = defaultServerName + serverPort = defaultServerPort + insecureTLS = defaultTlsNotVerify + requestTimeout = defaultRequestTimeout + idleConnectionTimeout = defaultIdleConnectionTimeout +} + +func TestRootCmdDefaultFlags(t *testing.T) { + resetRootCmdStatus() + err := ExecuteCmd() + assert.NoError(t, err) + assert.Equal(t, defaultServerName, serverName) + assert.Equal(t, defaultServerPort, serverPort) + assert.Equal(t, defaultTlsNotVerify, insecureTLS) + assert.Equal(t, defaultRequestTimeout, requestTimeout) + assert.Equal(t, defaultIdleConnectionTimeout, idleConnectionTimeout) +} + +func TestRootCmdWithCustomArgs(t *testing.T) { + resetRootCmdStatus() + customServerName := "sdkms.custom.fortanix.com" + customServerPort := uint16(8080) + customInsecureTLS := true + customRequestTimeout := 120 * time.Second + customIdleConnectionTimeout := 300 * time.Second + + rootCmd.SetArgs([]string{ + "--server", customServerName, + "--port", fmt.Sprint(customServerPort), + "--insecure", + "--request-timeout", fmt.Sprint(customRequestTimeout), + "--idle-connection-timeout", fmt.Sprint(customIdleConnectionTimeout), + }) + + err := ExecuteCmd() + + assert.NoError(t, err) + assert.Equal(t, customServerName, serverName) + assert.Equal(t, customServerPort, serverPort) + assert.Equal(t, customInsecureTLS, insecureTLS) + assert.Equal(t, customRequestTimeout, requestTimeout) + assert.Equal(t, customIdleConnectionTimeout, idleConnectionTimeout) +} + +func TestRootCmdWithCustomShortArgs(t *testing.T) { + resetRootCmdStatus() + + customServerName := "sdkms.custom.fortanix.com" + customServerPort := uint16(8080) + + rootCmd.SetArgs([]string{ + "-s", customServerName, + "-p", fmt.Sprint(customServerPort), + }) + + err := ExecuteCmd() + + assert.NoError(t, err) + assert.Equal(t, customServerName, serverName) + assert.Equal(t, customServerPort, serverPort) + assert.Equal(t, defaultTlsNotVerify, insecureTLS) + assert.Equal(t, defaultRequestTimeout, requestTimeout) + assert.Equal(t, defaultIdleConnectionTimeout, idleConnectionTimeout) +} + +func TestRootCmdWithInvalidArgs(t *testing.T) { + resetRootCmdStatus() + + invalidServerPort := "invalid-server-port" + invalidRequestTimeout := "invalid-request-timeout" + invalidIdleConnectionTimeout := "invalid-idle-connection-timeout" + var err error + + rootCmd.SetArgs([]string{ + "--port", invalidServerPort, + }) + err = ExecuteCmd() + assert.Error(t, err) + assert.Contains(t, err.Error(), "invalid argument") + + rootCmd.SetArgs([]string{ + "--request-timeout", invalidRequestTimeout, + }) + err = ExecuteCmd() + assert.Error(t, err) + assert.Contains(t, err.Error(), "invalid argument") + assert.Contains(t, err.Error(), "invalid duration") + + rootCmd.SetArgs([]string{ + "--idle-connection-timeout", invalidIdleConnectionTimeout, + }) + err = ExecuteCmd() + assert.Error(t, err) + assert.Contains(t, err.Error(), "invalid argument") + assert.Contains(t, err.Error(), "invalid duration") +} diff --git a/go.mod b/go.mod index 378acae..1ecce4b 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,14 @@ require ( github.com/google/uuid v1.6.0 github.com/montanaflynn/stats v0.7.1 github.com/spf13/cobra v1.8.0 + github.com/stretchr/testify v1.9.0 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/pkg/errors v0.8.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d0b8d12..849e2b2 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fortanix/sdkms-client-go v0.4.0 h1:5cKiFJ4rzc69mhsVVI5Ma5ynr/k5vhvws0yfzfIro/k= github.com/fortanix/sdkms-client-go v0.4.0/go.mod h1:gjylIGX+6poVSe+JkbNsLTvseLd+rLjvcGFgXpW56Lo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -7,12 +9,18 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index ecd12b2..844f982 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,16 @@ package main -import "github.com/fortanix/dsm-perf-tool/cmd" +import ( + "fmt" + "os" + + "github.com/fortanix/dsm-perf-tool/cmd" +) func main() { - cmd.Execute() + if err := cmd.ExecuteCmd(); err != nil { + fmt.Println(err) + os.Exit(1) + } }