软件测试,从测试对象来区分,可以划为系统软件和应用软件两大块。应用软件是为了某种特定的用途而被开发的软件,包括终端用户的衣食出行、教育、娱乐等,简单理解,和用户相关联的大部分软件都是应用软件。而系统软件是用来管理硬件或者服务上层软件的,比如操作系统、驱动管理等用户基本不直接打交道的软件,大部分处于应用软件下一层的位置。
---加个应景图?应用软件在系统软件上面---
应用软件一般是为了解决实际问题而专门设计的业务代码,在使用过程用户体验性强,所见即所得,输入后即有输出响应。因此,在测试过程中,应用软件更多的是通过输入和输出结果就能判断代码的正确性,即每个功能特性是否都实现了,代码运行的结果是否正确。而系统软件一般是偏底层作为服务支撑类,例如操作系统,它的主要作用就是服务于上层应用。内存管理、进程调度以及对文件系统的管理等一些核心功能都是用于服务应用的,这些特性模块仅从输入输出结果的测试很难保证其质量。比如内存管理,我们首先想到的是它会分配内存,用完在回收内存。启动一个进程进行验证,运行一段时间,然后退出,不出意外整个过程应该很顺利,即使同时启动多个进程进行验证,大概率也能得到满意的结果。这样的内存管理是否就没问题呢,不一定,我们可以对前面的验证过程稍加改动,写个脚本对进程循环的启停,或者对一批应用进程做这种验证,再去检查内存,验证效果可能就不同,甚至提供的机器内存本身就可以动态调整,测试效果肯定又会不一样了。
从以上分析,可以看到,应用软件的测试重点会关注到软件本身,它的功能、代码执行结果以及相应条件下的性能,这也是用户在上线后关注的焦点,而对于一些外部因素,比如断电业务不能再使用,网络波动导致消息发送很慢,甚至无法发送等,对于这些导致的问题,通常不会影响到对软件本身的评价。而系统软件除了它自身的功能需满足外,更重要的是在各种不确定的外部环境下还能否也正常工作。比如常见的数据库管理软件mysql,让数据有序的存储并管理起来,以供业务能按预期正常工作是它重要功能,但也是它最下限基础功能。业务在使用mysql的时候其实对它应对极端场景的能力更为关注,比如应用程序跑飞、进程异常、系统重启等等,在这些异常环境下,数据库系统能怎样处理正在交易的数据,落盘、容灾、容错等,这些能力在生产使用中会更重要。
区块链是一个分布式的共享账本及数据库,它的定义很长,我们用几个关键字来描述下它,“去中心化、加密算法、不可篡改、可以追溯、集体维护、公开透明”,所有这些特点,都是为了服务上层应用,从它的特性我们把区块链归类为系统软件中。区块链平台一般是由分布在不同区域、不同机器上的节点组成,节点间通过网络构成一个分布式系统,区块链实质上就是一个分布式系统软件。因此,在质量管理上,系统软件和分布式系统是区块链测试的两个大方向。目前业界主要有公有链、联盟链以及私有链三种模式,不管哪种运转模式,对于区块链这种底层平台软件,测试过程应至少需包含四大块内容,分别为功能、性能、可靠性和安全性,下面从这四个角度讨论区块链平台的一些测试思路。
功能
任何软件,不管是系统软件还是应用软件,首先会关注它具有的功能,这基本上决定了一个软件的可用范围。区块链作为一个分布式的系统软件,在质量体系建立过程,基础功能是每个版本必须重点测试的部分,它覆盖了区块链能服务于应用所具备的基础能力,下面讨论几个比较关注的功能。
环境支持
一个软件的使用,我们首先考虑的是它能在怎样的环境下运行,通常来说两方面,硬件环境和软件环境。硬件要求,主流的X86架构、ARM架构等是否支持,或者说腾讯云、阿里云以及华为云等云服务器能否适配。
而软件环境除了外部条件还要考虑自身因素,比如操作系统类型以及版本,依赖的组件或者库。对于区块链这类分布式软件,节点间组网模式采用内网、外网以及混合组网,还有采用Nginx代理进出的方式,以上都是在构建区块链环境时需规划考虑的。
节点管理
作为区块链运转的载体,所有的事情几乎都要节点参与,网络通信、逻辑运算、交易、数据验证等,而区块链一般是由多个节点组成协同工作,因此节点属性及对节点的管理至关重要。根据节点的分工不同,可分为记账节点和观察节点,记账节点负责打包共识,观察节点同步最高块数据,不同节点类型可进行切换。
在实际管理中,节点能由管理者操作加入或者退出区块链网络,而不影响业务的正常运行,以及扩容新增节点。长期使用的软件,一般都会迭代更新,区块链节点也应能够进行升级,包括灰度升级能力,升级后业务正常运行。
连接
区块链的显著特点它是一个分布式系统,因此连接尤为重要,节点间任一网络抖动都可能影响到区块链的正常工作。只有连接正常,才能保证后续的交易、共识、同步等功能特性正常展开。
在区块链系统中,涉及到连接的地方主要有节点间p2p连接、节点与客户端的连接,以及链下机构间通过链上节点进行通信。通常在环境条件正常时,以上连接都能顺利进行,并且通过网络连接命令和日志信息能查询对应结果。而真正考验连接的健壮性是在异常环境下系统的应对能力,以及环境恢复正常之后,连接能否也恢复正常。
实际生产应用中,会影响连接的因素很多,区块链系统本身来看,节点(SDK)证书合法性、黑白名单等将影响节点发起的连接能否成功。更常见的是外部环境对连接的影响,比如节点所在的服务器断连、网络的闪断或者带宽偏低、端口及网卡故障,以及CPU、内存的使用过高,甚至是机器重启导致进程重启等,这些都会对连接产生严重的影响。在测试验证过程,这些异常因素出现时,连接效果是不确定的,最坏的结果就是断连。但是在以上各种外部故障问题解决,环境恢复正常后,连接也应当能恢复正常,而不用去重启进程,这些在测试过程需重点检查。
连接的边界很多,需要通过一些工具或命令进行模拟,在清楚连接的原理和过程之后,要做的就是把各种可能影响连接的因素模拟出来,或者是多个场景的混合模型进行组合,验证代码处理逻辑的正确性。
共识算法
正所谓“无共识,不区块”,作为区块链的核心属性,共识机制不仅决定记账节点如何打包出块,还需要提供系统能正常工作的容错机制,并且保证各共识节点对交易执行结果达成一致。
一个底层平台选择哪种共识算法,主要与该平台使用的场景以及想解决的问题有关。它能支持的共识机制类型,以及在不同的场景,共识算法是否可插拔,提供便利的算法配置方式。因此底层平台完成共识算法选型后,我们需要验证的是,这种共识机制能否按预期算法完成从交易触发到数据落盘,以及在容错和容灾范围内依然正常工作。区块链平台上线前,对其使用的共识算法需要做严格的测试验证,涉及功能、安全、易用性等各方面。
共识过程一般包括打包、执行、签名、验证、落盘等主要阶段,任一阶段出现问题都会导致流程无法进行,对应节点无法参与共识,甚至整个链无法工作。对共识算法的质量要求实际上就是在共识的某个阶段遇到问题,它的应对机制是否可行,而不是卡在那或者直接系统崩溃。就比如打包,正常节点打完包执行之后发出去,其他节点共识。但遇到节点打包失败情况,其他节点如何反应,一般共识会有超时机制,如果此时在模拟下节点机器时间的改动,就能验到系统时间对共识的影响了。所以在测试共识算法前,需要清楚共识内部主要流程,才能对每一步骤构造场景进行相应测试。对于一个区块链平台,只是保证共识每一步逻辑没问题还远远不够,这只是证明它能正常共识,还需考虑更多外部场景,比如每个节点所处的环境就可能不一样,导致大家共识效率也会不一样。
在系统正常运行,无故障、无欺诈节点时,能正确共识,各节点数据能一致,但是在涉及一些安全方面,平台也要有相应处理机制,比如共识过程某节点把交易篡改了,网络中其他节点能识别该欺诈节点信息并做相应处理。处于网络中的节点不可避免的会受到外部环境干扰,导致节点不能正常工作,共识算法在应对这类故障时,应具备容错能力,保证故障节点数少于理论值区块链系统还能正常共识。在复杂的多群组架构中,一个记账节点可能会同时属于多个群组,系统需要保证节点在不同群组能独立共识独立存储。
智能合约
作为区块链2.0的标签,智能合约犹如灵魂,通过代码的运行展示了区块链这种新型技术的独特魅力。如何最大程度发挥合约特性,关键还看区块链平台提供了哪些合约管理能力。
合约的本质是由语言写出来的一些代码,通过区块链平台提供的执行环境,运行其中的代码逻辑,达到预期目标。平台支持的合约语言越丰富,用户实现功能选择的余地就越多,对项目尽早落地能有更好的保障。通用的solidity合约以其语法简单、操作便利等优势而广泛使用,而对于有高性能要求的应用,预编译合约将会是更好的选择。以及逐渐开始流行的rust、go等语言在合约中使用,让项目的合约开发选择有了多样性,满足了不同开发者要求。
除了合约语言的支持,合约的使用和管理对区块链平台是一个更重要的评测标准。包括合约的部署方式是否简便,即能提供哪些语言支持的客户端或者中间件工具部署合约,以及发送交易。合约是否支持升级,升级后如何管理版本。除了合约本身的升级,区块链节点升级后,已经部署的老合约也应当能继续调用,兼容性都没问题,正常发送交易。
随着对合约使用灵活性要求越来越高,像普通软件一样,合约的生命管理周期也纳入了区块链平台测试范围。从合约编写、部署、调用一直到废弃,这一整个过程需要验证的功能点非常多,我们只从合约的角度考虑。拿solidity语言来说,需要验证提供的各种变量类型、语法表达式、控制接口等合约结构,在区块链平台是否都能跑通。某些安全场景下,能否冻结或者销毁合约,使之不能再被调用执行,在需要使用时,又能解冻。
同步
在环境正常时,区块链各节点数据都应一致,同步特性至关重要。区块链系统同步主要包括交易同步、区块同步和状态同步,只有每个场景下的同步始终保持正常,区块链才能正常工作。
连接正常时,客户端发送到节点的交易,应当能同步到网络中其他节点。不同的区块链平台,根据节点的类型,组网模式,会采用不同的同步逻辑。区块同步涉及场景较多,新入网节点、进程停止一段时间在重启、节点遭遇故障导致数据丢失等,都会触发区块同步逻辑,以及在没有交易处理时,节点间也会保持状态的同步,以上都涉及到很多的同步场景,在测试中需对每一个场景设计详细、全面的验证过程,包括一些场景的交叉测试。
存储
区块链从狭隘角度看,是一个数据库,可用于存储数据,类比常见的业务存储模式,需要从数据组织模式和数据存储介质,以及容灾等几大块展开测试验证。区块链存储也类似,各种区块的数据在存储前需要进行相应的组织管理再存到介质中,但是区块链数据在落盘存储前要经历较漫长复杂的共识过程,也就是最终的数据都是共识确认过的。
可以从账户状态和存储介质对区块链的存储进行功能和稳定性测试。账户状态对应着合约局部变量的状态存储形式,根据平台提供的选择,配置成默克尔树结构或者分布式存储的世界状态模型,来进行相应的测试验证。而对于存储介质的选择,主要看区块链平台提供了哪些存储驱动,常见的leveldb、rocksdb、mysql,因此可以将账户状态模型和存储介质引擎进行组合测试。
存储功能的验证主要还是稳定性和正确性,在落盘成功的基础上还要保证节点间数据都一致。每个节点根据条件可以选择不同的存储介质,而涉及到存储的地方很多,共识,同步等都要存储,可采用混沌模型测试,各场景进行组合,验证每个节点存储稳定且数据正确。
兼容
任何产品在使用周期内,不论硬件还是软件,兼容性是一个不能避开的话题。区块链是一个复杂系统软件,涉及很多模块特性,以及最为重要的链上数据,所以在架构设计和升级时,兼容性必须谨慎规划和全面测试。
在区块链系统中,兼容性主要考虑两大块,自身兼容和周边兼容。对于自身兼容主要关注的是,在完成一次区块链版本升级后,链上历史数据是否还能正常使用,包括各种业务操作以及历史功能特性都能正常运行。而周边兼容则需要考虑周边组件和工具等配套,甚至一些版本的对应关系。
在分布式系统中,处于不同条件下节点管理方式可能存在差异,因此还需考虑灰度升级的情况,也就是节点有新老版本共存的现象,这种模式下需要测试验证的场景会较多,所有的功能特性在新老节点上都应操作验证一遍。
接口
类似于操作系统为应用层提供了系统调用接口,用于访问内核,区块链也有许多RPC接口供外部调用,根据实际需要调用合约,去链上读或者写数据,或者直接http协议调用RPC接口。接口的测试重点在输入稳定输出正确,多关注边界,外部对节点的访问能持续不断连。接口测试采用自动化是比较简单的,同时模拟接口在一定压力访问下,客户端对节点发送交易,链上共识能否保持正常。
数据治理
链上有大量的数据,怎样管理这些数据以供使用,特别是在业务量大的应用中,面对海量的链上数据,如何做适当的处理,让历史数据归档甚至是删除,而又不影响业务的正常运行。这些都离不开现在越来越热的一个话题--数据治理,即数据有了,怎么去治理和利用它。
想要最优化管理和利用链上数据,主要还是看区块链平台自身属性和相关组件能提供什么工具。链上主要有区块数据、交易数据以及状态数据,常见的治理方式有数据导出、数据导入、数据裁剪等,不同的需求对应不同数据治理方式。
数据导出
对于上层应用来说,区块链上的数据不易查看和使用,可以通过数据导出工具将数据迁移到mysql或者oracle中,后续做成可视化报表或者进行业务对账,就可以利用数据库中的数据完成相关设计。整个过程主要关注导出数据的正确性,是否和链上的数据一致,以及数据缺失、重复和覆盖等现象。
数据裁剪
随着区块链长时间运行,业务产生的数据越来越多,对存储和性能都是很大的考验,但另一方面链上有大量使用率低的冷数据,严重影响查询性能,这时就可以考虑对数据进行裁剪。举个例子,区块链块高到达三万时,可以将前两万块数据进行裁剪,链上只保留最新一万块的数据,同时,被裁剪的数据保存在其他地方能继续被使用。裁剪不仅是工具处理数据的过程,还要保证被裁剪的数据可用性。数据裁剪后所有上层业务需保证继续正常运行,包括已部署的合约业务和新部署的合约,都能正常调用,同时节点自身的退网、入网、同步、兼容性等各种特性都不受影响。被裁剪的数据虽然不在链上,但链上业务运行过程还是可能会用到,因此涉及到这部分数据的测试场景也需要全覆盖验证。
数据导入
在区块链系统中,当有新节点加入组网时,为了和其他节点保持同样状态,需要从其他节点同步数据,直到块高相同。这种同步方式需要考虑两方面的影响,一是在块高很大时,同步完所有数据需要耗费很长时间,另一方面节点从其他节点同步数据过程,也会影响系统性能。通过已导出的全量链上数据,来快速完成这部分同步工作,使新节点快速达到链上最新状态。用这种数据导入的方式能快速完成同步过程,而不对原组网产生影响。除了新入网节点,在遇到突发情况导致组网中节点数据丢失时,采用数据导入让节点快速同步数据。对数据导入特性的验证,重点是数据被导入后新节点功能的完整性,也就是网络中老节点具有的特性,新节点也完全一致,打包、执行交易、同步等功能都正常。
性能
作为一个底层平台,性能一个很关键的指标,它决定了上层应用在高峰期能跑多少的业务量。一个系统中每个接口,每个功能特性都会涉及到性能,但并非都需要压出其性能。对于区块链来说,重点关注的是它处理交易的性能,从客户端发起交易,签名,到节点打包、共识,最后数据落盘,这一完整过程系统的性能。
任何一个性能数据背后都对应着软件和硬件配置组合的结果,包括cpu、内存、磁盘、带宽等硬件条件,以及压测的合约类型、交易大小,节点组网模式等因素都会影响性能结果。理论上,代码自己没有逻辑错误,只要配置跟上,性能是可以无限的。但实际生产条件肯定有个上限,因此压测的性能数据可以提供两份,生产常用的硬件及软件配置条件下的,和实验室里高配的硬件和软件时的性能数据。
性能压测可以达到两个目的,一是压出系统的性能,还一个是通过压测发现代码的一些bug,比如cpu、内存等硬件没有发现瓶颈,但是性能确一直上不去,这可能就是代码实现的逻辑有问题了。在性能数据基础上,继续加大交易并发量,就能对系统做进行压力测试,验证其他指标。在性能数据基础上,适当减少交易并发量,也能对系统进行稳定性测试。
可靠性
区块链测试与传统的软件测试有较大区别,文章开头很大篇幅讨论了系统软件和应用软件的侧重点,底层系统软件更关注稳定性,而上层应用软件在于功能特性。因此,在区块链质量体系的构建过程中,可靠性是最重要的内容之一,需要投入大量的资源去模拟各种可能的场景,完成可靠性验证。
熟悉区块链之后会发现,它边界比较模糊。传统的软件,不管是是独立的应用程序,还是客户端/服务器模式的应用程序,都有明显的系统边界,可以通过UI用户界面或者客户端去进行测试。区块链底层,则是一个完全去中心化的分布式网络。这个网络有可能跨越多个子网、多个数据中心、多个运营商、甚至多个国家,其边界是模糊的。对于区块链底层的测试,不仅仅是前端API与某个区块链节点之间的测试,还涉及大量区块链节点与节点之间的测试。所以,如果只是单一的去做某个特性的测试,比如连接或者同步,同样条件,这次成功,下次可能就会失败,因为区块链是个分布式的系统软件,一个节点的正常不代表整个系统正常。
既然是一个分布式的软件,测试过程也需要融入分布式思想,而不能停留在中心化软件上。某个节点在同步,其他节点可能在共识,包括节点所在机器环境也可能随时发生变化,在场景模拟的过程,需要将软件、硬件以及区块链自身操作进行各种组合验证,称为混沌测试。常用的混沌测试工具有操作系统自带的iptables、tc、 wondershaper 等,可用于模拟机器间连接、端口是否可用、丢包、带宽控制,或者使用开源工具ChaosBlade也能完成以上模拟,包括cpu、内存等使用率。在结合前面章节讨论的节点连接、共识、同步等特性测试方法,进行各种混合测试。区块链的边界比较模糊,而混沌测试法正是通过模拟的方式,让系统尽可能运行在边界处,就比如PBFT共识算法,四节点的网络,让其中三个正常运行,剩下的一个节点进程停止,比同时让四个节点都正常跑着,进行场景模拟会更容易发现一些边界问题。所有场景模拟过程,可同时进行一些压力测试,保证时刻有交易在链上处理。
安全
任何产品在上线前都会考虑安全的问题,对软件来说安全威胁主要有人为主观因素和自然客观因素两种,为应对各种安全风险,有监管提前预防的措施,比如设置机器或者端口访问权限,或者通过拉专线进行联络等。还有的是通过技术手段来防范这些安全隐患,本章主要讨论采用相关的技术手段来保证区块链的安全。
区块链系统涉及的安全包括很多方面,从连接到共识、从算法到隐私保护,都和安全息息相关,安全措施覆盖的越全面,系统被攻击的概率越低,运行更稳健。区块链是由节点组成,而对于非法节点的加入,平台是否提供了证书网络准入机制或者黑白名单特性,解决非法连接和入网问题。链上大量的数据或者各种类型的表,需要提供权限管理机制给不同用户授予不同操作权限,包括部署合约及发送交易。
而对于加密算法,需要考虑能否支持国密算法,以及在隐私保护中,同态加密和群环签名是都具备。落盘数据能否进行加密,而不影响系统的正常运行,包括在多群组中,数据是否隔离等,以上都是作为一个区块链底层平台需要覆盖到的安全措施。
总结
以上从四个方面对区块链平台应具备的基本要素进行了简要讨论,但一个区块链系统涉及的内容远不止这些,每个功能特性都是作为区块链的一个重要标签。除了完成上面各种场景的测试验证,还应结合具体业务模型,在区块链上进行大量的实际应用批跑,只有经过长时间的运行,稳定性才能越来越高。