diff --git a/Makefile b/Makefile index f170d1802..9175a7ebe 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .SILENT: POCKETD_HOME := ./localnet/pocketd -POCKET_NODE = 127.0.0.1:36657 # The pocket rollup node (full node and sequencer in the localnet context) +POCKET_NODE := tcp://127.0.0.1:36657 # The pocket rollup node (full node and sequencer in the localnet context) ######################## ### Makefile Helpers ### @@ -98,6 +98,10 @@ localnet_regenesis: ## Regenerate the localnet genesis file ### Tests ### ############# +.PHONY: test_e2e +test_e2e: ## Run all E2E tests + export POCKET_NODE=$(POCKET_NODE) POCKETD_HOME=../../$(POCKETD_HOME) && go test -v ./e2e/tests/... -tags=e2e + .PHONY: go_test go_test: go_version_check ## Run all go tests go test -v ./... @@ -157,4 +161,4 @@ todo_count: ## Print a count of all the TODOs in the project .PHONY: todo_this_commit todo_this_commit: ## List all the TODOs needed to be done in this commit - grep --exclude-dir={.git,vendor,prototype,.vscode} --exclude=Makefile -r -e "TODO_IN_THIS_COMMIT" -e "DISCUSS_IN_THIS_COMMIT" \ No newline at end of file + grep --exclude-dir={.git,vendor,prototype,.vscode} --exclude=Makefile -r -e "TODO_IN_THIS_COMMIT" -e "DISCUSS_IN_THIS_COMMIT" diff --git a/e2e/tests/help.feature b/e2e/tests/help.feature new file mode 100644 index 000000000..156ec5194 --- /dev/null +++ b/e2e/tests/help.feature @@ -0,0 +1,7 @@ +Feature: Root Namespace + + Scenario: User Needs Help + Given the user has the pocketd binary installed + When the user runs the command "help" + Then the user should be able to see standard output containing "Available Commands" + And the pocketd binary should exit without error \ No newline at end of file diff --git a/e2e/tests/init_test.go b/e2e/tests/init_test.go new file mode 100644 index 000000000..0ab3be752 --- /dev/null +++ b/e2e/tests/init_test.go @@ -0,0 +1,95 @@ +//go:build e2e + +package e2e + +import ( + "fmt" + "regexp" + "strings" + "testing" + + "github.com/regen-network/gocuke" + "github.com/stretchr/testify/require" +) + +var addrRe *regexp.Regexp + +func init() { + addrRe = regexp.MustCompile(`address:\s+(pokt1\w+)`) +} + +type suite struct { + gocuke.TestingT + pocketd *pocketdBin +} + +func (s *suite) Before() { + s.pocketd = new(pocketdBin) +} + +// TestFeatures runs the e2e tests specified in any .features files in this directory +// * This test suite assumes that a LocalNet is running +func TestFeatures(t *testing.T) { + gocuke.NewRunner(t, &suite{}).Path("*.feature").Run() +} + +func (s *suite) TheUserHasThePocketdBinaryInstalled() { + s.TheUserRunsTheCommand("help") +} + +func (s *suite) ThePocketdBinaryShouldExitWithoutError() { + require.NoError(s, s.pocketd.result.Err) +} + +func (s *suite) TheUserRunsTheCommand(cmd string) { + cmds := strings.Split(cmd, " ") + res, err := s.pocketd.RunCommand(cmds...) + s.pocketd.result = res + if err != nil { + s.Fatalf("error running command %s: %s", cmd, err) + } +} + +func (s *suite) TheUserShouldBeAbleToSeeStandardOutputContaining(arg1 string) { + if !strings.Contains(s.pocketd.result.Stdout, arg1) { + s.Fatalf("stdout must contain %s", arg1) + } +} + +func (s *suite) TheUserSendsUpoktToAnotherAddress(amount int64) { + addrs := s.getAddresses() + args := []string{ + "tx", + "bank", + "send", + addrs[0], + addrs[1], + fmt.Sprintf("%dupokt", amount), + "--keyring-backend", + "test", + "-y", + } + res, err := s.pocketd.RunCommandOnHost("", args...) + if err != nil { + s.Fatalf("error sending upokt: %s", err) + } + s.pocketd.result = res +} + +func (s *suite) getAddresses() [2]string { + var strs [2]string + res, err := s.pocketd.RunCommand( + "keys", "list", "--keyring-backend", "test", + ) + if err != nil { + s.Fatalf("error getting keys: %s", err) + } + matches := addrRe.FindAllStringSubmatch(res.Stdout, -1) + if len(matches) >= 2 { + strs[0] = matches[0][1] + strs[1] = matches[len(matches)-1][1] + } else { + s.Fatalf("could not find two addresses in output: %s", res.Stdout) + } + return strs +} diff --git a/e2e/tests/node.go b/e2e/tests/node.go new file mode 100644 index 000000000..4a025cae5 --- /dev/null +++ b/e2e/tests/node.go @@ -0,0 +1,79 @@ +//go:build e2e + +package e2e + +import ( + "fmt" + "os" + "os/exec" +) + +var ( + // defaultRPCURL used by pocketdBin to run remote commands + defaultRPCURL = os.Getenv("POCKET_NODE") + // defaultRPCPort is the default RPC port that pocketd listens on + defaultRPCPort = 36657 + // defaultRPCHost is the default RPC host that pocketd listens on + defaultRPCHost = "127.0.0.1" + // defaultHome is the default home directory for pocketd + defaultHome = os.Getenv("POCKETD_HOME") +) + +func init() { + if defaultRPCURL == "" { + defaultRPCURL = fmt.Sprintf("tcp://%s:%d", defaultRPCHost, defaultRPCPort) + } + if defaultHome == "" { + defaultHome = "./localnet/pocketd" + } +} + +// commandResult combines the stdout, stderr, and err of an operation +type commandResult struct { + Stdout string + Stderr string + Err error +} + +// PocketClient is a single function interface for interacting with a node +type PocketClient interface { + RunCommand(...string) (*commandResult, error) + RunCommandOnHost(string, ...string) (*commandResult, error) +} + +// Ensure that pocketdBin struct fulfills PocketClient +var _ PocketClient = &pocketdBin{} + +// pocketdBin holds the reults of the last command that was run +type pocketdBin struct { + result *commandResult // stores the result of the last command that was run +} + +// RunCommand runs a command on the local machine using the pocketd binary +func (p *pocketdBin) RunCommand(args ...string) (*commandResult, error) { + return p.runCmd(args...) +} + +// RunCommandOnHost runs a command on specified host with the given args +func (p *pocketdBin) RunCommandOnHost(rpcUrl string, args ...string) (*commandResult, error) { + if rpcUrl == "" { + rpcUrl = defaultRPCURL + } + args = append(args, "--node", rpcUrl) + return p.runCmd(args...) +} + +// runCmd is a helper to run a command using the local pocketd binary with the flags provided +func (p *pocketdBin) runCmd(args ...string) (*commandResult, error) { + base := []string{"--home", defaultHome} + args = append(base, args...) + cmd := exec.Command("pocketd", args...) + r := &commandResult{} + out, err := cmd.Output() + if err != nil { + return nil, err + } + r.Stdout = string(out) + p.result = r + return r, nil +} diff --git a/e2e/tests/send.feature b/e2e/tests/send.feature new file mode 100644 index 000000000..1e2bdf2f8 --- /dev/null +++ b/e2e/tests/send.feature @@ -0,0 +1,8 @@ +Feature: Tx Namespace + + Scenario: User can send uPOKT + Given the user has the pocketd binary installed + When the user sends 10000 uPOKT to another address + Then the user should be able to see standard output containing "txhash:" + And the user should be able to see standard output containing "code: 0" + And the pocketd binary should exit without error diff --git a/go.mod b/go.mod index 6867f8051..4b4af11b9 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 + github.com/regen-network/gocuke v0.6.2 github.com/spf13/cast v1.5.1 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 @@ -40,6 +41,7 @@ require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/benbjohnson/clock v1.3.0 // indirect @@ -59,6 +61,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cockroachdb/apd/v3 v3.1.0 // indirect github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect @@ -71,6 +74,8 @@ require ( github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/creachadair/taskgroup v0.6.0 // indirect + github.com/cucumber/common/gherkin/go/v22 v22.0.0 // indirect + github.com/cucumber/common/messages/go/v17 v17.1.1 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -98,6 +103,7 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gofrs/uuid v4.3.1+incompatible // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/glog v1.1.0 // indirect @@ -126,6 +132,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect @@ -262,6 +269,7 @@ require ( google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools/v3 v3.5.0 // indirect lukechampine.com/blake3 v1.1.7 // indirect nhooyr.io/websocket v1.8.7 // indirect pgregory.net/rapid v0.5.5 // indirect diff --git a/go.sum b/go.sum index d17f52f79..48ddd50c7 100644 --- a/go.sum +++ b/go.sum @@ -270,6 +270,9 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E= +github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -419,6 +422,7 @@ github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= @@ -487,7 +491,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/daixiang0/gci v0.4.2/go.mod h1:d0f+IJhr9loBtIq+ebwhRoTt1LGbPH96ih8bKlsRT9E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= @@ -676,8 +682,10 @@ github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -925,8 +933,9 @@ github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoD github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= @@ -1662,6 +1671,7 @@ github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= +github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= @@ -2833,11 +2843,11 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=