184 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
| package driver
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| type changingFileSystem struct {
 | |
| 	StorageDriver
 | |
| 	fileset   []string
 | |
| 	keptFiles map[string]bool
 | |
| }
 | |
| 
 | |
| func (cfs *changingFileSystem) List(_ context.Context, _ string) ([]string, error) {
 | |
| 	return cfs.fileset, nil
 | |
| }
 | |
| 
 | |
| func (cfs *changingFileSystem) Stat(_ context.Context, path string) (FileInfo, error) {
 | |
| 	kept, ok := cfs.keptFiles[path]
 | |
| 	if ok && kept {
 | |
| 		return &FileInfoInternal{
 | |
| 			FileInfoFields: FileInfoFields{
 | |
| 				Path: path,
 | |
| 			},
 | |
| 		}, nil
 | |
| 	}
 | |
| 	return nil, PathNotFoundError{}
 | |
| }
 | |
| 
 | |
| type fileSystem struct {
 | |
| 	StorageDriver
 | |
| 	// maps folder to list results
 | |
| 	fileset map[string][]string
 | |
| }
 | |
| 
 | |
| func (cfs *fileSystem) List(_ context.Context, path string) ([]string, error) {
 | |
| 	return cfs.fileset[path], nil
 | |
| }
 | |
| 
 | |
| func (cfs *fileSystem) Stat(_ context.Context, path string) (FileInfo, error) {
 | |
| 	_, isDir := cfs.fileset[path]
 | |
| 	return &FileInfoInternal{
 | |
| 		FileInfoFields: FileInfoFields{
 | |
| 			Path:  path,
 | |
| 			IsDir: isDir,
 | |
| 			Size:  int64(len(path)),
 | |
| 		},
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| func (cfs *fileSystem) isDir(path string) bool {
 | |
| 	_, isDir := cfs.fileset[path]
 | |
| 	return isDir
 | |
| }
 | |
| 
 | |
| func TestWalkFileRemoved(t *testing.T) {
 | |
| 	d := &changingFileSystem{
 | |
| 		fileset: []string{"zoidberg", "bender"},
 | |
| 		keptFiles: map[string]bool{
 | |
| 			"zoidberg": true,
 | |
| 		},
 | |
| 	}
 | |
| 	infos := []FileInfo{}
 | |
| 	err := WalkFallback(context.Background(), d, "", func(fileInfo FileInfo) error {
 | |
| 		infos = append(infos, fileInfo)
 | |
| 		return nil
 | |
| 	})
 | |
| 	if len(infos) != 1 || infos[0].Path() != "zoidberg" {
 | |
| 		t.Errorf(fmt.Sprintf("unexpected path set during walk: %s", infos))
 | |
| 	}
 | |
| 	if err != nil {
 | |
| 		t.Fatalf(err.Error())
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestWalkFallback(t *testing.T) {
 | |
| 	d := &fileSystem{
 | |
| 		fileset: map[string][]string{
 | |
| 			"/":        {"/file1", "/folder1", "/folder2"},
 | |
| 			"/folder1": {"/folder1/file1"},
 | |
| 			"/folder2": {"/folder2/file1"},
 | |
| 		},
 | |
| 	}
 | |
| 	noopFn := func(fileInfo FileInfo) error { return nil }
 | |
| 
 | |
| 	tcs := []struct {
 | |
| 		name     string
 | |
| 		fn       WalkFn
 | |
| 		from     string
 | |
| 		expected []string
 | |
| 		err      bool
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "walk all",
 | |
| 			fn:   noopFn,
 | |
| 			expected: []string{
 | |
| 				"/file1",
 | |
| 				"/folder1",
 | |
| 				"/folder1/file1",
 | |
| 				"/folder2",
 | |
| 				"/folder2/file1",
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "skip directory",
 | |
| 			fn: func(fileInfo FileInfo) error {
 | |
| 				if fileInfo.Path() == "/folder1" {
 | |
| 					return ErrSkipDir
 | |
| 				}
 | |
| 				if strings.Contains(fileInfo.Path(), "/folder1") {
 | |
| 					t.Fatalf("skipped dir %s and should not walk %s", "/folder1", fileInfo.Path())
 | |
| 				}
 | |
| 				return nil
 | |
| 			},
 | |
| 			expected: []string{
 | |
| 				"/file1",
 | |
| 				"/folder1", // return ErrSkipDir, skip anything under /folder1
 | |
| 				// skip /folder1/file1
 | |
| 				"/folder2",
 | |
| 				"/folder2/file1",
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "stop early",
 | |
| 			fn: func(fileInfo FileInfo) error {
 | |
| 				if fileInfo.Path() == "/folder1/file1" {
 | |
| 					return ErrSkipDir
 | |
| 				}
 | |
| 				return nil
 | |
| 			},
 | |
| 			expected: []string{
 | |
| 				"/file1",
 | |
| 				"/folder1",
 | |
| 				"/folder1/file1",
 | |
| 				// stop early
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "from folder",
 | |
| 			fn:   noopFn,
 | |
| 			expected: []string{
 | |
| 				"/folder1/file1",
 | |
| 			},
 | |
| 			from: "/folder1",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range tcs {
 | |
| 		var walked []string
 | |
| 		if tc.from == "" {
 | |
| 			tc.from = "/"
 | |
| 		}
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			err := WalkFallback(context.Background(), d, tc.from, func(fileInfo FileInfo) error {
 | |
| 				walked = append(walked, fileInfo.Path())
 | |
| 				if fileInfo.IsDir() != d.isDir(fileInfo.Path()) {
 | |
| 					t.Fatalf("fileInfo isDir not matching file system: expected %t actual %t", d.isDir(fileInfo.Path()), fileInfo.IsDir())
 | |
| 				}
 | |
| 				return tc.fn(fileInfo)
 | |
| 			})
 | |
| 			if tc.err && err == nil {
 | |
| 				t.Fatalf("expected err")
 | |
| 			}
 | |
| 			if !tc.err && err != nil {
 | |
| 				t.Fatalf(err.Error())
 | |
| 			}
 | |
| 			compareWalked(t, tc.expected, walked)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func compareWalked(t *testing.T, expected, walked []string) {
 | |
| 	if len(walked) != len(expected) {
 | |
| 		t.Fatalf("Mismatch number of fileInfo walked %d expected %d; walked %s; expected %s;", len(walked), len(expected), walked, expected)
 | |
| 	}
 | |
| 	for i := range walked {
 | |
| 		if walked[i] != expected[i] {
 | |
| 			t.Fatalf("expected walked to come in order expected: walked %s", walked)
 | |
| 		}
 | |
| 	}
 | |
| }
 |