Skip to content

Commit 938e6d2

Browse files
committed
chore: refactor test setup to allow for injection of docker client
1 parent aa1af66 commit 938e6d2

10 files changed

+230
-187
lines changed

execution/evm/test/execution_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88
"time"
99

10+
tastoradocker "github.com/celestiaorg/tastora/framework/docker"
1011
"github.com/ethereum/go-ethereum/common"
1112
ethTypes "github.com/ethereum/go-ethereum/core/types"
1213
"github.com/ethereum/go-ethereum/ethclient"
@@ -59,8 +60,10 @@ func TestEngineExecution(t *testing.T) {
5960
genesisStateRoot := common.HexToHash(GENESIS_STATEROOT)
6061
GenesisStateRoot := genesisStateRoot[:]
6162

63+
dockerClient, dockerNetworkID := tastoradocker.Setup(t)
64+
6265
t.Run("Build chain", func(tt *testing.T) {
63-
rethNode := SetupTestRethNode(t)
66+
rethNode := SetupTestRethNode(t, dockerClient, dockerNetworkID)
6467

6568
ni, err := rethNode.GetNetworkInfo(context.TODO())
6669
require.NoError(tt, err)
@@ -158,7 +161,7 @@ func TestEngineExecution(t *testing.T) {
158161

159162
// start new container and try to sync
160163
t.Run("Sync chain", func(tt *testing.T) {
161-
rethNode := SetupTestRethNode(t)
164+
rethNode := SetupTestRethNode(t, dockerClient, dockerNetworkID)
162165

163166
ni, err := rethNode.GetNetworkInfo(context.TODO())
164167
require.NoError(tt, err)

execution/evm/test/test_helpers.go

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ import (
99
mathrand "math/rand"
1010
"net/http"
1111
"strings"
12-
"sync"
1312
"testing"
1413
"time"
1514

16-
"github.com/celestiaorg/tastora/framework/docker"
1715
"github.com/celestiaorg/tastora/framework/docker/evstack/reth"
1816
"github.com/celestiaorg/tastora/framework/types"
1917
"github.com/golang-jwt/jwt/v5"
@@ -22,12 +20,10 @@ import (
2220
"go.uber.org/zap/zaptest"
2321
)
2422

25-
// Test-scoped Docker client/network mapping to avoid conflicts between tests
26-
var (
27-
dockerClients = make(map[string]types.TastoraDockerClient)
28-
dockerNetworks = make(map[string]string)
29-
dockerMutex sync.RWMutex
30-
)
23+
// (Docker client/network are now provided by callers)
24+
25+
// RethNodeOpt allows tests to customize the reth node builder before building.
26+
type RethNodeOpt func(b *reth.NodeBuilder)
3127

3228
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
3329

@@ -40,47 +36,32 @@ func randomString(n int) string {
4036
return string(b)
4137
}
4238

43-
// getTestScopedDockerSetup returns a Docker client and network ID that are scoped to the specific test.
44-
func getTestScopedDockerSetup(t testing.TB) (types.TastoraDockerClient, string) {
45-
t.Helper()
46-
47-
testKey := t.Name()
48-
dockerMutex.Lock()
49-
defer dockerMutex.Unlock()
50-
51-
dockerCli, exists := dockerClients[testKey]
52-
if !exists {
53-
cli, netID := docker.Setup(t)
54-
dockerClients[testKey] = cli
55-
dockerNetworks[testKey] = netID
56-
dockerCli = cli
57-
}
58-
dockerNetID := dockerNetworks[testKey]
59-
60-
return dockerCli, dockerNetID
61-
}
62-
6339
// SetupTestRethNode creates a single Reth node for testing purposes.
64-
func SetupTestRethNode(t testing.TB) *reth.Node {
40+
func SetupTestRethNode(t testing.TB, client types.TastoraDockerClient, networkID string, opts ...RethNodeOpt) *reth.Node {
6541
t.Helper()
6642
ctx := context.Background()
6743

68-
dockerCli, dockerNetID := getTestScopedDockerSetup(t)
69-
7044
testName := fmt.Sprintf("%s-%s", t.Name(), randomString(6))
7145
logger := zap.NewNop()
7246
if testing.Verbose() {
7347
logger = zaptest.NewLogger(t)
7448
}
75-
n, err := new(reth.NodeBuilder).
49+
b := new(reth.NodeBuilder).
7650
WithTestName(testName).
7751
WithLogger(logger).
7852
WithImage(reth.DefaultImage()).
7953
WithBin("ev-reth").
80-
WithDockerClient(dockerCli).
81-
WithDockerNetworkID(dockerNetID).
82-
WithGenesis([]byte(reth.DefaultEvolveGenesisJSON())).
83-
Build(ctx)
54+
WithDockerClient(client).
55+
WithDockerNetworkID(networkID).
56+
WithGenesis([]byte(reth.DefaultEvolveGenesisJSON()))
57+
58+
for _, opt := range opts {
59+
if opt != nil {
60+
opt(b)
61+
}
62+
}
63+
64+
n, err := b.Build(ctx)
8465
t.Cleanup(func() {
8566
_ = n.Remove(context.Background())
8667
})

test/e2e/evm_contract_e2e_test.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
package e2e
44

55
import (
6-
"context"
7-
"crypto/ecdsa"
8-
"math/big"
9-
"path/filepath"
10-
"testing"
11-
"time"
12-
13-
"github.com/ethereum/go-ethereum"
14-
"github.com/ethereum/go-ethereum/common"
6+
"context"
7+
"crypto/ecdsa"
8+
"math/big"
9+
"path/filepath"
10+
"testing"
11+
"time"
12+
13+
tastoradocker "github.com/celestiaorg/tastora/framework/docker"
14+
"github.com/ethereum/go-ethereum"
15+
"github.com/ethereum/go-ethereum/common"
1516
"github.com/ethereum/go-ethereum/common/hexutil"
1617
"github.com/ethereum/go-ethereum/core/types"
1718
"github.com/ethereum/go-ethereum/crypto"
@@ -49,7 +50,7 @@ func TestEvmContractDeploymentAndInteraction(t *testing.T) {
4950
workDir := t.TempDir()
5051
sequencerHome := filepath.Join(workDir, "evm-sequencer")
5152

52-
client, _, cleanup := setupTestSequencer(t, sequencerHome)
53+
client, _, cleanup := setupTestSequencer(t, sequencerHome)
5354
defer cleanup()
5455

5556
ctx := t.Context()
@@ -241,9 +242,10 @@ func TestEvmContractEvents(t *testing.T) {
241242
// setupTestSequencer sets up a single sequencer node for testing.
242243
// Returns the ethclient, genesis hash, and a cleanup function.
243244
func setupTestSequencer(t testing.TB, homeDir string, extraArgs ...string) (*ethclient.Client, string, func()) {
244-
sut := NewSystemUnderTest(t)
245+
sut := NewSystemUnderTest(t)
245246

246-
genesisHash, seqEthURL := setupSequencerOnlyTest(t, sut, homeDir, extraArgs...)
247+
dcli, netID := tastoradocker.Setup(t)
248+
genesisHash, seqEthURL := setupSequencerOnlyTest(t, sut, homeDir, dcli, netID, extraArgs...)
247249
t.Logf("Sequencer started at %s (Genesis: %s)", seqEthURL, genesisHash)
248250

249251
client, err := ethclient.Dial(seqEthURL)

test/e2e/evm_da_restart_e2e_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"testing"
2525
"time"
2626

27+
tastoradocker "github.com/celestiaorg/tastora/framework/docker"
2728
"github.com/ethereum/go-ethereum/common"
2829
"github.com/ethereum/go-ethereum/ethclient"
2930
"github.com/stretchr/testify/require"
@@ -56,7 +57,8 @@ func TestEvmDARestartWithPendingBlocksE2E(t *testing.T) {
5657
sut := NewSystemUnderTest(t)
5758

5859
// Setup sequencer and get genesis hash
59-
genesisHash, seqURL := setupSequencerOnlyTest(t, sut, nodeHome)
60+
dcli, netID := tastoradocker.Setup(t)
61+
genesisHash, seqURL := setupSequencerOnlyTest(t, sut, nodeHome, dcli, netID)
6062
t.Logf("Genesis hash: %s", genesisHash)
6163

6264
// Connect to EVM

test/e2e/evm_force_inclusion_e2e_test.go

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"testing"
1414
"time"
1515

16+
tastoradocker "github.com/celestiaorg/tastora/framework/docker"
1617
"github.com/ethereum/go-ethereum/common"
1718
"github.com/ethereum/go-ethereum/ethclient"
1819
"github.com/rs/zerolog"
@@ -77,13 +78,15 @@ func setupSequencerWithForceInclusion(t *testing.T, sut *SystemUnderTest, nodeHo
7778
t.Helper()
7879

7980
// Use common setup (no full node needed initially)
80-
jwtSecret, _, genesisHash, endpoints, _ := setupCommonEVMTest(t, sut, false)
81+
dcli, netID := tastoradocker.Setup(t)
82+
env := setupCommonEVMEnv(t, sut, dcli, netID)
83+
// Use env fields inline below to reduce local vars
8184

8285
// Create passphrase file
8386
passphraseFile := createPassphraseFile(t, nodeHome)
8487

8588
// Create JWT secret file
86-
jwtSecretFile := createJWTSecretFile(t, nodeHome, jwtSecret)
89+
jwtSecretFile := createJWTSecretFile(t, nodeHome, env.SequencerJWT)
8790

8891
// Initialize sequencer node
8992
output, err := sut.RunCmd(evmSingleBinaryPath,
@@ -102,25 +105,25 @@ func setupSequencerWithForceInclusion(t *testing.T, sut *SystemUnderTest, nodeHo
102105
args := []string{
103106
"start",
104107
"--evm.jwt-secret-file", jwtSecretFile,
105-
"--evm.genesis-hash", genesisHash,
108+
"--evm.genesis-hash", env.GenesisHash,
106109
"--evnode.node.block_time", DefaultBlockTime,
107110
"--evnode.node.aggregator=true",
108111
"--evnode.signer.passphrase_file", passphraseFile,
109112
"--home", nodeHome,
110113
"--evnode.da.block_time", DefaultDABlockTime,
111-
"--evnode.da.address", endpoints.GetDAAddress(),
114+
"--evnode.da.address", env.Endpoints.GetDAAddress(),
112115
"--evnode.da.namespace", DefaultDANamespace,
113116
"--evnode.da.forced_inclusion_namespace", "forced-inc",
114-
"--evnode.rpc.address", endpoints.GetRollkitRPCListen(),
115-
"--evnode.p2p.listen_address", endpoints.GetRollkitP2PAddress(),
116-
"--evm.engine-url", endpoints.GetSequencerEngineURL(),
117-
"--evm.eth-url", endpoints.GetSequencerEthURL(),
117+
"--evnode.rpc.address", env.Endpoints.GetRollkitRPCListen(),
118+
"--evnode.p2p.listen_address", env.Endpoints.GetRollkitP2PAddress(),
119+
"--evm.engine-url", env.Endpoints.GetSequencerEngineURL(),
120+
"--evm.eth-url", env.Endpoints.GetSequencerEthURL(),
118121
"--force-inclusion-server", fiAddr,
119122
}
120123
sut.ExecCmd(evmSingleBinaryPath, args...)
121-
sut.AwaitNodeUp(t, endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
124+
sut.AwaitNodeUp(t, env.Endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
122125

123-
return genesisHash, endpoints.GetSequencerEthURL()
126+
return env.GenesisHash, env.Endpoints.GetSequencerEthURL()
124127
}
125128

126129
func TestEvmSequencerForceInclusionE2E(t *testing.T) {
@@ -192,10 +195,11 @@ func TestEvmFullNodeForceInclusionE2E(t *testing.T) {
192195
// --- Start Sequencer Setup ---
193196
// We manually setup sequencer here because we need the force inclusion flag,
194197
// and we need to capture variables for full node setup.
195-
jwtSecret, fullNodeJwtSecret, genesisHash, endpoints, _ := setupCommonEVMTest(t, sut, true)
198+
dcli2, netID2 := tastoradocker.Setup(t)
199+
env := setupCommonEVMEnv(t, sut, dcli2, netID2, WithFullNode())
196200

197201
passphraseFile := createPassphraseFile(t, sequencerHome)
198-
jwtSecretFile := createJWTSecretFile(t, sequencerHome, jwtSecret)
202+
jwtSecretFile := createJWTSecretFile(t, sequencerHome, env.SequencerJWT)
199203

200204
output, err := sut.RunCmd(evmSingleBinaryPath,
201205
"init",
@@ -212,38 +216,38 @@ func TestEvmFullNodeForceInclusionE2E(t *testing.T) {
212216
seqArgs := []string{
213217
"start",
214218
"--evm.jwt-secret-file", jwtSecretFile,
215-
"--evm.genesis-hash", genesisHash,
219+
"--evm.genesis-hash", env.GenesisHash,
216220
"--evnode.node.block_time", DefaultBlockTime,
217221
"--evnode.node.aggregator=true",
218222
"--evnode.signer.passphrase_file", passphraseFile,
219223
"--home", sequencerHome,
220224
"--evnode.da.block_time", DefaultDABlockTime,
221-
"--evnode.da.address", endpoints.GetDAAddress(),
225+
"--evnode.da.address", env.Endpoints.GetDAAddress(),
222226
"--evnode.da.namespace", DefaultDANamespace,
223227
"--evnode.da.forced_inclusion_namespace", "forced-inc",
224-
"--evnode.rpc.address", endpoints.GetRollkitRPCListen(),
225-
"--evnode.p2p.listen_address", endpoints.GetRollkitP2PAddress(),
226-
"--evm.engine-url", endpoints.GetSequencerEngineURL(),
227-
"--evm.eth-url", endpoints.GetSequencerEthURL(),
228+
"--evnode.rpc.address", env.Endpoints.GetRollkitRPCListen(),
229+
"--evnode.p2p.listen_address", env.Endpoints.GetRollkitP2PAddress(),
230+
"--evm.engine-url", env.Endpoints.GetSequencerEngineURL(),
231+
"--evm.eth-url", env.Endpoints.GetSequencerEthURL(),
228232
"--force-inclusion-server", fiAddr,
229233
}
230234
sut.ExecCmd(evmSingleBinaryPath, seqArgs...)
231-
sut.AwaitNodeUp(t, endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
235+
sut.AwaitNodeUp(t, env.Endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
232236
t.Log("Sequencer is up with force inclusion enabled")
233237
// --- End Sequencer Setup ---
234238

235239
// --- Start Full Node Setup ---
236240
// Reuse setupFullNode helper which handles genesis copying and node startup
237-
setupFullNode(t, sut, fullNodeHome, sequencerHome, fullNodeJwtSecret, genesisHash, endpoints.GetRollkitP2PAddress(), endpoints)
241+
setupFullNode(t, sut, fullNodeHome, sequencerHome, env.FullNodeJWT, env.GenesisHash, env.Endpoints.GetRollkitP2PAddress(), env.Endpoints)
238242
t.Log("Full node is up")
239243
// --- End Full Node Setup ---
240244

241245
// Connect to clients
242-
seqClient, err := ethclient.Dial(endpoints.GetSequencerEthURL())
246+
seqClient, err := ethclient.Dial(env.Endpoints.GetSequencerEthURL())
243247
require.NoError(t, err)
244248
defer seqClient.Close()
245249

246-
fnClient, err := ethclient.Dial(endpoints.GetFullNodeEthURL())
250+
fnClient, err := ethclient.Dial(env.Endpoints.GetFullNodeEthURL())
247251
require.NoError(t, err)
248252
defer fnClient.Close()
249253

@@ -284,10 +288,11 @@ func setupMaliciousSequencer(t *testing.T, sut *SystemUnderTest, nodeHome string
284288
t.Helper()
285289

286290
// Use common setup with full node support
287-
jwtSecret, fullNodeJwtSecret, genesisHash, endpoints, _ := setupCommonEVMTest(t, sut, true)
291+
env := setupCommonEVMEnv(t, sut, WithFullNode())
292+
// Use env fields inline below to reduce local vars
288293

289294
passphraseFile := createPassphraseFile(t, nodeHome)
290-
jwtSecretFile := createJWTSecretFile(t, nodeHome, jwtSecret)
295+
jwtSecretFile := createJWTSecretFile(t, nodeHome, env.SequencerJWT)
291296

292297
output, err := sut.RunCmd(evmSingleBinaryPath,
293298
"init",
@@ -303,25 +308,25 @@ func setupMaliciousSequencer(t *testing.T, sut *SystemUnderTest, nodeHome string
303308
seqArgs := []string{
304309
"start",
305310
"--evm.jwt-secret-file", jwtSecretFile,
306-
"--evm.genesis-hash", genesisHash,
311+
"--evm.genesis-hash", env.GenesisHash,
307312
"--evnode.node.block_time", DefaultBlockTime,
308313
"--evnode.node.aggregator=true",
309314
"--evnode.signer.passphrase_file", passphraseFile,
310315
"--home", nodeHome,
311316
"--evnode.da.block_time", DefaultDABlockTime,
312-
"--evnode.da.address", endpoints.GetDAAddress(),
317+
"--evnode.da.address", env.Endpoints.GetDAAddress(),
313318
"--evnode.da.namespace", DefaultDANamespace,
314319
// CRITICAL: Set sequencer to listen to WRONG namespace - it won't see forced txs
315320
"--evnode.da.forced_inclusion_namespace", "wrong-namespace",
316-
"--evnode.rpc.address", endpoints.GetRollkitRPCListen(),
317-
"--evnode.p2p.listen_address", endpoints.GetRollkitP2PAddress(),
318-
"--evm.engine-url", endpoints.GetSequencerEngineURL(),
319-
"--evm.eth-url", endpoints.GetSequencerEthURL(),
321+
"--evnode.rpc.address", env.Endpoints.GetRollkitRPCListen(),
322+
"--evnode.p2p.listen_address", env.Endpoints.GetRollkitP2PAddress(),
323+
"--evm.engine-url", env.Endpoints.GetSequencerEngineURL(),
324+
"--evm.eth-url", env.Endpoints.GetSequencerEthURL(),
320325
}
321326
sut.ExecCmd(evmSingleBinaryPath, seqArgs...)
322-
sut.AwaitNodeUp(t, endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
327+
sut.AwaitNodeUp(t, env.Endpoints.GetRollkitRPCAddress(), NodeStartupTimeout)
323328

324-
return genesisHash, fullNodeJwtSecret, endpoints
329+
return env.GenesisHash, env.FullNodeJWT, env.Endpoints
325330
}
326331

327332
// setupFullNodeWithForceInclusionCheck sets up a full node that WILL verify forced inclusion txs

0 commit comments

Comments
 (0)