代码质量测试 code-quality-testing

了解管道代码质量测试的工作方式以及其提高部署质量的方式。

简介 introduction

在管道执行期间,软件会捕获许多量度。然后将这些量度与企业所有者定义的关键绩效指标 (KPI) 进行比较。或者,将它们与 Adobe Managed Services 设定的标准进行比较。

这些结果使用三级评级系统进行报告。

三层评级 three-tiered-ratings

管道中有三项审核:

  • 代码质量
  • 性能测试
  • 安全性测试

对于这三项审核中的每项审核,审核所确定的问题具有一个三层结构。

  • 重要 – 导致管道立即失效的问题。
  • 重要 – 导致管道进入暂停状态的问题。部署经理、项目经理或企业所有者可以忽略这些问题。如果确实如此,管道就会按预期进行。或者,他们可以接受这些问题,导致管道因故障而停止。重要故障的覆盖受超时的约束。
  • 信息 – 仅供参考并且对管道执行没有影响的问题。
NOTE
在仅代码质量管道中,无法覆盖代码质量审核中的重要故障,因为代码质量测试步骤是管道中的最后一个步骤。

代码质量测试 code-quality-testing-step

此测试步骤评估应用程序代码的质量,这是仅考虑代码质量的管道的主要目的。它在所有非生产和生产管道中的构建步骤之后立即执行。要了解更多信息,请转至 配置非生产管道

代码质量测试将扫描源代码以确保它符合特定的质量标准。

该软件通过将 SonarQube 分析、使用 OakPAL 的内容包级别检查和使用 Dispatcher Optimization Tool 的 Dispatcher 验证配合使用来实现这一点。

有 100 多条规则结合了通用 Java 规则和特定于 AEM 的规则。 一些特定于 AEM 的规则基于来自 AEM Engineering 的最佳实践而创建,这些规则称作Custom Code Quality Rules

TIP
使用此链接下载规则的完整列表。

代码质量测试的结果按此表中汇总的评级交付。

名称
定义
类别
故障阈值
安全性评级
A = 无漏洞
B = 至少 1 个次要漏洞
C = 至少 1 个主要漏洞
D = 至少 1 个严重漏洞
E = 至少 1 个阻断漏洞
严重
< B
可靠性评级
A = 无错误
B = 至少 1 个次要错误
C = 至少 1 个主要错误
D = 至少 1 个严重错误
E = 至少 1 个阻断错误
重要
< C
可维护性评级

定义为代码异味的未完成修复成本占应用程序已用时间的百分比

  • A = <=5%
  • B = 6-10%
  • C = 11-20%
  • D = 21-50%
  • E = >50%
重要
< A
范围

在以下公式中结合使用单元测试行覆盖率和条件覆盖率来定义:
Coverage = (CT + CF + LC) / (2 * B + EL)

  • CT = 在运行单元测试时已评估为 true 至少一次的条件
  • CF = 在运行单元测试时已评估为 false 至少一次的条件
  • LC = 覆盖的行 = lines_to_cover - uncovered_lines
  • B = 条件总数
  • EL = 可执行的行总数 (lines_to_cover)
重要
< 50%
跳过的单元测试
跳过的单元测试数
信息
> 1
未结问题
整体问题类型 – 漏洞、错误和代码异味
信息
> 0
重复行

定义为重复块中涉及的行数。 在以下条件下,代码块被视为重复。
非 Java 项目:

  • 应有至少 100 个连续和重复的令牌。
  • 这些令牌应至少分布在:
  • 30 个代码行(对于 COBOL)
  • 20 个代码行(对于 ABAP)
  • 10 个代码行(对于其他语言)

Java 项目:

  • 无论令牌和行的数量如何,都应至少有 10 个连续和重复的语句。

检测重复项时将忽略缩进和字符串文本的差异。

信息
> 1%
Cloud Service 兼容性
确定的 Cloud Service 兼容性问题数
信息
> 0
NOTE
有关更多详细信息,请参阅 SonarQube 的量度定义
NOTE
要了解有关 Cloud Manager 执行的自定义代码质量规则的更多信息,请参阅Custom Code Quality Rules

处理误报 dealing-with-false-positives

质量扫描过程并不完善,有时会错误地识别实际上并不是问题的问题。这种情况称作误报。

在这些情况下,可以使用标准 Java @SuppressWarnings 注释为源代码添加注释,并将规则 ID 指定为注释属性。例如,一种常见误报是用于检测硬编码密码的 SonarQube 规则可能会妨碍识别硬编码密码的方式。

