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  }