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 }