-
Notifications
You must be signed in to change notification settings - Fork 0
/
suite.go
234 lines (190 loc) · 7.9 KB
/
suite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package testutil
import (
"fmt"
"math/big"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/suite"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/incubus-network/fury/app"
"github.com/incubus-network/fury/tests/e2e/runner"
"github.com/incubus-network/fury/tests/util"
)
const (
FundedAccountName = "whale"
// use coin type 60 so we are compatible with accounts from `fury add keys --eth <name>`
// these accounts use the ethsecp256k1 signing algorithm that allows the signing client
// to manage both sdk & evm txs.
Bip44CoinType = 60
IbcPort = "transfer"
IbcChannel = "channel-0"
)
// DeployedErc20 is a type that wraps the details of the pre-deployed erc20 used by the e2e test suite.
// The Address comes from SuiteConfig.FuryErc20Address
// The CosmosDenom is fetched from the EnabledConversionPairs param of x/evmutil.
// The tests expect the following:
// - the funded account has a nonzero balance of the erc20
// - the erc20 is enabled for conversion to sdk.Coin
// - the corresponding sdk.Coin is enabled as an earn vault denom
// These requirements are checked in InitFuryEvmData().
type DeployedErc20 struct {
Address common.Address
CosmosDenom string
}
// E2eTestSuite is a testify test suite for running end-to-end integration tests on Fury.
type E2eTestSuite struct {
suite.Suite
config SuiteConfig
runner runner.NodeRunner
Fury *Chain
Ibc *Chain
UpgradeHeight int64
DeployedErc20 DeployedErc20
cost costSummary
enableRefunds bool
}
// costSummary wraps info about what funds get irrecoverably spent by the test suite run
type costSummary struct {
sdkAddress string
evmAddress string
erc20BalanceBefore *big.Int
erc20BalanceAfter *big.Int
sdkBalanceBefore sdk.Coins
sdkBalanceAfter sdk.Coins
}
// String implements fmt.Stringer
func (s costSummary) String() string {
before := sdk.NewCoins(s.sdkBalanceBefore...).Add(sdk.NewCoin("erc20", sdkmath.NewIntFromBigInt(s.erc20BalanceBefore)))
after := sdk.NewCoins(s.sdkBalanceAfter...).Add(sdk.NewCoin("erc20", sdkmath.NewIntFromBigInt(s.erc20BalanceAfter)))
cost, _ := before.SafeSub(after...)
return fmt.Sprintf("Cost Summary for %s (%s):\nbefore:\n%s\nafter:\n%s\ncost:\n%s\n",
s.sdkAddress, s.evmAddress, util.PrettyPrintCoins(before), util.PrettyPrintCoins(after), util.PrettyPrintCoins(cost),
)
}
// SetupSuite is run before all tests. It initializes chain connections and sets up the
// account used for funding accounts in the tests.
func (suite *E2eTestSuite) SetupSuite() {
var err error
fmt.Println("setting up test suite.")
app.SetSDKConfig()
suiteConfig := ParseSuiteConfig()
suite.config = suiteConfig
suite.DeployedErc20 = DeployedErc20{
Address: common.HexToAddress(suiteConfig.FuryErc20Address),
// Denom is fetched in InitFuryEvmData()
}
// setup the correct NodeRunner for the given config
if suiteConfig.Kvtool != nil {
suite.runner = suite.SetupKvtoolNodeRunner()
} else if suiteConfig.LiveNetwork != nil {
suite.runner = suite.SetupLiveNetworkNodeRunner()
} else {
panic("expected either kvtool or live network configs to be defined")
}
chains := suite.runner.StartChains()
furychain := chains.MustGetChain("fury")
suite.Fury, err = NewChain(suite.T(), furychain, suiteConfig.FundedAccountMnemonic)
if err != nil {
suite.runner.Shutdown()
suite.T().Fatalf("failed to create fury chain querier: %s", err)
}
if suiteConfig.IncludeIbcTests {
ibcchain := chains.MustGetChain("ibc")
suite.Ibc, err = NewChain(suite.T(), ibcchain, suiteConfig.FundedAccountMnemonic)
if err != nil {
suite.runner.Shutdown()
suite.T().Fatalf("failed to create ibc chain querier: %s", err)
}
}
suite.InitFuryEvmData()
whale := suite.Fury.GetAccount(FundedAccountName)
suite.cost = costSummary{
sdkAddress: whale.SdkAddress.String(),
evmAddress: whale.EvmAddress.Hex(),
sdkBalanceBefore: suite.Fury.QuerySdkForBalances(whale.SdkAddress),
erc20BalanceBefore: suite.Fury.GetErc20Balance(suite.DeployedErc20.Address, whale.EvmAddress),
}
}
// TearDownSuite is run after all tests have run.
// In the event of a panic during the tests, it is run after testify recovers.
func (suite *E2eTestSuite) TearDownSuite() {
fmt.Println("tearing down test suite.")
whale := suite.Fury.GetAccount(FundedAccountName)
if suite.enableRefunds {
suite.cost.sdkBalanceAfter = suite.Fury.QuerySdkForBalances(whale.SdkAddress)
suite.cost.erc20BalanceAfter = suite.Fury.GetErc20Balance(suite.DeployedErc20.Address, whale.EvmAddress)
fmt.Println("==BEFORE REFUNDS==")
fmt.Println(suite.cost)
fmt.Println("attempting to return all unused funds")
suite.Fury.ReturnAllFunds()
fmt.Println("==AFTER REFUNDS==")
}
// calculate & output cost summary for funded account
suite.cost.sdkBalanceAfter = suite.Fury.QuerySdkForBalances(whale.SdkAddress)
suite.cost.erc20BalanceAfter = suite.Fury.GetErc20Balance(suite.DeployedErc20.Address, whale.EvmAddress)
fmt.Println(suite.cost)
// TODO: track asset denoms & then return all funds to initial funding account.
// close all account request channels
suite.Fury.Shutdown()
if suite.Ibc != nil {
suite.Ibc.Shutdown()
}
// gracefully shutdown docker container(s)
suite.runner.Shutdown()
}
// SetupKvtoolNodeRunner is a helper method for building a KvtoolRunnerConfig from the suite config.
func (suite *E2eTestSuite) SetupKvtoolNodeRunner() *runner.KvtoolRunner {
// upgrade tests are only supported on kvtool networks
suite.UpgradeHeight = suite.config.Kvtool.FuryUpgradeHeight
suite.enableRefunds = false
runnerConfig := runner.KvtoolRunnerConfig{
FuryConfigTemplate: suite.config.Kvtool.FuryConfigTemplate,
IncludeIBC: suite.config.IncludeIbcTests,
ImageTag: "local",
EnableAutomatedUpgrade: suite.config.Kvtool.IncludeAutomatedUpgrade,
FuryUpgradeName: suite.config.Kvtool.FuryUpgradeName,
FuryUpgradeHeight: suite.config.Kvtool.FuryUpgradeHeight,
FuryUpgradeBaseImageTag: suite.config.Kvtool.FuryUpgradeBaseImageTag,
SkipShutdown: suite.config.SkipShutdown,
}
return runner.NewKvtoolRunner(runnerConfig)
}
// SetupLiveNetworkNodeRunner is a helper method for building a LiveNodeRunner from the suite config.
func (suite *E2eTestSuite) SetupLiveNetworkNodeRunner() *runner.LiveNodeRunner {
// live network setup doesn't presently support ibc
if suite.config.IncludeIbcTests {
panic("ibc tests not supported for live network configuration")
}
suite.enableRefunds = true
runnerConfig := runner.LiveNodeRunnerConfig{
FuryRpcUrl: suite.config.LiveNetwork.FuryRpcUrl,
FuryGrpcUrl: suite.config.LiveNetwork.FuryGrpcUrl,
FuryEvmRpcUrl: suite.config.LiveNetwork.FuryEvmRpcUrl,
}
return runner.NewLiveNodeRunner(runnerConfig)
}
// SkipIfIbcDisabled should be called at the start of tests that require IBC.
// It gracefully skips the current test if IBC tests are disabled.
func (suite *E2eTestSuite) SkipIfIbcDisabled() {
if !suite.config.IncludeIbcTests {
suite.T().SkipNow()
}
}
// SkipIfUpgradeDisabled should be called at the start of tests that require automated upgrades.
// It gracefully skips the current test if upgrades are dissabled.
// Note: automated upgrade tests are currently only enabled for Kvtool suite runs.
func (suite *E2eTestSuite) SkipIfUpgradeDisabled() {
if suite.config.Kvtool != nil && suite.config.Kvtool.IncludeAutomatedUpgrade {
suite.T().SkipNow()
}
}
// FuryHomePath returns the OS-specific filepath for the fury home directory
// Assumes network is running with kvtool installed from the sub-repository in tests/e2e/kvtool
func (suite *E2eTestSuite) FuryHomePath() string {
return filepath.Join("kvtool", "full_configs", "generated", "fury", "initstate", ".fury")
}
// BigIntsEqual is a helper method for comparing the equality of two big ints
func (suite *E2eTestSuite) BigIntsEqual(expected *big.Int, actual *big.Int, msg string) {
suite.Truef(expected.Cmp(actual) == 0, "%s (expected: %s, actual: %s)", msg, expected.String(), actual.String())
}