Skip to content

Commit 1b69313

Browse files
authored
refactor(e2e): extract shared test helpers to DockerTestSuite (#3017)
refactor(docker-e2e): extract shared test helpers to DockerTestSuite Extract common EVM test infrastructure to reusable helpers: - RethSetup struct and SetupRethNode() for Reth node setup - SetupCelestiaAndDABridge() returns DA address - WaitForEVMHealthy() for evmsingle health checks - SetupEthClient() creates and verifies eth client - WaitForTxIncluded() waits for transaction inclusion Refactor EVMSingleUpgradeTestSuite to use the shared helpers, reducing code duplication and enabling future test reuse.
1 parent 9c61f18 commit 1b69313

File tree

2 files changed

+135
-138
lines changed

2 files changed

+135
-138
lines changed

test/docker-e2e/docker_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,30 @@ package docker_e2e
55
import (
66
"context"
77
"fmt"
8+
"net"
9+
"net/http"
810
"os"
911
"strings"
1012
"testing"
13+
"time"
1114

1215
"cosmossdk.io/math"
1316
tastoradocker "github.com/celestiaorg/tastora/framework/docker"
1417
"github.com/celestiaorg/tastora/framework/docker/container"
1518
"github.com/celestiaorg/tastora/framework/docker/cosmos"
1619
da "github.com/celestiaorg/tastora/framework/docker/dataavailability"
1720
"github.com/celestiaorg/tastora/framework/docker/evstack"
21+
"github.com/celestiaorg/tastora/framework/docker/evstack/evmsingle"
22+
"github.com/celestiaorg/tastora/framework/docker/evstack/reth"
1823
"github.com/celestiaorg/tastora/framework/testutil/sdkacc"
1924
tastoratypes "github.com/celestiaorg/tastora/framework/types"
2025
sdk "github.com/cosmos/cosmos-sdk/types"
2126
"github.com/cosmos/cosmos-sdk/types/module/testutil"
2227
"github.com/cosmos/cosmos-sdk/x/auth"
2328
"github.com/cosmos/cosmos-sdk/x/bank"
2429
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
30+
"github.com/ethereum/go-ethereum/common"
31+
"github.com/ethereum/go-ethereum/ethclient"
2532
"github.com/stretchr/testify/suite"
2633
)
2734

@@ -243,3 +250,113 @@ func getEvNodeImage() container.Image {
243250

244251
return container.NewImage(repo, tag, "10001:10001")
245252
}
253+
254+
// RethSetup holds the configuration returned after setting up a Reth node.
255+
type RethSetup struct {
256+
Node *reth.Node
257+
EngineURL string // internal container-to-container URL
258+
EthURL string // internal container-to-container URL
259+
EthURLExternal string // host-accessible URL
260+
JWTSecret string
261+
GenesisHash string
262+
}
263+
264+
// SetupRethNode creates and starts a Reth node, waiting for it to be ready.
265+
func (s *DockerTestSuite) SetupRethNode(ctx context.Context) RethSetup {
266+
rethNode, err := reth.NewNodeBuilder(s.T()).
267+
WithGenesis([]byte(reth.DefaultEvolveGenesisJSON())).
268+
WithDockerClient(s.dockerClient).
269+
WithDockerNetworkID(s.dockerNetworkID).
270+
Build(ctx)
271+
s.Require().NoError(err)
272+
s.Require().NoError(rethNode.Start(ctx))
273+
274+
var setup RethSetup
275+
s.Require().Eventually(func() bool {
276+
networkInfo, err := rethNode.GetNetworkInfo(ctx)
277+
if err != nil {
278+
return false
279+
}
280+
conn, err := net.DialTimeout("tcp", net.JoinHostPort("0.0.0.0", networkInfo.External.Ports.RPC), time.Second)
281+
if err != nil {
282+
return false
283+
}
284+
conn.Close()
285+
setup.EngineURL = fmt.Sprintf("http://%s:%s", networkInfo.Internal.Hostname, networkInfo.Internal.Ports.Engine)
286+
setup.EthURL = fmt.Sprintf("http://%s:%s", networkInfo.Internal.Hostname, networkInfo.Internal.Ports.RPC)
287+
setup.EthURLExternal = fmt.Sprintf("http://0.0.0.0:%s", networkInfo.External.Ports.RPC)
288+
return true
289+
}, 60*time.Second, 2*time.Second, "reth did not start in time")
290+
291+
genesisHash, err := rethNode.GenesisHash(ctx)
292+
s.Require().NoError(err)
293+
294+
setup.Node = rethNode
295+
setup.JWTSecret = rethNode.JWTSecretHex()
296+
setup.GenesisHash = genesisHash
297+
return setup
298+
}
299+
300+
// SetupCelestiaAndDABridge starts Celestia chain and DA bridge, returns the DA address.
301+
func (s *DockerTestSuite) SetupCelestiaAndDABridge(ctx context.Context) string {
302+
s.celestia = s.CreateChain()
303+
s.Require().NoError(s.celestia.Start(ctx))
304+
305+
s.daNetwork = s.CreateDANetwork()
306+
bridgeNode := s.daNetwork.GetBridgeNodes()[0]
307+
308+
chainID := s.celestia.GetChainID()
309+
genesisHash := s.getGenesisHash(ctx)
310+
networkInfo, err := s.celestia.GetNodes()[0].GetNetworkInfo(ctx)
311+
s.Require().NoError(err)
312+
313+
s.StartBridgeNode(ctx, bridgeNode, chainID, genesisHash, networkInfo.Internal.Hostname)
314+
315+
daWallet, err := bridgeNode.GetWallet()
316+
s.Require().NoError(err)
317+
s.FundWallet(ctx, daWallet, 100_000_000_00)
318+
319+
bridgeNetworkInfo, err := bridgeNode.GetNetworkInfo(ctx)
320+
s.Require().NoError(err)
321+
return fmt.Sprintf("http://%s:%s", bridgeNetworkInfo.Internal.IP, bridgeNetworkInfo.Internal.Ports.RPC)
322+
}
323+
324+
// WaitForEVMHealthy waits for an evmsingle node to respond to health checks.
325+
func (s *DockerTestSuite) WaitForEVMHealthy(ctx context.Context, node *evmsingle.Node) {
326+
networkInfo, err := node.GetNetworkInfo(ctx)
327+
s.Require().NoError(err)
328+
329+
healthURL := fmt.Sprintf("http://0.0.0.0:%s/health/live", networkInfo.External.Ports.RPC)
330+
s.Require().Eventually(func() bool {
331+
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, healthURL, nil)
332+
resp, err := http.DefaultClient.Do(req)
333+
if err != nil {
334+
return false
335+
}
336+
defer resp.Body.Close()
337+
return resp.StatusCode == http.StatusOK
338+
}, 120*time.Second, 2*time.Second, "evm node did not become healthy")
339+
}
340+
341+
// SetupEthClient creates an Ethereum client and verifies connectivity.
342+
func (s *DockerTestSuite) SetupEthClient(ctx context.Context, url, expectedChainID string) *ethclient.Client {
343+
ethClient, err := ethclient.Dial(url)
344+
s.Require().NoError(err)
345+
346+
chainID, err := ethClient.ChainID(ctx)
347+
s.Require().NoError(err)
348+
s.Require().Equal(expectedChainID, chainID.String())
349+
350+
return ethClient
351+
}
352+
353+
// WaitForTxIncluded waits for a transaction to be included in a block successfully.
354+
func (s *DockerTestSuite) WaitForTxIncluded(ctx context.Context, client *ethclient.Client, txHash common.Hash) {
355+
s.Require().Eventually(func() bool {
356+
receipt, err := client.TransactionReceipt(ctx, txHash)
357+
if err != nil {
358+
return false
359+
}
360+
return receipt.Status == 1
361+
}, 30*time.Second, time.Second, "transaction %s was not included", txHash.Hex())
362+
}

0 commit comments

Comments
 (0)