在Java集成测试中运行Pantheon节点

尝试为Java以太坊应用程序编写集成测试时,您可能遇到的第一个问题是,您需要一个运行节点来连接以发送事务。解决此问题的一个选择是在后台手动运行节点,但如果要在CI管道中运行测试,并且迫使代码库的所有贡献者手动运行节点,这将变得难以管理。幸运的是,这是一个更好的方法

先决条件

使用Testcontainers运行节点

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

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

包括Testcontainers库

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


 org.testcontainers
 testcontainers
 1.12.0
 test

启动万神殿

在所有测试执行之前,而不是在每次测试之前,启动Pantheon一次更好,更高效。为了实现这种行为,我们实例化了一个GenericContainer带有@ClassRuleJUnit注释的静态注释。

在项目测试文件夹中创建一个新类,并将下面的代码添加到它:

ClassRule

@ClassRule
public 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会实例化a,并将docker镜像名称作为参数。我们在这个实例中使用了Pantheon的1.1.3版本,并且我们使用该withExposedPorts(..)方法公开HTTP和websocket RPC的标准默认端口。

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

  • --miner-enabled:启用挖矿,以便我们在测试中发送的事务包含在块中。
  • --miner-coinbase:将coinbase设置为您拥有私钥的帐户。启用挖矿时必须执行此操作。在这里,我们将帐户设置为众所周知的Pantheon开发帐户,在开发模式下自动加载以太坊。
  • --rpc-http-enabled:启用HTTP RPC端点,以便Web3j可以连接。
  • --rpc-ws-enabled:启用websocket RPC端点。如果您只测试HTTP,则不需要这样做。
  • --network=dev:将网络类型设置为dev。这将启动一个私有开发节点,具有预定义的配置,可以更轻松地挖矿CPU使用率。

有关所有可用Pantheon命令的完整列表,请阅读官方文档

等待万神殿开始

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

使用Web3j连接Pantheon容器

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

final Integer port = pantheonContainer.getMappedPort(8545);
Web3j web3j = Web3j.build(new HttpService(
 "http://localhost:" + port), 500, Async.defaultExecutorService());

Credentials credentials = Credentials.create("0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63");

映射端口

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

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

轮询间隔

默认情况下,Web3j每隔10秒轮询连接的以太坊客户端,以获取最新挖矿的块并检查是否已发出事件等操作。我们的Pantheon测试网络通常比每10秒创建块更快,因此减少Web3j中的轮询间隔应该会提高测试的速度。我们可以将轮询间隔传递给Web3j.build静态方法,在上面,我们将间隔配置为500ms。

测试凭证

在我们的私人开发网络中发送交易仍然需要天然气,因此我们必须能够访问具有正余额的帐户,并且开发网络的某些帐户预先加载了比您需要的更多的测试以太坊这里记录了这些帐户的私钥,这使得生成Credentials在测试中使用的对象变得容易。

停止万神殿/ Web3j

当我们使用@ClassRule注释时,停止Pantheon容器会在测试类执行结束时自动处理。最好在每次测试后关闭web3j实例:

@After
public void shutdownWeb3j() {
 web3j.shutdown();
}

摘要

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

您可以在java-web3j-pantheon-testing项目中找到一个示例测试类,演示本教程中GitHub中描述的代码

提示:投资有风险,入市需谨慎,本资讯不作为投资理财建议。请理性投资,切实提高风险防范意识;如有发现的违法犯罪线索,可积极向有关部门举报反映。
你可能还喜欢