简体   繁体   English

Goconvey引起恐慌与詹金斯的常规

[英]Goconvey causing panic with go routine on Jenkins

I have a set of test that use GoConvey with Go 1.3.1 that work just fine locally. 我有一套测试,使用GoConvey和Go 1.3.1在本地工作得很好。 But when I trigger a build with Jenkins, with the Go 1.3.1 as well, I get a panic from Goconvey related to a go routine I use in my test. 但是当我用Jenkins触发构建时,还有Go 1.3.1,我得到了Goconvey的恐慌,这与我在测试中使用的go例程有关。

The test may be seen here: 测试可以在这里看到:

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()
    })
}

The error here: 这里的错误:

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

Because you are trying to perform an assertion from another goroutine, you'll need to make use of the recently added context struct ( C ) in the func() signature, then call So off of that context. 因为您尝试从另一个goroutine执行断言,所以您需要在func()签名中使用最近添加的上下文结构( C ),然后从该上下文调用So Here's your version with a slight modification: 这是您的版本稍作修改:

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()
})

This was a result of pull request #264 . 这是拉请求#264的结果。

This exception is launched by context.go#mustGetCurrentContext() . context.go#mustGetCurrentContext()启动此异常。
you can see a test triggering that same exception in story_conventions_test.go#TestFailureModeNoContext 您可以在story_conventions_test.go#TestFailureModeNoContext看到触发相同异常的测试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
})

From the test example, if seems that calling a goroutine from within a goroutine from within a Convey test would trigger the no context panic. 从测试示例来看,如果看起来在Convey测试中从goroutine中调用goroutine会触发无上下文恐慌。

Since Jenkins launches the tests from a goroutine, that might explain why your GoConvey test fails (even though it runs when you are calling go test directly, outside of Jenkins) 由于Jenkins从goroutine启动测试,这可能解释了为什么你的GoConvey测试失败了(即使你在Jenkins之外直接调用go test时运行)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM