Skip to content

Commit 7b7b028

Browse files
committed
Improve coverage for fs operations
* TestCopyDir: add subdirectory to the test case; extend test to handle multiple files in different directories. * Add tests for error conditions in CopyDir: source directory cannot be read; destination directory cannot be read; files cannot be read. * Add tests for error conditions in IsRegular. * Add tests for error conditions in IsDir. This addresses issue golang#41. Signed-off-by: Marcelo E. Magallon <[email protected]>
1 parent 82f1514 commit 7b7b028

File tree

1 file changed

+259
-41
lines changed

1 file changed

+259
-41
lines changed

fs_test.go

Lines changed: 259 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package dep
77
import (
88
"io/ioutil"
99
"os"
10+
"path"
1011
"path/filepath"
1112
"testing"
1213

@@ -25,52 +26,164 @@ func TestCopyDir(t *testing.T) {
2526
t.Fatal(err)
2627
}
2728

28-
srcf, err := os.Create(filepath.Join(srcdir, "myfile"))
29-
if err != nil {
30-
t.Fatal(err)
29+
files := []struct {
30+
path string
31+
contents string
32+
fi os.FileInfo
33+
}{
34+
{path: "myfile", contents: "hello world"},
35+
{path: filepath.Join("subdir", "file"), contents: "subdir file"},
3136
}
3237

33-
want := "hello world"
34-
if _, err = srcf.Write([]byte(want)); err != nil {
35-
t.Fatal(err)
38+
// Create structure indicated in 'files'
39+
for i, file := range files {
40+
fn := filepath.Join(srcdir, file.path)
41+
dn := path.Dir(fn)
42+
if err = os.MkdirAll(dn, 0755); err != nil {
43+
t.Fatal(err)
44+
}
45+
46+
fh, err := os.Create(fn)
47+
if err != nil {
48+
t.Fatal(err)
49+
}
50+
51+
if _, err = fh.Write([]byte(file.contents)); err != nil {
52+
t.Fatal(err)
53+
}
54+
fh.Close()
55+
56+
files[i].fi, err = os.Stat(fn)
57+
if err != nil {
58+
t.Fatal(err)
59+
}
3660
}
37-
srcf.Close()
3861

3962
destdir := filepath.Join(dir, "dest")
4063
if err = CopyDir(srcdir, destdir); err != nil {
4164
t.Fatal(err)
4265
}
4366

44-
dirOK, err := IsDir(destdir)
67+
// Compare copy against structure indicated in 'files'
68+
for _, file := range files {
69+
fn := filepath.Join(srcdir, file.path)
70+
71+
dn := path.Dir(fn)
72+
dirOK, err := IsDir(dn)
73+
if err != nil {
74+
t.Fatal(err)
75+
}
76+
if !dirOK {
77+
t.Fatalf("expected %s to be a directory", dn)
78+
}
79+
80+
got, err := ioutil.ReadFile(fn)
81+
if err != nil {
82+
t.Fatal(err)
83+
}
84+
85+
if file.contents != string(got) {
86+
t.Fatalf("expected: %s, got: %s", file.contents, string(got))
87+
}
88+
89+
gotinfo, err := os.Stat(fn)
90+
if err != nil {
91+
t.Fatal(err)
92+
}
93+
94+
if file.fi.Mode() != gotinfo.Mode() {
95+
t.Fatalf("expected %s: %#v\n to be the same mode as %s: %#v",
96+
file.path, file.fi.Mode(), fn, gotinfo.Mode())
97+
}
98+
}
99+
}
100+
101+
func TestCopyDirFailSrc(t *testing.T) {
102+
var srcdir, dstdir string
103+
104+
err, cleanup := setupInaccesibleDir(func(dir string) (err error) {
105+
srcdir = filepath.Join(dir, "src")
106+
return os.MkdirAll(srcdir, 0755)
107+
})
108+
109+
defer cleanup()
110+
45111
if err != nil {
46112
t.Fatal(err)
47113
}
48-
if !dirOK {
49-
t.Fatalf("expected %s to be a directory", destdir)
114+
115+
dir, err := ioutil.TempDir("", "dep")
116+
if err != nil {
117+
t.Fatal(err)
50118
}
119+
defer os.RemoveAll(dir)
51120

52-
destf := filepath.Join(destdir, "myfile")
53-
got, err := ioutil.ReadFile(destf)
121+
dstdir = filepath.Join(dir, "dst")
122+
if err = CopyDir(srcdir, dstdir); err == nil {
123+
t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir)
124+
}
125+
}
126+
127+
func TestCopyDirFailDst(t *testing.T) {
128+
var srcdir, dstdir string
129+
130+
dir, err := ioutil.TempDir("", "dep")
54131
if err != nil {
55132
t.Fatal(err)
56133
}
134+
defer os.RemoveAll(dir)
57135

58-
if want != string(got) {
59-
t.Fatalf("expected: %s, got: %s", want, string(got))
136+
srcdir = filepath.Join(dir, "src")
137+
if err = os.MkdirAll(srcdir, 0755); err != nil {
138+
t.Fatal(err)
60139
}
61140

62-
wantinfo, err := os.Stat(srcf.Name())
141+
err, cleanup := setupInaccesibleDir(func(dir string) error {
142+
dstdir = filepath.Join(dir, "dst")
143+
return nil
144+
})
145+
146+
defer cleanup()
147+
63148
if err != nil {
64149
t.Fatal(err)
65150
}
66151

67-
gotinfo, err := os.Stat(destf)
152+
if err = CopyDir(srcdir, dstdir); err == nil {
153+
t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir)
154+
}
155+
}
156+
157+
func TestCopyDirFailOpen(t *testing.T) {
158+
var srcdir, dstdir string
159+
160+
dir, err := ioutil.TempDir("", "dep")
68161
if err != nil {
69162
t.Fatal(err)
70163
}
164+
defer os.RemoveAll(dir)
71165

72-
if wantinfo.Mode() != gotinfo.Mode() {
73-
t.Fatalf("expected %s: %#v\n to be the same mode as %s: %#v", srcf.Name(), wantinfo.Mode(), destf, gotinfo.Mode())
166+
srcdir = filepath.Join(dir, "src")
167+
if err = os.MkdirAll(srcdir, 0755); err != nil {
168+
t.Fatal(err)
169+
}
170+
171+
srcfn := filepath.Join(srcdir, "file")
172+
srcf, err := os.Create(srcfn)
173+
if err != nil {
174+
t.Fatal(err)
175+
}
176+
srcf.Close()
177+
178+
// setup source file so that it cannot be read
179+
if err = os.Chmod(srcfn, 0222); err != nil {
180+
t.Fatal(err)
181+
}
182+
183+
dstdir = filepath.Join(dir, "dst")
184+
185+
if err = CopyDir(srcdir, dstdir); err == nil {
186+
t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir)
74187
}
75188
}
76189

@@ -121,31 +234,119 @@ func TestCopyFile(t *testing.T) {
121234
}
122235
}
123236

237+
func TestCopyFileFail(t *testing.T) {
238+
dir, err := ioutil.TempDir("", "dep")
239+
if err != nil {
240+
t.Fatal(err)
241+
}
242+
defer os.RemoveAll(dir)
243+
244+
srcf, err := os.Create(filepath.Join(dir, "srcfile"))
245+
if err != nil {
246+
t.Fatal(err)
247+
}
248+
srcf.Close()
249+
250+
var dstdir string
251+
252+
err, cleanup := setupInaccesibleDir(func(dir string) error {
253+
dstdir = filepath.Join(dir, "dir")
254+
return os.Mkdir(dstdir, 0777)
255+
})
256+
257+
defer cleanup()
258+
259+
if err != nil {
260+
t.Fatal(err)
261+
}
262+
263+
fn := filepath.Join(dstdir, "file")
264+
if err := CopyFile(srcf.Name(), fn); err == nil {
265+
t.Fatalf("expected error for %s, got none", fn)
266+
}
267+
}
268+
269+
func setupInaccesibleDir(op func(dir string) error) (err error, cleanup func()) {
270+
cleanup = func() {}
271+
272+
dir, err := ioutil.TempDir("", "dep")
273+
if err != nil {
274+
return err, cleanup
275+
}
276+
277+
subdir := filepath.Join(dir, "dir")
278+
279+
cleanup = func() {
280+
os.Chmod(subdir, 0777)
281+
os.RemoveAll(dir)
282+
}
283+
284+
if err = os.Mkdir(subdir, 0777); err != nil {
285+
return err, cleanup
286+
}
287+
288+
if err = op(subdir); err != nil {
289+
return err, cleanup
290+
}
291+
292+
if err = os.Chmod(subdir, 0666); err != nil {
293+
return err, cleanup
294+
}
295+
296+
return err, cleanup
297+
}
298+
124299
func TestIsRegular(t *testing.T) {
125300
wd, err := os.Getwd()
126301
if err != nil {
127302
t.Fatal(err)
128303
}
129304

130-
tests := map[string]bool{
131-
wd: false,
132-
filepath.Join(wd, "testdata"): false,
133-
filepath.Join(wd, "cmd", "dep", "main.go"): true,
134-
filepath.Join(wd, "this_file_does_not_exist.thing"): false,
305+
var fn string
306+
307+
err, cleanup := setupInaccesibleDir(func(dir string) error {
308+
fn = filepath.Join(dir, "file")
309+
fh, err := os.Create(fn)
310+
if err != nil {
311+
return err
312+
}
313+
314+
return fh.Close()
315+
})
316+
317+
defer cleanup()
318+
319+
if err != nil {
320+
t.Fatal(err)
321+
}
322+
323+
tests := map[string]struct {
324+
exists bool
325+
err bool
326+
}{
327+
wd: {false, true},
328+
filepath.Join(wd, "testdata"): {false, true},
329+
filepath.Join(wd, "cmd", "dep", "main.go"): {true, false},
330+
filepath.Join(wd, "this_file_does_not_exist.thing"): {false, false},
331+
fn: {false, true},
135332
}
136333

137334
for f, want := range tests {
138335
got, err := IsRegular(f)
139336
if err != nil {
140-
if !want {
141-
// this is the case where we expect an error so continue
142-
// to the check below
143-
continue
337+
if want.exists != got {
338+
t.Fatalf("expected %t for %s, got %t", want.exists, f, got)
339+
}
340+
if !want.err {
341+
t.Fatalf("expected no error, got %v", err)
342+
}
343+
} else {
344+
if want.err {
345+
t.Fatalf("expected error for %s, got none", f)
144346
}
145-
t.Fatalf("expected no error, got %v", err)
146347
}
147348

148-
if got != want {
349+
if got != want.exists {
149350
t.Fatalf("expected %t for %s, got %t", want, f, got)
150351
}
151352
}
@@ -158,26 +359,43 @@ func TestIsDir(t *testing.T) {
158359
t.Fatal(err)
159360
}
160361

161-
tests := map[string]bool{
162-
wd: true,
163-
filepath.Join(wd, "testdata"): true,
164-
filepath.Join(wd, "main.go"): false,
165-
filepath.Join(wd, "this_file_does_not_exist.thing"): false,
362+
var dn string
363+
364+
err, cleanup := setupInaccesibleDir(func(dir string) error {
365+
dn = filepath.Join(dir, "dir")
366+
return os.Mkdir(dn, 0777)
367+
})
368+
369+
defer cleanup()
370+
371+
if err != nil {
372+
t.Fatal(err)
373+
}
374+
375+
tests := map[string]struct {
376+
exists bool
377+
err bool
378+
}{
379+
wd: {true, false},
380+
filepath.Join(wd, "testdata"): {true, false},
381+
filepath.Join(wd, "main.go"): {false, false},
382+
filepath.Join(wd, "this_file_does_not_exist.thing"): {false, true},
383+
filepath.Join(dn): {false, true},
166384
}
167385

168386
for f, want := range tests {
169387
got, err := IsDir(f)
170388
if err != nil {
171-
if !want {
172-
// this is the case where we expect an error so continue
173-
// to the check below
174-
continue
389+
if want.exists != got {
390+
t.Fatalf("expected %t for %s, got %t", want.exists, f, got)
391+
}
392+
if !want.err {
393+
t.Fatalf("expected no error, got %v", err)
175394
}
176-
t.Fatalf("expected no error, got %v", err)
177395
}
178396

179-
if got != want {
180-
t.Fatalf("expected %t for %s, got %t", want, f, got)
397+
if got != want.exists {
398+
t.Fatalf("expected %t for %s, got %t", want.exists, f, got)
181399
}
182400
}
183401

0 commit comments

Comments
 (0)