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

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