try some more tsting

This commit is contained in:
Dominic Breuker
2018-02-26 07:41:28 +01:00
parent d1c18d901a
commit 2750defb63
17 changed files with 262 additions and 28 deletions

View File

View File

View File

View File

@@ -0,0 +1,53 @@
package walker
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
const maxInt = int(^uint(0) >> 1)
func Walk(root string, depth int) (dirCh chan string, errCh chan error, doneCh chan struct{}) {
if depth < 0 {
depth = maxInt
}
dirCh = make(chan string)
errCh = make(chan error)
doneCh = make(chan struct{})
go func() {
defer close(dirCh)
descent(root, depth-1, dirCh, errCh, doneCh)
}()
return dirCh, errCh, doneCh
}
func descent(dir string, depth int, dirCh chan string, errCh chan error, doneCh chan struct{}) {
_, err := os.Stat(dir)
if err != nil {
errCh <- fmt.Errorf("visiting %s: %v", dir, err)
return
}
select {
case dirCh <- dir:
case <-doneCh:
return
}
if depth < 0 {
return
}
ls, err := ioutil.ReadDir(dir)
if err != nil {
errCh <- fmt.Errorf("opening dir %s: %v", dir, err)
}
for _, e := range ls {
if e.IsDir() {
newDir := filepath.Join(dir, e.Name())
descent(newDir, depth-1, dirCh, errCh, doneCh)
}
}
}

View File

@@ -0,0 +1,84 @@
package walker
import (
"reflect"
"strings"
"testing"
)
func TestWalk(t *testing.T) {
tests := []struct {
root string
depth int
errCh chan error
result []string
errs []string
}{
{root: "testdata", depth: 999, errCh: newErrCh(), result: []string{
"testdata",
"testdata/subdir",
"testdata/subdir/subsubdir",
}, errs: make([]string, 0)},
{root: "testdata", depth: -1, errCh: newErrCh(), result: []string{
"testdata",
"testdata/subdir",
"testdata/subdir/subsubdir",
}, errs: []string{}},
{root: "testdata", depth: 1, errCh: newErrCh(), result: []string{
"testdata",
"testdata/subdir",
}, errs: []string{}},
{root: "testdata", depth: 0, errCh: newErrCh(), result: []string{
"testdata",
}, errs: []string{}},
{root: "testdata/subdir", depth: 1, errCh: newErrCh(), result: []string{
"testdata/subdir",
"testdata/subdir/subsubdir",
}, errs: []string{}},
{root: "testdata/non-existing-dir", depth: 1, errCh: newErrCh(), result: []string{}, errs: []string{"visiting testdata/non-existing-dir"}},
}
for i, tt := range tests {
dirCh, errCh, doneCh := Walk(tt.root, tt.depth)
dirs, errs := getAllDirsAndErrors(dirCh, errCh)
if !reflect.DeepEqual(dirs, tt.result) {
t.Fatalf("[%d] Wrong number of dirs found: %+v", i, dirs)
}
if !reflect.DeepEqual(errs, tt.errs) {
t.Fatalf("[%d] Wrong number of errs found: %+v vs %+v", i, errs, tt.errs)
}
close(doneCh)
}
}
func getAllDirsAndErrors(dirCh chan string, errCh chan error) ([]string, []string) {
dirs := make([]string, 0)
errs := make([]string, 0)
doneDirsCh := make(chan struct{})
go func() {
defer close(doneDirsCh)
defer close(errCh)
for d := range dirCh {
dirs = append(dirs, d)
}
}()
doneErrsCh := make(chan struct{})
go func() {
defer close(doneErrsCh)
for err := range errCh {
tokens := strings.SplitN(err.Error(), ":", 2)
errs = append(errs, tokens[0])
}
}()
<-doneDirsCh
<-doneErrsCh
return dirs, errs
}
func newErrCh() chan error {
return make(chan error)
}