使用Java集成测试Pantheon运行节点情况

区块链研究实验室 view 91 2020-8-12 21:20
share to
Scan QR code with WeChat

使用Java集成测试Pantheon运行节点情况

尝试为Java Ethereum应用程序编写集成测试时,您可能遇到的第一个问题是您需要一个运行中的节点来连接以发送事务。解决此问题的一种方法是在后台手动运行节点,但是如果要在CI管道中运行测试,则很难管理,并且强制所有代码库的参与者都手动运行节点不是理想的选择。幸运的是,有更好的方法!

环境准备

运行中的Docker守护程序

对Junit的理解

要测试的代码。https://github.com/kauri-io/java-web3j-pantheon-testing/blob/4814ff2c81d5e1141671b4d1f0680e901bc72051/src/test/java/io/kauri/java/test/TestWeb3jPantheon.java#L63

使用Testcontainers运行节点

Testcontainers是一个有用的库,可让您以编程方式在测试代码中启动Docker容器,并且有多个以太坊客户端将现成的Docker容器上载到Dockerhub,这使此任务更加容易。

在本指南中,我将介绍如何在集成测试期间启动和关闭Pantheon节点,因此您不必手动或在CI管道内启动节点

添加Testcontainers库

我们通过maven Central获得Testcontainers库的依赖关系,因此要包含该库,请将以下依赖关系添加到pom.xml(或Gradle中的等效项)中:

org.testcontainerstestcontainers1.12.0test

启动Pantheon

最好在执行所有测试之前而不是在每次测试之前启动Pantheon,这样才能更好,性能更高。为了实现此行为,我们实例化了一个带有@ClassRule JUnit批注的静态GenericContainer。

在项目测试文件夹中创建一个new class,并将以下代码添加到其中:

ClassRule

@ClassRulepublic static final GenericContainer pantheonContainer = new GenericContainer("pegasyseng/pantheon:1.1.3") .withExposedPorts(8545, 8546) .withCommand( "--miner-enabled", "--miner-coinbase=0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", "--rpc-http-enabled", "--rpc-ws-enabled", "--network=dev") .waitingFor(Wait.forHttp("/liveness").forStatusCode(200).forPort(8545));

在运行任何测试之前,将实例化GenericContainer,并以docker映像名称作为参数。在这种情况下,我们使用的是Pantheon的1.1.3版本,并通过withExposedPorts(..)方法公开了HTTP和websocket RPC的标准默认端口。

我们设置一些运runtime令参数,这些参数以适合测试以下内容的方式配置节点:

miner-enabled:启用挖掘,以便我们在测试中发送的交易包含在块中。

miner-coinbase:将coinbase设置为您具有私钥的帐户。启用挖掘时,这是必需的。在这里,我们将帐户设置为众所周知的Pantheon开发帐户,在开发模式下该帐户会自动随Ether加载。

rpc-http-enabled:启用HTTP RPC端点,以便Web3j可以连接。

rpc-ws-enabled:启用websocket RPC端点。如果仅测试HTTP,则不需要这样做。

network = dev:将网络类型设置为dev。这将启动具有预定义配置的私有开发节点,以简化CPU使用率的挖掘。

等待Pantheon启动

在运行测试之前,我们必须等待Pantheon启动。Pantheon具有自动配置的活动性端点,因此testcontainers会自动轮询端口8545上的/liveness端点,直到它返回200响应为止。然后我们可以确信Pantheon正在运行。

使用Web3j连接到Pantheon容器

Pantheon现在应该已启动并在localhost上运行。现在您可以连接到测试类中的Pantheon节点,并执行以太坊操作,例如使用Web3j发送事务:

private Web3j web3j;private Credentials credentials =  Credentials.create("0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63"); @Beforepublic void initWeb3() { final Integer port = pantheonContainer.getMappedPort(8545); web3j = Web3j.build(new HttpService( "http://localhost:" + port), 500, Async.defaultExecutorService());}

映射端口

创建容器时,我们公开了默认的JSON RPC端口8545,但未将其映射到localhost上的同一端口。而是自动选择一个随机可用的端口,这很有用,因为它消除了端口在测试计算机上未打开的可能性(例如如果您并行运行测试,则可能会发生这种情况)。

要获取映射的端口号,请在容器上调用getMappedPort(..)方法。构造Web3j连接URL时,可以使用这些端口。

轮询间隔

默认情况下,Web3j每10秒钟对连接的以太坊客户端进行一次轮询,以获取诸如获取最新的挖出的区块以及检查是否已发出事件之类的操作。我们的Pantheon测试网络通常比每10秒要快得多,因此,缩短Web3j中的轮询间隔应该可以提高测试速度。我们可以将轮询间隔传递给Web3j.build静态方法,而在上面,我们将间隔配置为500ms。

测试证书

在我们的私有dev网络中发送事务仍然需要gas,因此我们必须能够访问一个余额为正的帐户,并且开发网络中有一些帐户预加载了比您所需要的更多的test Ether!这里记录了这些帐户的私钥,这使得生成Credentials对象以在测试中使用变得容易。

Pantheon/Web3j

由于我们使用@ClassRule批注,因此在测试类执行结束时会自动处理停止Pantheon容器的操作。不过,在每次测试后关闭web3j实例是一个好主意:

@Afterpublic void shutdownWeb3j() { web3j.shutdown();}

总结

使用Testcontainers库启动Pantheon节点是确保测试可以访问以太坊节点的便捷方法。这使得在您的持续集成通道中运行测试变得很轻松,也意味着其他第三方贡献者可以更轻松地在本地计算机上运行您的测试。

btcfans公众号

Scan QR code with WeChat

Link
Disclaimer:

Tags: Java Pantheon
Previous: 使用Google Data Studio创建以太坊DeFi实时仪表板 Next: Cortex链上的 “Hello World”AI DApp编写,编译,部署和执行

Related