【问题标题】:Goconvey causing panic with go routine on JenkinsGoconvey 在 Jenkins 上使用 goroutine 引起恐慌
【发布时间】:2015-07-11 05:25:39
【问题描述】:

我有一组使用 GoConvey 和 Go 1.3.1 的测试,在本地工作得很好。但是,当我使用 Jenkins 以及 Go 1.3.1 触发构建时,Goconvey 对我在测试中使用的 go 例程感到恐慌。

测试可以在这里看到:

func TestListApplication(t *testing.T) {
    s := &Session{}
    s.Username = "foo"
    s.Password = "bar"
    ts := serveHTTP(t)
    defer ts.Close()
    s.Baseurl = ts.URL
    s.initialize()

    go func() {
        <-s.Comms.AppCount
    }()

    Convey("TestListApplication", t, func() {
        s.Comms.MainWaitGroup.Add(1)

        application := &Application{}
        err := json.Unmarshal(applicationJSON(), application)
        So(err, ShouldBeNil)

        revisions := &Revisions{}
        err = json.Unmarshal(revisionsJSON(), revisions)
        So(err, ShouldBeNil)

        var wg sync.WaitGroup
        wg.Add(1)
        go func() {
            defer wg.Done()
            line := <-s.Comms.Msg
            So(line, ShouldEqual, "3        admin       foo\n")
        }()
        s.listApplication(application, revisions)
        wg.Wait()
    })
}

这里的错误:

86 assertions thus far

..
88 assertions thus far

panic: Convey operation made without context on goroutine stack.
Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ?

goroutine 115 [running]:
runtime.panic(0x350d80, 0xc208083050)
    /Users/administrator/jenkins/tools/org.jenkinsci.plugins.golang.GolangInstallation/1.3.1/src/pkg/runtime/panic.c:279 +0xf5
github.com/smartystreets/goconvey/convey.conveyPanic(0x4960d0, 0x78, 0x0, 0x0, 0x0)
    /Users/administrator/jenkins/workspace/tropoCLI/golang/src/github.com/smartystreets/goconvey/convey/context.go:20 +0x6a
github.com/smartystreets/goconvey/convey.mustGetCurrentContext(0x5ecea0)
    /Users/administrator/jenkins/workspace/tropoCLI/golang/src/github.com/smartystreets/goconvey/convey/context.go:52 +0x57
github.com/smartystreets/goconvey/convey.So(0x2d78e0, 0xc208001e80, 0x48f210, 0xc208001e60, 0x1, 0x1)
    /Users/administrator/jenkins/workspace/tropoCLI/golang/src/github.com/smartystreets/goconvey/convey/doc.go:123 +0x1e
_/Users/administrator/jenkins/workspace/tropoCLI.func·048()
    /Users/administrator/jenkins/workspace/tropoCLI/tropoCLI_test.go:222 +0x17d
created by _/Users/administrator/jenkins/workspace/tropoCLI.func·049
    /Users/administrator/jenkins/workspace/tropoCLI/tropoCLI_test.go:223 +0x398

goroutine 16 [chan receive]:
testing.RunTests(0x48f340, 0x5ed680, 0x29, 0x29, 0x48f701)
    /Users/administrator/jenkins/tools/org.jenkinsci.plugins.golang.GolangInstallation/1.3.1/src/pkg/testing/testing.go:505 +0x923
testing.Main(0x48f340, 0x5ed680, 0x29, 0x29, 0x5f5b40, 0x0, 0x0, 0x5f5b40, 0x0, 0x0)
    /Users/administrator/jenkins/tools/org.jenkinsci.plugins.golang.GolangInstallation/1.3.1/src/pkg/testing/testing.go:435 +0x84
main.main()
    _/Users/administrator/jenkins/workspace/tropoCLI/_test/_testmain.go:127 +0x9c

【问题讨论】:

    标签: jenkins go tdd goconvey


    【解决方案1】:

    因为您正试图从另一个 goroutine 执行断言,您需要在 func() 签名中使用最近添加的上下文结构 (C),然后从该上下文调用 So。这是您的版本稍作修改:

    Convey("TestListApplication", t, func(c C) {
        s.Comms.MainWaitGroup.Add(1)
    
        application := &Application{}
        err := json.Unmarshal(applicationJSON(), application)
        So(err, ShouldBeNil)
    
        revisions := &Revisions{}
        err = json.Unmarshal(revisionsJSON(), revisions)
        So(err, ShouldBeNil)
    
        var wg sync.WaitGroup
        wg.Add(1)
        go func() {
            defer wg.Done()
            line := <-s.Comms.Msg
            c.So(line, ShouldEqual, "3        admin       foo\n")
        }()
        s.listApplication(application, revisions)
        wg.Wait()
    })
    

    这是拉request #264的结果。

    【讨论】:

      【解决方案2】:

      此异常由context.go#mustGetCurrentContext() 发起。
      您可以在 story_conventions_test.go#TestFailureModeNoContext 中看到一个触发相同异常的测试

      Convey("Foo", t, func() {
          done := make(chan int, 1)
          go func() {
              defer func() { done <- 1 }()
              defer expectPanic(t, noStackContext)
              So(len("I have no context"), ShouldBeGreaterThan, 0)
          }()
          <-done
      })
      

      从测试示例中,如果从 Convey 测试中的 goroutine 中调用 goroutine 似乎会触发无上下文恐慌。

      由于 Jenkins 从 goroutine 启动测试,这可能解释了您的 GoConvey 测试失败的原因(即使它在您直接调用 go test 时在 Jenkins 之外运行)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-12
        • 2019-05-10
        • 2018-05-28
        • 1970-01-01
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多