/middleware/commands_test.go
Go | 291 lines | 288 code | 2 blank | 1 comment | 0 complexity | bfd2522c155325a97c099b6a02b3caab MD5 | raw file
- package middleware
- import (
- "fmt"
- "runtime"
- "strings"
- "testing"
- )
- func TestParseUnixCommand(t *testing.T) {
- tests := []struct {
- input string
- expected []string
- }{
- // 0 - emtpy command
- {
- input: ``,
- expected: []string{},
- },
- // 1 - command without arguments
- {
- input: `command`,
- expected: []string{`command`},
- },
- // 2 - command with single argument
- {
- input: `command arg1`,
- expected: []string{`command`, `arg1`},
- },
- // 3 - command with multiple arguments
- {
- input: `command arg1 arg2`,
- expected: []string{`command`, `arg1`, `arg2`},
- },
- // 4 - command with single argument with space character - in quotes
- {
- input: `command "arg1 arg1"`,
- expected: []string{`command`, `arg1 arg1`},
- },
- // 5 - command with multiple spaces and tab character
- {
- input: "command arg1 arg2\targ3",
- expected: []string{`command`, `arg1`, `arg2`, `arg3`},
- },
- // 6 - command with single argument with space character - escaped with backspace
- {
- input: `command arg1\ arg2`,
- expected: []string{`command`, `arg1 arg2`},
- },
- // 7 - single quotes should escape special chars
- {
- input: `command 'arg1\ arg2'`,
- expected: []string{`command`, `arg1\ arg2`},
- },
- }
- for i, test := range tests {
- errorPrefix := fmt.Sprintf("Test [%d]: ", i)
- errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
- actual, _ := parseUnixCommand(test.input)
- if len(actual) != len(test.expected) {
- t.Errorf(errorPrefix+"Expected %d parts, got %d: %#v."+errorSuffix, len(test.expected), len(actual), actual)
- continue
- }
- for j := 0; j < len(actual); j++ {
- if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
- t.Errorf(errorPrefix+"Expected: %v Actual: %v (index %d)."+errorSuffix, expectedPart, actualPart, j)
- }
- }
- }
- }
- func TestParseWindowsCommand(t *testing.T) {
- tests := []struct {
- input string
- expected []string
- }{
- { // 0 - empty command - do not fail
- input: ``,
- expected: []string{},
- },
- { // 1 - cmd without args
- input: `cmd`,
- expected: []string{`cmd`},
- },
- { // 2 - multiple args
- input: `cmd arg1 arg2`,
- expected: []string{`cmd`, `arg1`, `arg2`},
- },
- { // 3 - multiple args with space
- input: `cmd "combined arg" arg2`,
- expected: []string{`cmd`, `combined arg`, `arg2`},
- },
- { // 4 - path without spaces
- input: `mkdir C:\Windows\foo\bar`,
- expected: []string{`mkdir`, `C:\Windows\foo\bar`},
- },
- { // 5 - command with space in quotes
- input: `"command here"`,
- expected: []string{`command here`},
- },
- { // 6 - argument with escaped quotes (two quotes)
- input: `cmd ""arg""`,
- expected: []string{`cmd`, `"arg"`},
- },
- { // 7 - argument with escaped quotes (backslash)
- input: `cmd \"arg\"`,
- expected: []string{`cmd`, `"arg"`},
- },
- { // 8 - two quotes (escaped) inside an inQuote element
- input: `cmd "a ""quoted value"`,
- expected: []string{`cmd`, `a "quoted value`},
- },
- // TODO - see how many quotes are dislayed if we use "", """, """""""
- { // 9 - two quotes outside an inQuote element
- input: `cmd a ""quoted value`,
- expected: []string{`cmd`, `a`, `"quoted`, `value`},
- },
- { // 10 - path with space in quotes
- input: `mkdir "C:\directory name\foobar"`,
- expected: []string{`mkdir`, `C:\directory name\foobar`},
- },
- { // 11 - space without quotes
- input: `mkdir C:\ space`,
- expected: []string{`mkdir`, `C:\`, `space`},
- },
- { // 12 - space in quotes
- input: `mkdir "C:\ space"`,
- expected: []string{`mkdir`, `C:\ space`},
- },
- { // 13 - UNC
- input: `mkdir \\?\C:\Users`,
- expected: []string{`mkdir`, `\\?\C:\Users`},
- },
- { // 14 - UNC with space
- input: `mkdir "\\?\C:\Program Files"`,
- expected: []string{`mkdir`, `\\?\C:\Program Files`},
- },
- { // 15 - unclosed quotes - treat as if the path ends with quote
- input: `mkdir "c:\Program files`,
- expected: []string{`mkdir`, `c:\Program files`},
- },
- { // 16 - quotes used inside the argument
- input: `mkdir "c:\P"rogra"m f"iles`,
- expected: []string{`mkdir`, `c:\Program files`},
- },
- }
- for i, test := range tests {
- errorPrefix := fmt.Sprintf("Test [%d]: ", i)
- errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
- actual := parseWindowsCommand(test.input)
- if len(actual) != len(test.expected) {
- t.Errorf(errorPrefix+"Expected %d parts, got %d: %#v."+errorSuffix, len(test.expected), len(actual), actual)
- continue
- }
- for j := 0; j < len(actual); j++ {
- if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
- t.Errorf(errorPrefix+"Expected: %v Actual: %v (index %d)."+errorSuffix, expectedPart, actualPart, j)
- }
- }
- }
- }
- func TestSplitCommandAndArgs(t *testing.T) {
- // force linux parsing. It's more robust and covers error cases
- runtimeGoos = "linux"
- defer func() {
- runtimeGoos = runtime.GOOS
- }()
- var parseErrorContent = "error parsing command:"
- var noCommandErrContent = "no command contained in"
- tests := []struct {
- input string
- expectedCommand string
- expectedArgs []string
- expectedErrContent string
- }{
- // 0 - emtpy command
- {
- input: ``,
- expectedCommand: ``,
- expectedArgs: nil,
- expectedErrContent: noCommandErrContent,
- },
- // 1 - command without arguments
- {
- input: `command`,
- expectedCommand: `command`,
- expectedArgs: nil,
- expectedErrContent: ``,
- },
- // 2 - command with single argument
- {
- input: `command arg1`,
- expectedCommand: `command`,
- expectedArgs: []string{`arg1`},
- expectedErrContent: ``,
- },
- // 3 - command with multiple arguments
- {
- input: `command arg1 arg2`,
- expectedCommand: `command`,
- expectedArgs: []string{`arg1`, `arg2`},
- expectedErrContent: ``,
- },
- // 4 - command with unclosed quotes
- {
- input: `command "arg1 arg2`,
- expectedCommand: "",
- expectedArgs: nil,
- expectedErrContent: parseErrorContent,
- },
- // 5 - command with unclosed quotes
- {
- input: `command 'arg1 arg2"`,
- expectedCommand: "",
- expectedArgs: nil,
- expectedErrContent: parseErrorContent,
- },
- }
- for i, test := range tests {
- errorPrefix := fmt.Sprintf("Test [%d]: ", i)
- errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
- actualCommand, actualArgs, actualErr := SplitCommandAndArgs(test.input)
- // test if error matches expectation
- if test.expectedErrContent != "" {
- if actualErr == nil {
- t.Errorf(errorPrefix+"Expected error with content [%s], found no error."+errorSuffix, test.expectedErrContent)
- } else if !strings.Contains(actualErr.Error(), test.expectedErrContent) {
- t.Errorf(errorPrefix+"Expected error with content [%s], found [%v]."+errorSuffix, test.expectedErrContent, actualErr)
- }
- } else if actualErr != nil {
- t.Errorf(errorPrefix+"Expected no error, found [%v]."+errorSuffix, actualErr)
- }
- // test if command matches
- if test.expectedCommand != actualCommand {
- t.Errorf(errorPrefix+"Expected command: [%s], actual: [%s]."+errorSuffix, test.expectedCommand, actualCommand)
- }
- // test if arguments match
- if len(test.expectedArgs) != len(actualArgs) {
- t.Errorf(errorPrefix+"Wrong number of arguments! Expected [%v], actual [%v]."+errorSuffix, test.expectedArgs, actualArgs)
- } else {
- // test args only if the count matches.
- for j, actualArg := range actualArgs {
- expectedArg := test.expectedArgs[j]
- if actualArg != expectedArg {
- t.Errorf(errorPrefix+"Argument at position [%d] differ! Expected [%s], actual [%s]"+errorSuffix, j, expectedArg, actualArg)
- }
- }
- }
- }
- }
- func ExampleSplitCommandAndArgs() {
- var commandLine string
- var command string
- var args []string
- // just for the test - change GOOS and reset it at the end of the test
- runtimeGoos = "windows"
- defer func() {
- runtimeGoos = runtime.GOOS
- }()
- commandLine = `mkdir /P "C:\Program Files"`
- command, args, _ = SplitCommandAndArgs(commandLine)
- fmt.Printf("Windows: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))
- // set GOOS to linux
- runtimeGoos = "linux"
- commandLine = `mkdir -p /path/with\ space`
- command, args, _ = SplitCommandAndArgs(commandLine)
- fmt.Printf("Linux: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))
- // Output:
- // Windows: mkdir /P "C:\Program Files": mkdir [/P,C:\Program Files]
- // Linux: mkdir -p /path/with\ space: mkdir [-p,/path/with space]
- }