Skip to content

Commit

Permalink
feat: duration for testsexecutions and for executions (#783)
Browse files Browse the repository at this point in the history
  • Loading branch information
exu authored Jan 17, 2022
1 parent 5bd9a18 commit 08d5f8a
Show file tree
Hide file tree
Showing 24 changed files with 109 additions and 41 deletions.
9 changes: 9 additions & 0 deletions api/v1/testkube.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,9 @@ components:
type: string
description: "test end time"
format: date-time
duration:
type: string
description: "test duration"
stepResults:
type: array
description: "steps execution restults"
Expand Down Expand Up @@ -1049,6 +1052,9 @@ components:
type: string
description: "test execution end time"
format: date-time
duration:
type: string
description: "test execution duration"
execution:
type: array
items:
Expand Down Expand Up @@ -1150,6 +1156,9 @@ components:
type: string
description: "test end time"
format: date-time
duration:
type: string
description: "test duration"
executionResult:
required: true
description: result get from executor
Expand Down
4 changes: 2 additions & 2 deletions cmd/kubectl-testkube/commands/scripts/execution_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (r ExecutionRawRenderer) Render(execution testkube.Execution, writer io.Wri
func (r ExecutionRawRenderer) Watch(execution testkube.Execution, writer io.Writer) error {
_, err := fmt.Fprintf(writer, "Status: %s, Duration: %s\n",
*execution.ExecutionResult.Status,
execution.Duration(),
execution.CalculateDuration(),
)

return err
Expand All @@ -81,7 +81,7 @@ func (r ExecutionRawRenderer) renderDetails(execution testkube.Execution, writer
_, err := fmt.Fprintf(writer, "Name: %s, Status: %s, Duration: %s\n",
execution.Name,
*execution.ExecutionResult.Status,
execution.Duration(),
execution.CalculateDuration(),
)

return err
Expand Down
11 changes: 7 additions & 4 deletions cmd/kubectl-testkube/commands/tests/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tests

import (
"os"
"time"

"github.com/kubeshop/testkube/pkg/api/v1/client"
"github.com/kubeshop/testkube/pkg/api/v1/testkube"
Expand All @@ -19,9 +20,12 @@ func GetClient(cmd *cobra.Command) (client.Client, string) {
return client, namespace
}

func printTestExecutionDetails(execution testkube.TestExecution) {
func printTestExecutionDetails(execution testkube.TestExecution, startTime time.Time) {
ui.Warn("Name:", execution.Name)
ui.Warn("Status:", string(*execution.Status)+"\n")
if execution.Status != nil {
ui.Warn("Status:", string(*execution.Status))
}
ui.Warn("Duration", execution.CalculateDuration().String()+"\n")
ui.Table(execution, os.Stdout)

ui.NL()
Expand All @@ -37,8 +41,7 @@ func uiPrintTestStatus(execution testkube.TestExecution) {
ui.Warn("Test execution started")

case testkube.TestStatusSuccess:
duration := execution.EndTime.Sub(execution.StartTime)
ui.Success("Test execution completed with sucess in " + duration.String())
ui.Success("Test execution completed with sucess in " + execution.Duration)

case testkube.TestStatusError:
ui.Errf("Test execution failed")
Expand Down
4 changes: 3 additions & 1 deletion cmd/kubectl-testkube/commands/tests/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tests

import (
"fmt"
"time"

"github.com/kubeshop/testkube/pkg/ui"
"github.com/spf13/cobra"
Expand All @@ -20,13 +21,14 @@ func NewTestExecutionCmd() *cobra.Command {
ui.ExitOnError("Invalid arguments", fmt.Errorf("please pass execution ID"))
}

startTime := time.Now()
client, _ := GetClient(cmd)

executionID := args[0]
execution, err := client.GetTestExecution(executionID)
ui.ExitOnError("getting recent execution data id:"+execution.Id, err)

printTestExecutionDetails(execution)
printTestExecutionDetails(execution, startTime)

uiPrintTestStatus(execution)

Expand Down
5 changes: 3 additions & 2 deletions cmd/kubectl-testkube/commands/tests/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func NewStartTestCmd() *cobra.Command {
}

testID := args[0]
startTime := time.Now()

client, namespace := GetClient(cmd)
namespacedName := fmt.Sprintf("%s/%s", namespace, testID)
Expand All @@ -43,12 +44,12 @@ func NewStartTestCmd() *cobra.Command {
executionCh, err := client.WatchTestExecution(execution.Id)
for execution := range executionCh {
ui.ExitOnError("watching test execution", err)
printTestExecutionDetails(execution)
printTestExecutionDetails(execution, startTime)
}
}

execution, err = client.GetTestExecution(execution.Id)
printTestExecutionDetails(execution)
printTestExecutionDetails(execution, startTime)
ui.ExitOnError("getting recent execution data id:"+execution.Id, err)

uiPrintTestStatus(execution)
Expand Down
6 changes: 4 additions & 2 deletions cmd/kubectl-testkube/commands/tests/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tests

import (
"fmt"
"time"

"github.com/kubeshop/testkube/pkg/ui"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -29,17 +30,18 @@ func NewWatchTestExecutionCmd() *cobra.Command {
}

client, _ := GetClient(cmd)
startTime := time.Now()

executionID := args[0]
executionCh, err := client.WatchTestExecution(executionID)
for execution := range executionCh {
ui.ExitOnError("watching test execution", err)
printTestExecutionDetails(execution)
printTestExecutionDetails(execution, startTime)
}

execution, err := client.GetTestExecution(executionID)
ui.ExitOnError("getting test excecution", err)
printTestExecutionDetails(execution)
printTestExecutionDetails(execution, startTime)
ui.ExitOnError("getting recent execution data id:"+execution.Id, err)

uiPrintTestStatus(execution)
Expand Down
2 changes: 1 addition & 1 deletion docs/installing.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ We're building Homebew tap for each release, so you can easily install TestKube

```sh
brew tap kubeshop/homebrew-testkube
brew install kubeshop/testkube
brew install kubeshop/testkube/testkube
```

If you want to upgrade testkube please run following command
Expand Down
2 changes: 1 addition & 1 deletion internal/app/api/v1/executions.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func newExecutionFromExecutionOptions(options client.ExecuteOptions) testkube.Ex
options.Request.Name,
options.ScriptSpec.Type_,
options.ScriptSpec.Content,
testkube.NewQueuedExecutionResult(),
testkube.NewPendingExecutionResult(),
options.Request.Params,
options.Request.Tags,
)
Expand Down
16 changes: 12 additions & 4 deletions internal/app/api/v1/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,17 @@ func (s TestKubeAPI) executeTest(ctx context.Context, test testkube.Test) (testE
s.TestExecutionResults.Insert(ctx, testExecution)

go func(testExecution testkube.TestExecution) {
defer func() {

defer func(testExecution *testkube.TestExecution) {
duration := testExecution.CalculateDuration()
testExecution.EndTime = time.Now()
s.TestExecutionResults.EndExecution(ctx, testExecution.Id, time.Now())
}()
testExecution.Duration = duration.String()

err := s.TestExecutionResults.EndExecution(ctx, testExecution.Id, testExecution.EndTime, duration)
if err != nil {
s.Log.Errorw("error setting end time", "error", err.Error())
}
}(&testExecution)

// compose all steps into one array
steps := append(test.Before, test.Steps...)
Expand Down Expand Up @@ -220,7 +227,7 @@ func (s TestKubeAPI) executeTestStep(ctx context.Context, testName string, step
case testkube.TestStepTypeExecuteScript:
executeScriptStep := step.Execute
options, err := s.GetExecuteOptions(executeScriptStep.Namespace, executeScriptStep.Name, testkube.ExecutionRequest{
Name: fmt.Sprintf("%s-%s", testName, executeScriptStep.Name),
Name: fmt.Sprintf("%s-%s-%s", testName, executeScriptStep.Name, rand.String(5)),
})

if err != nil {
Expand Down Expand Up @@ -306,6 +313,7 @@ func mapToTestExecutionSummary(executions []testkube.TestExecution) []testkube.T
Status: execution.Status,
StartTime: execution.StartTime,
EndTime: execution.EndTime,
Duration: execution.Duration,
Execution: executionsSummary,
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/api/repository/result/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type Repository interface {
// StartExecution updates execution start time
StartExecution(ctx context.Context, id string, startTime time.Time) error
// EndExecution updates execution end time
EndExecution(ctx context.Context, id string, endTime time.Time) error
EndExecution(ctx context.Context, id string, endTime time.Time, duration time.Duration) error
// GetTags get all available tags
GetTags(ctx context.Context) (tags []string, err error)
}
4 changes: 2 additions & 2 deletions internal/pkg/api/repository/result/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ func (r *MongoRepository) StartExecution(ctx context.Context, id string, startTi
}

// EndExecution updates execution end time
func (r *MongoRepository) EndExecution(ctx context.Context, id string, endTime time.Time) (err error) {
_, err = r.Coll.UpdateOne(ctx, bson.M{"id": id}, bson.M{"$set": bson.M{"endtime": endTime}})
func (r *MongoRepository) EndExecution(ctx context.Context, id string, endTime time.Time, duration time.Duration) (err error) {
_, err = r.Coll.UpdateOne(ctx, bson.M{"id": id}, bson.M{"$set": bson.M{"endtime": endTime, "duration": duration.String()}})
return
}

Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/api/repository/testresult/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ type Repository interface {
// StartExecution updates execution start time
StartExecution(ctx context.Context, id string, startTime time.Time) error
// EndExecution updates execution end time
EndExecution(ctx context.Context, id string, endTime time.Time) error
EndExecution(ctx context.Context, id string, endTime time.Time, duration time.Duration) error
}
4 changes: 2 additions & 2 deletions internal/pkg/api/repository/testresult/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ func (r *MongoRepository) StartExecution(ctx context.Context, id string, startTi
}

// EndExecution updates execution end time
func (r *MongoRepository) EndExecution(ctx context.Context, id string, endTime time.Time) (err error) {
_, err = r.Coll.UpdateOne(ctx, bson.M{"id": id}, bson.M{"$set": bson.M{"endtime": endTime}})
func (r *MongoRepository) EndExecution(ctx context.Context, id string, endTime time.Time, duration time.Duration) (err error) {
_, err = r.Coll.UpdateOne(ctx, bson.M{"id": id}, bson.M{"$set": bson.M{"endtime": endTime, "duration": duration.String()}})
return
}

Expand Down
4 changes: 3 additions & 1 deletion pkg/api/v1/testkube/model_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ type Execution struct {
// test start time
StartTime time.Time `json:"startTime,omitempty"`
// test end time
EndTime time.Time `json:"endTime,omitempty"`
EndTime time.Time `json:"endTime,omitempty"`
// test duration
Duration string `json:"duration,omitempty"`
ExecutionResult *ExecutionResult `json:"executionResult,omitempty"`
// execution tags
Tags []string `json:"tags,omitempty"`
Expand Down
6 changes: 5 additions & 1 deletion pkg/api/v1/testkube/model_execution_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,16 @@ func (e Execution) Errw(msg string, err error) Execution {

func (e *Execution) Start() {
e.StartTime = time.Now()
if e.ExecutionResult != nil {
e.ExecutionResult.Status = ExecutionStatusPending
}
}

func (e *Execution) Stop() {
e.EndTime = time.Now()
e.Duration = e.CalculateDuration().String()
}
func (e *Execution) Duration() time.Duration {
func (e *Execution) CalculateDuration() time.Duration {

end := e.EndTime
start := e.StartTime
Expand Down
6 changes: 0 additions & 6 deletions pkg/api/v1/testkube/model_execution_result_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ func NewPendingExecutionResult() ExecutionResult {
}
}

func NewQueuedExecutionResult() ExecutionResult {
return ExecutionResult{
Status: StatusPtr(QUEUED_ExecutionStatus),
}
}

func NewErrorExecutionResult(err error) ExecutionResult {
return ExecutionResult{
Status: StatusPtr(ERROR__ExecutionStatus),
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1/testkube/model_test_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type TestExecution struct {
StartTime time.Time `json:"startTime,omitempty"`
// test end time
EndTime time.Time `json:"endTime,omitempty"`
// test duration
Duration string `json:"duration,omitempty"`
// steps execution restults
StepResults []TestStepExecutionResult `json:"stepResults,omitempty"`
// test execution tags
Expand Down
16 changes: 16 additions & 0 deletions pkg/api/v1/testkube/model_test_execution_extended.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ func (e TestExecution) IsCompleted() bool {
return *e.Status == *TestStatusError || *e.Status == *TestStatusSuccess
}

func (e *TestExecution) CalculateDuration() time.Duration {

end := e.EndTime
start := e.StartTime

if start.UnixNano() <= 0 && end.UnixNano() <= 0 {
return time.Duration(0)
}

if end.UnixNano() <= 0 {
end = time.Now()
}

return end.Sub(e.StartTime)
}

func (e TestExecution) Table() (header []string, output [][]string) {
header = []string{"Step", "Status", "ID", "Error"}
output = make([][]string, 0)
Expand Down
4 changes: 3 additions & 1 deletion pkg/api/v1/testkube/model_test_execution_summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type TestExecutionSummary struct {
// test execution start time
StartTime time.Time `json:"startTime,omitempty"`
// test execution end time
EndTime time.Time `json:"endTime,omitempty"`
EndTime time.Time `json:"endTime,omitempty"`
// test execution duration
Duration string `json:"duration,omitempty"`
Execution []TestStepExecutionSummary `json:"execution,omitempty"`
}
4 changes: 2 additions & 2 deletions pkg/jobs/jobclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (c *JobClient) LaunchK8sJobSync(image string, repo result.Repository, execu
// save stop time
defer func() {
execution.Stop()
repo.EndExecution(ctx, execution.Id, execution.EndTime)
repo.EndExecution(ctx, execution.Id, execution.EndTime, execution.CalculateDuration())
}()

// wait for complete
Expand Down Expand Up @@ -149,7 +149,7 @@ func (c *JobClient) LaunchK8sJob(image string, repo result.Repository, execution
// save stop time
defer func() {
execution.Stop()
repo.EndExecution(ctx, execution.Id, execution.EndTime)
repo.EndExecution(ctx, execution.Id, execution.EndTime, execution.CalculateDuration())
}()
// wait for complete
if err := wait.PollImmediate(time.Second, time.Duration(0)*time.Second, k8sclient.HasPodSucceeded(c.ClientSet, pod.Name, c.Namespace)); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions pkg/rand/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package rand

import (
"math/rand"
"time"
)

func init() {
rand.Seed(time.Now().UnixNano())
}
7 changes: 0 additions & 7 deletions pkg/rand/names.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
package rand

import (
"math/rand"
"time"

petname "github.com/dustinkirkland/golang-petname"
)

func init() {
rand.Seed(time.Now().UnixNano())
}

func Name() string {
return petname.Generate(3, "-")
}
13 changes: 13 additions & 0 deletions pkg/rand/string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package rand

import "math/rand"

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func String(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
Loading

0 comments on commit 08d5f8a

Please sign in to comment.