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 }