6

从精准化测试看ASM在Android中的强势插入-读懂diff

 2 years ago
source link: https://blog.csdn.net/eclipsexys/article/details/118256993
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

b161e942b741cc35f70ff58e606b56c6.png

点击上方蓝字关注我,知识会给你力量

5a9aec5b56c531ffe985838b2bc69a14.png

我们计算增量代码覆盖率的基础,就是要找出两个版本代码的差异,在Git环境下,我们可以很方便的通过Git脚本来获取这些数据。

Git获取diff信息

git diff命令可以使用如下格式,用来对比不同commit(或分支)间的增量代码:

git diff [<options>] <commit> <commit>

其中commit可以是分支名,也可以是commit的id,对比分支间的差异,可以简写为 git diff targetBranchName,表示对比当前分支与目标分支间的代码差异。

下面这张图,就是通过git diff指令获取的一段更新diff信息,如下所示。

git diff HEAD~1 HEAD

输出如下:

c2fe6a822091e73c1655b8578d7ef211.png image-20210621155525706

diff指令,一定会有两个输入,即A和B,图中第一行,就标记了A和B文件。

对于版本A,它的符号是一个减号(「-」);而对于版本B ,它会使用一个加号(「+」)。

图中的第三四行,就是被标记的两个文件,针对这个标记,存在下面几种情况。

  • diff文件是新增文件,则---后面是/dev/null

  • diff文件被删除,则+++后面是/dev/null

  • diff发生修改,则---和+++后面都有文件名

通过这个,就可以区分文件状态。

Chunk Header

git diff的每个修改,都会生成一个Chunk Header,对应图中的「@@」和「@@」符号之间。

@@ -31,21 +31,25 @@

这里表示,从A版本的第31行开始,变更了21行,B版本从31行开始,变更了25行。

但是,我只是加了4行log啊,这是什么鬼??

其实git diff指令不仅仅会给出变更行,而且还会带上前后默认3行的修改信息,作为上下文,所以才会有这么多的修改。

所以,我们需要再利用git的一个指令:

--unified=<n>,简写为-U<n>

来指定上下文关联的代码行数,这里设置为-U0,表示只关心实际的变更。

加上这个参数后,输出如下:

0ab262b97fb1086388830153675c9a60.png image-20210625145214250

加了这个参数后,Chunk Header同样会有三种情况:

  • -/+号后面只有一个数字,设为N,那么表示增加(+)、删除(-)了1行,行号为N,例如+34,就是第34行,增加了1行。

  • -/+号后面有两个数字,第1个数字设为N,且第二个数字为0,那么表示第N行没有变化,增加(+)、删除(-)了0行,这有啥意义呢?其实这就表示该内容是新增的。

  • -/+号后面有两个数字,第1个数字设为N,第二个数字为M,那么表示从N行开始,增加(+)、删除(-)了M行,这用于标记多行的修改。

那么有了这样一个认知后,就可以通过正则来检出这些数据。

git diff HEAD~1 HEAD -U0 | ggrep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'

借助这样一个正则表达式和grep,就可以从diff信息中找出修改的文件和行号,执行如下:

这里要注意,Mac下grep是用的2.5.1-FreeBSD版本,所以不支持 -P指令,需要安装GNU Grep,通过brew install grep来安装即可,安装好之后,通过ggrep来调用GNU Grep(如果是Linux的话,那么可以直接使用grep)。

如果在脚本中,可以借助正则表达式来获取。

Pattern.compile("^@@ -(\\d+),?(\\d+)? \\+(\\d+),?(\\d+)? @@.*");

这样通过下面的代码就可以获取新文件的修改行:

以上就是我们获取增量信息的基础,借助git的这些指令,我们就为后续JaCoco探针的插入,提供了Diff的信息,从而可以实现增量探针机制。

向大家推荐下我的网站 https://xuyisheng.top/  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下????


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK