Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new txtar command adduser #1471

Merged
merged 14 commits into from
Jan 10, 2024
5 changes: 5 additions & 0 deletions gno.land/cmd/gnoland/testdata/adduser-err.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
gnoland start

# should fail if user is added after node is started
! adduser test5
stderr '"adduser" error: adduser must be used before starting node'
30 changes: 30 additions & 0 deletions gno.land/cmd/gnoland/testdata/adduser.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
adduser test8

## start a new node
gnoland start

## add bar.gno package located in $WORK directory as gno.land/r/foobar/bar
gnokey maketx addpkg -pkgdir $WORK/bar -pkgpath gno.land/r/foobar/bar -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test8

## execute Render
gnokey maketx run -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test8 $WORK/script/script.gno

## compare render
stdout 'main: --- hello from foo ---'
stdout 'OK!'
stdout 'GAS WANTED: 200000'
stdout 'GAS USED: '

-- bar/bar.gno --
package bar

func Render(path string) string {
return "hello from foo"
}

-- script/script.gno --
package main
import "gno.land/r/foobar/bar"
func main() {
println("main: ---", bar.Render(""), "---")
}
8 changes: 8 additions & 0 deletions gno.land/pkg/integration/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
// - `--remote`, `--insecure-password-stdin`, and `--home` flags are set automatically to
// communicate with the gnoland node.
//
// 3. `adduser`:
// - Creates a new user in the default keybase directory
deelawn marked this conversation as resolved.
Show resolved Hide resolved
// - Must be run before `gnoland start`.
//
// 4. `sleep`:
// - Sleeps for a specified duration string, parsed by `time.ParseDuration`.
// - Defaults to 1 second if no duration is specified.
//
// Logging:
//
// Gnoland logs aren't forwarded to stdout to avoid overwhelming the tests with too much
Expand Down
86 changes: 84 additions & 2 deletions gno.land/pkg/integration/testing_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

import (
"context"
"errors"
"fmt"
"hash/crc32"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"time"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/tm2/pkg/bft/node"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/bip39"
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
"github.com/gnolang/gno/tm2/pkg/crypto/keys/client"
"github.com/gnolang/gno/tm2/pkg/log"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/rogpeppe/go-internal/testscript"
)

Expand Down Expand Up @@ -71,6 +76,10 @@
// Testscripts run concurrently by default, so we need to be prepared for that.
nodes := map[string]*testNode{}

// Track new user balances added via the `adduser` command. These are added to the genesis
// state when the node is started.
var newUserBalances []gnoland.Balance

updateScripts, _ := strconv.ParseBool(os.Getenv("UPDATE_SCRIPTS"))
persistWorkDir, _ := strconv.ParseBool(os.Getenv("TESTWORK"))
return testscript.Params{
Expand Down Expand Up @@ -126,15 +135,15 @@
}

logger := ts.Value("_logger").(log.Logger) // grab logger
sid := ts.Getenv("SID") // grab session id
sid := getNodeSID(ts) // grab session id

var cmd string
cmd, args = args[0], args[1:]

var err error
switch cmd {
case "start":
if _, ok := nodes[sid]; ok {
if nodeIsRunning(nodes, sid) {
err = fmt.Errorf("node already started")
break
}
Expand All @@ -144,6 +153,16 @@

// Generate config and node
cfg, _ := TestingNodeConfig(t, gnoRootDir)

// Add balances for users added via the `adduser` command.
genesis := cfg.Genesis
genesisState := gnoland.GnoGenesisState{
Balances: genesis.AppState.(gnoland.GnoGenesisState).Balances,
Txs: genesis.AppState.(gnoland.GnoGenesisState).Txs,
}
genesisState.Balances = append(genesisState.Balances, newUserBalances...)
cfg.Genesis.AppState = genesisState

n, remoteAddr := TestingInMemoryNode(t, logger, cfg)

// Register cleanup
Expand Down Expand Up @@ -211,10 +230,73 @@

tsValidateError(ts, "gnokey", neg, err)
},
"sleep": func(ts *testscript.TestScript, neg bool, args []string) {
deelawn marked this conversation as resolved.
Show resolved Hide resolved
d := time.Second
if len(args) > 0 {
var err error
if d, err = time.ParseDuration(args[0]); err != nil {
ts.Fatalf("unable to parse duration %q: %s", args[1], err)
}

Check warning on line 239 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L233-L239

Added lines #L233 - L239 were not covered by tests
}

time.Sleep(d)

Check warning on line 242 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L242

Added line #L242 was not covered by tests
},
// adduser commands must be executed before starting the node; it errors out otherwise.
"adduser": func(ts *testscript.TestScript, neg bool, args []string) {
deelawn marked this conversation as resolved.
Show resolved Hide resolved
deelawn marked this conversation as resolved.
Show resolved Hide resolved
if nodeIsRunning(nodes, getNodeSID(ts)) {
tsValidateError(ts, "adduser", neg, errors.New("adduser must be used before starting node"))
return
}

Check warning on line 249 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L245-L249

Added lines #L245 - L249 were not covered by tests

if len(args) == 0 {
ts.Fatalf("new user name required")
}

Check warning on line 253 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L251-L253

Added lines #L251 - L253 were not covered by tests

entropy, err := bip39.NewEntropy(256)
if err != nil {
ts.Fatalf("error creating entropy: %v", err)
}

Check warning on line 258 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L255-L258

Added lines #L255 - L258 were not covered by tests

mnemonic, err := bip39.NewMnemonic(entropy)
if err != nil {
ts.Fatalf("error generating mnemonic: %v", err)
}

Check warning on line 263 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L260-L263

Added lines #L260 - L263 were not covered by tests

accountName := args[0]
kb, err := keys.NewKeyBaseFromDir(gnoHomeDir)
if err != nil {
ts.Fatalf("unable to fetch keybase: %v", err)
}

Check warning on line 269 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L265-L269

Added lines #L265 - L269 were not covered by tests

var keyInfo keys.Info
if keyInfo, err = kb.CreateAccount(accountName, mnemonic, "", "", 0, 0); err != nil {
ts.Fatalf("unable to create account: %v", err)
}

Check warning on line 274 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L271-L274

Added lines #L271 - L274 were not covered by tests

address := keyInfo.GetAddress()
newUserBalances = append(
newUserBalances,
gnoland.Balance{
Address: address,
Amount: std.Coins{std.NewCoin("ugnot", 1000000000000000000)},
},
)
ts.Setenv("USER_SEED_"+accountName, mnemonic)
ts.Setenv("USER_ADDR_"+accountName, address.String())

Check warning on line 285 in gno.land/pkg/integration/testing_integration.go

View check run for this annotation

Codecov / codecov/patch

gno.land/pkg/integration/testing_integration.go#L276-L285

Added lines #L276 - L285 were not covered by tests
},
},
}
}

func getNodeSID(ts *testscript.TestScript) string {
return ts.Getenv("SID")
}

func nodeIsRunning(nodes map[string]*testNode, sid string) bool {
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
_, ok := nodes[sid]
return ok
}

func getTestingLogger(env *testscript.Env, logname string) (log.Logger, error) {
var path string

Expand Down
Loading