github.com/kubeshop/testkube@v1.17.23/pkg/api/v1/testkube/model_execution_extended.go (about) 1 package testkube 2 3 import ( 4 "fmt" 5 "time" 6 7 "go.mongodb.org/mongo-driver/bson/primitive" 8 9 "github.com/kubeshop/testkube/pkg/utils" 10 ) 11 12 func NewExecutionWithID(id, testType, testName string) *Execution { 13 return &Execution{ 14 Id: id, 15 ExecutionResult: &ExecutionResult{ 16 Status: ExecutionStatusQueued, 17 }, 18 TestName: testName, 19 TestType: testType, 20 Labels: map[string]string{}, 21 } 22 } 23 24 func NewExecution(id, testNamespace, testName, testSuiteName, executionName, testType string, 25 executionNumber int, content *TestContent, result ExecutionResult, 26 variables map[string]Variable, testSecretUUID, testSuiteSecretUUID string, 27 labels map[string]string) Execution { 28 if id == "" { 29 id = primitive.NewObjectID().Hex() 30 } 31 32 return Execution{ 33 Id: id, 34 TestName: testName, 35 TestSuiteName: testSuiteName, 36 TestNamespace: testNamespace, 37 Name: executionName, 38 Number: int32(executionNumber), 39 TestType: testType, 40 ExecutionResult: &result, 41 Variables: variables, 42 TestSecretUUID: testSecretUUID, 43 TestSuiteSecretUUID: testSuiteSecretUUID, 44 Content: content, 45 Labels: labels, 46 } 47 } 48 49 func NewFailedExecution(err error) Execution { 50 return Execution{ 51 Id: primitive.NewObjectID().Hex(), 52 ExecutionResult: &ExecutionResult{ 53 ErrorMessage: err.Error(), 54 Status: ExecutionStatusFailed, 55 }, 56 } 57 } 58 59 // NewQueued execution for executions status used in test executions 60 func NewQueuedExecution() *Execution { 61 return &Execution{ 62 ExecutionResult: &ExecutionResult{ 63 Status: ExecutionStatusQueued, 64 }, 65 } 66 } 67 68 type Executions []Execution 69 70 func (executions Executions) Table() (header []string, output [][]string) { 71 header = []string{"Id", "Name", "Test Name", "Type", "Status", "Labels"} 72 73 for _, e := range executions { 74 status := "unknown" 75 if e.ExecutionResult != nil && e.ExecutionResult.Status != nil { 76 status = string(*e.ExecutionResult.Status) 77 } 78 79 output = append(output, []string{ 80 e.Id, 81 e.Name, 82 e.TestName, 83 e.TestType, 84 status, 85 MapToString(e.Labels), 86 }) 87 } 88 89 return 90 } 91 92 func (e *Execution) WithContent(content *TestContent) *Execution { 93 e.Content = content 94 return e 95 } 96 97 func (e *Execution) WithVariables(variables map[string]Variable) *Execution { 98 e.Variables = variables 99 return e 100 } 101 102 func (e *Execution) Err(err error) Execution { 103 if e.ExecutionResult == nil { 104 e.ExecutionResult = &ExecutionResult{} 105 } 106 107 e.ExecutionResult.Err(err) 108 return *e 109 } 110 func (e *Execution) Errw(id, msg string, err error) Execution { 111 if e.ExecutionResult == nil { 112 e.ExecutionResult = &ExecutionResult{} 113 } 114 115 e.Id = id 116 e.ExecutionResult.Err(fmt.Errorf(msg, err)) 117 return *e 118 } 119 120 func (e *Execution) Start() { 121 e.StartTime = time.Now() 122 if e.ExecutionResult != nil { 123 e.ExecutionResult.Status = ExecutionStatusRunning 124 } 125 } 126 127 func (e *Execution) Stop() { 128 e.EndTime = time.Now() 129 duration := e.CalculateDuration() 130 e.Duration = utils.RoundDuration(duration).String() 131 e.DurationMs = int32(duration.Milliseconds()) 132 } 133 134 func (e *Execution) CalculateDuration() time.Duration { 135 136 end := e.EndTime 137 start := e.StartTime 138 139 if start.UnixNano() <= 0 && end.UnixNano() <= 0 { 140 return time.Duration(0) 141 } 142 143 if end.UnixNano() <= 0 { 144 end = time.Now() 145 } 146 147 return end.Sub(e.StartTime) 148 } 149 func (e Execution) IsFailed() bool { 150 if e.ExecutionResult == nil { 151 return true 152 } 153 154 return *e.ExecutionResult.Status == FAILED_ExecutionStatus 155 } 156 157 func (e Execution) IsAborted() bool { 158 if e.ExecutionResult == nil { 159 return true 160 } 161 162 return *e.ExecutionResult.Status == ABORTED_ExecutionStatus 163 } 164 165 func (e Execution) IsRunning() bool { 166 if e.ExecutionResult == nil { 167 return true 168 } 169 170 return *e.ExecutionResult.Status == RUNNING_ExecutionStatus 171 } 172 173 func (e Execution) IsQueued() bool { 174 if e.ExecutionResult == nil { 175 return true 176 } 177 178 return *e.ExecutionResult.Status == QUEUED_ExecutionStatus 179 } 180 181 func (e Execution) IsCanceled() bool { 182 if e.ExecutionResult == nil { 183 return true 184 } 185 186 return *e.ExecutionResult.Status == ABORTED_ExecutionStatus 187 } 188 189 func (e Execution) IsTimeout() bool { 190 if e.ExecutionResult == nil { 191 return true 192 } 193 194 return *e.ExecutionResult.Status == TIMEOUT_ExecutionStatus 195 } 196 197 func (e Execution) IsPassed() bool { 198 if e.ExecutionResult == nil { 199 return true 200 } 201 202 return *e.ExecutionResult.Status == PASSED_ExecutionStatus 203 } 204 205 func (e *Execution) WithID() *Execution { 206 if e.Id == "" { 207 e.Id = primitive.NewObjectID().Hex() 208 } 209 210 return e 211 } 212 213 func (e *Execution) convertDots(fn func(string) string) *Execution { 214 labels := make(map[string]string, len(e.Labels)) 215 for key, value := range e.Labels { 216 labels[fn(key)] = value 217 } 218 e.Labels = labels 219 220 envs := make(map[string]string, len(e.Envs)) 221 for key, value := range e.Envs { 222 envs[fn(key)] = value 223 } 224 e.Envs = envs 225 226 vars := make(map[string]Variable, len(e.Variables)) 227 for key, value := range e.Variables { 228 vars[fn(key)] = value 229 } 230 e.Variables = vars 231 return e 232 } 233 234 func (e *Execution) EscapeDots() *Execution { 235 return e.convertDots(utils.EscapeDots) 236 } 237 238 func (e *Execution) UnscapeDots() *Execution { 239 return e.convertDots(utils.UnescapeDots) 240 }