github.com/kubeshop/testkube@v1.17.23/contrib/executor/artillery/pkg/runner/artillery_helper.go (about) 1 package runner 2 3 import ( 4 "encoding/json" 5 "os" 6 7 "github.com/pkg/errors" 8 9 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 10 ) 11 12 // ArtilleryExecutionResult ... 13 type ArtilleryExecutionResult struct { 14 Output string 15 Result ArtilleryTestResult 16 } 17 18 // Mapping ... 19 type Mapping struct { 20 RelativeAccuracy float64 `json:"relativeAccuracy"` 21 Offset float64 `json:"_offset"` 22 Gamma float64 `json:"gamma"` 23 Multiplier float64 `json:"_multiplier"` 24 MinPossible float64 `json:"minPossible"` 25 MaxPossible float64 `json:"maxPossible"` 26 } 27 28 // Store ... 29 type Store struct { 30 ChunkSize float64 `json:"chunkSize"` 31 Bins []float64 `json:"bins"` 32 Count float64 `json:"count"` 33 MinKey float64 `json:"minKey"` 34 MaxKey float64 `json:"maxKey"` 35 Offset float64 `json:"offset"` 36 } 37 38 // HistogramMetrics ... 39 type HistogramMetrics struct { 40 Mapping Mapping `json:"mapping"` 41 Store Store `json:"store"` 42 NegativeStore Store `json:"negativeStore"` 43 ZeroCount int `json:"zeroCount"` 44 Count int `json:"count"` 45 Min float64 `json:"min"` 46 Max float64 `json:"max"` 47 Sum float64 `json:"sum"` 48 } 49 50 // Summary ... 51 type Summary struct { 52 Min float64 `json:"min"` 53 Max float64 `json:"max"` 54 Count float64 `json:"count"` 55 P50 float64 `json:"p50"` 56 Median float64 `json:"median"` 57 P75 float64 `json:"p75"` 58 P90 float64 `json:"p90"` 59 P95 float64 `json:"p95"` 60 P99 float64 `json:"p99"` 61 P999 float64 `json:"p999"` 62 } 63 64 type Counters struct { 65 VusersCreated int `json:"vusers.created"` 66 HTTPRequests int `json:"http.requests"` 67 HTTPCodes200 int `json:"http.codes.200"` 68 HTTPResponses int `json:"http.responses"` 69 PluginsExpectOk int `json:"plugins.expect.ok"` 70 PluginsExpectOkStatusCode int `json:"plugins.expect.ok.statusCode"` 71 PluginsExpectOkContentType int `json:"plugins.expect.ok.contentType"` 72 PluginsMetricsByEndpointGetRequestCodes200 int `json:"plugins.metrics-by-endpoint.getRequest.codes.200"` 73 VusersFailed int `json:"vusers.failed"` 74 VusersCompleted int `json:"vusers.completed"` 75 PluginsMetricsByEndpointPostRequestCodes200 int `json:"plugins.metrics-by-endpoint.postRequest.codes.200"` 76 } 77 type Histograms struct { 78 HTTPResponseTime HistogramMetrics `json:"http.response_time"` 79 PluginsMetricsByEndpointResponseTimeGetRequest HistogramMetrics `json:"plugins.metrics-by-endpoint.response_time.getRequest"` 80 VusersSessionLength HistogramMetrics `json:"vusers.session_length"` 81 PluginsMetricsByEndpointResponseTimePostRequest HistogramMetrics `json:"plugins.metrics-by-endpoint.response_time.postRequest"` 82 } 83 type Summaries struct { 84 HTTPResponseTime Summary `json:"http.response_time"` 85 PluginsMetricsByEndpointResponseTimeGetRequest Summary `json:"plugins.metrics-by-endpoint.response_time.getRequest"` 86 VusersSessionLength Summary `json:"vusers.session_length"` 87 PluginsMetricsByEndpointResponseTimePostRequest Summary `json:"plugins.metrics-by-endpoint.response_time.postRequest"` 88 } 89 type Metrics struct { 90 Counters Counters `json:"counters"` 91 Histograms Histograms `json:"histograms"` 92 HTTPRequestRate float64 `json:"http.request_rate"` 93 FirstCounterAt float64 `json:"firstCounterAt"` 94 FirstHistogramAt float64 `json:"firstHistogramAt"` 95 LastCounterAt float64 `json:"lastCounterAt"` 96 LastHistogramAt float64 `json:"lastHistogramAt"` 97 FirstMetricAt float64 `json:"firstMetricAt"` 98 LastMetricAt float64 `json:"lastMetricAt"` 99 Summaries Summaries `json:"summaries"` 100 } 101 102 // ArtilleryTestResult ... 103 type ArtilleryTestResult struct { 104 Aggregate Metrics `json:"aggregate"` 105 Intermediate []Metrics `json:"intermediate"` 106 } 107 108 // Validate checks if Execution has valid data in context of Artillery executor 109 func (r *ArtilleryRunner) Validate(execution testkube.Execution) error { 110 111 if execution.Content == nil { 112 return errors.Errorf("can't find any content to run in execution data: %+v", execution) 113 } 114 115 return nil 116 } 117 118 // GetArtilleryExecutionResult - fetch results from output report file 119 func (r *ArtilleryRunner) GetArtilleryExecutionResult(testReportFile string, out []byte) (ArtilleryExecutionResult, error) { 120 result := ArtilleryExecutionResult{} 121 result.Output = string(out) 122 data, err := os.ReadFile(testReportFile) 123 if err != nil { 124 return result, err 125 } 126 err = json.Unmarshal(data, &result.Result) 127 if err != nil { 128 return result, err 129 } 130 return result, nil 131 } 132 133 // MapTestSummaryToResults - map test results open-api format 134 func MapTestSummaryToResults(artilleryResult ArtilleryExecutionResult) testkube.ExecutionResult { 135 136 status := testkube.StatusPtr(testkube.PASSED_ExecutionStatus) 137 if artilleryResult.Result.Aggregate.Counters.VusersFailed > 0 { 138 status = testkube.StatusPtr(testkube.FAILED_ExecutionStatus) 139 140 } 141 result := testkube.ExecutionResult{ 142 Output: artilleryResult.Output, 143 OutputType: "text/plain", 144 Status: status, 145 } 146 return result 147 148 } 149 150 func makeSuccessExecution(out []byte) (result testkube.ExecutionResult) { 151 status := testkube.PASSED_ExecutionStatus 152 result.Status = &status 153 result.Output = string(out) 154 result.OutputType = "text/plain" 155 156 return result 157 }