Skip to content

Commit 4145e54

Browse files
authored
Simultaneous Networks (#105)
1 parent e524853 commit 4145e54

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1137
-698
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
environment/charts/mockserver-config/static/initializerJson.json
23

34
# Hardhat config that might sneak through
45
node_modules/

actions/setup.go

Lines changed: 196 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package actions
22

33
import (
4+
"fmt"
45
"os"
56
"path/filepath"
67
"strings"
@@ -23,24 +24,77 @@ const (
2324
KeepEnvironmentsAlways = "always"
2425
)
2526

26-
// DefaultSuiteSetup holds the data for a default setup
27-
type DefaultSuiteSetup struct {
28-
Config *config.Config
27+
// NetworkInfo helps delineate network information in a multi-network setup
28+
type NetworkInfo struct {
2929
Client client.BlockchainClient
3030
Wallets client.BlockchainWallets
3131
Deployer contracts.ContractDeployer
3232
Link contracts.LinkToken
33-
Env environment.Environment
3433
Network client.BlockchainNetwork
3534
}
3635

37-
// DefaultLocalSetup setup minimum required components for test
38-
func DefaultLocalSetup(
39-
envName string,
36+
// buildNetworkInfo initializes the network's blockchain client and gathers all test-relevant network information
37+
func buildNetworkInfo(network client.BlockchainNetwork, env environment.Environment) (NetworkInfo, error) {
38+
// Initialize blockchain client
39+
var bcc client.BlockchainClient
40+
var err error
41+
switch network.Config().Type {
42+
case client.BlockchainTypeEVMMultinode:
43+
bcc, err = environment.NewBlockchainClients(env, network)
44+
case client.BlockchainTypeEVM:
45+
bcc, err = environment.NewBlockchainClient(env, network)
46+
}
47+
if err != nil {
48+
return NetworkInfo{}, err
49+
}
50+
51+
// Initialize wallets
52+
wallets, err := network.Wallets()
53+
if err != nil {
54+
return NetworkInfo{}, err
55+
}
56+
contractDeployer, err := contracts.NewContractDeployer(bcc)
57+
if err != nil {
58+
return NetworkInfo{}, err
59+
}
60+
link, err := contractDeployer.DeployLinkTokenContract(wallets.Default())
61+
if err != nil {
62+
return NetworkInfo{}, err
63+
}
64+
return NetworkInfo{
65+
Client: bcc,
66+
Wallets: wallets,
67+
Deployer: contractDeployer,
68+
Link: link,
69+
Network: network,
70+
}, nil
71+
}
72+
73+
// SuiteSetup enables common use cases, and safe handling of different blockchain networks for test scenarios
74+
type SuiteSetup interface {
75+
Config() *config.Config
76+
Environment() environment.Environment
77+
78+
DefaultNetwork() NetworkInfo
79+
Network(index int) (NetworkInfo, error)
80+
Networks() []NetworkInfo
81+
82+
TearDown() func()
83+
}
84+
85+
// SingleNetworkSuiteSetup holds the data for a default setup
86+
type SingleNetworkSuiteSetup struct {
87+
config *config.Config
88+
env environment.Environment
89+
network NetworkInfo
90+
}
91+
92+
// SingleNetworkSetup setup minimum required components for test
93+
func SingleNetworkSetup(
4094
initialDeployInitFunc environment.K8sEnvSpecInit,
4195
initFunc client.BlockchainNetworkInit,
4296
configPath string,
43-
) (*DefaultSuiteSetup, error) {
97+
) (SuiteSetup, error) {
4498
conf, err := config.NewConfig(configPath)
4599
if err != nil {
46100
return nil, err
@@ -50,105 +104,201 @@ func DefaultLocalSetup(
50104
return nil, err
51105
}
52106

53-
env, err := environment.NewK8sEnvironment(envName, conf, network)
107+
env, err := environment.NewK8sEnvironment(conf, network)
54108
if err != nil {
55109
return nil, err
56110
}
57-
58111
err = env.DeploySpecs(initialDeployInitFunc)
59112
if err != nil {
60113
return nil, err
61114
}
62115

63-
// Initialize blockchain client
64-
var bcc client.BlockchainClient
65-
switch network.Config().Type {
66-
case client.BlockchainTypeEVMMultinode:
67-
bcc, err = environment.NewBlockchainClients(env, network)
68-
case client.BlockchainTypeEVM:
69-
bcc, err = environment.NewBlockchainClient(env, network)
70-
}
116+
networkInfo, err := buildNetworkInfo(network, env)
71117
if err != nil {
72118
return nil, err
73119
}
74120

75-
// Initialize wallets
76-
wallets, err := network.Wallets()
121+
// configure default retry
122+
retry.DefaultAttempts = conf.Retry.Attempts
123+
retry.DefaultDelayType = func(n uint, err error, config *retry.Config) time.Duration {
124+
return conf.Retry.LinearDelay
125+
}
126+
127+
return &SingleNetworkSuiteSetup{
128+
config: conf,
129+
env: env,
130+
network: networkInfo,
131+
}, nil
132+
}
133+
134+
// Config retrieves the general config for the suite
135+
func (s *SingleNetworkSuiteSetup) Config() *config.Config {
136+
return s.config
137+
}
138+
139+
// Environment retrieves the general environment for the suite
140+
func (s *SingleNetworkSuiteSetup) Environment() environment.Environment {
141+
return s.env
142+
}
143+
144+
// DefaultNetwork returns the only network in a single network environment
145+
func (s *SingleNetworkSuiteSetup) DefaultNetwork() NetworkInfo {
146+
return s.network
147+
}
148+
149+
// Network returns the only network in a single network environment
150+
func (s *SingleNetworkSuiteSetup) Network(index int) (NetworkInfo, error) {
151+
return s.network, nil
152+
}
153+
154+
// Networks returns the only network in a single network environment
155+
func (s *SingleNetworkSuiteSetup) Networks() []NetworkInfo {
156+
return []NetworkInfo{s.network}
157+
}
158+
159+
// TearDown checks for test failure, writes logs if there is one, then tears down the test environment, based on the
160+
// keep_environments config value
161+
func (s *SingleNetworkSuiteSetup) TearDown() func() {
162+
return teardown(*s.config, s.env, s.network.Client)
163+
}
164+
165+
// multiNetworkSuiteSetup holds the data for a multiple network setup
166+
type multiNetworkSuiteSetup struct {
167+
config *config.Config
168+
env environment.Environment
169+
networks []NetworkInfo
170+
}
171+
172+
// MultiNetworkSetup enables testing across multiple networks
173+
func MultiNetworkSetup(
174+
initialDeployInitFunc environment.K8sEnvSpecInit,
175+
multiNetworkInitialization client.MultiNetworkInit,
176+
configPath string,
177+
) (SuiteSetup, error) {
178+
conf, err := config.NewConfig(configPath)
77179
if err != nil {
78180
return nil, err
79181
}
80-
contractDeployer, err := contracts.NewContractDeployer(bcc)
182+
networks, err := multiNetworkInitialization(conf)
81183
if err != nil {
82184
return nil, err
83185
}
84-
balance, err := contractDeployer.Balance(wallets.Default())
186+
187+
env, err := environment.NewK8sEnvironment(conf, networks...)
85188
if err != nil {
86189
return nil, err
87190
}
88-
log.Info().Str("Address", wallets.Default().Address()).Str("ETH", balance.String()).Msg("Deployer balance")
89-
link, err := contractDeployer.DeployLinkTokenContract(wallets.Default())
191+
192+
err = env.DeploySpecs(initialDeployInitFunc)
90193
if err != nil {
91194
return nil, err
92195
}
196+
197+
allNetworks := make([]NetworkInfo, len(networks))
198+
for index, network := range networks {
199+
networkInfo, err := buildNetworkInfo(network, env)
200+
if err != nil {
201+
return nil, err
202+
}
203+
allNetworks[index] = networkInfo
204+
}
205+
93206
// configure default retry
94207
retry.DefaultAttempts = conf.Retry.Attempts
95208
retry.DefaultDelayType = func(n uint, err error, config *retry.Config) time.Duration {
96209
return conf.Retry.LinearDelay
97210
}
98-
return &DefaultSuiteSetup{
99-
Config: conf,
100-
Client: bcc,
101-
Wallets: wallets,
102-
Deployer: contractDeployer,
103-
Link: link,
104-
Env: env,
105-
Network: network,
211+
return &multiNetworkSuiteSetup{
212+
config: conf,
213+
env: env,
214+
networks: allNetworks,
106215
}, nil
107216
}
108217

218+
// Config retrieves the general config for the suite
219+
func (s *multiNetworkSuiteSetup) Config() *config.Config {
220+
return s.config
221+
}
222+
223+
// Environment retrieves the general environment for the suite
224+
func (s *multiNetworkSuiteSetup) Environment() environment.Environment {
225+
return s.env
226+
}
227+
228+
// DefaultNetwork returns the network information for the first / only network in the suite
229+
func (s *multiNetworkSuiteSetup) DefaultNetwork() NetworkInfo {
230+
return s.networks[0]
231+
}
232+
233+
// Network returns the network information for the network with the supplied ID. If there is more than 1 network with
234+
// that ID, the first one encountered is returned.
235+
func (s *multiNetworkSuiteSetup) Network(index int) (NetworkInfo, error) {
236+
if len(s.networks) <= index {
237+
return NetworkInfo{}, fmt.Errorf("No network at the index '%d'. Total amount of networks: %v", index, len(s.networks))
238+
}
239+
return s.networks[index], nil
240+
}
241+
242+
// Networks returns the network information for all the networks with the supplied ID.
243+
func (s *multiNetworkSuiteSetup) Networks() []NetworkInfo {
244+
return s.networks
245+
}
246+
109247
// TearDown checks for test failure, writes logs if there is one, then tears down the test environment, based on the
110248
// keep_environments config value
111-
func (s *DefaultSuiteSetup) TearDown() func() {
249+
func (s *multiNetworkSuiteSetup) TearDown() func() {
250+
clients := make([]client.BlockchainClient, len(s.networks))
251+
for index, network := range s.networks {
252+
clients[index] = network.Client
253+
}
254+
return teardown(*s.config, s.env, clients...)
255+
}
256+
257+
// TearDown checks for test failure, writes logs if there is one, then tears down the test environment, based on the
258+
// keep_environments config value
259+
func teardown(config config.Config, env environment.Environment, clients ...client.BlockchainClient) func() {
112260
if ginkgo.CurrentGinkgoTestDescription().Failed { // If a test fails, dump logs
113-
logsFolder := filepath.Join(s.Config.ConfigFileLocation, "/logs/")
261+
logsFolder := filepath.Join(config.ConfigFileLocation, "/logs/")
114262
if _, err := os.Stat(logsFolder); os.IsNotExist(err) {
115263
if err = os.Mkdir(logsFolder, 0755); err != nil {
116264
log.Err(err).Str("Log Folder", logsFolder).Msg("Error creating logs directory")
117265
}
118266
}
119267
testLogFolder := filepath.Join(logsFolder, strings.Replace(ginkgo.CurrentGinkgoTestDescription().TestText, " ", "-", -1)+
120-
"_"+s.Env.ID()+"/")
268+
"_"+env.ID()+"/")
121269
// Create specific test folder
122270
if _, err := os.Stat(testLogFolder); os.IsNotExist(err) {
123271
if err = os.Mkdir(testLogFolder, 0755); err != nil {
124272
log.Err(err).Str("Log Folder", testLogFolder).Msg("Error creating logs directory")
125273
}
126274
}
127275

128-
s.Env.WriteArtifacts(testLogFolder)
276+
env.WriteArtifacts(testLogFolder)
129277
log.Info().Str("Log Folder", testLogFolder).Msg("Wrote environment logs")
130278
}
131279
return func() {
132-
if err := s.Client.Close(); err != nil {
133-
log.Error().
134-
Str("Network", s.Config.Network).
135-
Msgf("Error while closing the Blockchain client: %v", err)
280+
for _, client := range clients {
281+
if err := client.Close(); err != nil {
282+
log.Err(err).
283+
Str("Network", client.GetNetworkName()).
284+
Msgf("Error while closing the Blockchain client")
285+
}
136286
}
137287

138-
switch strings.ToLower(s.Config.KeepEnvironments) {
288+
switch strings.ToLower(config.KeepEnvironments) {
139289
case KeepEnvironmentsNever:
140-
s.Env.TearDown()
290+
env.TearDown()
141291
case KeepEnvironmentsOnFail:
142292
if !ginkgo.CurrentGinkgoTestDescription().Failed {
143-
s.Env.TearDown()
293+
env.TearDown()
144294
} else {
145-
log.Info().Str("Namespace", s.Env.ID()).Msg("Kept environment due to test failure")
295+
log.Info().Str("Namespace", env.ID()).Msg("Kept environment due to test failure")
146296
}
147297
case KeepEnvironmentsAlways:
148-
log.Info().Str("Namespace", s.Env.ID()).Msg("Kept environment")
298+
log.Info().Str("Namespace", env.ID()).Msg("Kept environment")
149299
return
150300
default:
151-
s.Env.TearDown()
301+
env.TearDown()
152302
}
153303
}
154304
}

cli/cmd/create_env.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ func createRunE(cmd *cobra.Command, _ []string) error {
3535
if err != nil {
3636
return err
3737
}
38-
cfg.Network = network
39-
networkConfig, err := client.NewNetworkFromConfig(cfg)
38+
cfg.Networks = []string{network}
39+
networkConfig, err := client.DefaultNetworkFromConfig(cfg)
4040
if err != nil {
4141
return err
4242
}
@@ -45,7 +45,7 @@ func createRunE(cmd *cobra.Command, _ []string) error {
4545
switch envType {
4646
case "chainlink":
4747
envSpec := environment.NewChainlinkCluster(nodes)
48-
env, err = environment.NewK8sEnvironment("basic-chainlink", cfg, networkConfig)
48+
env, err = environment.NewK8sEnvironment(cfg, networkConfig)
4949
if err != nil {
5050
return err
5151
}

cli/cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func init() {
3333
createCmd.Flags().StringP(FlagType, "t", "chainlink", "type of environment to deploy")
3434
createCmd.Flags().IntP(FlagNodeCount, "c", 3, "number of Chainlink nodes to deploy")
3535
createCmd.Flags().StringP(FlagNetwork,
36-
"n", "ethereum_hardhat", "the network to deploy the Chainlink cluster on")
36+
"n", "ethereum_geth", "the network to deploy the Chainlink cluster on")
3737
}
3838

3939
// Execute runs the root command

0 commit comments

Comments
 (0)