DDS协议测试实践及问题分析
在上一篇文章中,我们对 DDS 协议测试的策略、方法和工具进行了详细的介绍。本文旨在进一步探讨如何利用这些方法和工具搭建实际的测试环境,并执行测试,进而揭示可能遇到的各类问题。
被测协议栈简介
在本次测试中,被测协议栈选择了一个在汽车行业内广泛使用的开源 DDS 产品。
近年来随着开源软件社区的不断发展和成熟,越来越多的整车厂在选择 DDS 协议栈实现时,开始青睐开源产品。相比商业化的 DDS 协议栈,开源产品具有显著的成本优势。此外,使用开源产品还可以让整车厂获得更大的自主可控性,以便根据自身需求对协议栈进行定制和优化。
然而天下没有免费的午餐,选择开源 DDS 协议栈也意味着使用者必须承担起产品质量的责任。与商业化产品不同,开源产品通常没有专门的团队负责质量保证。因此,开源 DDS 协议栈的使用者必须投入额外的精力和资源,甚至组建专门的软件团队,来全面评估、测试和维护所选择的开源产品,以确保其功能和性能满足汽车行业的严苛要求。
在本篇文章中我们试图准确地识别出可能存在的问题,希望为汽车行业用户在选择开源 DDS 协议栈时提供实用的参考。
测试环境搭建
被测的 DDS 协议栈部署在一台运行 Ubuntu 操作系统的 x 86 服务器上。这种部署方式能够为 DDS 协议栈提供一个简单、稳定,且一致的运行环境,避免资源或网络配置错误等原因导致的测试结果不可信。
同时,为了全面评估 DDS 协议栈的功能和性能,我们在 DDS 之上部署了两个专门设计的测试应用程序。这两个应用程序的主要目的是模拟真实场景下的应用程序对 DDS 接口的调用,以验证 DDS 能够正确地处理各种请求并返回预期的结果。通过这种方式, 可以全面检验 DDS 的接口是否符合 OMG DDS 标准,以及是否能够满足汽车行业的特定需求。
为了实现对测试过程的自动化控制和管理,我们在上位机中开发了一套专门的测试脚本。这些脚本负责向 DDS 测试应用程序发送各种测试指令,根据预定的逻辑对测试应用程序的行为进行编排和调度。测试过程全自动化,无需任何人工干预,能够确保测试过程的一致性和可重复性。
此外,为了方便工程师对测试用例进行管理和监控,上位机软件还提供了一个直观的图形化界面。通过这个界面,测试人员可以轻松地创建、编辑和组织测试用例,并实时监控测试的执行状态和结果。
需要强调的是,测试环境可以根据用户的具体需求进行灵活地配置。比如将 DDS 测试程序部署在一个或多个真实的 ECU 中,以帮助我们发现系统性的网络配置问题、兼容性问题或性能问题等,包括防火墙、IP 地址、端口号、TSN 约束、时间同步、网络拓扑结构问题,DDS 中间件与不同硬件和软件平台之间的兼容性问题,也包括吞吐量、延迟、资源占用等指标。从而全面评估 DDS 分布式系统在实际应用场景下的可靠性、兼容性和性能表现,为系统的开发和优化提供重要的依据。
测试用例介绍
测试用例覆盖了 OMG DDS 规范中定义的所有软件接口,共 406 条测试用例,内容如下:
- 接口行为测试,包括正常调用时的行为测试,以及错误调用的故障行为测试,共计 353 条用例
- QoS 测试,即 OMG DDS 中定义的各项 QoS 的功能测试,共计 53 条用例
关于性能测试,由于 DDS 的性能很大程度上取决于硬件平台的性能和资源情况,以及操作系统的调度和管理机制,故在测试服务器中得到的性能测试结果与实际系统的性能表现可能相差很大,故本次测试不包含性能测试。
测试结果分析
概览
本次测试共计执行 406 个测试用例,通过194个,失败 212 个,通过率为 47.78%。如下为各模块的通过情况。
问题示例
功能缺失
如下表格列出了部分当前版本 DDS 缺失的接口。这些缺失的接口对于 DDS 分布式系统的功能和性能具有直接或间接的影响。重要的是,开发者文档可能并未明确指出这些接口功能的缺失,这种情况可能会对系统的稳定性和可靠性带来潜在风险。因此,用户在使用 DDS 时需要对这些潜在的缺陷保持警觉,并采取相应的预防措施。此外,用户应当积极参与开源社区讨论,关注产品的更新日志,以便及时了解和补充这些关键接口的功能,从而降低系统运行中的不确定性和风险。
表 1: 功能缺失问题示例
涉及接口或功能 |
问题描述 |
get_discovered_participants |
这是两个与发现机制相关的接口,它们用于获取有关在 DDS 域中发现的 DomainParticipant 的信息,如 QoS 策略、名称等。这使得应用程序能够查询和了解其他 DomainParticipant 的配置和能力。被测 DDS 缺失此功能。 |
ignore_participant |
允许应用程序在 DDS 域中动态地忽略特定的DomainParticipant、Publication或Subscription,从而细化和优化数据分发的过程。这些操作的主要目的是为了提高效率和性能,通过减少不必要的数据交换来节省资源。被测 DDS 缺失此功能。 |
begin_coherent_changes |
允许Publisher以一种一致的方式进行一系列数据变更,确保这些变更作为一个整体被Subscriber接收和处理,从而维护数据的一致性和完整性。主要影响 Presentation QoS 的功能。被测 DDS 缺失此功能。 |
copy_from_topic_qos |
该接口用于将一个对象的QoS设置复制到另一个对象。被测 DDS 缺失此功能。 |
create_datawriter 的 DATAWRITER_QOS_USE_TOPIC_QOS 特性 |
在创建 DataWriter 时直接使用主题 QoS。被测 DDS 缺失此功能。 |
... |
... |
图3: 功能缺失问题的测试报告示例
行为错误
当开发者根据官方文档调用特定 API 时,软件表现出的行为与文档描述不一致。这种不一致性可能表现为返回错误的结果、触发未预期的副作用或完全无响应。这种情况下,开发者不得不投入大量的时间去排查和定位问题。
表 2:API 行为错误示例
涉及接口或功能 |
问题描述 |
lookup_instance |
这个接口返回一个特定数据实例的句柄(handle)。这个句柄唯一地标识了一个数据实例,此接口没有返回正确的句柄。 |
set_default_topic_qos |
这两个接口用于设置或获取默认的 QoS 策略,当设置错误的 QoS 时,却能够返回成功,或获取的值与设置的值不一致 |
wait_for_acknowledgments |
针对可靠传输的数据,这个接口用于等待至所有之前发送的数据被 DataReader 接收,而实际情况是,当数据未被接收时,此接口并未阻塞至超时就返回了。 |
get_liveliness_lost_status |
get_liveliness_lost_status 允许 DataWriter 获取有关其活跃性丢失(liveliness lost)的状态信息。即当 DataWriter 没有在预定的时间间隔内向订阅者声明其活跃性时,这个接口提供活跃性丢失的次数。实际情况是该接口并没有返回正确的次数。 |
TimeBasedFilterQos |
TimeBasedFilterQos 是一种 QoS 策略,用于控制 DataReader 接收数据样本的最小间隔时间。这个 QoS 策略旨在减少应用程序处理数据的负担,特别是在数据发布速率远高于应用程序处理能力时。实际情况是 DataReader 没有按照规则来过滤数据。 |
... |
... |
图4: 行为错误测试报告示例
异常终止
此类问题指的是当应用程序在某些场景下调用特定接口时,DDS 中间件出现异常终止。这类问题的严重性在于其难以被发现、排查和修复。问题的隐蔽性在于异常通常只在特定的条件下触发,这些条件可能包括特定的数据模式、并发级别或资源使用情况,使得在常规测试中难以触发和识别。同时,即使问题被成功识别,修复工作也同样困难重重,这需要精确修改复杂的代码逻辑,还需要确保不会对 DDS 的其他功能造成负面影响。
由于 DDS 中间件作为系统的基础软件,其稳定性对整个系统的运行至关重要。同时,基础软件的不稳定性会对上层应用和最终用户产生连锁反应,极大地影响整个系统的质量和用户体验。因此,解决 DDS 中间件的异常终止问题,不仅是提升软件质量的技术挑战,也是确保系统整体稳定性和可靠性的重要一环。
表 3: DDS 软件异常终止问题示例
涉及接口或功能 |
问题描述 |
find_topic |
创建一个名为"TopicName"的主题。随后创建一个 DomainParticipant(DP),并启动线程。DP 调用 find_topic 搜索名为"TopicName"的主题,设置超时时间为 10 秒,等待至超时结束后删除所有创建的实体。在最后删除 DP 时 DDS 异常终止。 |
create_datareader |
调用 create_datawriter/create_datareader 时,参数使用空值,此时 DDS 异常终止。 |
get_datareaders |
调用 get_datareaders 时,使用带 Key 的类型作为传入参数,此时 DDS 抛出内存不足异常。 |
notify_datareaders |
配置 DPFQos 的 entity_factory. Autoenable_created_entities 属性为 false,确保创建的实体默认状态为未使能。接着,DPF 调用 set_qos 来设置 qos 参数,然后创建包括 DomainParticipant、Publisher、Subscriber、Topic、DataWriter、DataReader。之后调用 Sub 的 notify_datareaders 接口,此时 DDS 异常终止。 |
on_offered_deadline_missed |
触发 Deadline Missed 场景,on_offered_deadline_missed 接口崩溃。 |
... |
... |
总结
经过本篇文章的介绍,相信读者已经对DDS的协议测试以及可能存在的问题有了大概的了解。
在敏捷开发模式下,软件需求不断增加,软件系统的规模和复杂度也在不断增长。然而,许多关键问题(尤其是性能问题)只有在软件达到一定规模和复杂度后才会暴露出来。一旦发现这些问题,修复的成本往往非常高昂,因为任何基础软件的改动可能会影响到整个系统,牵一发而动全身。
相比之下,如果在项目早期就能够模拟实际的应用场景,并对 DDS 进行全面的功能和性能测试,开发团队可以深入了解 DDS 的行为特点,甚至软件缺陷,识别性能瓶颈,从而及时调整设计,优化实现。这种“前置”的测试方法不仅能够显著降低后期的修复成本,能够提高整个系统的质量和可靠性,帮助系统应对未来的挑战。
本文介绍了南京臻融科技有限公司(以下简称“臻融科技”)开发的DDS协议测试工具。臻融科技在过去十年里,一直致力于DDS产品及其相关工具链的自主研发,并且在国内关键行业领域取得了最高的市场份额。这款DDS协议测试工具在DDS研发过程中已经历了近十年的不断迭代,证明了其产品的成熟性和可靠性。臻融科技与北汇信息的合作,旨在将这套工具引入汽车行业,以协助客户建立DDS测试能力,提供高品质的测试服务和相关培训,进而加快DDS在汽车行业的推广和应用。
本文来自博客园,作者:{北汇信息},转载请注明原文链接:{https://www.cnblogs.com/polelink/}