github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/cli/opts/envfile_test.go (about)

     1  package opts
     2  
     3  import (
     4  	"bufio"
     5  	"os"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  func tmpFileWithContent(t *testing.T, content string) string {
    12  	t.Helper()
    13  	tmpFile, err := os.CreateTemp("", "envfile-test")
    14  	if err != nil {
    15  		t.Fatal(err)
    16  	}
    17  	defer tmpFile.Close()
    18  
    19  	_, err = tmpFile.WriteString(content)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  	t.Cleanup(func() {
    24  		_ = os.Remove(tmpFile.Name())
    25  	})
    26  	return tmpFile.Name()
    27  }
    28  
    29  // Test ParseEnvFile for a file with a few well formatted lines
    30  func TestParseEnvFileGoodFile(t *testing.T) {
    31  	content := `foo=bar
    32      baz=quux
    33  # comment
    34  
    35  _foobar=foobaz
    36  with.dots=working
    37  and_underscore=working too
    38  `
    39  	// Adding a newline + a line with pure whitespace.
    40  	// This is being done like this instead of the block above
    41  	// because it's common for editors to trim trailing whitespace
    42  	// from lines, which becomes annoying since that's the
    43  	// exact thing we need to test.
    44  	content += "\n    \t  "
    45  	tmpFile := tmpFileWithContent(t, content)
    46  
    47  	lines, err := ParseEnvFile(tmpFile)
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  
    52  	expectedLines := []string{
    53  		"foo=bar",
    54  		"baz=quux",
    55  		"_foobar=foobaz",
    56  		"with.dots=working",
    57  		"and_underscore=working too",
    58  	}
    59  
    60  	if !reflect.DeepEqual(lines, expectedLines) {
    61  		t.Fatal("lines not equal to expectedLines")
    62  	}
    63  }
    64  
    65  // Test ParseEnvFile for an empty file
    66  func TestParseEnvFileEmptyFile(t *testing.T) {
    67  	tmpFile := tmpFileWithContent(t, "")
    68  
    69  	lines, err := ParseEnvFile(tmpFile)
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  
    74  	if len(lines) != 0 {
    75  		t.Fatal("lines not empty; expected empty")
    76  	}
    77  }
    78  
    79  // Test ParseEnvFile for a non existent file
    80  func TestParseEnvFileNonExistentFile(t *testing.T) {
    81  	_, err := ParseEnvFile("foo_bar_baz")
    82  	if err == nil {
    83  		t.Fatal("ParseEnvFile succeeded; expected failure")
    84  	}
    85  	if _, ok := err.(*os.PathError); !ok {
    86  		t.Fatalf("Expected a PathError, got [%v]", err)
    87  	}
    88  }
    89  
    90  // Test ParseEnvFile for a badly formatted file
    91  func TestParseEnvFileBadlyFormattedFile(t *testing.T) {
    92  	content := `foo=bar
    93      f   =quux
    94  `
    95  	tmpFile := tmpFileWithContent(t, content)
    96  
    97  	_, err := ParseEnvFile(tmpFile)
    98  	if err == nil {
    99  		t.Fatalf("Expected an ErrBadKey, got nothing")
   100  	}
   101  	if _, ok := err.(ErrBadKey); !ok {
   102  		t.Fatalf("Expected an ErrBadKey, got [%v]", err)
   103  	}
   104  	expectedMessage := "poorly formatted environment: variable 'f   ' contains whitespaces"
   105  	if err.Error() != expectedMessage {
   106  		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
   107  	}
   108  }
   109  
   110  // Test ParseEnvFile for a file with a line exceeding bufio.MaxScanTokenSize
   111  func TestParseEnvFileLineTooLongFile(t *testing.T) {
   112  	content := "foo=" + strings.Repeat("a", bufio.MaxScanTokenSize+42)
   113  	tmpFile := tmpFileWithContent(t, content)
   114  
   115  	_, err := ParseEnvFile(tmpFile)
   116  	if err == nil {
   117  		t.Fatal("ParseEnvFile succeeded; expected failure")
   118  	}
   119  }
   120  
   121  // ParseEnvFile with a random file, pass through
   122  func TestParseEnvFileRandomFile(t *testing.T) {
   123  	content := `first line
   124  another invalid line`
   125  	tmpFile := tmpFileWithContent(t, content)
   126  
   127  	_, err := ParseEnvFile(tmpFile)
   128  	if err == nil {
   129  		t.Fatalf("Expected an ErrBadKey, got nothing")
   130  	}
   131  	if _, ok := err.(ErrBadKey); !ok {
   132  		t.Fatalf("Expected an ErrBadKey, got [%v]", err)
   133  	}
   134  	expectedMessage := "poorly formatted environment: variable 'first line' contains whitespaces"
   135  	if err.Error() != expectedMessage {
   136  		t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
   137  	}
   138  }
   139  
   140  // ParseEnvFile with environment variable import definitions
   141  func TestParseEnvVariableDefinitionsFile(t *testing.T) {
   142  	content := `# comment=
   143  UNDEFINED_VAR
   144  HOME
   145  `
   146  	tmpFile := tmpFileWithContent(t, content)
   147  
   148  	variables, err := ParseEnvFile(tmpFile)
   149  	if nil != err {
   150  		t.Fatal("There must not be any error")
   151  	}
   152  
   153  	if "HOME="+os.Getenv("HOME") != variables[0] {
   154  		t.Fatal("the HOME variable is not properly imported as the first variable (but it is the only one to import)")
   155  	}
   156  
   157  	if len(variables) != 1 {
   158  		t.Fatal("exactly one variable is imported (as the other one is not set at all)")
   159  	}
   160  }
   161  
   162  // ParseEnvFile with empty variable name
   163  func TestParseEnvVariableWithNoNameFile(t *testing.T) {
   164  	content := `# comment=
   165  =blank variable names are an error case
   166  `
   167  	tmpFile := tmpFileWithContent(t, content)
   168  
   169  	_, err := ParseEnvFile(tmpFile)
   170  	if nil == err {
   171  		t.Fatal("if a variable has no name parsing an environment file must fail")
   172  	}
   173  }