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

     1  package parser
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"io"
     7  	"strings"
     8  
     9  	"github.com/pkg/errors"
    10  
    11  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    12  )
    13  
    14  var ErrEmptyReport = errors.New("empty JTL report")
    15  
    16  func ParseJTLReport(report io.Reader, resultOutput []byte) (testkube.ExecutionResult, error) {
    17  	var buf bytes.Buffer
    18  	tee := io.TeeReader(report, &buf)
    19  	xml := isXML(tee)
    20  	report = io.MultiReader(&buf, report)
    21  	if xml {
    22  		return parseXMLReport(report, resultOutput)
    23  	}
    24  
    25  	return parseCSVReport(report, resultOutput)
    26  }
    27  
    28  func isXML(r io.Reader) bool {
    29  	scanner := bufio.NewScanner(r)
    30  	var firstLine string
    31  	for scanner.Scan() {
    32  		line := scanner.Text()
    33  		trimmedLine := strings.TrimSpace(line)
    34  		if trimmedLine != "" {
    35  			firstLine = trimmedLine
    36  			break
    37  		}
    38  	}
    39  
    40  	return strings.HasPrefix(strings.TrimSpace(firstLine), "<?xml") || strings.HasPrefix(strings.TrimSpace(firstLine), "<testResults")
    41  }
    42  
    43  func parseXMLReport(report io.Reader, resultOutput []byte) (testkube.ExecutionResult, error) {
    44  	data, err := io.ReadAll(report)
    45  	if err != nil {
    46  		return testkube.ExecutionResult{}, errors.Wrap(err, "error reading jtl report")
    47  	}
    48  
    49  	xmlResults, err := parseXML(data)
    50  	if err != nil {
    51  		return testkube.ExecutionResult{}, errors.Wrap(err, "error parsing xml jtl report")
    52  	}
    53  
    54  	if xmlResults.Samples == nil && xmlResults.HTTPSamples == nil {
    55  		return testkube.ExecutionResult{}, errors.WithStack(ErrEmptyReport)
    56  	}
    57  
    58  	return mapXMLResultsToExecutionResults(resultOutput, xmlResults), nil
    59  }
    60  
    61  func parseCSVReport(report io.Reader, resultOutput []byte) (testkube.ExecutionResult, error) {
    62  	csvResults, err := parseCSV(report)
    63  	if err != nil {
    64  		return testkube.ExecutionResult{}, errors.Wrap(err, "error parsing csv jtl report")
    65  	}
    66  
    67  	if len(csvResults.Results) == 0 {
    68  		return testkube.ExecutionResult{}, errors.WithStack(ErrEmptyReport)
    69  	}
    70  
    71  	return mapCSVResultsToExecutionResults(resultOutput, csvResults), nil
    72  }