Closed fmnisme closed 5 years ago
应该换成: -gcflags "all=-N -l"
我本地是 go1.11 版本,测试结果是 -gcflags=-l 生效啊
我是g1.10, 这段代码就不行
-i -v -gcflags=-l
b/b.go:
package b
func F2() string {
return "F2"
}
func F() string {
return F2()
}
main.go
import (
"b"
"fmt"
"github.com/agiledragon/gomonkey"
)
func main() {
gomonkey.ApplyFunc(b.F2, func() string {
return "patched"
})
fmt.Printf("%v\n", b.F())
}
我是go1.11,上述情况-gcflags=-l
的确不生效。我之前是在测试代码中验证的,同时我们只在测试代码中使用 gomonkey 了,于是问题来了,为啥-gcflags=-l
在go test中生效?
示例代码:
func gg() int {
return mm()
}
func mm() int {
return 1
}
func TestMMApplyFunc(t *testing.T) {
Convey("TestMMApplyFunc", t, func() {
Convey("inline", func() {
patches := ApplyFunc(mm, func() int {
return 2
})
defer patches.Reset()
i := gg()
So(i, ShouldEqual, 2)
})
})
}
运行结果:
$ go version
go version go1.11 darwin/amd64
$ go test -gcflags=-l apply_func_test.go
ok command-line-arguments (cached)
$ go test -gcflags "all=-N -l" apply_func_test.go
ok command-line-arguments (cached)
我简单修改了@fmnisme main.go的代码:
package main
import (
"fmt"
"github.com/agiledragon/gomonkey"
"zte.com.cn/knitter/gomon/b"
)
func G2() string {
return "G2"
}
func G() string {
return G2()
}
func main() {
gomonkey.ApplyFunc(b.F2, func() string {
return "patchedF2"
})
gomonkey.ApplyFunc(G2, func() string {
return "patchedG2"
})
fmt.Printf("b.F: %v\n", b.F())
fmt.Printf("main.G: %v\n", G())
}
结果是:
[root@LIN-98C5F567B8E gomon]# go version
go version go1.11.1 linux/amd64
[root@LIN-98C5F567B8E gomon]# go run main.go
b.F: F2
main.G: G2
[root@LIN-98C5F567B8E gomon]# go run -gcflags "-N -l" main.go
b.F: F2
main.G: patchedG2
[root@LIN-98C5F567B8E gomon]# go run -gcflags "all=-N -l" main.go
b.F: patchedF2
main.G: patchedG2
[root@LIN-98C5F567B8E gomon]# go run -gcflags "all=-l" main.go
b.F: patchedF2
main.G: patchedG2
在结合golang对“all”的说明:
go help packages
.....
- "all" expands to all packages found in all the GOPATH
trees. For example, 'go list all' lists all the packages on the local
system. When using modules, "all" expands to all packages in
the main module and their dependencies, including dependencies
needed by tests of any of those.
......
我认为问题在于,F2函数在main之外的b包里,G2函数在main包内,这样仅使用“-N -l”时,golang编译器默认只对当前的顶层main包使用“-N -l”参数,而使用“all=-N -l”时,对b包也使用了“-N -l”参数,从而使对b包内的F函数禁用内联功能发挥出来。
@agiledragon 我改了测试代码: b.go
package b
func F2() string {
return "F2"
}
func F() string {
return F2()
}
func GG() int {
return MM()
}
func MM() int {
return 1
}
main_test.go
package main
import (
"testing"
. "github.com/agiledragon/gomonkey"
"github.com/smartystreets/goconvey/convey"
"zte.com.cn/knitter/gomon/b"
)
func gg() int {
return mm()
}
func mm() int {
return 1
}
func TestMMApplyFunc(t *testing.T) {
convey.Convey("TestMMApplyFunc", t, func() {
convey.Convey("inline", func() {
patches := ApplyFunc(mm, func() int {
return 2
})
defer patches.Reset()
i := gg()
convey.So(i, convey.ShouldEqual, 2)
})
convey.Convey("inter packages inline", func() {
patches := ApplyFunc(b.MM, func() int {
return 2
})
defer patches.Reset()
i := b.GG()
convey.So(i, convey.ShouldEqual, 2)
})
})
}
[root@LIN-98C5F567B8E gomon]# go version
go version go1.11.1 linux/amd64
[root@LIN-98C5F567B8E gomon]# go test
xx
Failures:
* /media/B/code/paasnw/src/zte.com.cn/knitter/gomon/gomon_test.go
Line 27:
Expected: '2'
Actual: '1'
(Should be equal)
* /media/B/code/paasnw/src/zte.com.cn/knitter/gomon/gomon_test.go
Line 36:
Expected: '2'
Actual: '1'
(Should be equal)
2 total assertions
--- FAIL: TestMMApplyFunc (0.00s)
FAIL
exit status 1
FAIL zte.com.cn/knitter/gomon 0.002s
[root@LIN-98C5F567B8E gomon]# go test -gcflags "all=-N -l"
..
2 total assertions
PASS
ok zte.com.cn/knitter/gomon 0.002s
[root@LIN-98C5F567B8E gomon]# go test -gcflags "all=-l"
..
2 total assertions
PASS
ok zte.com.cn/knitter/gomon 0.002s
[root@LIN-98C5F567B8E gomon]# go test -gcflags "-l"
.x
Failures:
* /media/B/code/paasnw/src/zte.com.cn/knitter/gomon/gomon_test.go
Line 36:
Expected: '2'
Actual: '1'
(Should be equal)
2 total assertions
--- FAIL: TestMMApplyFunc (0.00s)
FAIL
exit status 1
FAIL zte.com.cn/knitter/gomon 0.002s
验证了我在上面对非测试的业务代码中做的判断,当跨包打桩时需要添加all参数。
go版本升级不考虑向前兼容,不符合里氏替换原则,前段时间有反射机制,这几天又有内联禁用。 go1.10之前内联禁用命令:-gcflags=-l go1.10及之后内联禁用命令:-gcflags=all=-l
应该换成: -gcflags "all=-N -l"