github.com/lazyboychen7/engine@v17.12.1-ce-rc2+incompatible/builder/dockerfile/parser/parser_test.go (about) 1 package parser 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "runtime" 11 "strings" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 const testDir = "testfiles" 19 const negativeTestDir = "testfiles-negative" 20 const testFileLineInfo = "testfile-line/Dockerfile" 21 22 func getDirs(t *testing.T, dir string) []string { 23 f, err := os.Open(dir) 24 require.NoError(t, err) 25 defer f.Close() 26 27 dirs, err := f.Readdirnames(0) 28 require.NoError(t, err) 29 return dirs 30 } 31 32 func TestParseErrorCases(t *testing.T) { 33 for _, dir := range getDirs(t, negativeTestDir) { 34 dockerfile := filepath.Join(negativeTestDir, dir, "Dockerfile") 35 36 df, err := os.Open(dockerfile) 37 require.NoError(t, err, dockerfile) 38 defer df.Close() 39 40 _, err = Parse(df) 41 assert.Error(t, err, dockerfile) 42 } 43 } 44 45 func TestParseCases(t *testing.T) { 46 for _, dir := range getDirs(t, testDir) { 47 dockerfile := filepath.Join(testDir, dir, "Dockerfile") 48 resultfile := filepath.Join(testDir, dir, "result") 49 50 df, err := os.Open(dockerfile) 51 require.NoError(t, err, dockerfile) 52 defer df.Close() 53 54 result, err := Parse(df) 55 require.NoError(t, err, dockerfile) 56 57 content, err := ioutil.ReadFile(resultfile) 58 require.NoError(t, err, resultfile) 59 60 if runtime.GOOS == "windows" { 61 // CRLF --> CR to match Unix behavior 62 content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1) 63 } 64 assert.Equal(t, result.AST.Dump()+"\n", string(content), "In "+dockerfile) 65 } 66 } 67 68 func TestParseWords(t *testing.T) { 69 tests := []map[string][]string{ 70 { 71 "input": {"foo"}, 72 "expect": {"foo"}, 73 }, 74 { 75 "input": {"foo bar"}, 76 "expect": {"foo", "bar"}, 77 }, 78 { 79 "input": {"foo\\ bar"}, 80 "expect": {"foo\\ bar"}, 81 }, 82 { 83 "input": {"foo=bar"}, 84 "expect": {"foo=bar"}, 85 }, 86 { 87 "input": {"foo bar 'abc xyz'"}, 88 "expect": {"foo", "bar", "'abc xyz'"}, 89 }, 90 { 91 "input": {`foo bar "abc xyz"`}, 92 "expect": {"foo", "bar", `"abc xyz"`}, 93 }, 94 { 95 "input": {"àöû"}, 96 "expect": {"àöû"}, 97 }, 98 { 99 "input": {`föo bàr "âbc xÿz"`}, 100 "expect": {"föo", "bàr", `"âbc xÿz"`}, 101 }, 102 } 103 104 for _, test := range tests { 105 words := parseWords(test["input"][0], NewDefaultDirective()) 106 assert.Equal(t, test["expect"], words) 107 } 108 } 109 110 func TestParseIncludesLineNumbers(t *testing.T) { 111 df, err := os.Open(testFileLineInfo) 112 require.NoError(t, err) 113 defer df.Close() 114 115 result, err := Parse(df) 116 require.NoError(t, err) 117 118 ast := result.AST 119 assert.Equal(t, 5, ast.StartLine) 120 assert.Equal(t, 31, ast.endLine) 121 assert.Len(t, ast.Children, 3) 122 expected := [][]int{ 123 {5, 5}, 124 {11, 12}, 125 {17, 31}, 126 } 127 for i, child := range ast.Children { 128 msg := fmt.Sprintf("Child %d", i) 129 assert.Equal(t, expected[i], []int{child.StartLine, child.endLine}, msg) 130 } 131 } 132 133 func TestParseWarnsOnEmptyContinutationLine(t *testing.T) { 134 dockerfile := bytes.NewBufferString(` 135 FROM alpine:3.6 136 137 RUN something \ 138 139 following \ 140 141 more 142 143 RUN another \ 144 145 thing 146 RUN non-indented \ 147 # this is a comment 148 after-comment 149 150 RUN indented \ 151 # this is an indented comment 152 comment 153 `) 154 155 result, err := Parse(dockerfile) 156 require.NoError(t, err) 157 warnings := result.Warnings 158 assert.Len(t, warnings, 3) 159 assert.Contains(t, warnings[0], "Empty continuation line found in") 160 assert.Contains(t, warnings[0], "RUN something following more") 161 assert.Contains(t, warnings[1], "RUN another thing") 162 assert.Contains(t, warnings[2], "will become errors in a future release") 163 } 164 165 func TestParseReturnsScannerErrors(t *testing.T) { 166 label := strings.Repeat("a", bufio.MaxScanTokenSize) 167 168 dockerfile := strings.NewReader(fmt.Sprintf(` 169 FROM image 170 LABEL test=%s 171 `, label)) 172 _, err := Parse(dockerfile) 173 assert.EqualError(t, err, "dockerfile line greater than max allowed size of 65535") 174 }