开源软件兼容性可信量化分析
课程:软件质量分析
作业
- 开源软件兼容性问题严重程度分成哪4级?分别表示什么风险?
- 版本间兼容性可信度量公式什么?等级划分表是什么?
- 阐述软件间兼容性测试框架以及面向Java和C++的工具平台框架
解答
题目:开源软件兼容性问题严重程度分成哪4级?分别表示什么风险?
解答:
开源软件兼容性问题严重程度等级分为High、Medium、Low、No,分别表示高、中、低和无风险。
题目:版本间兼容性可信度量公式什么?等级划分表是什么?
解答:
参照玻尔兹曼熵公式,可得出计算软件版本间兼容性问题严重程度的玻尔兹曼加权熵𝐻公式:
H = ∑ i α i ∗ l g ( n i + 1 ) H = \displaystyle\sum_{i}^{}\alpha _{i}*lg(n_{i} + 1) H=i∑αi∗lg(ni+1)
α i = λ i λ h + λ m + λ l + λ o \alpha_{i} = \frac{\lambda_{i}}{\lambda_{h} + \lambda_{m} + \lambda_{l} + \lambda_{o}} αi=λh+λm+λl+λoλi
i ∈ ( h , m , l , o ) i \in (h, m, l, o) i∈(h,m,l,o)
其中,
- $ n_{h} + n_{m} + n_{l} + n_{o} $分别表示检测出的严重程度为High、Medium、Low、No的兼容性问题数量;
- $ \lambda_{h} + \lambda_{m} + \lambda_{l} + \lambda_{o} 分别表示 H i g h 、 M e d i u m 、 L o w 、 N o 的风险因子,我们根据近似黄金分割比设置各风险因子的值: 分别表示High、Medium、Low、No的风险因子,我们根据近似黄金分割比设置各风险因子的值: 分别表示High、Medium、Low、No的风险因子,我们根据近似黄金分割比设置各风险因子的值: \lambda_{h} = 0.9, \lambda_{m} = 0.7, \lambda_{l} = 0.4, \lambda_{o} = 0.1 $;
- $ \alpha_{h} + \alpha_{m} + \alpha_{l} + \alpha_{o} $分别表示High、Medium、Low、No的风险因子归一化权重;
在公式中 l g ( n i + 1 ) lg(n_{i}+1) lg(ni+1)取 n i + 1 n_{i}+1 ni+1一方面是为了满足对数函数的定义域,另一方面是为了当 n i n_{i} ni为0时,该严重程度对应的熵 α i ∗ l g ( n i + 1 ) \alpha _{i}*lg(n_{i} + 1) αi∗lg(ni+1)为0,表示没有兼容性风险。
在此,版本间兼容性可信度量考虑了各种严重程度兼容性问题出现的次数。因为新旧版本源代码是固定的,出现越严重的不兼容问题,且出现次数越多,则版本间的不兼容程度就越大,熵也会增加。
然后,我们需要根据玻尔兹曼加权熵 H H H,通过以下公式得到可信值𝐾:
K = e − H K = e^{-H} K=e−H
- H H H:软件版本间不兼容严重程度的熵,取值范围为 [ 0 , + ∞ ) [0,+∞) [0,+∞),该值越大,说明软件两版本间不兼容度越大,两者越不兼容。
- K K K:软件版本间兼容性可信度量值,取值范围为 ( 0 , 1 ] (0,1] (0,1]。该值越大,说明软件两版本间兼容性可信性越高,两版本间越兼容。
为了将最终可信值 T T T范围映射到 [ 1 , 10 ] [1,10] [1,10],我们对该模型进一步改进,得到如下最终的软件版 本间兼容性可信度量模型:
T = { 10 ∗ e − H ( 0.1 ≤ e − H ≤ 1 ) 1 ( 0 ≤ e − H < 0.1 ) T = \left\{\begin{matrix} 10 * e^{-H} & (0.1 \le e^{-H} \le 1 ) \\ 1 & (0 \le e^{-H} < 0.1 ) \end{matrix}\right. T={10∗e−H1(0.1≤e−H≤1)(0≤e−H<0.1)
H = ∑ i α i ∗ l g ( n i + 1 ) H = \displaystyle\sum_{i}^{}\alpha _{i}*lg(n_{i} + 1) H=i∑αi∗lg(ni+1)
α i = λ i λ h + λ m + λ l + λ o \alpha_{i} = \frac{\lambda_{i}}{\lambda_{h} + \lambda_{m} + \lambda_{l} + \lambda_{o}} αi=λh+λm+λl+λoλi
i ∈ ( h , m , l , o ) i \in (h, m, l, o) i∈(h,m,l,o)
- $ n_{h} + n_{m} + n_{l} + n_{o} $分别表示检测出的严重程度为High、Medium、Low、No的兼容性问题数量;
- $ \lambda_{h} + \lambda_{m} + \lambda_{l} + \lambda_{o} 分别表示 H i g h 、 M e d i u m 、 L o w 、 N o 的风险因子,我们根据近似黄金分割比设置各风险因子的值: 分别表示High、Medium、Low、No的风险因子,我们根据近似黄金分割比设置各风险因子的值: 分别表示High、Medium、Low、No的风险因子,我们根据近似黄金分割比设置各风险因子的值: \lambda_{h} = 0.9, \lambda_{m} = 0.7, \lambda_{l} = 0.4, \lambda_{o} = 0.1 $;
在计算得到开源软件版本间兼容性可信值后,我们还要进行开源软件版本间兼容性可信等级划分在进行可信等级划分时,我们不仅考虑开源软件版本间兼容性可信值,还要考虑版本间API变更的规模(即API变更的数量),变更规模越大,不兼容度越高,可信度越低。而API变更包括:良性变更(向下兼容的变更:严重程度为No)和破坏性变更(不向下兼容的变更:严重程度为High、Medium、Low),我们都会将其纳入考虑; 而另一方面,对于不兼容变更数量定义划分规则时的阈值是很难确定的,所以我们最终考虑使用不兼容变更密度作为可信等级划分的条件之一。
最终,我们得到的开源软件版本间兼容性可信等级划分:
等级 | T | d h d_{h} dh | d m d_{m} dm | d l d_{l} dl | 或满足 |
---|---|---|---|---|---|
V级 | 9 ≤ T 9 \leq T 9≤T | d h = 0 d_{h} = 0 dh=0 | d m = 0 d_{m} = 0 dm=0 | d l ≤ 0.4 d_{l} \leq 0.4 dl≤0.4 | 无 |
IV级 | 7 ≤ T < 9 7 \leq T < 9 7≤T<9 | d h = 0 d_{h} = 0 dh=0 | d m ≤ 0.4 d_{m} \leq 0.4 dm≤0.4 | d l ≤ 0.7 d_{l} \leq 0.7 dl≤0.7 | 或 9 ≤ T 9 \leq T 9≤T且不能评为 V 级别 |
III级 | 4 ≤ T < 7 4 \leq T < 7 4≤T<7 | d h ≤ 0.4 d_{h} \leq 0.4 dh≤0.4 | d m ≤ 0.7 d_{m} \leq 0.7 dm≤0.7 | - | 或 7 ≤ T 7 \leq T 7≤T且不能评为 IV 级别及以上 |
II级 | 2 ≤ T < 4 2 \leq T < 4 2≤T<4 | d h ≤ 0.7 d_{h} \leq 0.7 dh≤0.7 | - | - | 或 4 ≤ T 4 \leq T 4≤T且不能评为 III 级别及以上 |
I级 | 1 ≤ T < 2 1 \leq T < 2 1≤T<2 | - | - | - | 或 2 ≤ T 2 \leq T 2≤T且不能评为 II 级别及以上 |
其中,T表示最终可信值,$ d_{h} + d_{m} + d_{l} $分别是High、Medium、Low的变更密度,计算公式如下所示:
d i = n i n h + n m + n l + n o ( i = h , m , l , o ) d_{i} = \frac{n_{i}}{n_{h} + n_{m} + n_{l} + n_{o}}(i = h, m, l, o) di=nh+nm+nl+noni(i=h,m,l,o)
$ n_{h} + n_{m} + n_{l} + n_{o} $分别表示检测出的严重程度为High、Medium、Low、No的兼容性问题数量。
题目:阐述软件间兼容性测试框架以及面向Java和C++的工具平台框架
解答:
软件间兼容性测试框架:
- 依赖库调用分析:分析主软件当前版本的源代码,从中提取主软件对直接依赖软件中API调用语句,从而知道有哪些API(类/接口/方法/…)被以何种形式调用(类继承/方法调用/方法重载…)。
- API差异分析:分析直接依赖软件的当前版本和默认版本中API存在的差异,即API相对于默认版本存在哪些变动(类被移除/方法参数数量变动/方法返回值类型变动…)。该分析可以借助已有的开源版本间兼容性测试工具进行。
- 软件间兼容性分析:针对从主软件源代码中的提取的API调用语句和直接依赖软件中的API差异,我们要分析这些API差异对API调用造成的影响,因为主软件通常只会调用直接依赖软件提供的部分API。我们基于预先设定的软件间兼容性规则,来判断是否会存在兼容性问题,以及兼容性问题的严重程度。
依据前述软件间兼容性测试框架,设计并实现Java-Compatibility工具:
- 依赖库调用分析:我们使用 JavaParser 框架来解析主软件的源代码,并分析其中API的调用情况,从而提取其中对直接依赖软件的API调用语句。
- API差异分析:我们使用 JAPICC 和 Revapi 工具来检测直接依赖软件当前版本和默认版本的API差异,读取差异报告并对其进行标准化。
- 软件间兼容性分析:我们则对Java软件间兼容性规则和兼容性可信度量进行了实现,最后得到兼容性测试和度量结果,并以Json格式输出结果报告。
Java软件间兼容性规则参考阶段一的Java兼容性度量指标进行设计,在API差异的基础上,考虑具体的API调用情况,共设计并实现了42条Java软件间兼容性规则。
API差异 | API差异描述 | API调用 | 严重程度等级 |
---|---|---|---|
Class_Or_Interface_Removed | 移除类/接口 | 调用了该类/接口(或者其字段或方法) | High |
未调用 | No | ||
Method_Without_Body_Added_To Interface | 接口新增待实现方法 | 该方法所在接口被实现 | High |
该方法所在接口未被实现 | No | ||
Method_Return_Type_Changed | 方法返回值类型变动 | 该方法被调用 | Medium |
未调用 | No | ||
Method_Runtim_Exception_Added | 方法新增运行时异常 | 该方法被调用 | Low |
未调用 | No | ||
… | … | … | … |
依据前述软件间兼容性测试框架,设计并实现Cpp-Compatibility工具:
- 依赖库调用分析:我们将主软件源代码与其所有依赖库一同编译(Linux环境),保留调试信息并生成动态链接库(.so)。然后,我们使用 pyelftools 库来读取和分析其中的调试信息,从而提取出主软件对依赖库的调用。
- API差异分析:我们使用 ABICC 工具来检测直接依赖软件当前版本和默认版本的API差异,然后读取 ABICC 生成的差异报告,并对其进行处理和标准化。
- 软件间兼容性分析:我们则对C/C++软件间兼容性规则和兼容性可信度量进行了实现,最后得到兼容性测试和度量结果,并以Json格式输出结果报告。
C/C++软件间兼容性规则参考阶段一的C/C++兼容性度量指标进行设计,在API差异的基础上,考虑具体的API调用情况,共设计并实现了66条Java软件间兼容性规则。
API差异 | API差异描述 | 语言限定 | API调用 | 严重程度等级 |
---|---|---|---|---|
Removed_Field | 数据类型中删除字段 | C/C++ | 该字段被调用 | High |
未调用 | No | |||
Added_Pure_Virtual_Method | 类新增纯虚方法 | C/C++ | 该类被调用 | High |
该类未被调用 | No | |||
Field_Pointer_Level_Changed | 字段指针等级改变 | C/C++ | 该字段被调用 | Medium |
未调用 | No | |||
Changed_Constant | 常数值发生改变 | C/C++ | 该常量被调用 | Low |
未调用 | No | |||
… | … | … | … |