refactor: share code between CLI tests

This commit is contained in:
Dirk McCormick
2020-10-26 13:50:07 +01:00
parent d4cdc6d334
commit b097a5fb0c
5 changed files with 188 additions and 249 deletions
+7 -7
View File
@@ -25,8 +25,8 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
defer cancel()
// Create mock CLI
mockCLI := newMockCLI(t, cmds)
clientCLI := mockCLI.client(clientNode.ListenAddr)
mockCLI := NewMockCLI(t, cmds)
clientCLI := mockCLI.Client(clientNode.ListenAddr)
// Get the miner address
addrs, err := clientNode.StateListMiners(ctx, types.EmptyTSK)
@@ -40,7 +40,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
cmd := []string{
"client", "query-ask", minerAddr.String(),
}
out := clientCLI.runCmd(cmd)
out := clientCLI.RunCmd(cmd)
require.Regexp(t, regexp.MustCompile("Ask:"), out)
// Create a deal (non-interactive)
@@ -53,7 +53,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
cmd = []string{
"client", "deal", dataCid.String(), minerAddr.String(), price, duration,
}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println("client deal", out)
// Create a deal (interactive)
@@ -77,7 +77,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
"no",
"yes",
}
out = clientCLI.runInteractiveCmd(cmd, interactiveCmds)
out = clientCLI.RunInteractiveCmd(cmd, interactiveCmds)
fmt.Println("client deal:\n", out)
// Wait for provider to start sealing deal
@@ -85,7 +85,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
for dealStatus != "StorageDealSealing" {
// client list-deals
cmd = []string{"client", "list-deals"}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println("list-deals:\n", out)
lines := strings.Split(out, "\n")
@@ -109,7 +109,7 @@ func RunClientTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNode)
cmd = []string{
"client", "retrieve", dataCid.String(), path,
}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println("retrieve:\n", out)
require.Regexp(t, regexp.MustCompile("Success"), out)
}
+45 -25
View File
@@ -11,14 +11,14 @@ import (
lcli "github.com/urfave/cli/v2"
)
type mockCLI struct {
type MockCLI struct {
t *testing.T
cmds []*lcli.Command
cctx *lcli.Context
out *bytes.Buffer
}
func newMockCLI(t *testing.T, cmds []*lcli.Command) *mockCLI {
func NewMockCLI(t *testing.T, cmds []*lcli.Command) *MockCLI {
// Create a CLI App with an --api-url flag so that we can specify which node
// the command should be executed against
app := &lcli.App{
@@ -36,15 +36,15 @@ func newMockCLI(t *testing.T, cmds []*lcli.Command) *mockCLI {
app.Setup()
cctx := lcli.NewContext(app, &flag.FlagSet{}, nil)
return &mockCLI{t: t, cmds: cmds, cctx: cctx, out: &out}
return &MockCLI{t: t, cmds: cmds, cctx: cctx, out: &out}
}
func (c *mockCLI) client(addr multiaddr.Multiaddr) *mockCLIClient {
return &mockCLIClient{t: c.t, cmds: c.cmds, addr: addr, cctx: c.cctx, out: c.out}
func (c *MockCLI) Client(addr multiaddr.Multiaddr) *MockCLIClient {
return &MockCLIClient{t: c.t, cmds: c.cmds, addr: addr, cctx: c.cctx, out: c.out}
}
// mockCLIClient runs commands against a particular node
type mockCLIClient struct {
// MockCLIClient runs commands against a particular node
type MockCLIClient struct {
t *testing.T
cmds []*lcli.Command
addr multiaddr.Multiaddr
@@ -52,7 +52,7 @@ type mockCLIClient struct {
out *bytes.Buffer
}
func (c *mockCLIClient) run(cmd []string, params []string, args []string) string {
func (c *MockCLIClient) run(cmd []string, params []string, args []string) string {
// Add parameter --api-url=<node api listener address>
apiFlag := "--api-url=" + c.addr.String()
params = append([]string{apiFlag}, params...)
@@ -66,28 +66,48 @@ func (c *mockCLIClient) run(cmd []string, params []string, args []string) string
return str
}
func (c *mockCLIClient) runCmd(input []string) string {
cmd := c.cmdByNameSub(input[0], input[1])
out, err := c.runCmdRaw(cmd, input[2:])
func (c *MockCLIClient) RunCmd(input []string) string {
out, err := c.RunCmdRaw(input)
require.NoError(c.t, err)
return out
}
func (c *mockCLIClient) cmdByNameSub(name string, sub string) *lcli.Command {
for _, c := range c.cmds {
if c.Name == name {
for _, s := range c.Subcommands {
if s.Name == sub {
return s
}
}
// Given an input, find the corresponding command or sub-command.
// eg "paych add-funds"
func (c *MockCLIClient) cmdByNameSub(input []string) (*lcli.Command, []string) {
name := input[0]
for _, cmd := range c.cmds {
if cmd.Name == name {
return c.findSubcommand(cmd, input[1:])
}
}
return nil
return nil, []string{}
}
func (c *mockCLIClient) runCmdRaw(cmd *lcli.Command, input []string) (string, error) {
func (c *MockCLIClient) findSubcommand(cmd *lcli.Command, input []string) (*lcli.Command, []string) {
// If there are no sub-commands, return the current command
if len(cmd.Subcommands) == 0 {
return cmd, input
}
// Check each sub-command for a match against the name
subName := input[0]
for _, subCmd := range cmd.Subcommands {
if subCmd.Name == subName {
// Found a match, recursively search for sub-commands
return c.findSubcommand(subCmd, input[1:])
}
}
return nil, []string{}
}
func (c *MockCLIClient) RunCmdRaw(input []string) (string, error) {
cmd, input := c.cmdByNameSub(input)
if cmd == nil {
panic("Could not find command " + input[0] + " " + input[1])
}
// prepend --api-url=<node api listener address>
apiFlag := "--api-url=" + c.addr.String()
input = append([]string{apiFlag}, input...)
@@ -104,7 +124,7 @@ func (c *mockCLIClient) runCmdRaw(cmd *lcli.Command, input []string) (string, er
return str, err
}
func (c *mockCLIClient) flagSet(cmd *lcli.Command) *flag.FlagSet {
func (c *MockCLIClient) flagSet(cmd *lcli.Command) *flag.FlagSet {
// Apply app level flags (so we can process --api-url flag)
fs := &flag.FlagSet{}
for _, f := range c.cctx.App.Flags {
@@ -123,11 +143,11 @@ func (c *mockCLIClient) flagSet(cmd *lcli.Command) *flag.FlagSet {
return fs
}
func (c *mockCLIClient) runInteractiveCmd(cmd []string, interactive []string) string {
func (c *MockCLIClient) RunInteractiveCmd(cmd []string, interactive []string) string {
c.toStdin(strings.Join(interactive, "\n") + "\n")
return c.runCmd(cmd)
return c.RunCmd(cmd)
}
func (c *mockCLIClient) toStdin(s string) {
func (c *MockCLIClient) toStdin(s string) {
c.cctx.App.Metadata["stdin"] = bytes.NewBufferString(s)
}
+6 -6
View File
@@ -18,8 +18,8 @@ func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNod
ctx := context.Background()
// Create mock CLI
mockCLI := newMockCLI(t, cmds)
clientCLI := mockCLI.client(clientNode.ListenAddr)
mockCLI := NewMockCLI(t, cmds)
clientCLI := mockCLI.Client(clientNode.ListenAddr)
// Create some wallets on the node to use for testing multisig
var walletAddrs []address.Address
@@ -48,7 +48,7 @@ func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNod
walletAddrs[1].String(),
walletAddrs[2].String(),
}
out := clientCLI.runCmd(cmd)
out := clientCLI.RunCmd(cmd)
fmt.Println(out)
// Extract msig robust address from output
@@ -68,12 +68,12 @@ func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNod
msigRobustAddr,
walletAddrs[3].String(),
}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println(out)
// msig inspect <msig>
cmd = []string{"msig", "inspect", "--vesting", "--decode-params", msigRobustAddr}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println(out)
// Expect correct balance
@@ -96,6 +96,6 @@ func RunMultisigTest(t *testing.T, cmds []*lcli.Command, clientNode test.TestNod
walletAddrs[3].String(),
"false",
}
out = clientCLI.runCmd(cmd)
out = clientCLI.RunCmd(cmd)
fmt.Println(out)
}
+46
View File
@@ -5,6 +5,9 @@ import (
"testing"
"time"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/api/test"
test2 "github.com/filecoin-project/lotus/node/test"
@@ -39,3 +42,46 @@ func StartOneNodeOneMiner(ctx context.Context, t *testing.T, blocktime time.Dura
// Create mock CLI
return full, fullAddr
}
func StartTwoNodesOneMiner(ctx context.Context, t *testing.T, blocktime time.Duration) ([]test.TestNode, []address.Address) {
n, sn := test2.RPCMockSbBuilder(t, test.TwoFull, test.OneMiner)
fullNode1 := n[0]
fullNode2 := n[1]
miner := sn[0]
// Get everyone connected
addrs, err := fullNode1.NetAddrsListen(ctx)
if err != nil {
t.Fatal(err)
}
if err := fullNode2.NetConnect(ctx, addrs); err != nil {
t.Fatal(err)
}
if err := miner.NetConnect(ctx, addrs); err != nil {
t.Fatal(err)
}
// Start mining blocks
bm := test.NewBlockMiner(ctx, t, miner, blocktime)
bm.MineBlocks()
// Send some funds to register the second node
fullNodeAddr2, err := fullNode2.WalletNew(ctx, types.KTSecp256k1)
if err != nil {
t.Fatal(err)
}
test.SendFunds(ctx, t, fullNode1, fullNodeAddr2, abi.NewTokenAmount(1e18))
// Get the first node's address
fullNodeAddr1, err := fullNode1.WalletDefaultAddress(ctx)
if err != nil {
t.Fatal(err)
}
// Create mock CLI
return n, []address.Address{fullNodeAddr1, fullNodeAddr2}
}