Failed in Test
Closed this issue · 5 comments
Hey thanks for the awesome package!
I met some problems when using supermonkey in test.
// main.go
package main
import (
"fmt"
)
func main() {
heyHey()
}
//go:noinline
func heyHey() {
fmt.Println("fake")
}
// main_test.go
package main
import (
"fmt"
"testing"
sm "github.com/cch123/supermonkey"
)
func Test_HeyHey(t *testing.T) {
fmt.Println("original function output:")
heyHey()
fmt.Println()
sm.PatchByFullSymbolName("main.heyHey", func() {
fmt.Println("please be polite")
})
fmt.Println("after patch, function output:")
heyHey()
fmt.Println()
sm.UnpatchAll()
fmt.Println("unpatch all, then output:")
heyHey()
}
And I run the test like
$go test -gcflags="-l" ./
original function output:
fake
The symbol is main.heyHey, and the patch target addr is 0, there may be 2 possible reasons
1. the function is inlined, please add //go:noinline to function comment or add -l to gcflags
2. your input for symbolName or pkg/obj/method is wrong, check by using go tool nm {your_bin_file}
--- FAIL: Test_HeyHey (0.00s)
panic: [recovered]
panic:
goroutine 20 [running]:
testing.tRunner.func1.1(0x1193940, 0x1222350)
/usr/local/Cellar/go/1.14.4/libexec/src/testing/testing.go:940 +0x2f5
testing.tRunner.func1(0xc0000d0360)
/usr/local/Cellar/go/1.14.4/libexec/src/testing/testing.go:943 +0x3f9
panic(0x1193940, 0x1222350)
/usr/local/Cellar/go/1.14.4/libexec/src/runtime/panic.go:969 +0x166
github.com/cch123/supermonkey.PatchByFullSymbolName(0x11e749e, 0xb, 0x1191d20, 0x11f4610)
/Users/kiyon/go/pkg/mod/github.com/cch123/supermonkey@v0.9.2/supermonkey.go:33 +0x326
learn-golang/supermonkey.Test_HeyHey(0xc0000d0360)
/Users/kiyon/Code/learn/learn-golang/supermonkey/main_test.go:15 +0xac
testing.tRunner(0xc0000d0360, 0x11f4618)
/usr/local/Cellar/go/1.14.4/libexec/src/testing/testing.go:991 +0xdc
created by testing.(*T).Run
/usr/local/Cellar/go/1.14.4/libexec/src/testing/testing.go:1042 +0x357
FAIL learn-golang/supermonkey 0.399s
FAIL
Did I miss something?
it seems the package name generated by test is not main, for example, on my machine:
if you want to patch a function, you need to provide its full package path(and a go.mod project will be some github.com/path/to/your/project/pkg.yourprivatefunction), I'll fix the doc as soon as possible
in Chinese
似乎 Go 的 test 生成的包名不是 main,而是我上面图前面那一串,是下划线 + 目录 + 函数名。
如果是在 go.mod 环境下的话,应该就是全路径,比如 github.com/cch123/elasticsql.Convert,这样的。
patch 的时候得写全路径,我是觉得 go.mod 或者有 GOPATH 的环境下问题不大?
我看看是不是能想办法对这种 test 环境做个特殊定制
Thanks for the quick response! I'll try the full package name.
@kiyonlin , I've done more tests on this, maybe it's hard to setup on linux. The default test binary generated by Go on linux does not have a symbol table, to make it work , I have to execute go test -c -o xxx.test && ./xxx.test
Alright, this is also an approach. I'm appreciate it very much.