以下代码在 AEM 项目中相当常见,其中包含用于连接到某些外部服务的代码。

@Property(label = "Service Password")
private static final String PROP_SERVICE_PASSWORD = "password";

之后,SonarQube 提出阻止程序漏洞。不过,在查看代码后,您会发现这个问题并不是漏洞,并且可以使用适当的规则 ID 注释代码。

@SuppressWarnings("squid:S2068")
@Property(label = "Service Password")
private static final String PROP_SERVICE_PASSWORD = "password";

但是,如果代码的实际上如下:

@Property(label = "Service Password", value = "mysecretpassword")
private static final String PROP_SERVICE_PASSWORD = "password";

那么,正确的解决方案是删除硬编码的密码。

NOTE
最佳做法是使 @SuppressWarnings 注释尽可能具体。也就是说,仅注释导致问题的特定语句或块。但是,可以在类级别进行注释。这样做可以更广泛地抑制警告。

安全性测试 security-testing

Cloud Manager 会在部署后在暂存环境上运行现有的 AEM 安全运行状况检查,并通过 UI 报告状态。结果是由环境中的所有 AEM 实例汇总而成。

可以随时通过 Web 控制台或操作仪表板执行这些相同的运行状况检查。

如果任一实例报告未通过给定的运行状况检查,则整个环境将无法通过此运行状况检查。与代码质量和性能测试一样,这些运行状况检查将分成多个类别并通过三层审核系统进行报告。唯一的区别是,如果进行安全性测试则测试中没有阈值。运行状况检查要么全部通过,要么全部未通过。

下表列出了运行状况检查。

名称
运行状况检查实施
类别
反序列化防火墙连接 API 已准备就绪处于可接受的状态。
反序列化防火墙连接 API 已准备就绪
严重
反序列化防火墙运行正常。
反序列化防火墙运行正常
严重
反序列化防火墙已加载。
反序列化防火墙已加载
严重
AuthorizableNodeName 实施不会在节点名称/路径中公开可授权 ID。
可授权的节点名称生成
严重
默认密码已更改。
默认登录帐户
严重
Sling 默认 GET Servlet 可抵御 DOS 攻击。
Sling Get Servlet
严重
正确配置了 Sling JavaScript 处理程序。
Sling JavaScript 处理程序
严重
已适当配置 Sling JSP 脚本处理程序。
Sling JSP 脚本处理程序
严重
已正确配置 SSL。
SSL 配置
严重
未找到明显不安全的用户配置文件策略。
用户配置文件默认访问
严重
已配置 Sling 引用过滤器来阻止 CSRF 攻击。
Sling 引用过滤器
重要
已适当配置 Adobe Granite HTML 库管理器。
CQ HTML 库管理器配置
重要
已禁用 CRXDE 支持捆绑包。
CRXDE 支持
重要
已禁用 Sling DavEx 捆绑包和 Servlet。
DavEx 运行状况检查
重要
未安装示例内容。
示例内容包
重要
已禁用 WCM 请求过滤器和 WCM 调试过滤器。
WCM 过滤器配置
重要
已适当配置 Sling WebDAV 捆绑包和 Servlet。
WebDAV 运行状况检查
重要
已配置 Web 服务器来阻止点击劫持攻击。
Web 服务器配置
重要
复制未使用 admin 用户。
复制和转移用户
信息

性能测试 performance-testing

AEM Sites aem-sites

Cloud Manager 对 AEM Sites 项目执行性能测试。性能测试通过启动虚拟用户(容器)来运行大约 30 分钟,这将模拟实际用户访问暂存环境中的页面来模拟流量。这些页面是使用爬网程序找到的。

虚拟用户 virtual-users

Cloud Manager 根据 企业所有者 角色设置的 KPI(响应时间和每分钟页面浏览量)启动虚拟用户或容器。这些 KPI 是在 创建或编辑程序时设置的

根据定义的 KPI,最多可启动十个模拟实际用户的容器。选择进行测试的页面将被拆分并分配给每个虚拟用户。

爬网程序 crawler

在 30 分钟的测试期开始之前,Cloud Manager 使用由客户成功工程师配置的一组URLs(包含一个或多个种子 URL)来对暂存环境进行爬网。从这些 URL 开始,检查每个页面的 HTML,并以广度优先的方式遍历链接。

  • 默认情况下,此爬网过程最多可处理 5000 个页面。
  • 可以通过设置管道变量CM_PERF_TEST_CRAWLER_MAX_PAGES来覆盖要测试的页面的最大数目。
    • 允许的值为 2000 - 7000
  • 来自爬网程序的请求的固定超时为 10 秒。

