From baab8ad65870894bb0e91a562b3968091350e356 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Tue, 20 May 2025 19:17:54 +0200 Subject: [PATCH 1/6] [tmpnet] Replace TestEnvironment.URIs with GetLocalNodeURIs() Previously it was possible to use TestEnvironment.URIs to access node API endpoints. If a node is running in a kube cluster, however, it won't be accessible from outside that cluster. Adding TestEnvironment.GetLocalNodeURIs and updating callers to use that ensures URIs that will work regardless of the location of nodes and test workloads. --- tests/antithesis/config.go | 5 +-- tests/e2e/p/validator_sets.go | 5 +-- tests/e2e/x/transfer/virtuous.go | 9 ++++-- tests/fixture/e2e/env.go | 52 ++++++++++++++++++++++++++------ tests/fixture/tmpnet/network.go | 4 +++ tests/fixture/tmpnet/utils.go | 43 +++++++++++++++++++++----- 6 files changed, 95 insertions(+), 23 deletions(-) diff --git a/tests/antithesis/config.go b/tests/antithesis/config.go index 4a6717b7048b..8807db7f1863 100644 --- a/tests/antithesis/config.go +++ b/tests/antithesis/config.go @@ -102,8 +102,9 @@ func configForNewNetwork( c := &Config{ Duration: duration, } - c.URIs = make(CSV, len(testEnv.URIs)) - for i, nodeURI := range testEnv.URIs { + localURIs := testEnv.GetLocalNodeURIs() + c.URIs = make(CSV, len(localURIs)) + for i, nodeURI := range localURIs { c.URIs[i] = nodeURI.URI } network := testEnv.GetNetwork() diff --git a/tests/e2e/p/validator_sets.go b/tests/e2e/p/validator_sets.go index ee81dda8fda4..86a261f086da 100644 --- a/tests/e2e/p/validator_sets.go +++ b/tests/e2e/p/validator_sets.go @@ -81,8 +81,9 @@ var _ = e2e.DescribePChain("[Validator Sets]", func() { require.NoError(err) tc.By("checking that validator sets are equal across all heights for all nodes", func() { - pvmClients := make([]platformvm.Client, len(env.URIs)) - for i, nodeURI := range env.URIs { + localURIs := env.GetLocalNodeURIs() + pvmClients := make([]platformvm.Client, len(localURIs)) + for i, nodeURI := range localURIs { pvmClients[i] = platformvm.NewClient(nodeURI.URI) // Ensure that the height of the target node is at least the expected height tc.Eventually( diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index bcb4138fdd8e..19b463ccb379 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -47,9 +47,12 @@ var _ = e2e.DescribeXChainSerial("[Virtuous Transfer Tx AVAX]", func() { ginkgo.It("can issue a virtuous transfer tx for AVAX asset", func() { - env := e2e.GetEnv(tc) - rpcEps := make([]string, len(env.URIs)) - for i, nodeURI := range env.URIs { + var ( + env = e2e.GetEnv(tc) + localURIs = env.GetLocalNodeURIs() + rpcEps = make([]string, len(localURIs)) + ) + for i, nodeURI := range localURIs { rpcEps[i] = nodeURI.URI } diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index bcdc4faef4a2..86b6e17fd077 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -46,8 +46,6 @@ type TestEnvironment struct { RootNetworkDir string // The directory where the test network configuration is stored NetworkDir string - // URIs used to access the API endpoints of nodes of the network - URIs []tmpnet.NodeURI // Pre-funded key for this ginkgo process PreFundedKey *secp256k1.PrivateKey // The duration to wait before shutting down private networks. A @@ -66,7 +64,6 @@ func GetEnv(tc tests.TestContext) *TestEnvironment { return &TestEnvironment{ RootNetworkDir: env.RootNetworkDir, NetworkDir: env.NetworkDir, - URIs: env.URIs, PreFundedKey: env.PreFundedKey, PrivateNetworkShutdownDelay: env.PrivateNetworkShutdownDelay, testContext: tc, @@ -219,21 +216,58 @@ func NewTestEnvironment(tc tests.TestContext, flagVars *FlagVars, desiredNetwork return &TestEnvironment{ RootNetworkDir: flagVars.RootNetworkDir(), NetworkDir: network.Dir, - URIs: uris, PrivateNetworkShutdownDelay: flagVars.NetworkShutdownDelay(), testContext: tc, } } -// Retrieve a random URI to naively attempt to spread API load across -// nodes. +// Retrieve the locally-accessible URIs for validator nodes of the shared network. +func (te *TestEnvironment) GetLocalNodeURIs() []tmpnet.NodeURI { + var ( + tc = te.testContext + network = te.GetNetwork() + ) + uris, err := network.GetLocalNodeURIs(tc.DefaultContext(), tc.DeferCleanup) + require.NoError(tc, err) + return uris +} + +// Retrieve a random URI to naively attempt to spread API load across nodes. func (te *TestEnvironment) GetRandomNodeURI() tmpnet.NodeURI { - r := rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 - nodeURI := te.URIs[r.Intn(len(te.URIs))] - te.testContext.Log().Info("targeting random node", + var ( + tc = te.testContext + r = rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 + network = te.GetNetwork() + availableNodes = []*tmpnet.Node{} + ) + + for _, node := range network.Nodes { + if node.IsEphemeral { + // Avoid returning URIs for nodes whose lifespan is indeterminate + continue + } + if !node.IsRunning() { + // Only running nodes have URIs + continue + } + availableNodes = append(availableNodes, node) + } + + // Use a local URI for the node to ensure compatibility with kube + randomNode := availableNodes[r.Intn(len(availableNodes))] + uri, cancel, err := randomNode.GetLocalURI(tc.DefaultContext()) + require.NoError(tc, err) + tc.DeferCleanup(cancel) + + nodeURI := tmpnet.NodeURI{ + NodeID: randomNode.NodeID, + URI: uri, + } + tc.Log().Info("targeting random node", zap.Stringer("nodeID", nodeURI.NodeID), zap.String("uri", nodeURI.URI), ) + return nodeURI } diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 0538a2fe6da5..474cc6da968f 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -771,6 +771,10 @@ func (n *Network) GetNodeURIs() []NodeURI { return GetNodeURIs(n.Nodes) } +func (n *Network) GetLocalNodeURIs(ctx context.Context, deferCleanupFunc func(func())) ([]NodeURI, error) { + return GetLocalNodeURIs(ctx, n.Nodes, deferCleanupFunc) +} + // Retrieves bootstrap IPs and IDs for all non-ephemeral nodes except the skipped one // (this supports collecting the bootstrap details for restarting a node). // diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index 6687b01ad8fd..0965ad3d8b40 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -53,6 +53,8 @@ type NodeURI struct { URI string } +// GetNodeURIs returns the URIs of the given nodes. Prefer GetLocalNodeURIs +// if targeting nodes that could be running in a Kubernetes cluster. func GetNodeURIs(nodes []*Node) []NodeURI { uris := make([]NodeURI, 0, len(nodes)) for _, node := range nodes { @@ -60,18 +62,45 @@ func GetNodeURIs(nodes []*Node) []NodeURI { // Avoid returning URIs for nodes whose lifespan is indeterminate continue } - // Only append URIs that are not empty. A node may have an - // empty URI if it is not currently running. - if node.IsRunning() { - uris = append(uris, NodeURI{ - NodeID: node.NodeID, - URI: node.URI, - }) + if !node.IsRunning() { + // Only running nodes have URIs + continue } + uris = append(uris, NodeURI{ + NodeID: node.NodeID, + URI: node.URI, + }) } return uris } +// GetLocalNodeURIs returns locally-accessible URIs for the given nodes. +func GetLocalNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func(func())) ([]NodeURI, error) { + uris := make([]NodeURI, 0, len(nodes)) + for _, node := range nodes { + if node.IsEphemeral { + // Avoid returning URIs for nodes whose lifespan is indeterminate + continue + } + if !node.IsRunning() { + // Only running nodes have URIs + continue + } + + uri, cancel, err := node.GetLocalURI(ctx) + if err != nil { + return nil, err + } + deferCleanupFunc(cancel) + uris = append(uris, NodeURI{ + NodeID: node.NodeID, + URI: uri, + }) + } + + return uris, nil +} + // Marshal to json with default prefix and indent. func DefaultJSONMarshal(v interface{}) ([]byte, error) { return json.MarshalIndent(v, "", " ") From 3692971a0c800511aebffe2abad9ea50d4bc1250 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Tue, 20 May 2025 19:35:04 +0200 Subject: [PATCH 2/6] fixup: Add check for available nodes --- tests/fixture/e2e/env.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 86b6e17fd077..904841942401 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -253,6 +253,8 @@ func (te *TestEnvironment) GetRandomNodeURI() tmpnet.NodeURI { availableNodes = append(availableNodes, node) } + require.NotEmpty(tc, availableNodes, "no available nodes to target") + // Use a local URI for the node to ensure compatibility with kube randomNode := availableNodes[r.Intn(len(availableNodes))] uri, cancel, err := randomNode.GetLocalURI(tc.DefaultContext()) From 6eb15fe154402c2d89ca6af069ab57c4668d2f5a Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Tue, 20 May 2025 19:47:08 +0200 Subject: [PATCH 3/6] fixup: extract filterAvailableNodes from get*URIs --- tests/fixture/tmpnet/utils.go | 51 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index 0965ad3d8b40..d026cae9c55c 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -53,19 +53,12 @@ type NodeURI struct { URI string } -// GetNodeURIs returns the URIs of the given nodes. Prefer GetLocalNodeURIs -// if targeting nodes that could be running in a Kubernetes cluster. +// GetNodeURIs returns the URIs of the given nodes provided they are running and not ephemeral. Prefer +// GetLocalNodeURIs if targeting nodes that could be running in a Kubernetes cluster. func GetNodeURIs(nodes []*Node) []NodeURI { - uris := make([]NodeURI, 0, len(nodes)) - for _, node := range nodes { - if node.IsEphemeral { - // Avoid returning URIs for nodes whose lifespan is indeterminate - continue - } - if !node.IsRunning() { - // Only running nodes have URIs - continue - } + availableNodes := filterAvailableNodes(nodes) + uris := make([]NodeURI, 0, len(availableNodes)) + for _, node := range availableNodes { uris = append(uris, NodeURI{ NodeID: node.NodeID, URI: node.URI, @@ -74,19 +67,12 @@ func GetNodeURIs(nodes []*Node) []NodeURI { return uris } -// GetLocalNodeURIs returns locally-accessible URIs for the given nodes. +// GetLocalNodeURIs returns locally-accessible URIs for the given nodes provided they are running and not +// ephemeral. func GetLocalNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func(func())) ([]NodeURI, error) { - uris := make([]NodeURI, 0, len(nodes)) - for _, node := range nodes { - if node.IsEphemeral { - // Avoid returning URIs for nodes whose lifespan is indeterminate - continue - } - if !node.IsRunning() { - // Only running nodes have URIs - continue - } - + availableNodes := filterAvailableNodes(nodes) + uris := make([]NodeURI, 0, len(availableNodes)) + for _, node := range availableNodes { uri, cancel, err := node.GetLocalURI(ctx) if err != nil { return nil, err @@ -101,6 +87,23 @@ func GetLocalNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func( return uris, nil } +// filteredAvailableNodes filters the provided nodes by whether they are running and not ephemeral. +func filterAvailableNodes(nodes []*Node) []*Node { + filteredNodes := make([]*Node, 0, len(nodes)) + for _, node := range nodes { + if node.IsEphemeral { + // Avoid returning URIs for nodes whose lifespan is indeterminate + continue + } + if !node.IsRunning() { + // Only running nodes have URIs + continue + } + filteredNodes = append(filteredNodes, node) + } + return filteredNodes +} + // Marshal to json with default prefix and indent. func DefaultJSONMarshal(v interface{}) ([]byte, error) { return json.MarshalIndent(v, "", " ") From 30824ff8800c001bee10a5d9e777299d4a229055 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Wed, 21 May 2025 12:54:08 +0200 Subject: [PATCH 4/6] fixup: Respond to reviewer feedback --- tests/antithesis/config.go | 2 +- tests/e2e/p/validator_sets.go | 2 +- tests/e2e/x/transfer/virtuous.go | 2 +- tests/fixture/e2e/env.go | 36 +++++++++++++++++++++++--------- tests/fixture/tmpnet/network.go | 17 +++++++++++---- tests/fixture/tmpnet/utils.go | 27 +++++++----------------- 6 files changed, 49 insertions(+), 37 deletions(-) diff --git a/tests/antithesis/config.go b/tests/antithesis/config.go index 8807db7f1863..f5f85192bd0e 100644 --- a/tests/antithesis/config.go +++ b/tests/antithesis/config.go @@ -102,7 +102,7 @@ func configForNewNetwork( c := &Config{ Duration: duration, } - localURIs := testEnv.GetLocalNodeURIs() + localURIs := testEnv.GetNodeURIs() c.URIs = make(CSV, len(localURIs)) for i, nodeURI := range localURIs { c.URIs[i] = nodeURI.URI diff --git a/tests/e2e/p/validator_sets.go b/tests/e2e/p/validator_sets.go index 86a261f086da..d45922ff59e0 100644 --- a/tests/e2e/p/validator_sets.go +++ b/tests/e2e/p/validator_sets.go @@ -81,7 +81,7 @@ var _ = e2e.DescribePChain("[Validator Sets]", func() { require.NoError(err) tc.By("checking that validator sets are equal across all heights for all nodes", func() { - localURIs := env.GetLocalNodeURIs() + localURIs := env.GetNodeURIs() pvmClients := make([]platformvm.Client, len(localURIs)) for i, nodeURI := range localURIs { pvmClients[i] = platformvm.NewClient(nodeURI.URI) diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index 19b463ccb379..3686cd445cdc 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -49,7 +49,7 @@ var _ = e2e.DescribeXChainSerial("[Virtuous Transfer Tx AVAX]", func() { func() { var ( env = e2e.GetEnv(tc) - localURIs = env.GetLocalNodeURIs() + localURIs = env.GetNodeURIs() rpcEps = make([]string, len(localURIs)) ) for i, nodeURI := range localURIs { diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 904841942401..f9df81c30ef6 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -207,27 +207,43 @@ func NewTestEnvironment(tc tests.TestContext, flagVars *FlagVars, desiredNetwork "not enough pre-funded keys for the requested number of parallel test processes", ) - uris := network.GetNodeURIs() - require.NotEmpty(uris, "network contains no nodes") - tc.Log().Info("network nodes are available", - zap.Any("uris", uris), - ) - - return &TestEnvironment{ + env := &TestEnvironment{ RootNetworkDir: flagVars.RootNetworkDir(), NetworkDir: network.Dir, PrivateNetworkShutdownDelay: flagVars.NetworkShutdownDelay(), testContext: tc, } + + if network.DefaultRuntimeConfig.Process != nil { + // Display node IDs and URIs for process-based networks since the nodes are guaranteed to be network accessible + uris := env.GetNodeURIs() + require.NotEmpty(uris, "network contains no nodes") + tc.Log().Info("network nodes are available", + zap.Any("uris", uris), + ) + } else { + // Only display node IDs for kube-based networks since the nodes may not be network accessible and + // port-forwarded URIs are ephemeral + nodeIDs := network.GetAvailableNodeIDs() + require.NotEmpty(nodeIDs, "network contains no nodes") + tc.Log().Info("network nodes are available. Not showing node URIs since kube nodes may be running remotely.", + zap.Any("nodeIDs", nodeIDs), + ) + } + + return env } -// Retrieve the locally-accessible URIs for validator nodes of the shared network. -func (te *TestEnvironment) GetLocalNodeURIs() []tmpnet.NodeURI { +// Retrieve URIs for validator nodes of the shared network. The URIs +// are only guaranteed to be accessible until the environment test +// context is torn down (usually the duration of execution of a single +// test). +func (te *TestEnvironment) GetNodeURIs() []tmpnet.NodeURI { var ( tc = te.testContext network = te.GetNetwork() ) - uris, err := network.GetLocalNodeURIs(tc.DefaultContext(), tc.DeferCleanup) + uris, err := network.GetNodeURIs(tc.DefaultContext(), tc.DeferCleanup) require.NoError(tc, err) return uris } diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 474cc6da968f..caacec47aecc 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -767,12 +767,21 @@ func (n *Network) GetNode(nodeID ids.NodeID) (*Node, error) { return nil, fmt.Errorf("%s is not known to the network", nodeID) } -func (n *Network) GetNodeURIs() []NodeURI { - return GetNodeURIs(n.Nodes) +// GetNodeURIs returns the URIs of nodes in the network that are running and not ephemeral. The URIs +// returned are guaranteed be reachable by the caller regardless of whether the nodes are running as +// local processes or in a kube cluster. +func (n *Network) GetNodeURIs(ctx context.Context, deferCleanupFunc func(func())) ([]NodeURI, error) { + return GetNodeURIs(ctx, n.Nodes, deferCleanupFunc) } -func (n *Network) GetLocalNodeURIs(ctx context.Context, deferCleanupFunc func(func())) ([]NodeURI, error) { - return GetLocalNodeURIs(ctx, n.Nodes, deferCleanupFunc) +// GetAvailableNodeIDs returns the node IDs of nodes in the network that are running and not ephemeral. +func (n *Network) GetAvailableNodeIDs() []string { + availableNodes := FilterAvailableNodes(n.Nodes) + ids := make([]string, len(availableNodes)) + for _, node := range availableNodes { + ids = append(ids, node.NodeID.String()) + } + return ids } // Retrieves bootstrap IPs and IDs for all non-ephemeral nodes except the skipped one diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index d026cae9c55c..df8757c6c0d0 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -53,24 +53,11 @@ type NodeURI struct { URI string } -// GetNodeURIs returns the URIs of the given nodes provided they are running and not ephemeral. Prefer -// GetLocalNodeURIs if targeting nodes that could be running in a Kubernetes cluster. -func GetNodeURIs(nodes []*Node) []NodeURI { - availableNodes := filterAvailableNodes(nodes) - uris := make([]NodeURI, 0, len(availableNodes)) - for _, node := range availableNodes { - uris = append(uris, NodeURI{ - NodeID: node.NodeID, - URI: node.URI, - }) - } - return uris -} - -// GetLocalNodeURIs returns locally-accessible URIs for the given nodes provided they are running and not -// ephemeral. -func GetLocalNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func(func())) ([]NodeURI, error) { - availableNodes := filterAvailableNodes(nodes) +// GetNodeURIs returns the URIs of the provided nodes that are running and not ephemeral. The URIs returned +// are guaranteed be reachable by the caller regardless of whether the nodes are running as local processes +// or in a kube cluster. +func GetNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func(func())) ([]NodeURI, error) { + availableNodes := FilterAvailableNodes(nodes) uris := make([]NodeURI, 0, len(availableNodes)) for _, node := range availableNodes { uri, cancel, err := node.GetLocalURI(ctx) @@ -87,8 +74,8 @@ func GetLocalNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func( return uris, nil } -// filteredAvailableNodes filters the provided nodes by whether they are running and not ephemeral. -func filterAvailableNodes(nodes []*Node) []*Node { +// FilteredAvailableNodes filters the provided nodes by whether they are running and not ephemeral. +func FilterAvailableNodes(nodes []*Node) []*Node { filteredNodes := make([]*Node, 0, len(nodes)) for _, node := range nodes { if node.IsEphemeral { From 163466c058ebb5fe1903be1ea1a2156a51b7fb4d Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Wed, 21 May 2025 13:09:41 +0200 Subject: [PATCH 5/6] fixup: Indicate the purpose of cleanup in docstrings --- tests/fixture/tmpnet/network.go | 4 ++-- tests/fixture/tmpnet/utils.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index caacec47aecc..50372907589c 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -768,8 +768,8 @@ func (n *Network) GetNode(nodeID ids.NodeID) (*Node, error) { } // GetNodeURIs returns the URIs of nodes in the network that are running and not ephemeral. The URIs -// returned are guaranteed be reachable by the caller regardless of whether the nodes are running as -// local processes or in a kube cluster. +// returned are guaranteed be reachable by the caller until the cleanup function is called regardless +// of whether the nodes are running as local processes or in a kube cluster. func (n *Network) GetNodeURIs(ctx context.Context, deferCleanupFunc func(func())) ([]NodeURI, error) { return GetNodeURIs(ctx, n.Nodes, deferCleanupFunc) } diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index df8757c6c0d0..0d2e2a8d3ed3 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -54,8 +54,8 @@ type NodeURI struct { } // GetNodeURIs returns the URIs of the provided nodes that are running and not ephemeral. The URIs returned -// are guaranteed be reachable by the caller regardless of whether the nodes are running as local processes -// or in a kube cluster. +// are guaranteed be reachable by the caller until the cleanup function is called regardless of whether the +// nodes are running as local processes or in a kube cluster. func GetNodeURIs(ctx context.Context, nodes []*Node, deferCleanupFunc func(func())) ([]NodeURI, error) { availableNodes := FilterAvailableNodes(nodes) uris := make([]NodeURI, 0, len(availableNodes)) From 3b29e5acc2e672c11154e4d054cb97eee1fcf146 Mon Sep 17 00:00:00 2001 From: Maru Newby Date: Wed, 21 May 2025 17:26:59 +0200 Subject: [PATCH 6/6] fixup: Respond to review feedback --- tests/fixture/e2e/env.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index f9df81c30ef6..5d7e95f7855d 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -227,7 +227,7 @@ func NewTestEnvironment(tc tests.TestContext, flagVars *FlagVars, desiredNetwork nodeIDs := network.GetAvailableNodeIDs() require.NotEmpty(nodeIDs, "network contains no nodes") tc.Log().Info("network nodes are available. Not showing node URIs since kube nodes may be running remotely.", - zap.Any("nodeIDs", nodeIDs), + zap.Strings("nodeIDs", nodeIDs), ) }