github.com/kubeshop/testkube@v1.17.23/contrib/executor/jmeter/pkg/parser/jtl.go (about)

     1  package parser
     2  
     3  import (
     4  	"encoding/csv"
     5  	"errors"
     6  	"io"
     7  	"strconv"
     8  	"time"
     9  )
    10  
    11  type Results struct {
    12  	HasError         bool
    13  	LastErrorMessage string
    14  	Results          []Result
    15  }
    16  
    17  type Result struct {
    18  	Success      bool
    19  	Error        string
    20  	Label        string
    21  	ResponseCode string
    22  	Duration     time.Duration
    23  }
    24  
    25  func ParseCSV(reader io.Reader) (results Results, err error) {
    26  	res, err := CSVToMap(reader)
    27  	if err != nil {
    28  		return
    29  	}
    30  
    31  	for _, r := range res {
    32  		result := MapElementToResult(r)
    33  		results.Results = append(results.Results, result)
    34  
    35  		if !result.Success {
    36  			results.HasError = true
    37  			results.LastErrorMessage = result.Error
    38  		}
    39  	}
    40  
    41  	return
    42  }
    43  
    44  func MapElementToResult(in map[string]string) Result {
    45  	elapsed, _ := strconv.Atoi(in["elapsed"])
    46  
    47  	return Result{
    48  		Success:      in["success"] == "true",
    49  		Error:        in["failureMessage"],
    50  		Label:        in["label"],
    51  		Duration:     time.Millisecond * time.Duration(elapsed),
    52  		ResponseCode: in["responseCode"],
    53  	}
    54  }
    55  
    56  // CSVToMap takes a reader and returns an array of dictionaries, using the header row as the keys
    57  func CSVToMap(reader io.Reader) ([]map[string]string, error) {
    58  	r := csv.NewReader(reader)
    59  	rows := []map[string]string{}
    60  	var header []string
    61  	for {
    62  		record, err := r.Read()
    63  		if errors.Is(err, io.EOF) {
    64  			break
    65  		}
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  		if header == nil {
    70  			header = record
    71  		} else {
    72  			dict := map[string]string{}
    73  			for i := range header {
    74  				dict[header[i]] = record[i]
    75  			}
    76  			rows = append(rows, dict)
    77  		}
    78  	}
    79  	return rows, nil
    80  }