Skip to content

Commit 1b7b9dd

Browse files
committed
WIP Migrate duplicate test e2e from avalanche-testing
1 parent 99e5aa5 commit 1b7b9dd

File tree

3 files changed

+102
-18
lines changed

3 files changed

+102
-18
lines changed

tests/e2e/e2e.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ func (te *TestEnvironment) Setup(
9999
return err
100100
}
101101

102+
// Need to always configure avalanchego. Even if using a
103+
// persistent network, avalanchego is required for operations like
104+
// node addition.
105+
if avalancheGoExecPath != "" {
106+
if _, err := os.Stat(avalancheGoExecPath); err != nil {
107+
return fmt.Errorf("could not find avalanchego binary: %w", err)
108+
}
109+
}
110+
te.avalancheGoExecPath = avalancheGoExecPath
111+
te.avalancheGoLogLevel = avalancheGoLogLevel
112+
102113
// TODO(marun) Maybe lazy-load so that errors only fail dependent tests?
103114
err = te.LoadKeys(testKeysFile)
104115
if err != nil {
@@ -111,25 +122,13 @@ func (te *TestEnvironment) Setup(
111122
tests.Outf("{{yellow}}Using a pre-existing network{{/}}\n")
112123

113124
// Read the URIs for the existing network so that tests can access the nodes.
114-
115125
err = te.refreshURIs()
116126
if err != nil {
117127
return err
118128
}
119129
} else {
120130
te.clusterType = StandAlone
121131

122-
// Create a new network
123-
124-
if avalancheGoExecPath != "" {
125-
if _, err := os.Stat(avalancheGoExecPath); err != nil {
126-
return fmt.Errorf("could not find avalanchego binary: %w", err)
127-
}
128-
}
129-
130-
te.avalancheGoExecPath = avalancheGoExecPath
131-
te.avalancheGoLogLevel = avalancheGoLogLevel
132-
133132
err := te.startCluster()
134133
if err != nil {
135134
return err
@@ -221,21 +220,30 @@ func (te *TestEnvironment) startCluster() error {
221220

222221
tests.Outf("{{green}}successfully started network: {{/}} %+v\n", resp.ClusterInfo.NodeNames)
223222

224-
ctx, cancel = context.WithTimeout(context.Background(), 2*time.Minute)
225-
_, err = te.GetRunnerClient().Health(ctx)
226-
cancel()
223+
err = te.CheckHealth()
227224
if err != nil {
228-
return fmt.Errorf("could not check network health: %w", err)
225+
return err
229226
}
230227

231-
tests.Outf("{{green}}network reporting health{{/}}\n")
232-
233228
te.isNetworkPristine = true
234229

235230
err = te.refreshURIs()
236231
return err
237232
}
238233

234+
func (te *TestEnvironment) CheckHealth() error {
235+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
236+
_, err := te.GetRunnerClient().Health(ctx)
237+
cancel()
238+
if err != nil {
239+
return fmt.Errorf("could not check network health: %w", err)
240+
}
241+
242+
tests.Outf("{{green}}network reporting health{{/}}\n")
243+
244+
return nil
245+
}
246+
239247
func (te *TestEnvironment) refreshURIs() error {
240248
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
241249
uriSlice, err := te.GetRunnerClient().URIs(ctx)
@@ -365,3 +373,16 @@ func (te *TestEnvironment) Teardown() error {
365373
tests.Outf("{{red}}shutting down network-runner client{{/}}\n")
366374
return te.closeRunnerClient()
367375
}
376+
377+
func (te *TestEnvironment) AddNode(name string, opts ...runner_sdk.OpOption) error {
378+
ctx, cancel := context.WithTimeout(context.Background(), DefaultShutdownTimeout)
379+
_, err := te.GetRunnerClient().AddNode(ctx, name, te.avalancheGoExecPath, opts...)
380+
cancel()
381+
if err != nil {
382+
return err
383+
}
384+
385+
tests.Outf("{{green}}added node %s{{/}}\n", name)
386+
387+
return nil
388+
}

tests/e2e/e2e_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
// ensure test packages are scanned by ginkgo
1717
_ "github.com/ava-labs/avalanchego/tests/e2e/banff"
18+
_ "github.com/ava-labs/avalanchego/tests/e2e/faultinjection"
1819
_ "github.com/ava-labs/avalanchego/tests/e2e/p"
1920
_ "github.com/ava-labs/avalanchego/tests/e2e/ping"
2021
_ "github.com/ava-labs/avalanchego/tests/e2e/static-handlers"
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package faultinjection
5+
6+
import (
7+
"fmt"
8+
"math/rand"
9+
"strings"
10+
11+
ginkgo "github.com/onsi/ginkgo/v2"
12+
"github.com/stretchr/testify/require"
13+
14+
runner_sdk "github.com/ava-labs/avalanche-network-runner-sdk"
15+
16+
"github.com/ava-labs/avalanchego/staking"
17+
"github.com/ava-labs/avalanchego/tests/e2e"
18+
)
19+
20+
var _ = ginkgo.Describe("Duplicate node handling", func() {
21+
require := require.New(ginkgo.GinkgoT())
22+
23+
ginkgo.It("should ensure that a given Node ID (i.e. staking keypair) can be used at most once on a network", func() {
24+
// TODO(marun) Ensure reliable node removal on teardown
25+
26+
// Minimize the potential for node name collision to allow for
27+
// iterating with a persistent network. The use of non-secure random
28+
// value is not security critical so the lint is ignored.
29+
//nolint:gosec
30+
baseNodeName := fmt.Sprintf("e2e-duplicate-node-%08x-", rand.Uint32())
31+
node1Name := baseNodeName + "1"
32+
33+
var stakingCert, stakingKey []byte
34+
ginkgo.By("generating a staking keypair", func() {
35+
var err error
36+
stakingCert, stakingKey, err = staking.NewCertAndKeyBytes()
37+
require.NoError(err)
38+
})
39+
40+
ginkgo.By("creating the first node using the staking keypair", func() {
41+
err := e2e.Env.AddNode(node1Name, runner_sdk.WithGlobalNodeConfig(fmt.Sprintf(
42+
`{""--staking-tls-cert-contents": "%s", "--staking-tls-key-contents": "%s"}`,
43+
// Escape newlines in the PEM-formatted keys to
44+
// ensure compatibility with grpc.
45+
strings.ReplaceAll(string(stakingCert), "\n", "\\n"),
46+
strings.ReplaceAll(string(stakingKey), "\n", "\\n"),
47+
)))
48+
require.NoError(err)
49+
err = e2e.Env.CheckHealth()
50+
require.NoError(err)
51+
})
52+
53+
// TODO(marun)
54+
// - Boot badNode2 with the same Certs
55+
// - Check the network peers are connected amongst the network with badNode1 (the first to go up)
56+
// - Check that badNode2 can't bootstrap (invalid peer alias)
57+
// - Remove badNode1
58+
// - Check that badNode2 can now bootstrap
59+
// - Check both nodes have/had the same nodeID
60+
// - Check the network peers are connected amongst the network with badNode2
61+
})
62+
})

0 commit comments

Comments
 (0)