@@ -2,6 +2,7 @@ package integration
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"hash/crc32"
7
8
"os"
@@ -10,15 +11,20 @@ import (
10
11
"strings"
11
12
"testing"
12
13
14
+ "github.com/gnolang/gno/gno.land/pkg/gnoland"
13
15
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
14
16
"github.com/gnolang/gno/tm2/pkg/bft/node"
15
17
"github.com/gnolang/gno/tm2/pkg/commands"
18
+ "github.com/gnolang/gno/tm2/pkg/crypto/bip39"
16
19
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
17
20
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
18
21
"github.com/gnolang/gno/tm2/pkg/log"
22
+ "github.com/gnolang/gno/tm2/pkg/std"
19
23
"github.com/rogpeppe/go-internal/testscript"
20
24
)
21
25
26
+ const numTestAccounts int = 4
27
+
22
28
type tSeqShim struct { * testing.T }
23
29
24
30
// noop Parallel method allow us to run test sequentially
@@ -71,6 +77,10 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
71
77
// Testscripts run concurrently by default, so we need to be prepared for that.
72
78
nodes := map [string ]* testNode {}
73
79
80
+ // Track new user balances added via the `adduser` command. These are added to the genesis
81
+ // state when the node is started.
82
+ var newUserBalances []gnoland.Balance
83
+
74
84
updateScripts , _ := strconv .ParseBool (os .Getenv ("UPDATE_SCRIPTS" ))
75
85
persistWorkDir , _ := strconv .ParseBool (os .Getenv ("TESTWORK" ))
76
86
return testscript.Params {
@@ -107,12 +117,25 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
107
117
env .Values ["_logger" ] = logger
108
118
}
109
119
110
- // Setup "test1" default account
120
+ // test1 must be created outside of the loop below because it is already included in genesis so
121
+ // attempting to recreate results in it getting overwritten and breaking existing tests that
122
+ // rely on its address being static.
111
123
kb .CreateAccount (DefaultAccount_Name , DefaultAccount_Seed , "" , "" , 0 , 0 )
112
-
113
124
env .Setenv ("USER_SEED_" + DefaultAccount_Name , DefaultAccount_Seed )
114
125
env .Setenv ("USER_ADDR_" + DefaultAccount_Name , DefaultAccount_Address )
115
126
127
+ // Create test accounts starting from test2.
128
+ for i := 1 ; i < numTestAccounts ; i ++ {
129
+ accountName := "test" + strconv .Itoa (i + 1 )
130
+
131
+ balance , err := createAccount (env , kb , accountName )
132
+ if err != nil {
133
+ return fmt .Errorf ("error creating account %s: %w" , accountName , err )
134
+ }
135
+
136
+ newUserBalances = append (newUserBalances , balance )
137
+ }
138
+
116
139
env .Setenv ("GNOROOT" , gnoRootDir )
117
140
env .Setenv ("GNOHOME" , gnoHomeDir )
118
141
@@ -126,15 +149,15 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
126
149
}
127
150
128
151
logger := ts .Value ("_logger" ).(log.Logger ) // grab logger
129
- sid := ts . Getenv ( "SID" ) // grab session id
152
+ sid := getNodeSID ( ts ) // grab session id
130
153
131
154
var cmd string
132
155
cmd , args = args [0 ], args [1 :]
133
156
134
157
var err error
135
158
switch cmd {
136
159
case "start" :
137
- if _ , ok := nodes [ sid ]; ok {
160
+ if nodeIsRunning ( nodes , sid ) {
138
161
err = fmt .Errorf ("node already started" )
139
162
break
140
163
}
@@ -144,6 +167,16 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
144
167
145
168
// Generate config and node
146
169
cfg , _ := TestingNodeConfig (t , gnoRootDir )
170
+
171
+ // Add balances for users added via the `adduser` command.
172
+ genesis := cfg .Genesis
173
+ genesisState := gnoland.GnoGenesisState {
174
+ Balances : genesis .AppState .(gnoland.GnoGenesisState ).Balances ,
175
+ Txs : genesis .AppState .(gnoland.GnoGenesisState ).Txs ,
176
+ }
177
+ genesisState .Balances = append (genesisState .Balances , newUserBalances ... )
178
+ cfg .Genesis .AppState = genesisState
179
+
147
180
n , remoteAddr := TestingInMemoryNode (t , logger , cfg )
148
181
149
182
// Register cleanup
@@ -211,10 +244,42 @@ func setupGnolandTestScript(t *testing.T, txtarDir string) testscript.Params {
211
244
212
245
tsValidateError (ts , "gnokey" , neg , err )
213
246
},
247
+ // adduser commands must be executed before starting the node; it errors out otherwise.
248
+ "adduser" : func (ts * testscript.TestScript , neg bool , args []string ) {
249
+ if nodeIsRunning (nodes , getNodeSID (ts )) {
250
+ tsValidateError (ts , "adduser" , neg , errors .New ("adduser must be used before starting node" ))
251
+ return
252
+ }
253
+
254
+ if len (args ) == 0 {
255
+ ts .Fatalf ("new user name required" )
256
+ }
257
+
258
+ kb , err := keys .NewKeyBaseFromDir (gnoHomeDir )
259
+ if err != nil {
260
+ ts .Fatalf ("unable to get keybase" )
261
+ }
262
+
263
+ balance , err := createAccount (ts , kb , args [0 ])
264
+ if err != nil {
265
+ ts .Fatalf ("error creating account %s: %s" , args [0 ], err )
266
+ }
267
+
268
+ newUserBalances = append (newUserBalances , balance )
269
+ },
214
270
},
215
271
}
216
272
}
217
273
274
+ func getNodeSID (ts * testscript.TestScript ) string {
275
+ return ts .Getenv ("SID" )
276
+ }
277
+
278
+ func nodeIsRunning (nodes map [string ]* testNode , sid string ) bool {
279
+ _ , ok := nodes [sid ]
280
+ return ok
281
+ }
282
+
218
283
func getTestingLogger (env * testscript.Env , logname string ) (log.Logger , error ) {
219
284
var path string
220
285
@@ -273,3 +338,35 @@ func tsValidateError(ts *testscript.TestScript, cmd string, neg bool, err error)
273
338
}
274
339
}
275
340
}
341
+
342
+ type envSetter interface {
343
+ Setenv (key , value string )
344
+ }
345
+
346
+ // createAccount creates a new account with the given name and adds it to the keybase.
347
+ func createAccount (env envSetter , kb keys.Keybase , accountName string ) (gnoland.Balance , error ) {
348
+ var balance gnoland.Balance
349
+ entropy , err := bip39 .NewEntropy (256 )
350
+ if err != nil {
351
+ return balance , fmt .Errorf ("error creating entropy: %w" , err )
352
+ }
353
+
354
+ mnemonic , err := bip39 .NewMnemonic (entropy )
355
+ if err != nil {
356
+ return balance , fmt .Errorf ("error generating mnemonic: %w" , err )
357
+ }
358
+
359
+ var keyInfo keys.Info
360
+ if keyInfo , err = kb .CreateAccount (accountName , mnemonic , "" , "" , 0 , 0 ); err != nil {
361
+ return balance , fmt .Errorf ("unable to create account: %w" , err )
362
+ }
363
+
364
+ address := keyInfo .GetAddress ()
365
+ env .Setenv ("USER_SEED_" + accountName , mnemonic )
366
+ env .Setenv ("USER_ADDR_" + accountName , address .String ())
367
+
368
+ return gnoland.Balance {
369
+ Address : address ,
370
+ Amount : std.Coins {std .NewCoin ("ugnot" , 1000000000000000000 )},
371
+ }, nil
372
+ }
0 commit comments