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 }