用于测试的页面集 page-sets

三个页面集选择页面。Cloud Manager 使用来自生产环境和暂存环境中的 AEM 实例的访问日志来确定以下存储桶。

  • 热门实时页面 - 确保测试实时客户访问的最受欢迎的页面。Cloud Manager 读取访问日志,并确定实时客户最常访问的前 25 个页面,并生成受欢迎 Popular Live Pages 列表。之后,在暂存环境中对也在该环境中提供的页面交集进行爬网。

  • 其他实时页面 – 确保对前 25 个受欢迎实时页面之外的页面(这些页面可能不受欢迎,但对测试很重要)进行测试。与受欢迎实时页面类似,这些页面提取自访问日志,并且也必须位于暂存环境中。

  • 新页面 – 测试新页面,虽然这些页面可能仅部署到暂存环境而未部署到生产环境,但必须进行测试。

跨所选页面集的流量分配 distribution-of-traffic

您可以在管道配置的​ 测试 ​选项卡上,从一到三个页面集中选择任一页面集。流量分配基于所选页面集数。也就是说,如果选定所有三个页面集,则每个页面集的查看次数占总页面查看次数的 33%。如果选定两个页面集,则每个页面集的查看次数占总页面查看次数的 50%。如果选定一个页面集,则该页面集的查看次数占总页面查看次数的 100%。

我们来看看以下示例。

  • 受欢迎实时页面集和新页面集的比例是 50/50。
  • 未使用其他实时页面。
  • 新页面集包含 3000 个页面。
  • 每分钟页面查看次数 KPI 设置为 200。

在 30 分钟的测试期间:

  • 受欢迎实时页面集中的 25 个页面均将被点击 120 次:((200 * 0.5) / 25) * 30 = 120
  • 新页面集中的 3000 个页面均将被点击 1 次:((200 * 0.5) / 3000) * 30 = 1

测试与报告 testing-reporting

Cloud Manager 通过在暂存发布服务器上以未经身份验证的用户身份(默认情况下)请求页面,来对 AEM Sites 项目执行性能测试,测试期间为 30 分钟。它测量每个页面的虚拟用户生成的指标(响应时间、错误率、每分钟的浏览量等)以及所有实例的各种系统级指标(CPU、内存、网络数据)。

下表总结了使用三层审核系统的性能测试矩阵。

量度
类别
故障阈值
页面请求错误率
严重
>= 2%
CPU 利用率
严重
>= 80%
磁盘 IO 等待时间
严重
>= 50%
95% 响应时间
重要
>= 项目级 KPI
峰值响应时间
重要
>= 18 秒
每分钟页面查看次数
重要
< 项目级 KPI
磁盘带宽利用率
重要
>= 90%
网络带宽利用率
重要
>= 90%
每分钟请求数
信息
>= 6000

请参阅经过身份验证的性能测试部分,了解有关将基本身份验证用于 Sites 和 Assets 的性能测试的更多详细信息。

NOTE
在测试期间,将对创作实例和发布实例进行监控。如果未获得某个实例的任何量度,则量度将报告为未知,并且对应的步骤将失败。

经过身份验证的性能测试 authenticated-performance-testing

如有必要,拥有认证站点的 AMS 客户可以指定一个用户名和密码,Cloud Manager 将在站点性能测试期间使用该用户名和密码访问网站。

用户名和密码将指定为名为 CM_PERF_TEST_BASIC_USERNAMECM_PERF_TEST_BASIC_PASSWORD 的管道变量。

用户名应存储在 string 变量中,密码应存储在 secretString 变量中。如果同时指定这两个变量,则每个来自性能测试爬网程序和测试虚拟用户的请求都包含这些凭据作为 HTTP 基本身份验证。

要使用 Cloud Manager CLI 设置这些变量,请运行:

$ aio cloudmanager:set-pipeline-variables <pipeline id> --variable CM_PERF_TEST_BASIC_USERNAME <username> --secret CM_PERF_TEST_BASIC_PASSWORD <password>

请参阅补丁用户管道变量 API 文档了解如何使用 API。

AEM Assets aem-assets

Cloud Manager 通过反复上传资产来对 AEM Assets 项目执行性能测试,测试时间为 30 分钟。

新用户引导要求 onboarding-requirement

