前言
HyperBench 为区块链提供了一套通用的性能测试方案,能够适配多种不同的区块链平台,基于脚本和虚拟机可以灵活快速地构建区块链性能测试用例,秉承高效、灵活、可扩展的设计理念,为区块链性能测试标准化、易用化助力,促进区块链技术发展,更好地为区块链业务赋能。
本篇我们主要为大家介绍如何使用HyperBench去测试以太坊。
快速开始
【前置要求】
编译HyperBench需要go版本为1.11及以上版本,使用下方wget命令即可下载go官网安装包:
wget https://golang.google.cn/dl/go1.17.7.linux-amd64.tar.gz
下载完成后将压缩包解压至/usr/local/;
tar -zxvf go1.17.7.linux-amd64.tar.gz -C /usr/local
解压完成后 vim 打开/etc/profile 文件,添加go相关环境变量;
vim /etc/profile
export GOROOT=/usr/local/go
export GOPATH=/usr/local/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
添加完成后 使用source命令使变量配置生效;
source /etc/profile --使变量配置生效
go version --查看golang的版本
#使用go version命令查看go是否安装完成
go version go1.17.7 linux/amd64 --打印输出
完成go环境配置后,首先使用go env命令为go添加一个国内的代理,这里是为了使go在安装一些依赖时可以更快的安装完成;
go env -w GOPROXY=https://goproxy.cn,direct
在编译HyperBench之前需要使用go get命令安装packr二进制,packr会在编译HyperBench时使用到,所以需要提前安装好;
go get -u github.com/gobuffalo/packr/v2/packr2
【编译安装HyperBench】
环境准备完成,那么接下来为大家介绍HyperBench源代码的clone以及编译。
首先源码可以通过github中HyperBench开源项目库clone到本地,项目可以使用https://github.com/hyperbench 进入,项目中可以看到三个库,本次视频使用到的库为hyperbench、hyperbench-plugins,进入到HyperBench仓库,在code菜单中选择https,点击地址右侧复制按钮。
接下来开始clone与编译HyperBench:
#首先创建一个hyperbench的运行目录并进入到目录
mkdir /opt/hyperbench
cd /opt/hyperbench
#然后使用git命令将hyperbench源码clone到本地
#这边为了方便演示所有的源码都已经clone好了,所以就只展示下
git clone https://github.com/hyperbench/hyperbench.git
#clone完成后进入到hyperbench源码目录
cd hyperbench
#使用make build命令编译hyperbench
make build
#编译完成后使用help来查看编译是否成功
./hyperbench --help
#如果有输出hyperbench命令使用说明则代表编译成功
Usage:
hyperbench [command]
Examples:
hyperbench --doc ./doc (generate document to specify path)
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
init init a stress test dir
new initialize a test plan
start start a benchmark
version get code version
worker start as a worker server
Flags:
--debug enable debug mode
--doc string use to create doc and specify the doc path
-h, --help help for hyperbench
Use "hyperbench [command] --help" for more information about a command.
HyperBench主程序编译完成后,还需要编译HyperBench的区块链适配插件
#进入到前面所创建的hyperbench目录
cd /opt/hyperbench
#使用git命令将hyperbench-plugins源码clone本地
git clone https://github.com/hyperbench/hyperbench-plugins.git
#clone完成后进入到hyperbench-plugins目录
cd hyperbench-plugins
#目录中可以看到hyperbench所适配的各个区块链平台
#本次视频是介绍hyperbench对以太坊区块链平台的测试,所以进入以太坊目录
cd eth/
#进入目录后使用make build命令编译插件
make build
#编译完成后可以在当前目录看到eth.so文件
#需要将eth.so文件copy到hyperbench主程序所在的目录
cp eth.so ../../hyperbench/eth.so
【编译安装并配置启动geth】
HyperBench主程序与插件编译完成后,我们还需要搭建一条以太坊私有链以作测试:
#首先创建一个geth目录
mkdir /opt/geth/
#进入目录
cd /opt/geth/
#进入到github上以太坊项目库
#使用git命令clone 以太坊源码
git clone https://github.com/ethereum/go-ethereum.git
#clone完成后进入源码目录
cd ethereum
#使用make命令编译geth主程序
make geth
#进入到build/bin/目录就能看到geth主程序
cd ./build/bin/
#使用./geth version查看编译是否成功
./geth version
#成功输出了版本信息则代表编译成功
#然后将geth文件copy到/usr/local/bin/目录,这样就可以在任何目录下执行geth命令
cp ./geth /usr/local/bin/
接下来需要创建geth初始化文件,本次教程重点在HyperBench,所以就不详细介绍geth的配置了。
初始化文件中需要注意的是alloc配置项,此配置项是以太坊区块链私链的创世账户,如果初始化时没有创建创世账户并且分配一定的原生币,那在后续测试中的转账交易就无法完成转账。
如果自己在测试中没有创世账户的话,可以使用本次教程提供的账户:
vim genesis.json
{
"config": {
"chainId": 777,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x2540be400",
"difficulty": "0x00002",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0x4e5786bf8546e60ca38aa68eb8dc82b1b24d26f3": {
"balance": "100000000000000000000000000000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
创建geth数据目录,并初始化目录
mkdir /opt/geth1/
#执行初始化命令
./geth --datadir /opt/geth1/ init ./genesis.json
#执行返回如下则为成功
INFO [10-18|10:41:55.859] Maximum peer count ETH=50 LES=0 total=50
INFO [10-18|10:41:55.860] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [10-18|10:41:55.864] Set global gas cap cap=50,000,000
INFO [10-18|10:41:55.865] Allocated cache and file handles database=/opt/geth1/geth/chaindata cache=16.00MiB handles=16
INFO [10-18|10:41:56.236] Opened ancient database database=/opt/geth1/geth/chaindata/ancient/chain readonly=false
INFO [10-18|10:41:56.236] Writing custom genesis block
INFO [10-18|10:41:56.238] Persisted trie from memory database nodes=1 size=153.00B time="171.63µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [10-18|10:41:56.239] Successfully wrote genesis state database=chaindata hash=ced4ca..c9a1f8
INFO [10-18|10:41:56.239] Allocated cache and file handles database=/opt/geth1/geth/lightchaindata cache=16.00MiB handles=16
INFO [10-18|10:41:56.513] Opened ancient database database=/opt/geth1/geth/lightchaindata/ancient/chain readonly=false
INFO [10-18|10:41:56.513] Writing custom genesis block
INFO [10-18|10:41:56.514] Persisted trie from memory database nodes=1 size=153.00B time="91.645µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [10-18|10:41:56.515] Successfully wrote genesis state
初始化完成后,在/opt/geth1/keystore/目录下新增文件
这个文件是在genesis.sjon配置中的创世账户的私钥,默认分配了余额
vim UTC--2022-10-17T08-41-53.685200708Z--4e5786bf8546e60ca38aa68eb8dc82b1b24d26f3
#文件内容
{"address":"4e5786bf8546e60ca38aa68eb8dc82b1b24d26f3","crypto":{"cipher":"aes-128-ctr","ciphertext":"f26e27f300b7ba46e968f8c656e534cbb706a15c825eb351d2ba4690d1b6bf26","cipherparams":{"iv":"bbb9f922fc48bcb2c1fb566453f328d8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f0ffc7fa97c82b94c2fcea53127ea3b8d5110c020830089283173e9d998cb8d9"},"mac":"2b6bdb9ae958ff55516ac313f4b68d5a8c66df018103903d1348a7158fe1fd2c"},"id":"654e1fa7-9c06-4643-bc3d-26b6186ff2cf","version":3}
启动geth
#使用geth命令启动以太坊私链vim sc
nohup geth --datadir "/opt/geth1/" --http --http.addr=0.0.0.0 --http.port 8545 --authrpc.port 8552 --http.corsdomain "*" --http.api "eth,net,web3,personal,admin,txpool,debug,miner" --nodiscover --maxpeers 30 --networkid 1981 --port 30303 --allow-insecure-unlock 2>> /opt/geth1/geth.log &
#启动命令中需要注意的是 --http.port 后续再hyperbench配置中会使用到
#启动命令中需要注意的是 --http.port 后续再hyperbench配置中会使用到
#进入geth数据目录
cd /opt/geth1/
#使用命令进入geth控制台
geth attach ./geth.ipc
#执行eth.acccounts查看当前链上账户
>eth.accounts
["4e5786bf8546e60ca38aa68eb8dc82b1b24d26f3"]
#如正确输出账户地址则代表启动成功
确认启动成功后,需要新增一个账户
#新增账户时为了方便测试,需要创建没有密码的账户
personal.newAccount("")
至此我们已经完成了以太坊私链的配置,结下来仅需配置HyperBench测试脚本启动我们的测试,详细完整的操作可在 ↓演示视频↓ 中进行学习!
https://v.qq.com/x/page/g3364pal2qb.html
【License】
HyperBench目前使用Apache 2.0许可证。具体请参见 github LICENSE文件👇
✨ 开源小贴士 ✨
对HyperBench感兴趣的小伙伴,可添加微信小助手18458407117,进入技术交流群讨论.
HyperBench github
https://github.com/hyperbench/hyperbench
HyperBench quickstart
https://github.com/hyperbench/hyperbench/blob/master/README.md
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element