Imported Upstream version 2.4.1
[scm/test.git] / vendor / github.com / git-lfs / go-netrc / netrc / netrc_test.go
1 // Copyright © 2010 Fazlul Shahriar <fshahriar@gmail.com> and
2 // Copyright © 2014 Blake Gentry <blakesgentry@gmail.com>.
3 // See LICENSE file for license details.
4
5 package netrc
6
7 import (
8         "bytes"
9         "fmt"
10         "io"
11         "io/ioutil"
12         "os"
13         "strings"
14         "testing"
15 )
16
17 var expectedMachines = []*Machine{
18         &Machine{Name: "mail.google.com", Login: "joe@gmail.com", Password: "somethingSecret", Account: "justagmail"},
19         &Machine{Name: "ray", Login: "demo", Password: "mypassword", Account: ""},
20         &Machine{Name: "weirdlogin", Login: "uname", Password: "pass#pass", Account: ""},
21         &Machine{Name: "google.com", Login: "alice@google.com", Password: "secure"},
22         &Machine{Name: "", Login: "anonymous", Password: "joe@example.com", Account: ""},
23 }
24 var expectedMacros = Macros{
25         "allput":  "put src/*",
26         "allput2": "  put src/*\nput src2/*",
27 }
28
29 func eqMachine(a *Machine, b *Machine) bool {
30         return a.Name == b.Name &&
31                 a.Login == b.Login &&
32                 a.Password == b.Password &&
33                 a.Account == b.Account
34 }
35
36 func testExpected(n *Netrc, t *testing.T) {
37         if len(expectedMachines) != len(n.machines) {
38                 t.Errorf("expected %d machines, got %d", len(expectedMachines), len(n.machines))
39         } else {
40                 for i, e := range expectedMachines {
41                         if !eqMachine(e, n.machines[i]) {
42                                 t.Errorf("bad machine; expected %v, got %v\n", e, n.machines[i])
43                         }
44                 }
45         }
46
47         if len(expectedMacros) != len(n.macros) {
48                 t.Errorf("expected %d macros, got %d", len(expectedMacros), len(n.macros))
49         } else {
50                 for k, v := range expectedMacros {
51                         if v != n.macros[k] {
52                                 t.Errorf("bad macro for %s; expected %q, got %q\n", k, v, n.macros[k])
53                         }
54                 }
55         }
56 }
57
58 var newTokenTests = []struct {
59         rawkind string
60         tkind   tkType
61 }{
62         {"machine", tkMachine},
63         {"\n\n\tmachine", tkMachine},
64         {"\n   machine", tkMachine},
65         {"default", tkDefault},
66         {"login", tkLogin},
67         {"password", tkPassword},
68         {"account", tkAccount},
69         {"macdef", tkMacdef},
70         {"\n # comment stuff ", tkComment},
71         {"\n # I am another comment", tkComment},
72         {"\n\t\n ", tkWhitespace},
73 }
74
75 var newTokenInvalidTests = []string{
76         " junk",
77         "sdfdsf",
78         "account#unspaced comment",
79 }
80
81 func TestNewToken(t *testing.T) {
82         for _, tktest := range newTokenTests {
83                 tok, err := newToken([]byte(tktest.rawkind))
84                 if err != nil {
85                         t.Fatal(err)
86                 }
87                 if tok.kind != tktest.tkind {
88                         t.Errorf("expected tok.kind %d, got %d", tktest.tkind, tok.kind)
89                 }
90                 if string(tok.rawkind) != tktest.rawkind {
91                         t.Errorf("expected tok.rawkind %q, got %q", tktest.rawkind, string(tok.rawkind))
92                 }
93         }
94
95         for _, tktest := range newTokenInvalidTests {
96                 _, err := newToken([]byte(tktest))
97                 if err == nil {
98                         t.Errorf("expected error with %q, got none", tktest)
99                 }
100         }
101 }
102
103 func TestParse(t *testing.T) {
104         r := netrcReader("examples/good.netrc", t)
105         n, err := Parse(r)
106         if err != nil {
107                 t.Fatal(err)
108         }
109         testExpected(n, t)
110 }
111
112 func TestParseFile(t *testing.T) {
113         n, err := ParseFile("examples/good.netrc")
114         if err != nil {
115                 t.Fatal(err)
116         }
117         testExpected(n, t)
118
119         _, err = ParseFile("examples/bad_default_order.netrc")
120         if err == nil {
121                 t.Error("expected an error parsing bad_default_order.netrc, got none")
122         } else if !err.(*Error).BadDefaultOrder() {
123                 t.Error("expected BadDefaultOrder() to be true, got false")
124         }
125
126         _, err = ParseFile("examples/this_file_doesnt_exist.netrc")
127         if err == nil {
128                 t.Error("expected an error loading this_file_doesnt_exist.netrc, got none")
129         } else if _, ok := err.(*os.PathError); !ok {
130                 t.Errorf("expected *os.Error, got %v", err)
131         }
132 }
133
134 func TestFindMachine(t *testing.T) {
135         m, err := FindMachine("examples/good.netrc", "ray")
136         if err != nil {
137                 t.Fatal(err)
138         }
139         if !eqMachine(m, expectedMachines[1]) {
140                 t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[1], m)
141         }
142         if m.IsDefault() {
143                 t.Errorf("expected m.IsDefault() to be false")
144         }
145
146         m, err = FindMachine("examples/good.netrc", "non.existent")
147         if err != nil {
148                 t.Fatal(err)
149         }
150         if !eqMachine(m, expectedMachines[4]) {
151                 t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[3], m)
152         }
153         if !m.IsDefault() {
154                 t.Errorf("expected m.IsDefault() to be true")
155         }
156 }
157
158 func TestNetrcFindMachine(t *testing.T) {
159         n, err := ParseFile("examples/good.netrc")
160         if err != nil {
161                 t.Fatal(err)
162         }
163
164         m := n.FindMachine("ray")
165         if !eqMachine(m, expectedMachines[1]) {
166                 t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[1], m)
167         }
168         if m.IsDefault() {
169                 t.Errorf("expected def to be false")
170         }
171
172         n = &Netrc{}
173         m = n.FindMachine("nonexistent")
174         if m != nil {
175                 t.Errorf("expected nil, got %v", m)
176         }
177 }
178
179 func TestMarshalText(t *testing.T) {
180         // load up expected netrc Marshal output
181         expected, err := ioutil.ReadAll(netrcReader("examples/good.netrc", t))
182         if err != nil {
183                 t.Fatal(err)
184         }
185
186         n, err := ParseFile("examples/good.netrc")
187         if err != nil {
188                 t.Fatal(err)
189         }
190
191         result, err := n.MarshalText()
192         if err != nil {
193                 t.Fatal(err)
194         }
195         if string(result) != string(expected) {
196                 t.Errorf("expected:\n%q\ngot:\n%q", string(expected), string(result))
197         }
198
199         // make sure tokens w/ no value are not serialized
200         m := n.FindMachine("mail.google.com")
201         m.UpdatePassword("")
202         result, err = n.MarshalText()
203         if err != nil {
204                 t.Fatal(err)
205         }
206         if strings.Contains(string(result), "\tpassword \n") {
207                 fmt.Println(string(result))
208                 t.Errorf("expected zero-value password token to not be serialzed")
209         }
210 }
211
212 var newMachineTests = []struct {
213         name     string
214         login    string
215         password string
216         account  string
217 }{
218         {"heroku.com", "dodging-samurai-42@heroku.com", "octocatdodgeballchampions", "2011+2013"},
219         {"bgentry.io", "special@test.com", "noacct", ""},
220         {"github.io", "2@test.com", "", "acctwithnopass"},
221         {"someotherapi.com", "", "passonly", ""},
222 }
223
224 func TestNewMachine(t *testing.T) {
225         n, err := ParseFile("examples/good.netrc")
226         if err != nil {
227                 t.Fatal(err)
228         }
229         testNewMachine(t, n)
230         n = &Netrc{}
231         testNewMachine(t, n)
232
233         // make sure that tokens without a value are not serialized at all
234         for _, test := range newMachineTests {
235                 n = &Netrc{}
236                 _ = n.NewMachine(test.name, test.login, test.password, test.account)
237
238                 bodyb, _ := n.MarshalText()
239                 body := string(bodyb)
240
241                 // ensure desired values are present when they should be
242                 if !strings.Contains(body, "machine") {
243                         t.Errorf("NewMachine() %s missing keyword 'machine'", test.name)
244                 }
245                 if !strings.Contains(body, test.name) {
246                         t.Errorf("NewMachine() %s missing value %q", test.name, test.name)
247                 }
248                 if test.login != "" && !strings.Contains(body, "login "+test.login) {
249                         t.Errorf("NewMachine() %s missing value %q", test.name, "login "+test.login)
250                 }
251                 if test.password != "" && !strings.Contains(body, "password "+test.password) {
252                         t.Errorf("NewMachine() %s missing value %q", test.name, "password "+test.password)
253                 }
254                 if test.account != "" && !strings.Contains(body, "account "+test.account) {
255                         t.Errorf("NewMachine() %s missing value %q", test.name, "account "+test.account)
256                 }
257
258                 // ensure undesired values are not present when they shouldn't be
259                 if test.login == "" && strings.Contains(body, "login") {
260                         t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "login")
261                 }
262                 if test.password == "" && strings.Contains(body, "password") {
263                         t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "password")
264                 }
265                 if test.account == "" && strings.Contains(body, "account") {
266                         t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "account")
267                 }
268         }
269 }
270
271 func testNewMachine(t *testing.T, n *Netrc) {
272         for _, test := range newMachineTests {
273                 mcount := len(n.machines)
274                 // sanity check
275                 bodyb, _ := n.MarshalText()
276                 body := string(bodyb)
277                 for _, value := range []string{test.name, test.login, test.password, test.account} {
278                         if value != "" && strings.Contains(body, value) {
279                                 t.Errorf("MarshalText() before NewMachine() contained unexpected %q", value)
280                         }
281                 }
282
283                 // test prefix for machine token
284                 prefix := "\n"
285                 if len(n.tokens) == 0 {
286                         prefix = ""
287                 }
288
289                 m := n.NewMachine(test.name, test.login, test.password, test.account)
290                 if m == nil {
291                         t.Fatalf("NewMachine() returned nil")
292                 }
293
294                 if len(n.machines) != mcount+1 {
295                         t.Errorf("n.machines count expected %d, got %d", mcount+1, len(n.machines))
296                 }
297                 // check values
298                 if m.Name != test.name {
299                         t.Errorf("m.Name expected %q, got %q", test.name, m.Name)
300                 }
301                 if m.Login != test.login {
302                         t.Errorf("m.Login expected %q, got %q", test.login, m.Login)
303                 }
304                 if m.Password != test.password {
305                         t.Errorf("m.Password expected %q, got %q", test.password, m.Password)
306                 }
307                 if m.Account != test.account {
308                         t.Errorf("m.Account expected %q, got %q", test.account, m.Account)
309                 }
310                 // check tokens
311                 checkToken(t, "nametoken", m.nametoken, tkMachine, prefix+"machine", test.name)
312                 checkToken(t, "logintoken", m.logintoken, tkLogin, "\n\tlogin", test.login)
313                 checkToken(t, "passtoken", m.passtoken, tkPassword, "\n\tpassword", test.password)
314                 checkToken(t, "accounttoken", m.accounttoken, tkAccount, "\n\taccount", test.account)
315                 // check marshal output
316                 bodyb, _ = n.MarshalText()
317                 body = string(bodyb)
318                 for _, value := range []string{test.name, test.login, test.password, test.account} {
319                         if !strings.Contains(body, value) {
320                                 t.Errorf("MarshalText() after NewMachine() did not include %q as expected", value)
321                         }
322                 }
323         }
324 }
325
326 func checkToken(t *testing.T, name string, tok *token, kind tkType, rawkind, value string) {
327         if tok == nil {
328                 t.Errorf("%s not defined", name)
329                 return
330         }
331         if tok.kind != kind {
332                 t.Errorf("%s expected kind %d, got %d", name, kind, tok.kind)
333         }
334         if string(tok.rawkind) != rawkind {
335                 t.Errorf("%s expected rawkind %q, got %q", name, rawkind, string(tok.rawkind))
336         }
337         if tok.value != value {
338                 t.Errorf("%s expected value %q, got %q", name, value, tok.value)
339         }
340         if tok.value != value {
341                 t.Errorf("%s expected value %q, got %q", name, value, tok.value)
342         }
343 }
344
345 func TestNewMachineGoesBeforeDefault(t *testing.T) {
346         n, err := ParseFile("examples/good.netrc")
347         if err != nil {
348                 t.Fatal(err)
349         }
350         m := n.NewMachine("mymachine", "mylogin", "mypassword", "myaccount")
351         if m2 := n.machines[len(n.machines)-2]; m2 != m {
352                 t.Errorf("expected machine %v, got %v", m, m2)
353         }
354 }
355
356 func TestRemoveMachine(t *testing.T) {
357         n, err := ParseFile("examples/good.netrc")
358         if err != nil {
359                 t.Fatal(err)
360         }
361
362         tests := []string{"mail.google.com", "weirdlogin"}
363
364         for _, name := range tests {
365                 mcount := len(n.machines)
366                 // sanity check
367                 m := n.FindMachine(name)
368                 if m == nil {
369                         t.Fatalf("machine %q not found", name)
370                 }
371                 if m.IsDefault() {
372                         t.Fatalf("expected machine %q, got default instead", name)
373                 }
374                 n.RemoveMachine(name)
375
376                 if len(n.machines) != mcount-1 {
377                         t.Errorf("n.machines count expected %d, got %d", mcount-1, len(n.machines))
378                 }
379
380                 // make sure Machine is no longer returned by FindMachine()
381                 if m2 := n.FindMachine(name); m2 != nil && !m2.IsDefault() {
382                         t.Errorf("Machine %q not removed from Machines list", name)
383                 }
384
385                 // make sure tokens are not present in tokens list
386                 for _, token := range []*token{m.nametoken, m.logintoken, m.passtoken, m.accounttoken} {
387                         if token != nil {
388                                 for _, tok2 := range n.tokens {
389                                         if tok2 == token {
390                                                 t.Errorf("token not removed from tokens list: %v", token)
391                                                 break
392                                         }
393                                 }
394                         }
395                 }
396
397                 bodyb, _ := n.MarshalText()
398                 body := string(bodyb)
399                 for _, value := range []string{m.Name, m.Login, m.Password, m.Account} {
400                         if value != "" && strings.Contains(body, value) {
401                                 t.Errorf("MarshalText() after RemoveMachine() contained unexpected %q", value)
402                         }
403                 }
404         }
405 }
406
407 func TestUpdateLogin(t *testing.T) {
408         n, err := ParseFile("examples/good.netrc")
409         if err != nil {
410                 t.Fatal(err)
411         }
412
413         tests := []struct {
414                 exists   bool
415                 name     string
416                 oldlogin string
417                 newlogin string
418         }{
419                 {true, "mail.google.com", "joe@gmail.com", "joe2@gmail.com"},
420                 {false, "heroku.com", "", "dodging-samurai-42@heroku.com"},
421         }
422
423         bodyb, _ := n.MarshalText()
424         body := string(bodyb)
425         for _, test := range tests {
426                 if strings.Contains(body, test.newlogin) {
427                         t.Errorf("MarshalText() before UpdateLogin() contained unexpected %q", test.newlogin)
428                 }
429         }
430
431         for _, test := range tests {
432                 m := n.FindMachine(test.name)
433                 if m.IsDefault() == test.exists {
434                         t.Errorf("expected machine %s to not exist, but it did", test.name)
435                 } else {
436                         if !test.exists {
437                                 m = n.NewMachine(test.name, test.newlogin, "", "")
438                         }
439                         if m == nil {
440                                 t.Errorf("machine %s was nil", test.name)
441                                 continue
442                         }
443                         m.UpdateLogin(test.newlogin)
444                         m := n.FindMachine(test.name)
445                         if m.Login != test.newlogin {
446                                 t.Errorf("expected new login %q, got %q", test.newlogin, m.Login)
447                         }
448                         if m.logintoken.value != test.newlogin {
449                                 t.Errorf("expected m.logintoken %q, got %q", test.newlogin, m.logintoken.value)
450                         }
451                 }
452         }
453
454         bodyb, _ = n.MarshalText()
455         body = string(bodyb)
456         for _, test := range tests {
457                 if test.exists && strings.Contains(body, test.oldlogin) {
458                         t.Errorf("MarshalText() after UpdateLogin() contained unexpected %q", test.oldlogin)
459                 }
460                 if !strings.Contains(body, test.newlogin) {
461                         t.Errorf("MarshalText after UpdatePassword did not contain %q as expected", test.newlogin)
462                 }
463         }
464 }
465
466 func TestUpdatePassword(t *testing.T) {
467         n, err := ParseFile("examples/good.netrc")
468         if err != nil {
469                 t.Fatal(err)
470         }
471
472         tests := []struct {
473                 exists      bool
474                 name        string
475                 oldpassword string
476                 newpassword string
477         }{
478                 {true, "ray", "mypassword", "supernewpass"},
479                 {false, "heroku.com", "", "octocatdodgeballchampions"},
480         }
481
482         bodyb, _ := n.MarshalText()
483         body := string(bodyb)
484         for _, test := range tests {
485                 if test.exists && !strings.Contains(body, test.oldpassword) {
486                         t.Errorf("MarshalText() before UpdatePassword() did not include %q as expected", test.oldpassword)
487                 }
488                 if strings.Contains(body, test.newpassword) {
489                         t.Errorf("MarshalText() before UpdatePassword() contained unexpected %q", test.newpassword)
490                 }
491         }
492
493         for _, test := range tests {
494                 m := n.FindMachine(test.name)
495                 if m.IsDefault() == test.exists {
496                         t.Errorf("expected machine %s to not exist, but it did", test.name)
497                 } else {
498                         if !test.exists {
499                                 m = n.NewMachine(test.name, "", test.newpassword, "")
500                         }
501                         if m == nil {
502                                 t.Errorf("machine %s was nil", test.name)
503                                 continue
504                         }
505                         m.UpdatePassword(test.newpassword)
506                         m = n.FindMachine(test.name)
507                         if m.Password != test.newpassword {
508                                 t.Errorf("expected new password %q, got %q", test.newpassword, m.Password)
509                         }
510                         if m.passtoken.value != test.newpassword {
511                                 t.Errorf("expected m.passtoken %q, got %q", test.newpassword, m.passtoken.value)
512                         }
513                 }
514         }
515
516         bodyb, _ = n.MarshalText()
517         body = string(bodyb)
518         for _, test := range tests {
519                 if test.exists && strings.Contains(body, test.oldpassword) {
520                         t.Errorf("MarshalText() after UpdatePassword() contained unexpected %q", test.oldpassword)
521                 }
522                 if !strings.Contains(body, test.newpassword) {
523                         t.Errorf("MarshalText() after UpdatePassword() did not contain %q as expected", test.newpassword)
524                 }
525         }
526 }
527
528 func TestNewFile(t *testing.T) {
529         var n Netrc
530
531         result, err := n.MarshalText()
532         if err != nil {
533                 t.Fatal(err)
534         }
535         if string(result) != "" {
536                 t.Errorf("expected empty result=\"\", got %q", string(result))
537         }
538
539         n.NewMachine("netrctest.heroku.com", "auser", "apassword", "")
540
541         result, err = n.MarshalText()
542         if err != nil {
543                 t.Fatal(err)
544         }
545         expected := `machine netrctest.heroku.com
546         login auser
547         password apassword`
548
549         if string(result) != expected {
550                 t.Errorf("expected result:\n%q\ngot:\n%q", expected, string(result))
551         }
552 }
553
554 func netrcReader(filename string, t *testing.T) io.Reader {
555         b, err := ioutil.ReadFile(filename)
556         if err != nil {
557                 t.Fatal(err)
558         }
559         return bytes.NewReader(b)
560 }