跳到主要内容

多平台例子

opensibyl 的目标之一是通用性,而业务形态千差万别,如何在支撑极其复杂的业务需求的同时,让系统保持整洁高效。标记系统是我们给出的答案。

核心:标记系统

信息

机制脱胎于业务。

前文我们也提到,目前CI基本已经规范化与体系化,同一次构建同一份代码可能会被数十个插件、平台加工,更别说插件市场里的。 而这些对于基础平台来说就是海量的定制化需求。

我们在制作sibyl2的前身时,因为无止境的业务需求扩张导致平台膨胀得过于臃肿。 后来经历一次革新,将sibyl2单独抽离成独立服务,只提供基础数据,业务需求统一由二方服务承接。

这样做我们是爽了,但二方平台开发者抱怨颇多:

  • 重复开发:平台之间的结果没法传递与复用,例如许多平台可能都需要的spring注解抽取能力,只能每个平台各自去实现一份
  • IO成本高:重复开发带来的大量重复数据IO,平台压力大
  • 不再有消息总线:消息在平台间无法传递,平台失去了原来的 消息总线 地位

我们希望提供一个足够简单的方式:

  • 业务之间能够自由传递处理结果,一次处理到处可见
  • 组件分离为基础组件与业务组件,基础组件完成各类基础标识的标记,业务组件利用现成的标记进行上层分析

这就是标记系统的来源。二方平台的开发至此分为两个部分:

  • 平台:直接根据标记取用对应的数据,不再需要额外盲查
  • 标记器:如果现有标记难以满足,则可以自定义标记器实现分析规则,供自己使用

而在此基础上,平台也做到了较好的分工:

  • sibyl平台只需要支撑好标记能力,而不需要理解标记本身的含义
  • 二方平台可以结合自己需要设计标记,利用标记与sibyl交互

使用

标记系统的使用也极其简单。一般有三种场景:

  • 直接使用 client 来分析并打标
  • 利用 sibyl2 分析器分析,后利用client打标
  • 利用任何其他工具、平台分析,后利用client打标

下面是一个找到仓库中所有单测方法并打上标的例子:

functions, _, err := apiClient.RegexQueryApi.
ApiV1RegexFuncGet(ctx).
Repo(projectName).
Rev(rev).
Field("name").
Regex("^Test.*").
Execute()
assert.Nil(t, err)
assert.NotEmpty(t, functions)
// tag these functions with `TEST_METHOD`
TagForCases := "TEST_METHOD"
for _, eachFunc := range functions {
eachFuncSign := eachFunc.GetSignature()
_, err := apiClient.TagApi.ApiV1TagFuncPost(ctx).Payload(openapi.ServiceTagUpload{
RepoId: &projectName,
RevHash: &rev,
Signature: &eachFuncSign,
Tag: &TagForCases,
}).Execute()
assert.Nil(t, err)
}

// query
functionsFromQuery, _, err := apiClient.TagApi.ApiV1TagFuncGet(ctx).Repo(projectName).Rev(rev).Tag(TagForCases).Execute()
for _, eachFunc := range functionsFromQuery {
core.Log.Infof("tag from query: %v", eachFunc)
}
assert.Nil(t, err)
assert.NotEmpty(t, functionsFromQuery)
assert.Equal(t, len(functions), len(functionsFromQuery))

相应的,如果后续其他平台也需要解析单测用例,则可以直接利用该标识从平台上拉取,而不再需要自己开发一套重复逻辑。

一些场景参考:

  • 冷热方法系统
  • 微服务接口分析
  • 用例管理
  • 结合 commitmsg 判断方法与哪个需求有关
  • 结合覆盖率标记方法的覆盖情况
  • ...