对于 Assets 性能测试,您的客户成功工程师将在暂存环境中引导作者期间创建 cloudmanager 用户和密码。性能测试步骤需要一个名为 cloudmanager 的用户和由 CSE 设置的相关密码。

此方法应保留在作者实例中,并且其权限保持不变。更改或删除它可能会导致资产性能测试失败。

用于测试的图像和资产 assets-for-testing

客户可以上传自己的资产进行测试。该过程可以从​ 管道设置 ​或​ 编辑 ​屏幕完成。支持 JPEG、PNG、GIF 和 BMP 等常见图像格式以及 Photoshop、Illustrator 和 Postscript 文件。

如果未上传图像,Cloud Manager 使用默认图像和 PDF 文档进行测试。

用于测试的资产的分配 distribution-of-assets

在​ 管道设置 ​或​ 编辑 ​屏幕中设置每分钟上传的每种类型资产数量。

例如,如果使用 70/30 拆分,则每分钟将上传 10 个资产,其中包括 7 个图像和 3 个文档。

测试与报告 testing-and-reporting

Cloud Manager 将使用 CSE 设置的用户名和密码在创作实例上创建一个文件夹。之后,使用开源库将资产上传到该文件夹中。使用开源库编写按 Assets 测试步骤运行的测试。每个资产的处理时间以及各种系统级量度都会在 30 分钟的测试持续时间内测量。此功能可以上传图像和 PDF 文档。

TIP
请参阅 配置生产管道 以了解更多信息。请参阅项目设置文档,了解如何设置项目和定义 KPI。

性能测试结果图表 performance-testing-results-graphs

“性能测试”对话框 ​中提供了许多量度。

量度列表

可以展开量度面板来显示图表和/或提供下载链接。

以图表形式展开的量度

此功能适用于以下量度。

  • CPU 利用率 – 测试期间的 CPU 利用率图表

  • 磁盘 I/O 等待时间 – 测试期间的磁盘 I/O 等待时间图表

  • 页面错误率 – 测试期间的每分钟页面错误图表

    • CSV 文件列出测试期间产生了错误的页面
  • 磁盘带宽利用率 – 测试期间的磁盘带宽利用率图表

  • 网络带宽利用率 – 测试期间的网络带宽利用率图表

  • 峰值响应时间 – 测试期间的每分钟峰值响应时间图表

  • 第 95 百分位响应时间 – 测试期间的每分钟第 95 百分位响应时间图表

    • 一个 CSV 文件,其中列出响应时间第 95 百分位数超过定义的 KPI 网页

内容包扫描优化 content-package-scanning-optimization

在质量分析过程中,Cloud Manager 会对 Maven 构建生成的内容包进行分析。 Cloud Manager 提供优化功能以加速此过程,当遵守某些打包限制时,这些优化功能将生效。

关键优化针对的是输出单个“全部”包的项目,其中包含构建生成的其他内容包,这些内容包被标记为已跳过。当 Cloud Manager 检测到此情况时,它不会解压缩“所有”包,而是直接扫描各个内容包并根据依赖关系对它们进行排序。 例如,考虑以下构建输出。

  • all/myco-all-1.0.0-SNAPSHOT.zip (content-package)
  • ui.apps/myco-ui.apps-1.0.0-SNAPSHOT.zip (skipped-content-package)
  • ui.content/myco-ui.content-1.0.0-SNAPSHOT.zip (skipped-content-package)

如果 myco-all-1.0.0-SNAPSHOT.zip 中的唯一项目是两个跳过的内容包,则会扫描两个嵌入包而不是“所有”内容包。

对于产生数十个嵌入包的项目,此优化已被证明可将每次管道执行时间节省 10 分钟以上。

当“所有”内容包包含跳过的内容包和 OSGi 捆绑包的组合时,可能会出现特殊情况。 例如,如果 myco-all-1.0.0-SNAPSHOT.zip 包含前面提到的两个嵌入式包以及一个或多个 OSGi 捆绑包,则仅使用 OSGi 捆绑包构建一个新的最小内容包。 此包始终名为 cloudmanager-synthetic-jar-package,并且包含的捆绑包将放置在 /apps/cloudmanager-synthetic-installer/install 中。

NOTE
  • 此优化不会影响部署到 AEM 的包。
  • 嵌入和跳过的内容包之间的匹配基于文件名。如果多个跳过的内容包共享相同的文件名或者文件名在嵌入过程中发生变化,则此优化会失败。
recommendation-more-help
c6cdc82b-cee9-48e0-a6ee-48149d5e72c3