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  }