1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 type PathTest
struct {
21 var cleantests
= []PathTest
{
24 {"abc/def", "abc/def"},
29 {"../../abc", "../../abc"},
33 // Empty is current dir
36 // Remove trailing slash
38 {"abc/def/", "abc/def"},
45 // Remove doubled slash
46 {"abc//def//ghi", "abc/def/ghi"},
53 {"abc/./def", "abc/def"},
54 {"/./abc/def", "/abc/def"},
58 {"abc/def/ghi/../jkl", "abc/def/jkl"},
59 {"abc/def/../ghi/../jkl", "abc/jkl"},
60 {"abc/def/..", "abc"},
61 {"abc/def/../..", "."},
62 {"/abc/def/../..", "/"},
63 {"abc/def/../../..", ".."},
64 {"/abc/def/../../..", "/"},
65 {"abc/def/../../../ghi/jkl/../../../mno", "../../mno"},
69 {"abc/./../def", "def"},
70 {"abc//./../def", "def"},
71 {"abc/../../././../def", "../../def"},
74 var wincleantests
= []PathTest
{
78 {`c:abc\..\..\.\.\..\def`, `c:..\..\def`},
79 {`c:\abc\def\..\..`, `c:\`},
80 {`c:\..\abc`, `c:\abc`},
81 {`c:..\abc`, `c:..\abc`},
85 {`\\i\..\i\c$`, `\i\c$`},
86 {`\\i\..\I\c$`, `\I\c$`},
87 {`\\host\share\foo\..\bar`, `\\host\share\bar`},
88 {`//host/share/foo/../baz`, `\\host\share\baz`},
89 {`\\a\b\..\c`, `\\a\b\c`},
93 func TestClean(t
*testing
.T
) {
95 if runtime
.GOOS
== "windows" {
96 for i
:= range tests
{
97 tests
[i
].result
= filepath
.FromSlash(tests
[i
].result
)
99 tests
= append(tests
, wincleantests
...)
101 for _
, test
:= range tests
{
102 if s
:= filepath
.Clean(test
.path
); s
!= test
.result
{
103 t
.Errorf("Clean(%q) = %q, want %q", test
.path
, s
, test
.result
)
105 if s
:= filepath
.Clean(test
.result
); s
!= test
.result
{
106 t
.Errorf("Clean(%q) = %q, want %q", test
.result
, s
, test
.result
)
110 if runtime
.GOMAXPROCS(0) > 1 {
111 t
.Log("skipping AllocsPerRun checks; GOMAXPROCS>1")
115 t
.Log("Skipping AllocsPerRun for gccgo")
118 for _
, test
:= range tests
{
119 allocs
:= testing
.AllocsPerRun(100, func() { filepath
.Clean(test
.result
) })
121 t
.Errorf("Clean(%q): %v allocs, want zero", test
.result
, allocs
)
126 const sep
= filepath
.Separator
128 var slashtests
= []PathTest
{
131 {"/a/b", string([]byte{sep
, 'a', sep
, 'b'})},
132 {"a//b", string([]byte{'a', sep
, sep
, 'b'})},
135 func TestFromAndToSlash(t
*testing
.T
) {
136 for _
, test
:= range slashtests
{
137 if s
:= filepath
.FromSlash(test
.path
); s
!= test
.result
{
138 t
.Errorf("FromSlash(%q) = %q, want %q", test
.path
, s
, test
.result
)
140 if s
:= filepath
.ToSlash(test
.result
); s
!= test
.path
{
141 t
.Errorf("ToSlash(%q) = %q, want %q", test
.result
, s
, test
.path
)
146 type SplitListTest
struct {
151 const lsep
= filepath
.ListSeparator
153 var splitlisttests
= []SplitListTest
{
155 {string([]byte{'a', lsep
, 'b'}), []string{"a", "b"}},
156 {string([]byte{lsep
, 'a', lsep
, 'b'}), []string{"", "a", "b"}},
159 var winsplitlisttests
= []SplitListTest
{
161 {`"a"`, []string{`a`}},
164 {`";"`, []string{`;`}},
165 {`"a;b"`, []string{`a;b`}},
166 {`";";`, []string{`;`, ``}},
167 {`;";"`, []string{``, `;`}},
170 {`a";"b`, []string{`a;b`}},
171 {`a; ""b`, []string{`a`, ` b`}},
172 {`"a;b`, []string{`a;b`}},
173 {`""a;b`, []string{`a`, `b`}},
174 {`"""a;b`, []string{`a;b`}},
175 {`""""a;b`, []string{`a`, `b`}},
176 {`a";b`, []string{`a;b`}},
177 {`a;b";c`, []string{`a`, `b;c`}},
178 {`"a";b";c`, []string{`a`, `b;c`}},
181 func TestSplitList(t
*testing
.T
) {
182 tests
:= splitlisttests
183 if runtime
.GOOS
== "windows" {
184 tests
= append(tests
, winsplitlisttests
...)
186 for _
, test
:= range tests
{
187 if l
:= filepath
.SplitList(test
.list
); !reflect
.DeepEqual(l
, test
.result
) {
188 t
.Errorf("SplitList(%#q) = %#q, want %#q", test
.list
, l
, test
.result
)
193 type SplitTest
struct {
194 path
, dir
, file
string
197 var unixsplittests
= []SplitTest
{
199 {"a/b/", "a/b/", ""},
205 var winsplittests
= []SplitTest
{
208 {`c:/foo`, `c:/`, `foo`},
209 {`c:/foo/bar`, `c:/foo/`, `bar`},
210 {`//host/share`, `//host/share`, ``},
211 {`//host/share/`, `//host/share/`, ``},
212 {`//host/share/foo`, `//host/share/`, `foo`},
213 {`\\host\share`, `\\host\share`, ``},
214 {`\\host\share\`, `\\host\share\`, ``},
215 {`\\host\share\foo`, `\\host\share\`, `foo`},
218 func TestSplit(t
*testing
.T
) {
219 var splittests
[]SplitTest
220 splittests
= unixsplittests
221 if runtime
.GOOS
== "windows" {
222 splittests
= append(splittests
, winsplittests
...)
224 for _
, test
:= range splittests
{
225 if d
, f
:= filepath
.Split(test
.path
); d
!= test
.dir || f
!= test
.file
{
226 t
.Errorf("Split(%q) = %q, %q, want %q, %q", test
.path
, d
, f
, test
.dir
, test
.file
)
231 type JoinTest
struct {
236 var jointests
= []JoinTest
{
242 {[]string{"a"}, "a"},
245 {[]string{"a", "b"}, "a/b"},
246 {[]string{"a", ""}, "a"},
247 {[]string{"", "b"}, "b"},
248 {[]string{"/", "a"}, "/a"},
249 {[]string{"/", ""}, "/"},
250 {[]string{"a/", "b"}, "a/b"},
251 {[]string{"a/", ""}, "a"},
252 {[]string{"", ""}, ""},
255 var winjointests
= []JoinTest
{
256 {[]string{`directory`, `file`}, `directory\file`},
257 {[]string{`C:\Windows\`, `System32`}, `C:\Windows\System32`},
258 {[]string{`C:\Windows\`, ``}, `C:\Windows`},
259 {[]string{`C:\`, `Windows`}, `C:\Windows`},
260 {[]string{`C:`, `Windows`}, `C:\Windows`},
261 {[]string{`\\host\share`, `foo`}, `\\host\share\foo`},
262 {[]string{`//host/share`, `foo/bar`}, `\\host\share\foo\bar`},
265 // join takes a []string and passes it to Join.
266 func join(elem
[]string, args
...string) string {
268 return filepath
.Join(args
...)
271 func TestJoin(t
*testing
.T
) {
272 if runtime
.GOOS
== "windows" {
273 jointests
= append(jointests
, winjointests
...)
275 for _
, test
:= range jointests
{
276 if p
:= join(test
.elem
); p
!= filepath
.FromSlash(test
.path
) {
277 t
.Errorf("join(%q) = %q, want %q", test
.elem
, p
, test
.path
)
282 type ExtTest
struct {
286 var exttests
= []ExtTest
{
288 {"path.pb.go", ".go"},
290 {"a.dir/b.go", ".go"},
294 func TestExt(t
*testing
.T
) {
295 for _
, test
:= range exttests
{
296 if x
:= filepath
.Ext(test
.path
); x
!= test
.ext
{
297 t
.Errorf("Ext(%q) = %q, want %q", test
.path
, x
, test
.ext
)
304 entries
[]*Node
// nil if the entry is a file
334 func walkTree(n
*Node
, path
string, f
func(path
string, n
*Node
)) {
336 for _
, e
:= range n
.entries
{
337 walkTree(e
, filepath
.Join(path
, e
.name
), f
)
341 func makeTree(t
*testing
.T
) {
342 walkTree(tree
, tree
.name
, func(path
string, n
*Node
) {
343 if n
.entries
== nil {
344 fd
, err
:= os
.Create(path
)
346 t
.Errorf("makeTree: %v", err
)
356 func markTree(n
*Node
) { walkTree(n
, "", func(path
string, n
*Node
) { n
.mark
++ }) }
358 func checkMarks(t
*testing
.T
, report
bool) {
359 walkTree(tree
, tree
.name
, func(path
string, n
*Node
) {
360 if n
.mark
!= 1 && report
{
361 t
.Errorf("node %s mark = %d; expected 1", path
, n
.mark
)
367 // Assumes that each node name is unique. Good enough for a test.
368 // If clear is true, any incoming error is cleared before return. The errors
369 // are always accumulated, though.
370 func mark(path
string, info os
.FileInfo
, err error
, errors
*[]error
, clear
bool) error
{
372 *errors
= append(*errors
, err
)
379 walkTree(tree
, tree
.name
, func(path
string, n
*Node
) {
387 func TestWalk(t
*testing
.T
) {
389 errors
:= make([]error
, 0, 10)
391 markFn
:= func(path
string, info os
.FileInfo
, err error
) error
{
392 return mark(path
, info
, err
, &errors
, clear
)
395 err
:= filepath
.Walk(tree
.name
, markFn
)
397 t
.Fatalf("no error expected, found: %s", err
)
399 if len(errors
) != 0 {
400 t
.Fatalf("unexpected errors: %s", errors
)
405 // Test permission errors. Only possible if we're not root
406 // and only on some file systems (AFS, FAT). To avoid errors during
407 // all.bash on those file systems, skip during go test -short.
408 if os
.Getuid() > 0 && !testing
.Short() {
409 // introduce 2 errors: chmod top-level directories to 0
410 os
.Chmod(filepath
.Join(tree
.name
, tree
.entries
[1].name
), 0)
411 os
.Chmod(filepath
.Join(tree
.name
, tree
.entries
[3].name
), 0)
413 // 3) capture errors, expect two.
414 // mark respective subtrees manually
415 markTree(tree
.entries
[1])
416 markTree(tree
.entries
[3])
417 // correct double-marking of directory itself
418 tree
.entries
[1].mark
--
419 tree
.entries
[3].mark
--
420 err
:= filepath
.Walk(tree
.name
, markFn
)
422 t
.Fatalf("expected no error return from Walk, got %s", err
)
424 if len(errors
) != 2 {
425 t
.Errorf("expected 2 errors, got %d: %s", len(errors
), errors
)
427 // the inaccessible subtrees were marked manually
431 // 4) capture errors, stop after first error.
432 // mark respective subtrees manually
433 markTree(tree
.entries
[1])
434 markTree(tree
.entries
[3])
435 // correct double-marking of directory itself
436 tree
.entries
[1].mark
--
437 tree
.entries
[3].mark
--
438 clear
= false // error will stop processing
439 err
= filepath
.Walk(tree
.name
, markFn
)
441 t
.Fatalf("expected error return from Walk")
443 if len(errors
) != 1 {
444 t
.Errorf("expected 1 error, got %d: %s", len(errors
), errors
)
446 // the inaccessible subtrees were marked manually
450 // restore permissions
451 os
.Chmod(filepath
.Join(tree
.name
, tree
.entries
[1].name
), 0770)
452 os
.Chmod(filepath
.Join(tree
.name
, tree
.entries
[3].name
), 0770)
456 if err
:= os
.RemoveAll(tree
.name
); err
!= nil {
457 t
.Errorf("removeTree: %v", err
)
461 var basetests
= []PathTest
{
475 var winbasetests
= []PathTest
{
481 {`\\host\share\`, `\`},
482 {`\\host\share\a`, `a`},
483 {`\\host\share\a\b`, `b`},
486 func TestBase(t
*testing
.T
) {
488 if runtime
.GOOS
== "windows" {
489 // make unix tests work on windows
490 for i
:= range tests
{
491 tests
[i
].result
= filepath
.Clean(tests
[i
].result
)
493 // add windows specific tests
494 tests
= append(tests
, winbasetests
...)
496 for _
, test
:= range tests
{
497 if s
:= filepath
.Base(test
.path
); s
!= test
.result
{
498 t
.Errorf("Base(%q) = %q, want %q", test
.path
, s
, test
.result
)
503 var dirtests
= []PathTest
{
518 var windirtests
= []PathTest
{
523 {`c:a\b\c`, `c:a\b`},
524 {`\\host\share\`, `\\host\share\`},
525 {`\\host\share\a`, `\\host\share\`},
526 {`\\host\share\a\b`, `\\host\share\a`},
529 func TestDir(t
*testing
.T
) {
531 if runtime
.GOOS
== "windows" {
532 // make unix tests work on windows
533 for i
:= range tests
{
534 tests
[i
].result
= filepath
.Clean(tests
[i
].result
)
536 // add windows specific tests
537 tests
= append(tests
, windirtests
...)
539 for _
, test
:= range tests
{
540 if s
:= filepath
.Dir(test
.path
); s
!= test
.result
{
541 t
.Errorf("Dir(%q) = %q, want %q", test
.path
, s
, test
.result
)
546 type IsAbsTest
struct {
551 var isabstests
= []IsAbsTest
{
554 {"/usr/bin/gcc", true},
562 var winisabstests
= []IsAbsTest
{
571 {`\\host\share\foo`, true},
572 {`//host/share/foo/bar`, true},
575 func TestIsAbs(t
*testing
.T
) {
576 var tests
[]IsAbsTest
577 if runtime
.GOOS
== "windows" {
578 tests
= append(tests
, winisabstests
...)
579 // All non-windows tests should fail, because they have no volume letter.
580 for _
, test
:= range isabstests
{
581 tests
= append(tests
, IsAbsTest
{test
.path
, false})
583 // All non-windows test should work as intended if prefixed with volume letter.
584 for _
, test
:= range isabstests
{
585 tests
= append(tests
, IsAbsTest
{"c:" + test
.path
, test
.isAbs
})
591 for _
, test
:= range tests
{
592 if r
:= filepath
.IsAbs(test
.path
); r
!= test
.isAbs
{
593 t
.Errorf("IsAbs(%q) = %v, want %v", test
.path
, r
, test
.isAbs
)
598 type EvalSymlinksTest
struct {
599 // If dest is empty, the path is created; otherwise the dest is symlinked to the path.
603 var EvalSymlinksTestDirs
= []EvalSymlinksTest
{
606 {"test/dir/link3", "../../"},
607 {"test/link1", "../test"},
608 {"test/link2", "dir"},
609 {"test/linkabs", "/"},
612 var EvalSymlinksTests
= []EvalSymlinksTest
{
614 {"test/dir", "test/dir"},
615 {"test/dir/../..", "."},
616 {"test/link1", "test"},
617 {"test/link2", "test/dir"},
618 {"test/link1/dir", "test/dir"},
619 {"test/link2/..", "test"},
620 {"test/dir/link3", "."},
621 {"test/link2/link3/test", "test"},
622 {"test/linkabs", "/"},
625 var EvalSymlinksAbsWindowsTests
= []EvalSymlinksTest
{
629 // simpleJoin builds a file name from the directory and path.
630 // It does not use Join because we don't want ".." to be evaluated.
631 func simpleJoin(dir
, path
string) string {
632 return dir
+ string(filepath
.Separator
) + path
635 func TestEvalSymlinks(t
*testing
.T
) {
636 tmpDir
, err
:= ioutil
.TempDir("", "evalsymlink")
638 t
.Fatal("creating temp dir:", err
)
640 defer os
.RemoveAll(tmpDir
)
642 // /tmp may itself be a symlink! Avoid the confusion, although
643 // it means trusting the thing we're testing.
644 tmpDir
, err
= filepath
.EvalSymlinks(tmpDir
)
646 t
.Fatal("eval symlink for tmp dir:", err
)
649 // Create the symlink farm using relative paths.
650 for _
, d
:= range EvalSymlinksTestDirs
{
652 path
:= simpleJoin(tmpDir
, d
.path
)
654 err
= os
.Mkdir(path
, 0755)
656 if runtime
.GOOS
!= "windows" {
657 err
= os
.Symlink(d
.dest
, path
)
665 var tests
[]EvalSymlinksTest
666 if runtime
.GOOS
== "windows" {
667 for _
, d
:= range EvalSymlinksTests
{
668 if d
.path
== d
.dest
{
669 // will test only real files and directories
670 tests
= append(tests
, d
)
671 // test "canonical" names
672 d2
:= EvalSymlinksTest
{
673 path
: strings
.ToUpper(d
.path
),
676 tests
= append(tests
, d2
)
680 tests
= EvalSymlinksTests
683 // Evaluate the symlink farm.
684 for _
, d
:= range tests
{
685 path
:= simpleJoin(tmpDir
, d
.path
)
686 dest
:= simpleJoin(tmpDir
, d
.dest
)
687 if filepath
.IsAbs(d
.dest
) {
690 if p
, err
:= filepath
.EvalSymlinks(path
); err
!= nil {
691 t
.Errorf("EvalSymlinks(%q) error: %v", d
.path
, err
)
692 } else if filepath
.Clean(p
) != filepath
.Clean(dest
) {
693 t
.Errorf("Clean(%q)=%q, want %q", path
, p
, dest
)
698 // Test directories relative to temporary directory.
699 // The tests are run in absTestDirs[0].
700 var absTestDirs
= []string{
706 // Test paths relative to temporary directory. $ expands to the directory.
707 // The tests are run in absTestDirs[0].
708 // We create absTestDirs first.
709 var absTests
= []string{
714 "../a/b/./c/../../.././a",
718 "$/a/b/c/../../.././a",
721 func TestAbs(t
*testing
.T
) {
722 oldwd
, err
:= os
.Getwd()
724 t
.Fatal("Getwd failed: ", err
)
726 defer os
.Chdir(oldwd
)
728 root
, err
:= ioutil
.TempDir("", "TestAbs")
730 t
.Fatal("TempDir failed: ", err
)
732 defer os
.RemoveAll(root
)
734 wd
, err
:= os
.Getwd()
736 t
.Fatal("getwd failed: ", err
)
740 t
.Fatal("chdir failed: ", err
)
744 for _
, dir
:= range absTestDirs
{
745 err
= os
.Mkdir(dir
, 0777)
747 t
.Fatal("Mkdir failed: ", err
)
751 err
= os
.Chdir(absTestDirs
[0])
753 t
.Fatal("chdir failed: ", err
)
756 for _
, path
:= range absTests
{
757 path
= strings
.Replace(path
, "$", root
, -1)
758 info
, err
:= os
.Stat(path
)
760 t
.Errorf("%s: %s", path
, err
)
764 abspath
, err
:= filepath
.Abs(path
)
766 t
.Errorf("Abs(%q) error: %v", path
, err
)
769 absinfo
, err
:= os
.Stat(abspath
)
770 if err
!= nil ||
!os
.SameFile(absinfo
, info
) {
771 t
.Errorf("Abs(%q)=%q, not the same file", path
, abspath
)
773 if !filepath
.IsAbs(abspath
) {
774 t
.Errorf("Abs(%q)=%q, not an absolute path", path
, abspath
)
776 if filepath
.IsAbs(path
) && abspath
!= filepath
.Clean(path
) {
777 t
.Errorf("Abs(%q)=%q, isn't clean", path
, abspath
)
782 type RelTests
struct {
783 root
, path
, want
string
786 var reltests
= []RelTests
{
788 {"a/b/.", "a/b", "."},
789 {"a/b", "a/b/.", "."},
790 {"./a/b", "a/b", "."},
791 {"a/b", "./a/b", "."},
792 {"ab/cd", "ab/cde", "../cde"},
793 {"ab/cd", "ab/c", "../c"},
794 {"a/b", "a/b/c/d", "c/d"},
795 {"a/b", "a/b/../c", "../c"},
796 {"a/b/../c", "a/b", "../b"},
797 {"a/b/c", "a/c/d", "../../c/d"},
798 {"a/b", "c/d", "../../c/d"},
799 {"a/b/c/d", "a/b", "../.."},
800 {"a/b/c/d", "a/b/", "../.."},
801 {"a/b/c/d/", "a/b", "../.."},
802 {"a/b/c/d/", "a/b/", "../.."},
803 {"../../a/b", "../../a/b/c/d", "c/d"},
804 {"/a/b", "/a/b", "."},
805 {"/a/b/.", "/a/b", "."},
806 {"/a/b", "/a/b/.", "."},
807 {"/ab/cd", "/ab/cde", "../cde"},
808 {"/ab/cd", "/ab/c", "../c"},
809 {"/a/b", "/a/b/c/d", "c/d"},
810 {"/a/b", "/a/b/../c", "../c"},
811 {"/a/b/../c", "/a/b", "../b"},
812 {"/a/b/c", "/a/c/d", "../../c/d"},
813 {"/a/b", "/c/d", "../../c/d"},
814 {"/a/b/c/d", "/a/b", "../.."},
815 {"/a/b/c/d", "/a/b/", "../.."},
816 {"/a/b/c/d/", "/a/b", "../.."},
817 {"/a/b/c/d/", "/a/b/", "../.."},
818 {"/../../a/b", "/../../a/b/c/d", "c/d"},
822 // can't do purely lexically
825 {"../..", "..", "err"},
830 var winreltests
= []RelTests
{
831 {`C:a\b\c`, `C:a/b/d`, `..\d`},
832 {`C:\`, `D:\`, `err`},
836 func TestRel(t
*testing
.T
) {
837 tests
:= append([]RelTests
{}, reltests
...)
838 if runtime
.GOOS
== "windows" {
839 for i
:= range tests
{
840 tests
[i
].want
= filepath
.FromSlash(tests
[i
].want
)
842 tests
= append(tests
, winreltests
...)
844 for _
, test
:= range tests
{
845 got
, err
:= filepath
.Rel(test
.root
, test
.path
)
846 if test
.want
== "err" {
848 t
.Errorf("Rel(%q, %q)=%q, want error", test
.root
, test
.path
, got
)
853 t
.Errorf("Rel(%q, %q): want %q, got error: %s", test
.root
, test
.path
, test
.want
, err
)
855 if got
!= test
.want
{
856 t
.Errorf("Rel(%q, %q)=%q, want %q", test
.root
, test
.path
, got
, test
.want
)
861 type VolumeNameTest
struct {
866 var volumenametests
= []VolumeNameTest
{
867 {`c:/foo/bar`, `c:`},
873 {`\\\host\share`, ``},
874 {`\\\host\\share`, ``},
879 {`\\host\share`, `\\host\share`},
880 {`//host/share`, `//host/share`},
881 {`\\host\share\`, `\\host\share`},
882 {`//host/share/`, `//host/share`},
883 {`\\host\share\foo`, `\\host\share`},
884 {`//host/share/foo`, `//host/share`},
885 {`\\host\share\\foo\\\bar\\\\baz`, `\\host\share`},
886 {`//host/share//foo///bar////baz`, `//host/share`},
887 {`\\host\share\foo\..\bar`, `\\host\share`},
888 {`//host/share/foo/../bar`, `//host/share`},
891 func TestVolumeName(t
*testing
.T
) {
892 if runtime
.GOOS
!= "windows" {
895 for _
, v
:= range volumenametests
{
896 if vol
:= filepath
.VolumeName(v
.path
); vol
!= v
.vol
{
897 t
.Errorf("VolumeName(%q)=%q, want %q", v
.path
, vol
, v
.vol
)
902 func TestDriveLetterInEvalSymlinks(t
*testing
.T
) {
903 if runtime
.GOOS
!= "windows" {
908 t
.Errorf("Current directory path %q is too short", wd
)
910 lp
:= strings
.ToLower(wd
)
911 up
:= strings
.ToUpper(wd
)
912 flp
, err
:= filepath
.EvalSymlinks(lp
)
914 t
.Fatalf("EvalSymlinks(%q) failed: %q", lp
, err
)
916 fup
, err
:= filepath
.EvalSymlinks(up
)
918 t
.Fatalf("EvalSymlinks(%q) failed: %q", up
, err
)
921 t
.Errorf("Results of EvalSymlinks do not match: %q and %q", flp
, fup
)
925 /* This test does not work gccgo, since the sources are arranged
928 func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
929 root, err := filepath.EvalSymlinks(runtime.GOROOT())
933 lib := filepath.Join(root, "lib")
934 src := filepath.Join(root, "src")
936 filepath.Walk(root, func(pth string, info os.FileInfo, err error) error {
943 return filepath.SkipDir
950 t.Fatalf("%q not seen", src)