gitlab.com/SkynetLabs/skyd@v1.6.9/cmd/skyc/maincmd_test.go (about)

     1  package main
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/spf13/cobra"
     8  	"gitlab.com/SkynetLabs/skyd/build"
     9  )
    10  
    11  // TestRootSkycCmd tests root siac command for expected outputs. The test
    12  // runs its own node and requires no service running at port 5555.
    13  func TestRootSkycCmd(t *testing.T) {
    14  	if testing.Short() {
    15  		t.SkipNow()
    16  	}
    17  	t.Parallel()
    18  
    19  	// Create a test node for this test group
    20  	groupDir := skycTestDir(t.Name())
    21  	n, err := newTestNode(groupDir)
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  	defer func() {
    26  		if err := n.Close(); err != nil {
    27  			t.Fatal(err)
    28  		}
    29  	}()
    30  
    31  	// Initialize siac root command with its subcommands and flags
    32  	root := getRootCmdForSkycCmdsTests(groupDir)
    33  
    34  	// define test constants:
    35  	// Regular expressions to check siac output
    36  
    37  	begin := "^"
    38  	nl := `
    39  ` // platform agnostic new line
    40  	end := "$"
    41  
    42  	// Capture root command usage for test comparison
    43  	// catch stdout and stderr
    44  	rootCmdUsagePattern := getCmdUsage(t, root)
    45  
    46  	IPv6addr := n.Address
    47  	IPv4Addr := strings.ReplaceAll(n.Address, "[::]", "localhost")
    48  
    49  	// Regex helpers
    50  	// \s+ to match 1 or more spaces. Helpful with the tab writter
    51  	// \d+ to match a number
    52  	rootCmdOutPattern := `Consensus:
    53    Synced: (No|Yes)
    54    Height:\s+\d+
    55  
    56  Wallet:
    57  (  Status: Locked|  Status:          unlocked
    58    Siacoin Balance: \d+(\.\d*|) (SC|KS|MS))
    59  
    60  Renter:
    61  File Summary:
    62    Files:\s+\d+
    63    Total Stored:\s+\d+(\.\d+|) ( B|kB|MB|GB|TB)
    64    Total Renewing Data:\s+\d+(\.\d+|) ( B|kB|MB|GB|TB)
    65  Repair Status:
    66    Last Health Check:\s+\d+(m)
    67    Repair Data Remaining:\s+\d+(\.\d+|) ( B|kB|MB|GB|TB)
    68    Stuck Repair Remaining:\s+\d+(\.\d+|) ( B|kB|MB|GB|TB)
    69    Stuck Chunks:\s+\d+
    70    Max Health:\s+\d+(\%)
    71    Min Redundancy:\s+(\d+.\d{2}|-)
    72    Lost Files:\s+\d+
    73  Contract Summary:
    74  (  Renew Window \(days\):  renew window not set)
    75    Active Contracts:\s+\d+
    76    Passive Contracts:\s+\d+
    77    Disabled Contracts:\s+\d+`
    78  
    79  	rootCmdVerbosePartPattern := `Global Rate limits: 
    80    Download Speed: (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))
    81    Upload Speed:   (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))
    82  
    83  Gateway Rate limits: 
    84    Download Speed: (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))
    85    Upload Speed:   (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))
    86  
    87  Renter Rate limits: 
    88    Download Speed: (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))
    89    Upload Speed:   (no limit|\d+(\.\d+)? (B/s|KB/s|MB/s|GB/s|TB/s))`
    90  
    91  	connectionRefusedPattern := `Could not get consensus status: \[failed to get reader response; GET request failed; Get "?http://127.0.0.1:5555/consensus"?: dial tcp 127.0.0.1:5555: connect: connection refused\]`
    92  	versionReplacer := strings.NewReplacer(".", `\.`, "?", `\?`)
    93  	skyClientVersionPattern := "Skynet Client v" + versionReplacer.Replace(build.NodeVersion)
    94  
    95  	// Define subtests
    96  	// We can't test siad on default address (port) when test node has
    97  	// dynamically allocated port, we have to use node address.
    98  	subTests := []skycCmdSubTest{
    99  		{
   100  			name:               "TestRootCmdWithShortAddressFlagIPv6",
   101  			test:               testGenericSkycCmd,
   102  			cmd:                root,
   103  			cmdStrs:            []string{"-a", IPv6addr},
   104  			expectedOutPattern: begin + rootCmdOutPattern + nl + nl + end,
   105  		},
   106  		{
   107  			name:               "TestRootCmdWithShortAddressFlagIPv4",
   108  			test:               testGenericSkycCmd,
   109  			cmd:                root,
   110  			cmdStrs:            []string{"-a", IPv4Addr},
   111  			expectedOutPattern: begin + rootCmdOutPattern + nl + nl + end,
   112  		},
   113  		{
   114  			name:               "TestRootCmdWithLongAddressFlagIPv6",
   115  			test:               testGenericSkycCmd,
   116  			cmd:                root,
   117  			cmdStrs:            []string{"--addr", IPv6addr},
   118  			expectedOutPattern: begin + rootCmdOutPattern + nl + nl + end,
   119  		},
   120  		{
   121  			name:               "TestRootCmdWithLongAddressFlagIPv4",
   122  			test:               testGenericSkycCmd,
   123  			cmd:                root,
   124  			cmdStrs:            []string{"--addr", IPv4Addr},
   125  			expectedOutPattern: begin + rootCmdOutPattern + nl + nl + end,
   126  		},
   127  		{
   128  			name:               "TestRootCmdWithVerboseFlag",
   129  			test:               testGenericSkycCmd,
   130  			cmd:                root,
   131  			cmdStrs:            []string{"--addr", IPv4Addr, "-v"},
   132  			expectedOutPattern: begin + rootCmdOutPattern + nl + nl + rootCmdVerbosePartPattern + nl + nl + end,
   133  		},
   134  		{
   135  			name:               "TestRootCmdWithInvalidFlag",
   136  			test:               testGenericSkycCmd,
   137  			cmd:                root,
   138  			cmdStrs:            []string{"-x"},
   139  			expectedOutPattern: begin + "Error: unknown shorthand flag: 'x' in -x" + nl + rootCmdUsagePattern + nl + end,
   140  		},
   141  		{
   142  			name:               "TestRootCmdWithInvalidAddress",
   143  			test:               testGenericSkycCmd,
   144  			cmd:                root,
   145  			cmdStrs:            []string{"-a", "127.0.0.1:5555"},
   146  			expectedOutPattern: begin + connectionRefusedPattern + nl + nl + end,
   147  		},
   148  		{
   149  			name:               "TestRootCmdWithHelpFlag",
   150  			test:               testGenericSkycCmd,
   151  			cmd:                root,
   152  			cmdStrs:            []string{"-h"},
   153  			expectedOutPattern: begin + skyClientVersionPattern + nl + nl + rootCmdUsagePattern + end,
   154  		},
   155  	}
   156  
   157  	// run tests
   158  	err = runSkycCmdSubTests(t, subTests)
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  }
   163  
   164  // getCmdUsage gets root command usage regex pattern by calling usage function
   165  func getCmdUsage(t *testing.T, cmd *cobra.Command) string {
   166  	// Capture usage by calling a usage function
   167  	c, err := newOutputCatcher()
   168  	if err != nil {
   169  		t.Fatal("Error starting catching stdout/stderr", err)
   170  	}
   171  	usageFunc := cmd.UsageFunc()
   172  	err = usageFunc(cmd)
   173  	if err != nil {
   174  		t.Fatal("Error getting reference root siac usage", err)
   175  	}
   176  	baseUsage, err := c.stop()
   177  
   178  	// Escape regex special chars
   179  	usage := escapeRegexChars(baseUsage)
   180  
   181  	// Inject 2 missing rows
   182  	beforeHelpCommand := "Perform gateway actions"
   183  	helpCommand := "  help        Help about any command"
   184  	nl := `
   185  `
   186  	usage = strings.ReplaceAll(usage, beforeHelpCommand, beforeHelpCommand+nl+helpCommand)
   187  	beforeHelpFlag := "the password for the API's http authentication"
   188  	helpFlag := `  -h, --help                   help for .*skyc(\.test|)`
   189  	cmdUsagePattern := strings.ReplaceAll(usage, beforeHelpFlag, beforeHelpFlag+nl+helpFlag)
   190  
   191  	return cmdUsagePattern
   192  }