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
5package ioutil_test
6
7import (
8	"bytes"
9	. "io/ioutil"
10	"os"
11	"path/filepath"
12	"runtime"
13	"testing"
14)
15
16func checkSize(t *testing.T, path string, size int64) {
17	dir, err := os.Stat(path)
18	if err != nil {
19		t.Fatalf("Stat %q (looking for size %d): %s", path, size, err)
20	}
21	if dir.Size() != size {
22		t.Errorf("Stat %q: size %d want %d", path, dir.Size(), size)
23	}
24}
25
26func TestReadFile(t *testing.T) {
27	filename := "rumpelstilzchen"
28	contents, err := ReadFile(filename)
29	if err == nil {
30		t.Fatalf("ReadFile %s: error expected, none found", filename)
31	}
32
33	filename = "ioutil_test.go"
34	contents, err = ReadFile(filename)
35	if err != nil {
36		t.Fatalf("ReadFile %s: %v", filename, err)
37	}
38
39	checkSize(t, filename, int64(len(contents)))
40}
41
42func TestWriteFile(t *testing.T) {
43	f, err := TempFile("", "ioutil-test")
44	if err != nil {
45		t.Fatal(err)
46	}
47	filename := f.Name()
48	data := "Programming today is a race between software engineers striving to " +
49		"build bigger and better idiot-proof programs, and the Universe trying " +
50		"to produce bigger and better idiots. So far, the Universe is winning."
51
52	if err := WriteFile(filename, []byte(data), 0644); err != nil {
53		t.Fatalf("WriteFile %s: %v", filename, err)
54	}
55
56	contents, err := ReadFile(filename)
57	if err != nil {
58		t.Fatalf("ReadFile %s: %v", filename, err)
59	}
60
61	if string(contents) != data {
62		t.Fatalf("contents = %q\nexpected = %q", string(contents), data)
63	}
64
65	// cleanup
66	f.Close()
67	os.Remove(filename) // ignore error
68}
69
70func TestReadOnlyWriteFile(t *testing.T) {
71	if os.Getuid() == 0 {
72		t.Skipf("Root can write to read-only files anyway, so skip the read-only test.")
73	}
74	if runtime.GOOS == "wasip1" {
75		t.Skip("file permissions are not supported by wasip1")
76	}
77
78	// We don't want to use TempFile directly, since that opens a file for us as 0600.
79	tempDir, err := TempDir("", t.Name())
80	if err != nil {
81		t.Fatalf("TempDir %s: %v", t.Name(), err)
82	}
83	defer os.RemoveAll(tempDir)
84	filename := filepath.Join(tempDir, "blurp.txt")
85
86	shmorp := []byte("shmorp")
87	florp := []byte("florp")
88	err = WriteFile(filename, shmorp, 0444)
89	if err != nil {
90		t.Fatalf("WriteFile %s: %v", filename, err)
91	}
92	err = WriteFile(filename, florp, 0444)
93	if err == nil {
94		t.Fatalf("Expected an error when writing to read-only file %s", filename)
95	}
96	got, err := ReadFile(filename)
97	if err != nil {
98		t.Fatalf("ReadFile %s: %v", filename, err)
99	}
100	if !bytes.Equal(got, shmorp) {
101		t.Fatalf("want %s, got %s", shmorp, got)
102	}
103}
104
105func TestReadDir(t *testing.T) {
106	dirname := "rumpelstilzchen"
107	_, err := ReadDir(dirname)
108	if err == nil {
109		t.Fatalf("ReadDir %s: error expected, none found", dirname)
110	}
111
112	dirname = ".."
113	list, err := ReadDir(dirname)
114	if err != nil {
115		t.Fatalf("ReadDir %s: %v", dirname, err)
116	}
117
118	foundFile := false
119	foundSubDir := false
120	for _, dir := range list {
121		switch {
122		case !dir.IsDir() && dir.Name() == "io_test.go":
123			foundFile = true
124		case dir.IsDir() && dir.Name() == "ioutil":
125			foundSubDir = true
126		}
127	}
128	if !foundFile {
129		t.Fatalf("ReadDir %s: io_test.go file not found", dirname)
130	}
131	if !foundSubDir {
132		t.Fatalf("ReadDir %s: ioutil directory not found", dirname)
133	}
134}
135