Skip to content

Commit b93fee7

Browse files
Merge #4121
4121: [Testing] Cleanup integration test bootstrap r=peterargue a=peterargue Refactor integration tests to simplify config and hopefully make them more stable. The main improvements: * Add healthchecks to all nodes via the admin server * Cleanup container dirs so they are removed at the end of the test * Consolidate access to ports into the `Container` object. This simplifies the interface and mades logic more explicit about which container is used * Add helper methods to get various grpc clients configured to interact with a node * Refactor observer setup so it's more consistent with other nodes * Refactor observer suite to reduce the number of network setup/teardowns * Fix flakiness in the observer integration suite Co-authored-by: Peter Argue <[email protected]>
2 parents bceb10b + 1221bea commit b93fee7

33 files changed

+943
-844
lines changed

admin/command_runner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,15 @@ func NewCommandRunnerBootstrapper() *CommandRunnerBootstrapper {
7676
func (r *CommandRunnerBootstrapper) Bootstrap(logger zerolog.Logger, bindAddress string, opts ...CommandRunnerOption) *CommandRunner {
7777
handlers := make(map[string]CommandHandler)
7878
commands := make([]interface{}, 0, len(r.handlers))
79+
80+
r.RegisterHandler("ping", func(ctx context.Context, req *CommandRequest) (interface{}, error) {
81+
return "pong", nil
82+
})
83+
7984
r.RegisterHandler("list-commands", func(ctx context.Context, req *CommandRequest) (interface{}, error) {
8085
return commands, nil
8186
})
87+
8288
for command, handler := range r.handlers {
8389
handlers[command] = handler
8490
commands = append(commands, command)

insecure/cmd/corrupted_builder.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cmd
33
import (
44
"fmt"
55
"net"
6-
"strconv"
76

87
"github.com/spf13/pflag"
98

@@ -19,7 +18,7 @@ import (
1918
)
2019

2120
// CorruptNetworkPort is the port number that gRPC server of the corrupt networking layer of the corrupted nodes is listening on.
22-
const CorruptNetworkPort = 4300
21+
const CorruptNetworkPort = "4300"
2322

2423
// CorruptedNodeBuilder creates a general flow node builder with corrupt network.
2524
type CorruptedNodeBuilder struct {
@@ -133,7 +132,7 @@ func (cnb *CorruptedNodeBuilder) enqueueNetworkingLayer() {
133132
return nil, fmt.Errorf("could not extract host address: %w", err)
134133
}
135134

136-
address := net.JoinHostPort(host, strconv.Itoa(CorruptNetworkPort))
135+
address := net.JoinHostPort(host, CorruptNetworkPort)
137136
ccf := corruptnet.NewCorruptConduitFactory(cnb.FlowNodeBuilder.Logger, cnb.FlowNodeBuilder.RootChainID)
138137

139138
cnb.Logger.Info().Hex("node_id", logging.ID(cnb.NodeID)).Msg("corrupted conduit factory initiated")

integration/client/admin_client.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package client
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"net/http"
9+
"strings"
10+
)
11+
12+
// AdminClient is a simple client for interacting with the Flow admin server
13+
type AdminClient struct {
14+
client *http.Client
15+
url string
16+
}
17+
18+
// Request is the request to the admin server.
19+
type Request struct {
20+
CommandName string `json:"commandName"`
21+
Data any `json:"data,omitempty"`
22+
}
23+
24+
// Response is the response from the admin server.
25+
type Response struct {
26+
Output any `json:"output"`
27+
}
28+
29+
// AdminClientOption is a function that configures an admin client.
30+
type AdminClientOption func(c *AdminClient)
31+
32+
// WithHTTPClient configures the admin client to use the provided HTTP client.
33+
func WithHTTPClient(client *http.Client) AdminClientOption {
34+
return func(c *AdminClient) {
35+
c.client = client
36+
}
37+
}
38+
39+
// WithTLS configures the admin client to use TLS when sending requests.
40+
func WithTLS(enabled bool) AdminClientOption {
41+
return func(c *AdminClient) {
42+
c.url = strings.Replace(c.url, "http://", "https://", 1)
43+
}
44+
}
45+
46+
// NewAdminClient creates a new admin client.
47+
func NewAdminClient(serverAddr string, opts ...AdminClientOption) *AdminClient {
48+
c := &AdminClient{
49+
client: &http.Client{},
50+
url: fmt.Sprintf("http://%s/admin/run_command", serverAddr),
51+
}
52+
53+
for _, apply := range opts {
54+
apply(c)
55+
}
56+
57+
return c
58+
}
59+
60+
// Ping sends a ping command to the server and returns an error if the response is not "pong".
61+
func (c *AdminClient) Ping(ctx context.Context) error {
62+
response, err := c.send(ctx, Request{
63+
CommandName: "ping",
64+
})
65+
if err != nil {
66+
return err
67+
}
68+
69+
if response.Output != "pong" {
70+
return fmt.Errorf("unexpected response: %v", response.Output)
71+
}
72+
73+
return nil
74+
}
75+
76+
// RunCommand sends a command to the server and returns the response.
77+
func (c *AdminClient) RunCommand(ctx context.Context, commandName string, data any) (*Response, error) {
78+
response, err := c.send(ctx, Request{
79+
CommandName: commandName,
80+
Data: data,
81+
})
82+
if err != nil {
83+
return nil, err
84+
}
85+
86+
return response, nil
87+
}
88+
89+
func (c *AdminClient) send(ctx context.Context, req Request) (*Response, error) {
90+
reqBody, err := json.Marshal(req)
91+
if err != nil {
92+
return nil, fmt.Errorf("failed to marshal request body: %w", err)
93+
}
94+
95+
resp, err := c.client.Post(c.url, "application/json", bytes.NewBuffer(reqBody))
96+
if err != nil {
97+
return nil, fmt.Errorf("failed to send request: %w", err)
98+
}
99+
defer resp.Body.Close()
100+
101+
var result Response
102+
err = json.NewDecoder(resp.Body).Decode(&result)
103+
if err != nil {
104+
return nil, fmt.Errorf("failed to decode response body: %w", err)
105+
}
106+
107+
return &result, nil
108+
}

integration/localnet/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
/trie/
55
docker-compose.nodes.yml
66
targets.nodes.json
7+
ports.nodes.json

integration/localnet/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ else
4646
go run -tags relic \
4747
-ldflags="-X 'github.com/onflow/flow-go/cmd/build.commit=${COMMIT}' \
4848
-X 'github.com/onflow/flow-go/cmd/build.semver=${VERSION}'" \
49-
bootstrap.go \
49+
builder/*.go \
5050
-loglevel=$(LOGLEVEL) \
5151
-collection=$(COLLECTION) \
5252
-consensus=$(CONSENSUS) \

0 commit comments

Comments
 (0)