Skip to content

Add detailed internal design document #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
xhd2015 opened this issue Mar 24, 2024 · 6 comments
Open

Add detailed internal design document #7

xhd2015 opened this issue Mar 24, 2024 · 6 comments
Labels
documentation Improvements or additions to documentation

Comments

@xhd2015
Copy link
Owner

xhd2015 commented Mar 24, 2024

The so-called IR rewriting sounds unfamiliar to people.What's it? How does it solve the problem that go-monkey suffers?How does it compare to other mock strategies?Can we dig further to employ this technique not only in mock, but also system tracing?

@xhd2015 xhd2015 added the documentation Improvements or additions to documentation label Mar 24, 2024
@WAY29
Copy link

WAY29 commented Mar 24, 2024

Hope for more Information about this technique. Maybe a detailed article?

@xhd2015
Copy link
Owner Author

xhd2015 commented Mar 24, 2024

I will add materials on this issue thread to supplement the design document.

@xhd2015
Copy link
Owner Author

xhd2015 commented Mar 27, 2024

A new gained technique: declare init bodies.

Description: the following code always panics no matter you have deleted __xgo_link_generate_init_regs_body 's body or replaced it with completely new contents.

The only difference with other linking names is that it is called from init.

So the best practice is to not include that panic.

However, in user written code there are also cases where a linked method is called from init, but they are all fine with a panic.

Still needs to dig into this.

func init() {
	__xgo_link_generate_init_regs_body()
}

func __xgo_link_generate_init_regs_body() {
	panic("failed to link __xgo_link_generate_init_regs_body")
}

See d6c2b3d#diff-61c14e77880a87918b0cf686da52025d4e0abdd7b94047196c7baf56eb59ce9fR35

@xhd2015
Copy link
Owner Author

xhd2015 commented Mar 29, 2024

the trap.Inspect(fn) implements a way to retrieve func info.
It has different internal paths for these function types:

  • package level function
    • PC lookup
  • struct method
    • -fm suffix check
    • struct.method proto existence check
    • dynamic retrieval
  • interface method
    • -fm suffix check
    • interface proto existence check
    • dynamic retrieval
  • closure
    • closure is registered using IR
    • PC lookup
  • generic function
    • fullName parsing to de-generic
    • generic template existence check
    • no dynamic retrieval since no recv, but is legal to do so
  • generic struct method
    • -fm suffix check
    • fullName parsing to de-generic
    • generic method template existence check
    • dynamic retrieval just for receiver
  • generic interface method
    • to be supported

@xhd2015
Copy link
Owner Author

xhd2015 commented Mar 29, 2024

the trap.Inspect(fn) implements a way to retrieve func info.
It has different internal paths for these function types:

As a result, xgo exposes a single powerful Mock API to users, because it handle these cases smartly. Hiding most complexity from users. All mock can be done in single unified form:

// package level func
mock.Mock(SomeFunc, interceptor)

// per-instance method
// only the bound instance `v` will be mocked
// `v` can be either a struct or an interface
mock.Mock(v.Method, interceptor)

// per-TParam generic function
// only the specified `int` version will be mocked
mock.Mock(GenericFunc[int], interceptor)

// per TParam and instance generic method
v := GenericStruct[int]
mock.Mock(v.Method, interceptor)

// closure can also be mocked
// less used, but also supported
mock.Mock(closure, interceptor)

However, behind the scene, this topic deserves a good description.

@anfreshman
Copy link

非常感谢作者开源了一个这样强大的mock工具,我想基于入门文档继续咨询一些设计与扩展相关的问题

  1. 这边有这样一种场景,希望对一个go web系统进行插桩,然后从另一个效能服务控制这些插桩的效果,比如go web中有一个ControllerA,我可以通过效能服务判断这个ControllerA是mock返回某个值,还是正常处理业务逻辑。但文档里似乎主要将xgo用于单个服务的单元测试mock,想咨询下这部分作者是否有一些实施建议,或者xgo是否有一些特性导致它不支持这样做?
  2. xgo集成了代码覆盖率功能,但是由于xgo本身会修改代码逻辑,我比较好奇在逻辑修改后,xgo是如何保证覆盖率正常工作的,如果文档中可以添加介绍这一部分可能会让使用者在使用时减少相关的顾虑

期待作者的回复

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants