github.com/kubeshop/testkube@v1.17.23/cmd/kubectl-testkube/commands/common/render/common.go (about) 1 package render 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 9 "gopkg.in/yaml.v2" 10 11 "github.com/kubeshop/testkube/pkg/api/v1/client" 12 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 13 "github.com/kubeshop/testkube/pkg/ui" 14 "github.com/kubeshop/testkube/pkg/utils" 15 ) 16 17 type OutputType string 18 19 const ( 20 OutputGoTemplate OutputType = "go" 21 OutputJSON OutputType = "json" 22 OutputYAML OutputType = "yaml" 23 OutputPretty OutputType = "pretty" 24 ) 25 26 type CliObjRenderer func(client client.Client, ui *ui.UI, obj interface{}) error 27 28 func RenderJSON(obj interface{}, w io.Writer) error { 29 return json.NewEncoder(w).Encode(obj) 30 } 31 32 func RenderYaml(obj interface{}, w io.Writer) error { 33 return yaml.NewEncoder(w).Encode(obj) 34 } 35 36 func RenderGoTemplate(item interface{}, w io.Writer, tpl string) error { 37 tmpl, err := utils.NewTemplate("result").Parse(tpl) 38 if err != nil { 39 return err 40 } 41 42 return tmpl.Execute(w, item) 43 } 44 45 func RenderGoTemplateList(list []interface{}, w io.Writer, tpl string) error { 46 tmpl, err := utils.NewTemplate("result").Parse(tpl) 47 if err != nil { 48 return err 49 } 50 51 for _, item := range list { 52 err := tmpl.Execute(w, item) 53 if err != nil { 54 return err 55 } 56 } 57 58 return nil 59 } 60 61 func RenderPrettyList(obj ui.TableData, w io.Writer) error { 62 ui.NL() 63 ui.Table(obj, w) 64 ui.NL() 65 return nil 66 } 67 68 func RenderExecutionResult(client client.Client, execution *testkube.Execution, logsOnly bool, showLogs bool) error { 69 result := execution.ExecutionResult 70 if result == nil { 71 ui.Errf("got execution without `Result`") 72 return nil 73 } 74 75 info, err := client.GetServerInfo() 76 ui.ExitOnError("getting server info", err) 77 78 ui.NL() 79 switch true { 80 case result.IsQueued(): 81 ui.Warn("Test queued for execution") 82 83 case result.IsRunning(): 84 ui.Warn("Test execution started") 85 86 case result.IsPassed(): 87 if showLogs { 88 PrintLogs(client, info, *execution) 89 } 90 91 if !logsOnly { 92 duration := execution.EndTime.Sub(execution.StartTime) 93 ui.Success("Test execution completed with success in " + duration.String()) 94 PrintExecutionURIs(execution, info.DashboardUri) 95 } 96 97 case result.IsAborted(): 98 ui.Warn("Test execution aborted") 99 100 case result.IsTimeout(): 101 ui.Warn("Test execution timeout") 102 103 case result.IsFailed(): 104 if showLogs { 105 PrintLogs(client, info, *execution) 106 } 107 108 if logsOnly { 109 ui.Info(result.ErrorMessage) 110 } else { 111 ui.UseStderr() 112 ui.Warn("Test execution failed:\n") 113 ui.Errf(result.ErrorMessage) 114 PrintExecutionURIs(execution, info.DashboardUri) 115 } 116 117 return errors.New(result.ErrorMessage) 118 119 default: 120 if logsOnly { 121 ui.Info(result.ErrorMessage) 122 } else { 123 ui.UseStderr() 124 ui.Warn("Test execution status unknown:\n") 125 ui.Errf(result.ErrorMessage) 126 } 127 128 if showLogs { 129 PrintLogs(client, info, *execution) 130 } 131 return errors.New(result.ErrorMessage) 132 } 133 134 return nil 135 } 136 137 func PrintLogs(client client.Client, info testkube.ServerInfo, execution testkube.Execution) { 138 if info.Features == nil || !info.Features.LogsV2 { 139 // fallback to default logs 140 ui.Info(execution.ExecutionResult.Output) 141 return 142 } 143 144 logsCh, err := client.LogsV2(execution.Id) 145 ui.ExitOnError("getting logs", err) 146 147 ui.H1("Logs:") 148 lastSource := "" 149 for log := range logsCh { 150 151 if log.Source != lastSource { 152 ui.H2("source: " + log.Source) 153 ui.NL() 154 lastSource = log.Source 155 } 156 157 if ui.Verbose { 158 ui.Print(log.Time.Format("2006-01-02 15:04:05") + " " + log.Content) 159 } else { 160 ui.Print(log.Content) 161 } 162 } 163 } 164 165 func PrintExecutionURIs(execution *testkube.Execution, dashboardURI string) { 166 ui.NL() 167 ui.ExecutionLink("Test URI:", fmt.Sprintf("%s/tests/%s", dashboardURI, execution.TestName)) 168 ui.ExecutionLink("Test Execution URI:", fmt.Sprintf("%s/tests/%s/executions/%s", dashboardURI, 169 execution.TestName, execution.Id)) 170 ui.NL() 171 } 172 173 func PrintTestSuiteExecutionURIs(execution *testkube.TestSuiteExecution, dashboardURI string) { 174 ui.NL() 175 testSuiteName := "" 176 if execution.TestSuite != nil { 177 testSuiteName = execution.TestSuite.Name 178 } 179 180 ui.ExecutionLink("Test Suite URI:", fmt.Sprintf("%s/test-suites/%s", dashboardURI, testSuiteName)) 181 ui.ExecutionLink("Test Suite Execution URI:", fmt.Sprintf("%s/test-suites/%s/executions/%s", dashboardURI, 182 testSuiteName, execution.Id)) 183 ui.NL() 184 }