github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/plugin/builtin/gotest/parser_test.go (about)

     1  package gotest
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/evergreen-ci/evergreen/testutil"
    12  	. "github.com/smartystreets/goconvey/convey"
    13  )
    14  
    15  func TestParserRegex(t *testing.T) {
    16  	Convey("With our test regexes", t, func() {
    17  		Convey("a test start should parse and match the test name", func() {
    18  			Convey("for vanilla logs", func() {
    19  				name, err := startInfoFromLogLine("=== RUN   TestParserFunctionality", startRegex)
    20  				So(err, ShouldBeNil)
    21  				So(name, ShouldEqual, "TestParserFunctionality")
    22  			})
    23  			Convey("and gocheck logs", func() {
    24  				name, err := startInfoFromLogLine("START: test_file.go:81: TestName.TearDownSuite", gocheckStartRegex)
    25  				So(err, ShouldBeNil)
    26  				So(name, ShouldEqual, "TestName.TearDownSuite")
    27  			})
    28  		})
    29  		Convey("a test end should parse and match the test name", func() {
    30  			Convey("for vanilla logs", func() {
    31  				name, status, dur, err := endInfoFromLogLine("--- FAIL: TestParserRegex (0.05s)", endRegex)
    32  				So(err, ShouldBeNil)
    33  				So(name, ShouldEqual, "TestParserRegex")
    34  				So(status, ShouldEqual, FAIL)
    35  				So(dur, ShouldEqual, time.Duration(50)*time.Millisecond)
    36  				name, status, dur, err = endInfoFromLogLine("--- PASS: TestParserRegex (0.00s)", endRegex)
    37  				So(err, ShouldBeNil)
    38  				So(name, ShouldEqual, "TestParserRegex")
    39  				So(status, ShouldEqual, PASS)
    40  				So(dur, ShouldEqual, time.Duration(0))
    41  			})
    42  			Convey("and gocheck logs", func() {
    43  				name, status, dur, err := endInfoFromLogLine(
    44  					"FAIL: adjust_test.go:40: AdjustSuite.TestAdjust", gocheckEndRegex)
    45  				So(err, ShouldBeNil)
    46  				So(name, ShouldEqual, "AdjustSuite.TestAdjust")
    47  				So(status, ShouldEqual, FAIL)
    48  				So(dur, ShouldEqual, time.Duration(0))
    49  				name, status, dur, err = endInfoFromLogLine(
    50  					"PASS: update_test.go:81: UpdateSuite.TearDownSuite	0.900s", gocheckEndRegex)
    51  				So(err, ShouldBeNil)
    52  				So(name, ShouldEqual, "UpdateSuite.TearDownSuite")
    53  				So(status, ShouldEqual, PASS)
    54  				So(dur, ShouldEqual, time.Duration(900)*time.Millisecond)
    55  			})
    56  		})
    57  	})
    58  
    59  }
    60  
    61  func TestParserFunctionality(t *testing.T) {
    62  	var parser Parser
    63  	cwd := testutil.GetDirectoryOfFile()
    64  
    65  	Convey("With a simple log file and parser", t, func() {
    66  		logdata, err := ioutil.ReadFile(filepath.Join(cwd, "testdata", "1_simple.log"))
    67  		testutil.HandleTestingErr(err, t, "couldn't open log file")
    68  		parser = &VanillaParser{Suite: "test"}
    69  
    70  		Convey("running parse on the given log file should succeed", func() {
    71  			err = parser.Parse(bytes.NewBuffer(logdata))
    72  			So(err, ShouldBeNil)
    73  
    74  			Convey("and logs should be the correct length", func() {
    75  				logs := parser.Logs()
    76  				So(len(logs), ShouldEqual, 18)
    77  			})
    78  
    79  			Convey("and there should be two test results", func() {
    80  				results := parser.Results()
    81  				So(len(results), ShouldEqual, 2)
    82  
    83  				Convey("with the proper fields matching the original log file", func() {
    84  					So(results[0].Name, ShouldEqual, "TestFailures")
    85  					So(results[0].Status, ShouldEqual, FAIL)
    86  					rTime, _ := time.ParseDuration("5.02s")
    87  					So(results[0].RunTime, ShouldEqual, rTime)
    88  					So(results[0].StartLine, ShouldEqual, 1)
    89  					So(results[0].EndLine, ShouldEqual, 14)
    90  					So(results[0].SuiteName, ShouldEqual, "test")
    91  					So(results[1].Name, ShouldEqual, "TestFailures2")
    92  					So(results[1].Status, ShouldEqual, FAIL)
    93  					rTime, _ = time.ParseDuration("2.00s")
    94  					So(results[1].RunTime, ShouldEqual, rTime)
    95  					So(results[1].StartLine, ShouldEqual, 15)
    96  					So(results[1].EndLine, ShouldEqual, 15)
    97  					So(results[1].SuiteName, ShouldEqual, "test")
    98  				})
    99  			})
   100  		})
   101  	})
   102  	Convey("With a gocheck log file and parser", t, func() {
   103  		logdata, err := ioutil.ReadFile(filepath.Join(cwd, "testdata", "2_simple.log"))
   104  		testutil.HandleTestingErr(err, t, "couldn't open log file")
   105  		parser = &VanillaParser{Suite: "gocheck_test"}
   106  
   107  		Convey("running parse on the given log file should succeed", func() {
   108  			err = parser.Parse(bytes.NewBuffer(logdata))
   109  			So(err, ShouldBeNil)
   110  
   111  			Convey("and logs should be the correct length", func() {
   112  				logs := parser.Logs()
   113  				So(len(logs), ShouldEqual, 15)
   114  			})
   115  
   116  			Convey("and there should be three test results", func() {
   117  				results := parser.Results()
   118  				So(len(results), ShouldEqual, 3)
   119  
   120  				Convey("with the proper fields matching the original log file", func() {
   121  					So(results[1].Name, ShouldEqual, "MyTestName.SetUpTest")
   122  					So(results[1].Status, ShouldEqual, PASS)
   123  					rTime, _ := time.ParseDuration("0.576s")
   124  					So(results[1].RunTime, ShouldEqual, rTime)
   125  					So(results[1].StartLine, ShouldEqual, 2)
   126  					So(results[1].EndLine, ShouldEqual, 4)
   127  					So(results[1].SuiteName, ShouldEqual, "gocheck_test")
   128  				})
   129  			})
   130  		})
   131  	})
   132  	Convey("un-terminated tests are failures", t, func() {
   133  		logdata, err := ioutil.ReadFile(filepath.Join(cwd, "testdata", "3_simple.log"))
   134  		testutil.HandleTestingErr(err, t, "couldn't open log file")
   135  		parser = &VanillaParser{Suite: "gocheck_test"}
   136  		err = parser.Parse(bytes.NewBuffer(logdata))
   137  		So(err, ShouldBeNil)
   138  
   139  		results := parser.Results()
   140  		So(len(results), ShouldEqual, 1)
   141  		So(results[0].Name, ShouldEqual, "TestFailures")
   142  		So(results[0].Status, ShouldEqual, FAIL)
   143  	})
   144  
   145  }
   146  
   147  func matchResultWithLog(tr *TestResult, logs []string) {
   148  	startLine := logs[tr.StartLine-1]
   149  	endLine := logs[tr.EndLine-1]
   150  	So(startLine, ShouldContainSubstring, tr.Name)
   151  	So(endLine, ShouldContainSubstring, tr.Name)
   152  	So(endLine, ShouldContainSubstring, tr.Status)
   153  }
   154  
   155  func TestParserOnRealTests(t *testing.T) {
   156  	// there are some issues with gccgo:
   157  	testutil.SkipTestUnlessAll(t, "TestParserOnRealTests")
   158  
   159  	var parser Parser
   160  
   161  	Convey("With a parser", t, func() {
   162  		parser = &VanillaParser{}
   163  		Convey("and some real test output", func() {
   164  			cmd := exec.Command("go", "test", "-v", "./.")
   165  			stdout, err := cmd.StdoutPipe()
   166  			testutil.HandleTestingErr(err, t, "error getting stdout pipe %v")
   167  			testutil.HandleTestingErr(cmd.Start(), t, "couldn't run tests %v")
   168  			err = parser.Parse(stdout)
   169  			testutil.HandleTestingErr(cmd.Wait(), t, "error waiting on test %v")
   170  
   171  			Convey("the parser should run successfully", func() {
   172  				So(err, ShouldBeNil)
   173  
   174  				Convey("and all results should line up with the logs", func() {
   175  					for _, result := range parser.Results() {
   176  						matchResultWithLog(result, parser.Logs())
   177  					}
   178  				})
   179  			})
   180  		})
   181  	})
   182  }