Skip to content
Jakegogo edited this page Oct 17, 2024 · 3 revisions

背景:

  1. 基于公司目前内部没有一款自己维护的适合公司业务迭代的后台mock框架,众多项目采用外界开源的gomonkey框架进行函数的mock,因其存在一些的稳定性的bug,不支持异包私有函数mock,同包私有方法mock等等问题, 加上团队目前实现一款稳定性和功能改进版: 无需unpath即可在mock过程中调用原函数的特性,可以支持到延迟模拟,参数更改,mock数据录制等功能, 同时在团队中长期的hook技术积累,具备字节码修改,框架高稳定性等能力沉淀。因此公开作为开源项目
  2. 目前有一半以上方案是基于gomock类似的实现方案, 此mock方案需要要求业务代码具备良好的接口设计,从而能顺利生成mock代码,而goom只需要指定函数名称或函数定义,就能支持到任意函数的mock,任意函数异常注入,延时模拟等扩展性功能
  3. mock不仅是流量回放的能力,甚至开源让单测更加智能化,解决mock数据构造的问题,方便开发使用。 同时作为AOP、mock技术建设的核心输出方,已在logreplay长期的线上验证,并将之推广到单测,接口测试,中间件MOCK等各类场景以及多方平台和用户
  4. 内部版的goom在去年的时候已经修复了众多bug, 也是基于开源的框架更新太慢等问题,所以自己维护了一套,同时加上我们自研的一些专利点包括私有函数mock,并发回调原函数,interfacemock(验证中),并在logreplay项目中经过了验证。同时为了响应多个团队联系我们说对私有函数的mock需求,于是发布了公开版的goom

功能特性:

  1. 私有(未导出)函数(或方法)的mock, 普通函数的mock
  2. mock过程中回调原函数(线程安全, 支持并发单测),已升级为trampoline模式
  3. 异常注入,对函数调用支持异常注入,延迟模拟等稳定性测试
  4. 支持interface mock (面向接口编程和测试)

bugfix

  1. fix proxy函数被回收导致空指针或指令错误的问题
  2. 函数开头指令包含地址跳转或者call指令,需要做地址修复问题
  3. 短函数超出跳转指令长度溢出问题
  4. 多次重复并发path时,产生的字节码并发修改问题解决

目前接入业务

  1. 数据研发中心
  2. 体育
  3. 企鹅号
  4. 社交娱乐
  5. 应用宝
  6. eptest
  7. logreplay
  8. AI效能
  9. CDG支付

将来

  1. 支持数据驱动测试
  2. 支持中间件Mock和Mock数据推荐
  3. 支持Mock锚点、代码重构

TODO features

  1. redis、mdb、http等中间件mocker
  2. if条件表达式支持
  3. mock数据上报管理
  4. 插件化midleware的mocker

解决方案

私有函数mock方案

  1. 私有方法mock: 采用解析go的ModuleData,取出函数名和私有函数地址的映射关系,对私有函数指针进行hook实现
  2. 未导出结构体mock: 方法是在当前包下写一个和fake一样的结构体, 这个结构体的属性和mock的结构属性体保持一致,但是不需要给它定义方法。(保证参数内存对齐)

参数回收问题解决方案

因go语言采取参数逃逸分析机制,对于简单参数无需放到堆内存中。而在调用栈扩容时,需要对栈进拷贝移动,根据argmap和stackmap对参数进行必要的指针修复。而mock函数对原先并无使用的参数加以使用,那么就会有参数引用失效的问题 解决方案:

  1. 对参数添加持有指针引用
  2. 对参数进行深拷贝

Contributor

@yongfuchen、@adrewchen、@ivyyi、@ianqu、@miliao