Source file src/cmd/go/internal/work/exec_test.go

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package work
     6  
     7  import (
     8  	"bytes"
     9  	"cmd/internal/objabi"
    10  	"cmd/internal/sys"
    11  	"fmt"
    12  	"math/rand"
    13  	"testing"
    14  	"time"
    15  	"unicode/utf8"
    16  )
    17  
    18  func TestEncodeArgs(t *testing.T) {
    19  	t.Parallel()
    20  	tests := []struct {
    21  		arg, want string
    22  	}{
    23  		{"", `""`},
    24  		{"hello", "hello"},
    25  		{"hello\n", "\"hello\n\""},
    26  		{"hello\\", `"hello\\"`},
    27  		{"hello\nthere", "\"hello\nthere\""},
    28  		{"\\\n", "\"\\\\\n\""},
    29  		{"hello world", `"hello world"`},
    30  		{"hello\tthere", "\"hello\tthere\""},
    31  		{`hello"there`, `"hello\"there"`},
    32  		{"hello$there", `"hello\$there"`},
    33  		{"hello`there", "\"hello\\`there\""},
    34  		{"simple", "simple"},
    35  	}
    36  	for _, test := range tests {
    37  		if got := encodeArg(test.arg); got != test.want {
    38  			t.Errorf("encodeArg(%q) = %q, want %q", test.arg, got, test.want)
    39  		}
    40  	}
    41  }
    42  
    43  func TestEncodeDecode(t *testing.T) {
    44  	t.Parallel()
    45  	tests := []string{
    46  		"",
    47  		"hello",
    48  		"hello\\there",
    49  		"hello\nthere",
    50  		"hello 中国",
    51  		"hello \n中\\国",
    52  		"hello$world",
    53  		"hello`world",
    54  		`hello"world`,
    55  	}
    56  	for _, arg := range tests {
    57  		encoded := encodeArg(arg)
    58  		args := objabi.ParseArgs([]byte(encoded))
    59  		if len(args) != 1 || args[0] != arg {
    60  			t.Errorf("ParseArgs(encodeArg(%q)) = %q (encoded: %q)", arg, args, encoded)
    61  		}
    62  	}
    63  }
    64  
    65  func TestEncodeDecodeFuzz(t *testing.T) {
    66  	if testing.Short() {
    67  		t.Skip("fuzz test is slow")
    68  	}
    69  	t.Parallel()
    70  
    71  	nRunes := sys.ExecArgLengthLimit + 100
    72  	rBuffer := make([]rune, nRunes)
    73  	buf := bytes.NewBuffer([]byte(string(rBuffer)))
    74  
    75  	seed := time.Now().UnixNano()
    76  	t.Logf("rand seed: %v", seed)
    77  	rng := rand.New(rand.NewSource(seed))
    78  
    79  	for i := 0; i < 50; i++ {
    80  		// Generate a random string of runes.
    81  		buf.Reset()
    82  		for buf.Len() < sys.ExecArgLengthLimit+1 {
    83  			var r rune
    84  			for {
    85  				r = rune(rng.Intn(utf8.MaxRune + 1))
    86  				if utf8.ValidRune(r) {
    87  					break
    88  				}
    89  			}
    90  			fmt.Fprintf(buf, "%c", r)
    91  		}
    92  		arg := buf.String()
    93  
    94  		encoded := encodeArg(arg)
    95  		args := objabi.ParseArgs([]byte(encoded))
    96  		if len(args) != 1 || args[0] != arg {
    97  			t.Errorf("[%d] ParseArgs(encodeArg(%q)) = %q [seed: %v]", i, arg, args, seed)
    98  		}
    99  	}
   100  }
   101  

View as plain text