os_test.go 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484
  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.
  4. package os_test
  5. import (
  6. "bytes"
  7. "errors"
  8. "flag"
  9. "fmt"
  10. "io"
  11. "io/ioutil"
  12. . "os"
  13. osexec "os/exec"
  14. "path/filepath"
  15. "reflect"
  16. "runtime"
  17. "sort"
  18. "strings"
  19. "sync"
  20. "syscall"
  21. "testing"
  22. "text/template"
  23. "time"
  24. )
  25. var supportsSymlinks = true
  26. var dot = []string{
  27. "dir_unix.go",
  28. "env.go",
  29. "error.go",
  30. "file.go",
  31. "os_test.go",
  32. "types.go",
  33. }
  34. type sysDir struct {
  35. name string
  36. files []string
  37. }
  38. var sysdir = func() (sd *sysDir) {
  39. switch runtime.GOOS {
  40. case "android":
  41. sd = &sysDir{
  42. "/system/etc",
  43. []string{
  44. "audio_policy.conf",
  45. "system_fonts.xml",
  46. },
  47. }
  48. case "windows":
  49. sd = &sysDir{
  50. Getenv("SystemRoot") + "\\system32\\drivers\\etc",
  51. []string{
  52. "networks",
  53. "protocol",
  54. "services",
  55. },
  56. }
  57. case "plan9":
  58. sd = &sysDir{
  59. "/lib/ndb",
  60. []string{
  61. "common",
  62. "local",
  63. },
  64. }
  65. default:
  66. sd = &sysDir{
  67. "/etc",
  68. []string{
  69. "group",
  70. "hosts",
  71. "passwd",
  72. },
  73. }
  74. }
  75. return
  76. }()
  77. func size(name string, t *testing.T) int64 {
  78. file, err := Open(name)
  79. if err != nil {
  80. t.Fatal("open failed:", err)
  81. }
  82. defer file.Close()
  83. var buf [100]byte
  84. len := 0
  85. for {
  86. n, e := file.Read(buf[0:])
  87. len += n
  88. if e == io.EOF {
  89. break
  90. }
  91. if e != nil {
  92. t.Fatal("read failed:", err)
  93. }
  94. }
  95. return int64(len)
  96. }
  97. func equal(name1, name2 string) (r bool) {
  98. switch runtime.GOOS {
  99. case "windows":
  100. r = strings.ToLower(name1) == strings.ToLower(name2)
  101. default:
  102. r = name1 == name2
  103. }
  104. return
  105. }
  106. func newFile(testName string, t *testing.T) (f *File) {
  107. // Use a local file system, not NFS.
  108. // On Unix, override $TMPDIR in case the user
  109. // has it set to an NFS-mounted directory.
  110. dir := ""
  111. if runtime.GOOS != "android" && runtime.GOOS != "windows" {
  112. dir = "/tmp"
  113. }
  114. f, err := ioutil.TempFile(dir, "_Go_"+testName)
  115. if err != nil {
  116. t.Fatalf("TempFile %s: %s", testName, err)
  117. }
  118. return
  119. }
  120. func newDir(testName string, t *testing.T) (name string) {
  121. // Use a local file system, not NFS.
  122. // On Unix, override $TMPDIR in case the user
  123. // has it set to an NFS-mounted directory.
  124. dir := ""
  125. if runtime.GOOS != "android" && runtime.GOOS != "windows" {
  126. dir = "/tmp"
  127. }
  128. name, err := ioutil.TempDir(dir, "_Go_"+testName)
  129. if err != nil {
  130. t.Fatalf("TempDir %s: %s", testName, err)
  131. }
  132. return
  133. }
  134. var sfdir = sysdir.name
  135. var sfname = sysdir.files[0]
  136. func TestStat(t *testing.T) {
  137. path := sfdir + "/" + sfname
  138. dir, err := Stat(path)
  139. if err != nil {
  140. t.Fatal("stat failed:", err)
  141. }
  142. if !equal(sfname, dir.Name()) {
  143. t.Error("name should be ", sfname, "; is", dir.Name())
  144. }
  145. filesize := size(path, t)
  146. if dir.Size() != filesize {
  147. t.Error("size should be", filesize, "; is", dir.Size())
  148. }
  149. }
  150. func TestFstat(t *testing.T) {
  151. path := sfdir + "/" + sfname
  152. file, err1 := Open(path)
  153. if err1 != nil {
  154. t.Fatal("open failed:", err1)
  155. }
  156. defer file.Close()
  157. dir, err2 := file.Stat()
  158. if err2 != nil {
  159. t.Fatal("fstat failed:", err2)
  160. }
  161. if !equal(sfname, dir.Name()) {
  162. t.Error("name should be ", sfname, "; is", dir.Name())
  163. }
  164. filesize := size(path, t)
  165. if dir.Size() != filesize {
  166. t.Error("size should be", filesize, "; is", dir.Size())
  167. }
  168. }
  169. func TestLstat(t *testing.T) {
  170. path := sfdir + "/" + sfname
  171. dir, err := Lstat(path)
  172. if err != nil {
  173. t.Fatal("lstat failed:", err)
  174. }
  175. if !equal(sfname, dir.Name()) {
  176. t.Error("name should be ", sfname, "; is", dir.Name())
  177. }
  178. filesize := size(path, t)
  179. if dir.Size() != filesize {
  180. t.Error("size should be", filesize, "; is", dir.Size())
  181. }
  182. }
  183. // Read with length 0 should not return EOF.
  184. func TestRead0(t *testing.T) {
  185. path := sfdir + "/" + sfname
  186. f, err := Open(path)
  187. if err != nil {
  188. t.Fatal("open failed:", err)
  189. }
  190. defer f.Close()
  191. b := make([]byte, 0)
  192. n, err := f.Read(b)
  193. if n != 0 || err != nil {
  194. t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
  195. }
  196. b = make([]byte, 100)
  197. n, err = f.Read(b)
  198. if n <= 0 || err != nil {
  199. t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
  200. }
  201. }
  202. func testReaddirnames(dir string, contents []string, t *testing.T) {
  203. file, err := Open(dir)
  204. if err != nil {
  205. t.Fatalf("open %q failed: %v", dir, err)
  206. }
  207. defer file.Close()
  208. s, err2 := file.Readdirnames(-1)
  209. if err2 != nil {
  210. t.Fatalf("readdirnames %q failed: %v", dir, err2)
  211. }
  212. for _, m := range contents {
  213. found := false
  214. for _, n := range s {
  215. if n == "." || n == ".." {
  216. t.Errorf("got %s in directory", n)
  217. }
  218. if equal(m, n) {
  219. if found {
  220. t.Error("present twice:", m)
  221. }
  222. found = true
  223. }
  224. }
  225. if !found {
  226. t.Error("could not find", m)
  227. }
  228. }
  229. }
  230. func testReaddir(dir string, contents []string, t *testing.T) {
  231. file, err := Open(dir)
  232. if err != nil {
  233. t.Fatalf("open %q failed: %v", dir, err)
  234. }
  235. defer file.Close()
  236. s, err2 := file.Readdir(-1)
  237. if err2 != nil {
  238. t.Fatalf("readdir %q failed: %v", dir, err2)
  239. }
  240. for _, m := range contents {
  241. found := false
  242. for _, n := range s {
  243. if equal(m, n.Name()) {
  244. if found {
  245. t.Error("present twice:", m)
  246. }
  247. found = true
  248. }
  249. }
  250. if !found {
  251. t.Error("could not find", m)
  252. }
  253. }
  254. }
  255. func TestReaddirnames(t *testing.T) {
  256. testReaddirnames(".", dot, t)
  257. testReaddirnames(sysdir.name, sysdir.files, t)
  258. }
  259. func TestReaddir(t *testing.T) {
  260. testReaddir(".", dot, t)
  261. testReaddir(sysdir.name, sysdir.files, t)
  262. }
  263. // Read the directory one entry at a time.
  264. func smallReaddirnames(file *File, length int, t *testing.T) []string {
  265. names := make([]string, length)
  266. count := 0
  267. for {
  268. d, err := file.Readdirnames(1)
  269. if err == io.EOF {
  270. break
  271. }
  272. if err != nil {
  273. t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
  274. }
  275. if len(d) == 0 {
  276. t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
  277. }
  278. names[count] = d[0]
  279. count++
  280. }
  281. return names[0:count]
  282. }
  283. // Check that reading a directory one entry at a time gives the same result
  284. // as reading it all at once.
  285. func TestReaddirnamesOneAtATime(t *testing.T) {
  286. // big directory that doesn't change often.
  287. dir := "/usr/bin"
  288. switch runtime.GOOS {
  289. case "android":
  290. dir = "/system/bin"
  291. case "plan9":
  292. dir = "/bin"
  293. case "windows":
  294. dir = Getenv("SystemRoot") + "\\system32"
  295. }
  296. file, err := Open(dir)
  297. if err != nil {
  298. t.Fatalf("open %q failed: %v", dir, err)
  299. }
  300. defer file.Close()
  301. all, err1 := file.Readdirnames(-1)
  302. if err1 != nil {
  303. t.Fatalf("readdirnames %q failed: %v", dir, err1)
  304. }
  305. file1, err2 := Open(dir)
  306. if err2 != nil {
  307. t.Fatalf("open %q failed: %v", dir, err2)
  308. }
  309. defer file1.Close()
  310. small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
  311. if len(small) < len(all) {
  312. t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
  313. }
  314. for i, n := range all {
  315. if small[i] != n {
  316. t.Errorf("small read %q mismatch: %v", small[i], n)
  317. }
  318. }
  319. }
  320. func TestReaddirNValues(t *testing.T) {
  321. if testing.Short() {
  322. t.Skip("test.short; skipping")
  323. }
  324. dir, err := ioutil.TempDir("", "")
  325. if err != nil {
  326. t.Fatalf("TempDir: %v", err)
  327. }
  328. defer RemoveAll(dir)
  329. for i := 1; i <= 105; i++ {
  330. f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
  331. if err != nil {
  332. t.Fatalf("Create: %v", err)
  333. }
  334. f.Write([]byte(strings.Repeat("X", i)))
  335. f.Close()
  336. }
  337. var d *File
  338. openDir := func() {
  339. var err error
  340. d, err = Open(dir)
  341. if err != nil {
  342. t.Fatalf("Open directory: %v", err)
  343. }
  344. }
  345. readDirExpect := func(n, want int, wantErr error) {
  346. fi, err := d.Readdir(n)
  347. if err != wantErr {
  348. t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
  349. }
  350. if g, e := len(fi), want; g != e {
  351. t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
  352. }
  353. }
  354. readDirNamesExpect := func(n, want int, wantErr error) {
  355. fi, err := d.Readdirnames(n)
  356. if err != wantErr {
  357. t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
  358. }
  359. if g, e := len(fi), want; g != e {
  360. t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
  361. }
  362. }
  363. for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
  364. // Test the slurp case
  365. openDir()
  366. fn(0, 105, nil)
  367. fn(0, 0, nil)
  368. d.Close()
  369. // Slurp with -1 instead
  370. openDir()
  371. fn(-1, 105, nil)
  372. fn(-2, 0, nil)
  373. fn(0, 0, nil)
  374. d.Close()
  375. // Test the bounded case
  376. openDir()
  377. fn(1, 1, nil)
  378. fn(2, 2, nil)
  379. fn(105, 102, nil) // and tests buffer >100 case
  380. fn(3, 0, io.EOF)
  381. d.Close()
  382. }
  383. }
  384. func touch(t *testing.T, name string) {
  385. f, err := Create(name)
  386. if err != nil {
  387. t.Fatal(err)
  388. }
  389. if err := f.Close(); err != nil {
  390. t.Fatal(err)
  391. }
  392. }
  393. func TestReaddirStatFailures(t *testing.T) {
  394. switch runtime.GOOS {
  395. case "windows", "plan9":
  396. // Windows and Plan 9 already do this correctly,
  397. // but are structured with different syscalls such
  398. // that they don't use Lstat, so the hook below for
  399. // testing it wouldn't work.
  400. t.Skipf("skipping test on %v", runtime.GOOS)
  401. }
  402. dir, err := ioutil.TempDir("", "")
  403. if err != nil {
  404. t.Fatalf("TempDir: %v", err)
  405. }
  406. defer RemoveAll(dir)
  407. touch(t, filepath.Join(dir, "good1"))
  408. touch(t, filepath.Join(dir, "x")) // will disappear or have an error
  409. touch(t, filepath.Join(dir, "good2"))
  410. defer func() {
  411. *LstatP = Lstat
  412. }()
  413. var xerr error // error to return for x
  414. *LstatP = func(path string) (FileInfo, error) {
  415. if xerr != nil && strings.HasSuffix(path, "x") {
  416. return nil, xerr
  417. }
  418. return Lstat(path)
  419. }
  420. readDir := func() ([]FileInfo, error) {
  421. d, err := Open(dir)
  422. if err != nil {
  423. t.Fatal(err)
  424. }
  425. defer d.Close()
  426. return d.Readdir(-1)
  427. }
  428. mustReadDir := func(testName string) []FileInfo {
  429. fis, err := readDir()
  430. if err != nil {
  431. t.Fatalf("%s: Readdir: %v", testName, err)
  432. }
  433. return fis
  434. }
  435. names := func(fis []FileInfo) []string {
  436. s := make([]string, len(fis))
  437. for i, fi := range fis {
  438. s[i] = fi.Name()
  439. }
  440. sort.Strings(s)
  441. return s
  442. }
  443. if got, want := names(mustReadDir("inital readdir")),
  444. []string{"good1", "good2", "x"}; !reflect.DeepEqual(got, want) {
  445. t.Errorf("initial readdir got %q; want %q", got, want)
  446. }
  447. xerr = ErrNotExist
  448. if got, want := names(mustReadDir("with x disappearing")),
  449. []string{"good1", "good2"}; !reflect.DeepEqual(got, want) {
  450. t.Errorf("with x disappearing, got %q; want %q", got, want)
  451. }
  452. xerr = errors.New("some real error")
  453. if _, err := readDir(); err != xerr {
  454. t.Errorf("with a non-ErrNotExist error, got error %v; want %v", err, xerr)
  455. }
  456. }
  457. func TestHardLink(t *testing.T) {
  458. // Hardlinks are not supported under windows or Plan 9.
  459. if runtime.GOOS == "plan9" {
  460. return
  461. }
  462. from, to := "hardlinktestfrom", "hardlinktestto"
  463. Remove(from) // Just in case.
  464. file, err := Create(to)
  465. if err != nil {
  466. t.Fatalf("open %q failed: %v", to, err)
  467. }
  468. defer Remove(to)
  469. if err = file.Close(); err != nil {
  470. t.Errorf("close %q failed: %v", to, err)
  471. }
  472. err = Link(to, from)
  473. if err != nil {
  474. t.Fatalf("link %q, %q failed: %v", to, from, err)
  475. }
  476. defer Remove(from)
  477. tostat, err := Stat(to)
  478. if err != nil {
  479. t.Fatalf("stat %q failed: %v", to, err)
  480. }
  481. fromstat, err := Stat(from)
  482. if err != nil {
  483. t.Fatalf("stat %q failed: %v", from, err)
  484. }
  485. if !SameFile(tostat, fromstat) {
  486. t.Errorf("link %q, %q did not create hard link", to, from)
  487. }
  488. }
  489. func TestSymlink(t *testing.T) {
  490. switch runtime.GOOS {
  491. case "android", "nacl", "plan9":
  492. t.Skipf("skipping on %s", runtime.GOOS)
  493. case "windows":
  494. if !supportsSymlinks {
  495. t.Skipf("skipping on %s", runtime.GOOS)
  496. }
  497. }
  498. from, to := "symlinktestfrom", "symlinktestto"
  499. Remove(from) // Just in case.
  500. file, err := Create(to)
  501. if err != nil {
  502. t.Fatalf("open %q failed: %v", to, err)
  503. }
  504. defer Remove(to)
  505. if err = file.Close(); err != nil {
  506. t.Errorf("close %q failed: %v", to, err)
  507. }
  508. err = Symlink(to, from)
  509. if err != nil {
  510. t.Fatalf("symlink %q, %q failed: %v", to, from, err)
  511. }
  512. defer Remove(from)
  513. tostat, err := Lstat(to)
  514. if err != nil {
  515. t.Fatalf("stat %q failed: %v", to, err)
  516. }
  517. if tostat.Mode()&ModeSymlink != 0 {
  518. t.Fatalf("stat %q claims to have found a symlink", to)
  519. }
  520. fromstat, err := Stat(from)
  521. if err != nil {
  522. t.Fatalf("stat %q failed: %v", from, err)
  523. }
  524. if !SameFile(tostat, fromstat) {
  525. t.Errorf("symlink %q, %q did not create symlink", to, from)
  526. }
  527. fromstat, err = Lstat(from)
  528. if err != nil {
  529. t.Fatalf("lstat %q failed: %v", from, err)
  530. }
  531. if fromstat.Mode()&ModeSymlink == 0 {
  532. t.Fatalf("symlink %q, %q did not create symlink", to, from)
  533. }
  534. fromstat, err = Stat(from)
  535. if err != nil {
  536. t.Fatalf("stat %q failed: %v", from, err)
  537. }
  538. if fromstat.Mode()&ModeSymlink != 0 {
  539. t.Fatalf("stat %q did not follow symlink", from)
  540. }
  541. s, err := Readlink(from)
  542. if err != nil {
  543. t.Fatalf("readlink %q failed: %v", from, err)
  544. }
  545. if s != to {
  546. t.Fatalf("after symlink %q != %q", s, to)
  547. }
  548. file, err = Open(from)
  549. if err != nil {
  550. t.Fatalf("open %q failed: %v", from, err)
  551. }
  552. file.Close()
  553. }
  554. func TestLongSymlink(t *testing.T) {
  555. switch runtime.GOOS {
  556. case "plan9", "nacl":
  557. t.Skipf("skipping on %s", runtime.GOOS)
  558. case "windows":
  559. if !supportsSymlinks {
  560. t.Skipf("skipping on %s", runtime.GOOS)
  561. }
  562. }
  563. s := "0123456789abcdef"
  564. // Long, but not too long: a common limit is 255.
  565. s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
  566. from := "longsymlinktestfrom"
  567. Remove(from) // Just in case.
  568. err := Symlink(s, from)
  569. if err != nil {
  570. t.Fatalf("symlink %q, %q failed: %v", s, from, err)
  571. }
  572. defer Remove(from)
  573. r, err := Readlink(from)
  574. if err != nil {
  575. t.Fatalf("readlink %q failed: %v", from, err)
  576. }
  577. if r != s {
  578. t.Fatalf("after symlink %q != %q", r, s)
  579. }
  580. }
  581. func TestRename(t *testing.T) {
  582. from, to := "renamefrom", "renameto"
  583. Remove(to) // Just in case.
  584. file, err := Create(from)
  585. if err != nil {
  586. t.Fatalf("open %q failed: %v", to, err)
  587. }
  588. if err = file.Close(); err != nil {
  589. t.Errorf("close %q failed: %v", to, err)
  590. }
  591. err = Rename(from, to)
  592. if err != nil {
  593. t.Fatalf("rename %q, %q failed: %v", to, from, err)
  594. }
  595. defer Remove(to)
  596. _, err = Stat(to)
  597. if err != nil {
  598. t.Errorf("stat %q failed: %v", to, err)
  599. }
  600. }
  601. func exec(t *testing.T, dir, cmd string, args []string, expect string) {
  602. r, w, err := Pipe()
  603. if err != nil {
  604. t.Fatalf("Pipe: %v", err)
  605. }
  606. defer r.Close()
  607. attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
  608. p, err := StartProcess(cmd, args, attr)
  609. if err != nil {
  610. t.Fatalf("StartProcess: %v", err)
  611. }
  612. w.Close()
  613. var b bytes.Buffer
  614. io.Copy(&b, r)
  615. output := b.String()
  616. fi1, _ := Stat(strings.TrimSpace(output))
  617. fi2, _ := Stat(expect)
  618. if !SameFile(fi1, fi2) {
  619. t.Errorf("exec %q returned %q wanted %q",
  620. strings.Join(append([]string{cmd}, args...), " "), output, expect)
  621. }
  622. p.Wait()
  623. }
  624. func TestStartProcess(t *testing.T) {
  625. switch runtime.GOOS {
  626. case "android", "nacl":
  627. t.Skipf("skipping on %s", runtime.GOOS)
  628. }
  629. var dir, cmd string
  630. var args []string
  631. if runtime.GOOS == "windows" {
  632. cmd = Getenv("COMSPEC")
  633. dir = Getenv("SystemRoot")
  634. args = []string{"/c", "cd"}
  635. } else {
  636. cmd = "/bin/pwd"
  637. dir = "/"
  638. args = []string{}
  639. }
  640. cmddir, cmdbase := filepath.Split(cmd)
  641. args = append([]string{cmdbase}, args...)
  642. // Test absolute executable path.
  643. exec(t, dir, cmd, args, dir)
  644. // Test relative executable path.
  645. exec(t, cmddir, cmdbase, args, cmddir)
  646. }
  647. func checkMode(t *testing.T, path string, mode FileMode) {
  648. dir, err := Stat(path)
  649. if err != nil {
  650. t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
  651. }
  652. if dir.Mode()&0777 != mode {
  653. t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
  654. }
  655. }
  656. func TestChmod(t *testing.T) {
  657. // Chmod is not supported under windows.
  658. if runtime.GOOS == "windows" {
  659. return
  660. }
  661. f := newFile("TestChmod", t)
  662. defer Remove(f.Name())
  663. defer f.Close()
  664. if err := Chmod(f.Name(), 0456); err != nil {
  665. t.Fatalf("chmod %s 0456: %s", f.Name(), err)
  666. }
  667. checkMode(t, f.Name(), 0456)
  668. if err := f.Chmod(0123); err != nil {
  669. t.Fatalf("chmod %s 0123: %s", f.Name(), err)
  670. }
  671. checkMode(t, f.Name(), 0123)
  672. }
  673. func checkSize(t *testing.T, f *File, size int64) {
  674. dir, err := f.Stat()
  675. if err != nil {
  676. t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
  677. }
  678. if dir.Size() != size {
  679. t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
  680. }
  681. }
  682. func TestFTruncate(t *testing.T) {
  683. f := newFile("TestFTruncate", t)
  684. defer Remove(f.Name())
  685. defer f.Close()
  686. checkSize(t, f, 0)
  687. f.Write([]byte("hello, world\n"))
  688. checkSize(t, f, 13)
  689. f.Truncate(10)
  690. checkSize(t, f, 10)
  691. f.Truncate(1024)
  692. checkSize(t, f, 1024)
  693. f.Truncate(0)
  694. checkSize(t, f, 0)
  695. _, err := f.Write([]byte("surprise!"))
  696. if err == nil {
  697. checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
  698. }
  699. }
  700. func TestTruncate(t *testing.T) {
  701. f := newFile("TestTruncate", t)
  702. defer Remove(f.Name())
  703. defer f.Close()
  704. checkSize(t, f, 0)
  705. f.Write([]byte("hello, world\n"))
  706. checkSize(t, f, 13)
  707. Truncate(f.Name(), 10)
  708. checkSize(t, f, 10)
  709. Truncate(f.Name(), 1024)
  710. checkSize(t, f, 1024)
  711. Truncate(f.Name(), 0)
  712. checkSize(t, f, 0)
  713. _, err := f.Write([]byte("surprise!"))
  714. if err == nil {
  715. checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
  716. }
  717. }
  718. // Use TempDir (via newFile) to make sure we're on a local file system,
  719. // so that timings are not distorted by latency and caching.
  720. // On NFS, timings can be off due to caching of meta-data on
  721. // NFS servers (Issue 848).
  722. func TestChtimes(t *testing.T) {
  723. f := newFile("TestChtimes", t)
  724. defer Remove(f.Name())
  725. f.Write([]byte("hello, world\n"))
  726. f.Close()
  727. testChtimes(t, f.Name())
  728. }
  729. // Use TempDir (via newDir) to make sure we're on a local file system,
  730. // so that timings are not distorted by latency and caching.
  731. // On NFS, timings can be off due to caching of meta-data on
  732. // NFS servers (Issue 848).
  733. func TestChtimesDir(t *testing.T) {
  734. name := newDir("TestChtimes", t)
  735. defer RemoveAll(name)
  736. testChtimes(t, name)
  737. }
  738. func testChtimes(t *testing.T, name string) {
  739. st, err := Stat(name)
  740. if err != nil {
  741. t.Fatalf("Stat %s: %s", name, err)
  742. }
  743. preStat := st
  744. // Move access and modification time back a second
  745. at := Atime(preStat)
  746. mt := preStat.ModTime()
  747. err = Chtimes(name, at.Add(-time.Second), mt.Add(-time.Second))
  748. if err != nil {
  749. t.Fatalf("Chtimes %s: %s", name, err)
  750. }
  751. st, err = Stat(name)
  752. if err != nil {
  753. t.Fatalf("second Stat %s: %s", name, err)
  754. }
  755. postStat := st
  756. /* Plan 9, NaCl:
  757. Mtime is the time of the last change of content. Similarly, atime is set whenever the
  758. contents are accessed; also, it is set whenever mtime is set.
  759. */
  760. pat := Atime(postStat)
  761. pmt := postStat.ModTime()
  762. if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" {
  763. t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
  764. }
  765. if !pmt.Before(mt) {
  766. t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
  767. }
  768. }
  769. func TestChdirAndGetwd(t *testing.T) {
  770. // TODO(brainman): file.Chdir() is not implemented on windows.
  771. if runtime.GOOS == "windows" {
  772. return
  773. }
  774. fd, err := Open(".")
  775. if err != nil {
  776. t.Fatalf("Open .: %s", err)
  777. }
  778. // These are chosen carefully not to be symlinks on a Mac
  779. // (unlike, say, /var, /etc), except /tmp, which we handle below.
  780. dirs := []string{"/", "/usr/bin", "/tmp"}
  781. // /usr/bin does not usually exist on Plan 9 or Android.
  782. switch runtime.GOOS {
  783. case "android":
  784. dirs = []string{"/", "/system/bin"}
  785. case "plan9":
  786. dirs = []string{"/", "/usr"}
  787. }
  788. oldwd := Getenv("PWD")
  789. for mode := 0; mode < 2; mode++ {
  790. for _, d := range dirs {
  791. if mode == 0 {
  792. err = Chdir(d)
  793. } else {
  794. fd1, err := Open(d)
  795. if err != nil {
  796. t.Errorf("Open %s: %s", d, err)
  797. continue
  798. }
  799. err = fd1.Chdir()
  800. fd1.Close()
  801. }
  802. if d == "/tmp" {
  803. Setenv("PWD", "/tmp")
  804. }
  805. pwd, err1 := Getwd()
  806. Setenv("PWD", oldwd)
  807. err2 := fd.Chdir()
  808. if err2 != nil {
  809. // We changed the current directory and cannot go back.
  810. // Don't let the tests continue; they'll scribble
  811. // all over some other directory.
  812. fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
  813. Exit(1)
  814. }
  815. if err != nil {
  816. fd.Close()
  817. t.Fatalf("Chdir %s: %s", d, err)
  818. }
  819. if err1 != nil {
  820. fd.Close()
  821. t.Fatalf("Getwd in %s: %s", d, err1)
  822. }
  823. if pwd != d {
  824. fd.Close()
  825. t.Fatalf("Getwd returned %q want %q", pwd, d)
  826. }
  827. }
  828. }
  829. fd.Close()
  830. }
  831. func TestSeek(t *testing.T) {
  832. f := newFile("TestSeek", t)
  833. defer Remove(f.Name())
  834. defer f.Close()
  835. const data = "hello, world\n"
  836. io.WriteString(f, data)
  837. type test struct {
  838. in int64
  839. whence int
  840. out int64
  841. }
  842. var tests = []test{
  843. {0, 1, int64(len(data))},
  844. {0, 0, 0},
  845. {5, 0, 5},
  846. {0, 2, int64(len(data))},
  847. {0, 0, 0},
  848. {-1, 2, int64(len(data)) - 1},
  849. {1 << 33, 0, 1 << 33},
  850. {1 << 33, 2, 1<<33 + int64(len(data))},
  851. }
  852. for i, tt := range tests {
  853. off, err := f.Seek(tt.in, tt.whence)
  854. if off != tt.out || err != nil {
  855. if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
  856. // Reiserfs rejects the big seeks.
  857. // http://code.google.com/p/go/issues/detail?id=91
  858. break
  859. }
  860. t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
  861. }
  862. }
  863. }
  864. type openErrorTest struct {
  865. path string
  866. mode int
  867. error error
  868. }
  869. var openErrorTests = []openErrorTest{
  870. {
  871. sfdir + "/no-such-file",
  872. O_RDONLY,
  873. syscall.ENOENT,
  874. },
  875. {
  876. sfdir,
  877. O_WRONLY,
  878. syscall.EISDIR,
  879. },
  880. {
  881. sfdir + "/" + sfname + "/no-such-file",
  882. O_WRONLY,
  883. syscall.ENOTDIR,
  884. },
  885. }
  886. func TestOpenError(t *testing.T) {
  887. for _, tt := range openErrorTests {
  888. f, err := OpenFile(tt.path, tt.mode, 0)
  889. if err == nil {
  890. t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
  891. f.Close()
  892. continue
  893. }
  894. perr, ok := err.(*PathError)
  895. if !ok {
  896. t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
  897. }
  898. if perr.Err != tt.error {
  899. if runtime.GOOS == "plan9" {
  900. syscallErrStr := perr.Err.Error()
  901. expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
  902. if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
  903. // Some Plan 9 file servers incorrectly return
  904. // EACCES rather than EISDIR when a directory is
  905. // opened for write.
  906. if tt.error == syscall.EISDIR && strings.HasSuffix(syscallErrStr, syscall.EACCES.Error()) {
  907. continue
  908. }
  909. t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
  910. }
  911. continue
  912. }
  913. if runtime.GOOS == "dragonfly" {
  914. // DragonFly incorrectly returns EACCES rather
  915. // EISDIR when a directory is opened for write.
  916. if tt.error == syscall.EISDIR && perr.Err == syscall.EACCES {
  917. continue
  918. }
  919. }
  920. t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
  921. }
  922. }
  923. }
  924. func TestOpenNoName(t *testing.T) {
  925. f, err := Open("")
  926. if err == nil {
  927. t.Fatal(`Open("") succeeded`)
  928. f.Close()
  929. }
  930. }
  931. func run(t *testing.T, cmd []string) string {
  932. // Run /bin/hostname and collect output.
  933. r, w, err := Pipe()
  934. if err != nil {
  935. t.Fatal(err)
  936. }
  937. defer r.Close()
  938. p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
  939. if err != nil {
  940. t.Fatal(err)
  941. }
  942. w.Close()
  943. var b bytes.Buffer
  944. io.Copy(&b, r)
  945. _, err = p.Wait()
  946. if err != nil {
  947. t.Fatalf("run hostname Wait: %v", err)
  948. }
  949. err = p.Kill()
  950. if err == nil {
  951. t.Errorf("expected an error from Kill running 'hostname'")
  952. }
  953. output := b.String()
  954. if n := len(output); n > 0 && output[n-1] == '\n' {
  955. output = output[0 : n-1]
  956. }
  957. if output == "" {
  958. t.Fatalf("%v produced no output", cmd)
  959. }
  960. return output
  961. }
  962. func TestHostname(t *testing.T) {
  963. // There is no other way to fetch hostname on windows, but via winapi.
  964. // On Plan 9 it can be taken from #c/sysname as Hostname() does.
  965. switch runtime.GOOS {
  966. case "android", "nacl", "plan9", "windows":
  967. t.Skipf("skipping on %s", runtime.GOOS)
  968. }
  969. // Check internal Hostname() against the output of /bin/hostname.
  970. // Allow that the internal Hostname returns a Fully Qualified Domain Name
  971. // and the /bin/hostname only returns the first component
  972. hostname, err := Hostname()
  973. if err != nil {
  974. t.Fatalf("%v", err)
  975. }
  976. want := run(t, []string{"/bin/hostname"})
  977. if hostname != want {
  978. i := strings.Index(hostname, ".")
  979. if i < 0 || hostname[0:i] != want {
  980. t.Errorf("Hostname() = %q, want %q", hostname, want)
  981. }
  982. }
  983. }
  984. func TestReadAt(t *testing.T) {
  985. f := newFile("TestReadAt", t)
  986. defer Remove(f.Name())
  987. defer f.Close()
  988. const data = "hello, world\n"
  989. io.WriteString(f, data)
  990. b := make([]byte, 5)
  991. n, err := f.ReadAt(b, 7)
  992. if err != nil || n != len(b) {
  993. t.Fatalf("ReadAt 7: %d, %v", n, err)
  994. }
  995. if string(b) != "world" {
  996. t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
  997. }
  998. }
  999. func TestWriteAt(t *testing.T) {
  1000. f := newFile("TestWriteAt", t)
  1001. defer Remove(f.Name())
  1002. defer f.Close()
  1003. const data = "hello, world\n"
  1004. io.WriteString(f, data)
  1005. n, err := f.WriteAt([]byte("WORLD"), 7)
  1006. if err != nil || n != 5 {
  1007. t.Fatalf("WriteAt 7: %d, %v", n, err)
  1008. }
  1009. b, err := ioutil.ReadFile(f.Name())
  1010. if err != nil {
  1011. t.Fatalf("ReadFile %s: %v", f.Name(), err)
  1012. }
  1013. if string(b) != "hello, WORLD\n" {
  1014. t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
  1015. }
  1016. }
  1017. func writeFile(t *testing.T, fname string, flag int, text string) string {
  1018. f, err := OpenFile(fname, flag, 0666)
  1019. if err != nil {
  1020. t.Fatalf("Open: %v", err)
  1021. }
  1022. n, err := io.WriteString(f, text)
  1023. if err != nil {
  1024. t.Fatalf("WriteString: %d, %v", n, err)
  1025. }
  1026. f.Close()
  1027. data, err := ioutil.ReadFile(fname)
  1028. if err != nil {
  1029. t.Fatalf("ReadFile: %v", err)
  1030. }
  1031. return string(data)
  1032. }
  1033. func TestAppend(t *testing.T) {
  1034. const f = "append.txt"
  1035. defer Remove(f)
  1036. s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
  1037. if s != "new" {
  1038. t.Fatalf("writeFile: have %q want %q", s, "new")
  1039. }
  1040. s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
  1041. if s != "new|append" {
  1042. t.Fatalf("writeFile: have %q want %q", s, "new|append")
  1043. }
  1044. s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
  1045. if s != "new|append|append" {
  1046. t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
  1047. }
  1048. err := Remove(f)
  1049. if err != nil {
  1050. t.Fatalf("Remove: %v", err)
  1051. }
  1052. s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
  1053. if s != "new&append" {
  1054. t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
  1055. }
  1056. s = writeFile(t, f, O_CREATE|O_RDWR, "old")
  1057. if s != "old&append" {
  1058. t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
  1059. }
  1060. s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
  1061. if s != "new" {
  1062. t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
  1063. }
  1064. }
  1065. func TestStatDirWithTrailingSlash(t *testing.T) {
  1066. // Create new temporary directory and arrange to clean it up.
  1067. path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_")
  1068. if err != nil {
  1069. t.Fatalf("TempDir: %s", err)
  1070. }
  1071. defer RemoveAll(path)
  1072. // Stat of path should succeed.
  1073. _, err = Stat(path)
  1074. if err != nil {
  1075. t.Fatalf("stat %s failed: %s", path, err)
  1076. }
  1077. // Stat of path+"/" should succeed too.
  1078. path += "/"
  1079. _, err = Stat(path)
  1080. if err != nil {
  1081. t.Fatalf("stat %s failed: %s", path, err)
  1082. }
  1083. }
  1084. func TestNilProcessStateString(t *testing.T) {
  1085. var ps *ProcessState
  1086. s := ps.String()
  1087. if s != "<nil>" {
  1088. t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
  1089. }
  1090. }
  1091. func TestSameFile(t *testing.T) {
  1092. fa, err := Create("a")
  1093. if err != nil {
  1094. t.Fatalf("Create(a): %v", err)
  1095. }
  1096. defer Remove(fa.Name())
  1097. fa.Close()
  1098. fb, err := Create("b")
  1099. if err != nil {
  1100. t.Fatalf("Create(b): %v", err)
  1101. }
  1102. defer Remove(fb.Name())
  1103. fb.Close()
  1104. ia1, err := Stat("a")
  1105. if err != nil {
  1106. t.Fatalf("Stat(a): %v", err)
  1107. }
  1108. ia2, err := Stat("a")
  1109. if err != nil {
  1110. t.Fatalf("Stat(a): %v", err)
  1111. }
  1112. if !SameFile(ia1, ia2) {
  1113. t.Errorf("files should be same")
  1114. }
  1115. ib, err := Stat("b")
  1116. if err != nil {
  1117. t.Fatalf("Stat(b): %v", err)
  1118. }
  1119. if SameFile(ia1, ib) {
  1120. t.Errorf("files should be different")
  1121. }
  1122. }
  1123. func TestDevNullFile(t *testing.T) {
  1124. f, err := Open(DevNull)
  1125. if err != nil {
  1126. t.Fatalf("Open(%s): %v", DevNull, err)
  1127. }
  1128. defer f.Close()
  1129. fi, err := f.Stat()
  1130. if err != nil {
  1131. t.Fatalf("Stat(%s): %v", DevNull, err)
  1132. }
  1133. name := filepath.Base(DevNull)
  1134. if fi.Name() != name {
  1135. t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
  1136. }
  1137. if fi.Size() != 0 {
  1138. t.Fatalf("wrong file size have %d want 0", fi.Size())
  1139. }
  1140. }
  1141. var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
  1142. func TestLargeWriteToConsole(t *testing.T) {
  1143. if !*testLargeWrite {
  1144. t.Skip("skipping console-flooding test; enable with -large_write")
  1145. }
  1146. b := make([]byte, 32000)
  1147. for i := range b {
  1148. b[i] = '.'
  1149. }
  1150. b[len(b)-1] = '\n'
  1151. n, err := Stdout.Write(b)
  1152. if err != nil {
  1153. t.Fatalf("Write to os.Stdout failed: %v", err)
  1154. }
  1155. if n != len(b) {
  1156. t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
  1157. }
  1158. n, err = Stderr.Write(b)
  1159. if err != nil {
  1160. t.Fatalf("Write to os.Stderr failed: %v", err)
  1161. }
  1162. if n != len(b) {
  1163. t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
  1164. }
  1165. }
  1166. func TestStatDirModeExec(t *testing.T) {
  1167. const mode = 0111
  1168. path, err := ioutil.TempDir("", "go-build")
  1169. if err != nil {
  1170. t.Fatalf("Failed to create temp directory: %v", err)
  1171. }
  1172. defer RemoveAll(path)
  1173. if err := Chmod(path, 0777); err != nil {
  1174. t.Fatalf("Chmod %q 0777: %v", path, err)
  1175. }
  1176. dir, err := Stat(path)
  1177. if err != nil {
  1178. t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
  1179. }
  1180. if dir.Mode()&mode != mode {
  1181. t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode()&mode, mode)
  1182. }
  1183. }
  1184. func TestReadAtEOF(t *testing.T) {
  1185. f := newFile("TestReadAtEOF", t)
  1186. defer Remove(f.Name())
  1187. defer f.Close()
  1188. _, err := f.ReadAt(make([]byte, 10), 0)
  1189. switch err {
  1190. case io.EOF:
  1191. // all good
  1192. case nil:
  1193. t.Fatalf("ReadAt succeeded")
  1194. default:
  1195. t.Fatalf("ReadAt failed: %s", err)
  1196. }
  1197. }
  1198. func testKillProcess(t *testing.T, processKiller func(p *Process)) {
  1199. t.Skip("gccgo does not have a go command")
  1200. switch runtime.GOOS {
  1201. case "android", "nacl":
  1202. t.Skipf("skipping on %s", runtime.GOOS)
  1203. }
  1204. dir, err := ioutil.TempDir("", "go-build")
  1205. if err != nil {
  1206. t.Fatalf("Failed to create temp directory: %v", err)
  1207. }
  1208. defer RemoveAll(dir)
  1209. src := filepath.Join(dir, "main.go")
  1210. f, err := Create(src)
  1211. if err != nil {
  1212. t.Fatalf("Failed to create %v: %v", src, err)
  1213. }
  1214. st := template.Must(template.New("source").Parse(`
  1215. package main
  1216. import "time"
  1217. func main() {
  1218. time.Sleep(time.Second)
  1219. }
  1220. `))
  1221. err = st.Execute(f, nil)
  1222. if err != nil {
  1223. f.Close()
  1224. t.Fatalf("Failed to execute template: %v", err)
  1225. }
  1226. f.Close()
  1227. exe := filepath.Join(dir, "main.exe")
  1228. output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
  1229. if err != nil {
  1230. t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
  1231. }
  1232. cmd := osexec.Command(exe)
  1233. err = cmd.Start()
  1234. if err != nil {
  1235. t.Fatalf("Failed to start test process: %v", err)
  1236. }
  1237. go func() {
  1238. time.Sleep(100 * time.Millisecond)
  1239. processKiller(cmd.Process)
  1240. }()
  1241. err = cmd.Wait()
  1242. if err == nil {
  1243. t.Errorf("Test process succeeded, but expected to fail")
  1244. }
  1245. }
  1246. func TestKillStartProcess(t *testing.T) {
  1247. testKillProcess(t, func(p *Process) {
  1248. err := p.Kill()
  1249. if err != nil {
  1250. t.Fatalf("Failed to kill test process: %v", err)
  1251. }
  1252. })
  1253. }
  1254. func TestGetppid(t *testing.T) {
  1255. switch runtime.GOOS {
  1256. case "nacl":
  1257. t.Skip("skipping on nacl")
  1258. case "plan9":
  1259. // TODO: golang.org/issue/8206
  1260. t.Skipf("skipping test on plan9; see issue 8206")
  1261. }
  1262. if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
  1263. fmt.Print(Getppid())
  1264. Exit(0)
  1265. }
  1266. cmd := osexec.Command(Args[0], "-test.run=TestGetppid")
  1267. cmd.Env = append(Environ(), "GO_WANT_HELPER_PROCESS=1")
  1268. // verify that Getppid() from the forked process reports our process id
  1269. output, err := cmd.CombinedOutput()
  1270. if err != nil {
  1271. t.Fatalf("Failed to spawn child process: %v %q", err, string(output))
  1272. }
  1273. childPpid := string(output)
  1274. ourPid := fmt.Sprintf("%d", Getpid())
  1275. if childPpid != ourPid {
  1276. t.Fatalf("Child process reports parent process id '%v', expected '%v'", childPpid, ourPid)
  1277. }
  1278. }
  1279. func TestKillFindProcess(t *testing.T) {
  1280. testKillProcess(t, func(p *Process) {
  1281. p2, err := FindProcess(p.Pid)
  1282. if err != nil {
  1283. t.Fatalf("Failed to find test process: %v", err)
  1284. }
  1285. err = p2.Kill()
  1286. if err != nil {
  1287. t.Fatalf("Failed to kill test process: %v", err)
  1288. }
  1289. })
  1290. }
  1291. var nilFileMethodTests = []struct {
  1292. name string
  1293. f func(*File) error
  1294. }{
  1295. {"Chdir", func(f *File) error { return f.Chdir() }},
  1296. {"Close", func(f *File) error { return f.Close() }},
  1297. {"Chmod", func(f *File) error { return f.Chmod(0) }},
  1298. {"Chown", func(f *File) error { return f.Chown(0, 0) }},
  1299. {"Read", func(f *File) error { _, err := f.Read(make([]byte, 0)); return err }},
  1300. {"ReadAt", func(f *File) error { _, err := f.ReadAt(make([]byte, 0), 0); return err }},
  1301. {"Readdir", func(f *File) error { _, err := f.Readdir(1); return err }},
  1302. {"Readdirnames", func(f *File) error { _, err := f.Readdirnames(1); return err }},
  1303. {"Seek", func(f *File) error { _, err := f.Seek(0, 0); return err }},
  1304. {"Stat", func(f *File) error { _, err := f.Stat(); return err }},
  1305. {"Sync", func(f *File) error { return f.Sync() }},
  1306. {"Truncate", func(f *File) error { return f.Truncate(0) }},
  1307. {"Write", func(f *File) error { _, err := f.Write(make([]byte, 0)); return err }},
  1308. {"WriteAt", func(f *File) error { _, err := f.WriteAt(make([]byte, 0), 0); return err }},
  1309. {"WriteString", func(f *File) error { _, err := f.WriteString(""); return err }},
  1310. }
  1311. // Test that all File methods give ErrInvalid if the receiver is nil.
  1312. func TestNilFileMethods(t *testing.T) {
  1313. for _, tt := range nilFileMethodTests {
  1314. var file *File
  1315. got := tt.f(file)
  1316. if got != ErrInvalid {
  1317. t.Errorf("%v should fail when f is nil; got %v", tt.name, got)
  1318. }
  1319. }
  1320. }
  1321. func mkdirTree(t *testing.T, root string, level, max int) {
  1322. if level >= max {
  1323. return
  1324. }
  1325. level++
  1326. for i := 'a'; i < 'c'; i++ {
  1327. dir := filepath.Join(root, string(i))
  1328. if err := Mkdir(dir, 0700); err != nil {
  1329. t.Fatal(err)
  1330. }
  1331. mkdirTree(t, dir, level, max)
  1332. }
  1333. }
  1334. // Test that simultaneous RemoveAll do not report an error.
  1335. // As long as it gets removed, we should be happy.
  1336. func TestRemoveAllRace(t *testing.T) {
  1337. if runtime.GOOS == "windows" {
  1338. // Windows has very strict rules about things like
  1339. // removing directories while someone else has
  1340. // them open. The racing doesn't work out nicely
  1341. // like it does on Unix.
  1342. t.Skip("skipping on windows")
  1343. }
  1344. n := runtime.GOMAXPROCS(16)
  1345. defer runtime.GOMAXPROCS(n)
  1346. root, err := ioutil.TempDir("", "issue")
  1347. if err != nil {
  1348. t.Fatal(err)
  1349. }
  1350. mkdirTree(t, root, 1, 6)
  1351. hold := make(chan struct{})
  1352. var wg sync.WaitGroup
  1353. for i := 0; i < 4; i++ {
  1354. wg.Add(1)
  1355. go func() {
  1356. defer wg.Done()
  1357. <-hold
  1358. err := RemoveAll(root)
  1359. if err != nil {
  1360. t.Errorf("unexpected error: %T, %q", err, err)
  1361. }
  1362. }()
  1363. }
  1364. close(hold) // let workers race to remove root
  1365. wg.Wait()
  1366. }