github.com/sercand/please@v13.4.0+incompatible/src/test/results.go (about)

     1  // Code for parsing the output of tests.
     2  
     3  package test
     4  
     5  import (
     6  	"encoding/xml"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  
    11  	"github.com/thought-machine/please/src/core"
    12  	"github.com/thought-machine/please/src/fs"
    13  )
    14  
    15  func parseTestResults(outputFile string) (core.TestSuite, error) {
    16  	return parseTestResultsDir(outputFile)
    17  }
    18  
    19  func parseTestResultsImpl(outputFile string) (core.TestSuite, error) {
    20  	bytes, err := ioutil.ReadFile(outputFile)
    21  	if err != nil {
    22  		return core.TestSuite{}, err
    23  	}
    24  	if len(bytes) == 0 {
    25  		return core.TestSuite{}, fmt.Errorf("No results")
    26  	} else if looksLikeJUnitXMLTestResults(bytes) {
    27  		testSuites, err := parseJUnitXMLTestResults(bytes)
    28  		testSuite := core.TestSuite{}
    29  		for _, suite := range testSuites.TestSuites {
    30  			testSuite.Collapse(suite)
    31  		}
    32  		return testSuite, err
    33  	} else {
    34  		return parseGoTestResults(bytes)
    35  	}
    36  }
    37  
    38  func parseTestResultsDir(outputDir string) (core.TestSuite, error) {
    39  	results := core.TestSuite{}
    40  	if !core.PathExists(outputDir) {
    41  		return results, fmt.Errorf("Didn't find any test results in %s", outputDir)
    42  	}
    43  	err := fs.Walk(outputDir, func(path string, isDir bool) error {
    44  		if !isDir {
    45  			fileResults, err := parseTestResultsImpl(path)
    46  			if err != nil {
    47  				return fmt.Errorf("Error parsing %s: %s", path, err)
    48  			}
    49  			results.Collapse(fileResults)
    50  		}
    51  		return nil
    52  	})
    53  	return results, err
    54  }
    55  
    56  // LoadPreviousFailures loads any failed tests from the given results file.
    57  // It returns the set of targets that should be run and any arguments for them.
    58  func LoadPreviousFailures(filename string) ([]core.BuildLabel, []string) {
    59  	f, err := os.Open(filename)
    60  	if err != nil {
    61  		log.Fatalf("Failed to read previous test results: %s", err)
    62  	}
    63  	defer f.Close()
    64  	// We have to read directly since the TestResults struct doesn't have all the information
    65  	// we'll need (e.g. it discards test suite names).
    66  	junit := jUnitXMLTestSuites{}
    67  	if err := xml.NewDecoder(f).Decode(&junit); err != nil {
    68  		log.Fatalf("Failed to read previous test results: %s", err)
    69  	}
    70  	labels := []core.BuildLabel{}
    71  	args := []string{}
    72  	for _, suite := range junit.TestSuites {
    73  		if suite.Failures > 0 {
    74  			labels = append(labels, core.ParseBuildLabel(suite.Name, "")) // These always have complete labels
    75  			for _, c := range suite.TestCases {
    76  				if c.Failure != nil || c.Error != nil {
    77  					args = append(args, c.Name)
    78  				}
    79  			}
    80  		}
    81  	}
    82  	return labels, args
    83  }