github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/integration/integration.go (about) 1 // Copyright Monax Industries Limited 2 // SPDX-License-Identifier: Apache-2.0 3 4 package integration 5 6 import ( 7 "context" 8 "fmt" 9 "os" 10 "path" 11 "strconv" 12 "sync/atomic" 13 "testing" 14 "time" 15 16 "github.com/hyperledger/burrow/acm" 17 "github.com/hyperledger/burrow/acm/validator" 18 "github.com/hyperledger/burrow/config" 19 "github.com/hyperledger/burrow/consensus/tendermint" 20 "github.com/hyperledger/burrow/core" 21 "github.com/hyperledger/burrow/execution" 22 "github.com/hyperledger/burrow/genesis" 23 "github.com/hyperledger/burrow/keys" 24 "github.com/hyperledger/burrow/logging" 25 "github.com/hyperledger/burrow/logging/logconfig" 26 "github.com/hyperledger/burrow/permission" 27 "github.com/hyperledger/burrow/rpc" 28 "github.com/hyperledger/burrow/testutil" 29 "github.com/stretchr/testify/require" 30 ) 31 32 const ( 33 ChainName = "Integration_Test_Chain" 34 ) 35 36 // Enable logger output during tests 37 38 var node uint64 = 0 39 40 func NoConsensus(conf *config.BurrowConfig) { 41 conf.Tendermint.Enabled = false 42 } 43 44 func CommitImmediately(conf *config.BurrowConfig) { 45 conf.Execution.TimeoutFactor = 0 46 } 47 48 func RunNode(t testing.TB, genesisDoc *genesis.GenesisDoc, privateAccounts []*acm.PrivateAccount, 49 options ...func(*config.BurrowConfig)) (kern *core.Kernel, shutdown func()) { 50 51 var err error 52 testConfig, cleanup := NewTestConfig(genesisDoc, options...) 53 // Uncomment for log output from tests 54 // testConfig.Logging = logconfig.New().Root(func(sink *logconfig.SinkConfig) *logconfig.SinkConfig { 55 // return sink.SetOutput(logconfig.StderrOutput()) 56 // }) 57 testConfig.Logging = logconfig.New().Root(func(sink *logconfig.SinkConfig) *logconfig.SinkConfig { 58 return sink.SetTransform(logconfig.FilterTransform(logconfig.IncludeWhenAllMatch, 59 "total_validator")).SetOutput(logconfig.StdoutOutput()) 60 }) 61 kern, err = TestKernel(privateAccounts[0], privateAccounts, testConfig) 62 require.NoError(t, err) 63 err = kern.Boot() 64 require.NoError(t, err) 65 // Sometimes better to not shutdown as logging errors on shutdown may obscure real issue 66 return kern, func() { 67 Shutdown(kern) 68 cleanup() 69 } 70 } 71 72 func NewTestConfig(genesisDoc *genesis.GenesisDoc, 73 options ...func(*config.BurrowConfig)) (conf *config.BurrowConfig, cleanup func()) { 74 75 nodeNumber := atomic.AddUint64(&node, 1) 76 name := fmt.Sprintf("node_%03d", nodeNumber) 77 conf = config.DefaultBurrowConfig() 78 conf.Logging = nil 79 testDir, cleanup := testutil.EnterTestDirectory() 80 conf.BurrowDir = path.Join(testDir, fmt.Sprintf(".burrow_%s", name)) 81 conf.GenesisDoc = genesisDoc 82 conf.Tendermint.Moniker = name 83 // Make blocks for purposes of tests 84 conf.Tendermint.CreateEmptyBlocks = tendermint.AlwaysCreateEmptyBlocks 85 conf.Keys.RemoteAddress = "" 86 // Assign run of ports 87 const freeport = "0" 88 conf.Tendermint.ListenHost = rpc.LocalHost 89 conf.Tendermint.ListenPort = freeport 90 conf.RPC.GRPC.ListenHost = rpc.LocalHost 91 conf.RPC.GRPC.ListenPort = freeport 92 conf.RPC.Metrics.ListenHost = rpc.LocalHost 93 conf.RPC.Metrics.ListenPort = freeport 94 conf.RPC.Info.ListenHost = rpc.LocalHost 95 conf.RPC.Info.ListenPort = freeport 96 conf.RPC.Web3.ListenHost = rpc.LocalHost 97 conf.RPC.Web3.ListenPort = freeport 98 conf.Execution.TimeoutFactor = 0.5 99 conf.Execution.VMOptions = []execution.VMOption{} 100 for _, opt := range options { 101 if opt != nil { 102 opt(conf) 103 } 104 } 105 return conf, cleanup 106 } 107 108 // We use this to wrap tests 109 func TestKernel(validatorAccount *acm.PrivateAccount, keysAccounts []*acm.PrivateAccount, 110 testConfig *config.BurrowConfig) (*core.Kernel, error) { 111 112 fmt.Println("Creating integration test Kernel...") 113 114 kern, err := core.NewKernel(testConfig.BurrowDir) 115 if err != nil { 116 return nil, err 117 } 118 119 logger := logging.NewNoopLogger() 120 kern.SetLogger(logger) 121 if testConfig.Logging != nil { 122 err := kern.LoadLoggerFromConfig(testConfig.Logging) 123 if err != nil { 124 return nil, err 125 } 126 } 127 128 kern.SetKeyClient(keys.NewLocalKeyClient(keys.NewMemoryKeyStore(keysAccounts...), logger)) 129 130 err = kern.LoadExecutionOptionsFromConfig(testConfig.Execution) 131 if err != nil { 132 return nil, err 133 } 134 135 err = kern.LoadState(testConfig.GenesisDoc) 136 if err != nil { 137 return nil, err 138 } 139 140 privVal := tendermint.NewPrivValidatorMemory(validatorAccount, validatorAccount) 141 142 err = kern.LoadTendermintFromConfig(testConfig, privVal) 143 if err != nil { 144 return nil, err 145 } 146 147 kern.AddProcesses(core.DefaultProcessLaunchers(kern, testConfig.RPC, testConfig.Keys)...) 148 return kern, nil 149 } 150 151 // TestGenesisDoc creates genesis from a set of accounts 152 // and validators from indices within that slice 153 func TestGenesisDoc(addressables []*acm.PrivateAccount, vals ...int) *genesis.GenesisDoc { 154 accounts := make(map[string]*acm.Account, len(addressables)) 155 for i, pa := range addressables { 156 account := acm.FromAddressable(pa) 157 account.Balance += 1 << 32 158 account.Permissions = permission.AllAccountPermissions.Clone() 159 accounts[fmt.Sprintf("user_%v", i)] = account 160 } 161 genesisTime, err := time.Parse("02-01-2006", "27-10-2017") 162 if err != nil { 163 panic("could not parse test genesis time") 164 } 165 166 validators := make(map[string]*validator.Validator) 167 for _, i := range vals { 168 name := fmt.Sprintf("user_%d", i) 169 validators[name] = validator.FromAccount(accounts[name], 1<<16) 170 // Tendermint validators use a different addressing scheme for secp256k1 171 accounts[name].Address = validators[name].GetAddress() 172 } 173 174 return genesis.MakeGenesisDocFromAccounts(ChainName, nil, genesisTime, accounts, validators) 175 } 176 177 // Default deterministic account generation helper, pass number of accounts to make 178 func MakePrivateAccounts(sec string, n int) []*acm.PrivateAccount { 179 accounts := make([]*acm.PrivateAccount, n) 180 for i := 0; i < n; i++ { 181 accounts[i] = acm.GeneratePrivateAccountFromSecret(sec + strconv.Itoa(i)) 182 } 183 return accounts 184 } 185 186 func MakeEthereumAccounts(sec string, n int) []*acm.PrivateAccount { 187 accounts := make([]*acm.PrivateAccount, n) 188 for i := 0; i < n; i++ { 189 accounts[i] = acm.GenerateEthereumAccountFromSecret(sec + strconv.Itoa(i)) 190 } 191 return accounts 192 } 193 194 func Shutdown(kern *core.Kernel) { 195 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 196 defer cancel() 197 err := kern.Shutdown(ctx) 198 if err != nil { 199 fmt.Fprintf(os.Stderr, "Error shutting down test kernel %v: %v", kern, err) 200 } 201 }