Skip to content

Commit

Permalink
test: add unit tests for root and getVersion
Browse files Browse the repository at this point in the history
  • Loading branch information
Taowyoo committed Apr 29, 2024
1 parent 51c4c36 commit d7e1cdf
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 124 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
105 changes: 105 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ package cmd
import (
"context"
"crypto/tls"
"encoding/csv"
"encoding/json"
"fmt"
"log"
"math"
"net"
"net/http"
"os"
"os/signal"
"reflect"
"strconv"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -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
}
61 changes: 61 additions & 0 deletions cmd/getVersion_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
107 changes: 0 additions & 107 deletions cmd/loadTest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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
}
25 changes: 13 additions & 12 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)")

}
Loading

0 comments on commit d7e1cdf

Please sign in to comment.