github.com/3JoB/vfs@v1.0.0/filesystem_test.go (about)

     1  package vfs
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"testing"
     7  )
     8  
     9  type openFS struct {
    10  	Filesystem
    11  	fn func(name string, flag int, perm os.FileMode) (File, error)
    12  }
    13  
    14  func (fs openFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
    15  	return fs.fn(name, flag, perm)
    16  }
    17  
    18  func TestCreate(t *testing.T) {
    19  	fs := openFS{
    20  		Filesystem: Dummy(errors.New("Not implemented")),
    21  		fn: func(name string, flag int, perm os.FileMode) (File, error) {
    22  			if name != "name" {
    23  				t.Errorf("Invalid name: %s", name)
    24  			}
    25  			if flag != os.O_RDWR|os.O_CREATE|os.O_TRUNC {
    26  				t.Errorf("Invalid flag: %d", flag)
    27  			}
    28  			if perm != 0666 {
    29  				t.Errorf("Invalid perm: %d", perm)
    30  			}
    31  			return nil, nil
    32  		},
    33  	}
    34  	_, err := Create(fs, "name")
    35  	if err != nil {
    36  		t.Fatalf("OpenFile not called")
    37  	}
    38  }
    39  
    40  func TestOpen(t *testing.T) {
    41  	fs := openFS{
    42  		Filesystem: Dummy(errors.New("Not implemented")),
    43  		fn: func(name string, flag int, perm os.FileMode) (File, error) {
    44  			if name != "name" {
    45  				t.Errorf("Invalid name: %s", name)
    46  			}
    47  			if flag != os.O_RDONLY {
    48  				t.Errorf("Invalid flag: %d", flag)
    49  			}
    50  			if perm != 0 {
    51  				t.Errorf("Invalid perm: %d", perm)
    52  			}
    53  			return nil, nil
    54  		},
    55  	}
    56  	_, err := Open(fs, "name")
    57  	if err != nil {
    58  		t.Fatalf("OpenFile not called")
    59  	}
    60  }
    61  
    62  type mkdirFS struct {
    63  	Filesystem
    64  	dirs map[string]os.FileInfo
    65  	perm os.FileMode
    66  }
    67  
    68  func (fs *mkdirFS) Mkdir(name string, perm os.FileMode) error {
    69  	if _, ok := fs.dirs[name]; ok {
    70  		return os.ErrExist
    71  	}
    72  	fs.perm = perm
    73  	fs.dirs[name] = DumFileInfo{
    74  		IName: name,
    75  		IDir:  true,
    76  		IMode: perm,
    77  	}
    78  	return nil
    79  }
    80  
    81  func (fs mkdirFS) Stat(name string) (os.FileInfo, error) {
    82  	return fs.Lstat(name)
    83  }
    84  
    85  func (fs mkdirFS) Lstat(name string) (os.FileInfo, error) {
    86  	if fi, ok := fs.dirs[name]; ok {
    87  		return fi, nil
    88  	}
    89  	return nil, os.ErrNotExist
    90  }
    91  
    92  func TestMkdirAll(t *testing.T) {
    93  	fs := &mkdirFS{
    94  		Filesystem: Dummy(errors.New("Not implemented")),
    95  		dirs:       make(map[string]os.FileInfo),
    96  	}
    97  	err := MkdirAll(fs, "/usr/src/linux", 0777)
    98  	if err != nil {
    99  		t.Fatalf("Mkdir failed")
   100  	}
   101  	if fs.perm != 0777 {
   102  		t.Errorf("Wrong perm: %d", fs.perm)
   103  	}
   104  	if _, ok := fs.dirs["/usr"]; !ok {
   105  		t.Errorf("Dir not created: /usr")
   106  	}
   107  	if _, ok := fs.dirs["/usr/src"]; !ok {
   108  		t.Errorf("Dir not created: /usr/src")
   109  	}
   110  	if _, ok := fs.dirs["/usr/src/linux"]; !ok {
   111  		t.Errorf("Dir not created: /usr/src/linux")
   112  	}
   113  }
   114  
   115  func TestMkdirAllExists(t *testing.T) {
   116  	fs := &mkdirFS{
   117  		Filesystem: Dummy(errors.New("Not implemented")),
   118  		dirs:       make(map[string]os.FileInfo),
   119  	}
   120  	// Make dir
   121  	fs.dirs["/usr/src/linux"] = DumFileInfo{IName: "linux", IDir: true}
   122  
   123  	err := MkdirAll(fs, "/usr/src/linux", 0777)
   124  	if err != nil {
   125  		t.Fatalf("Mkdir failed")
   126  	}
   127  }
   128  
   129  func TestMkdirAllFirstExists(t *testing.T) {
   130  	fs := &mkdirFS{
   131  		Filesystem: Dummy(errors.New("Not implemented")),
   132  		dirs:       make(map[string]os.FileInfo),
   133  	}
   134  	// Make dir
   135  	fs.dirs["/usr"] = DumFileInfo{IName: "usr", IDir: true}
   136  
   137  	err := MkdirAll(fs, "/usr/src/linux/", 0777)
   138  	if err != nil {
   139  		t.Fatalf("Mkdir failed")
   140  	}
   141  
   142  	if _, ok := fs.dirs["/usr/src"]; !ok {
   143  		t.Errorf("Dir not created: /usr/src")
   144  	}
   145  	if _, ok := fs.dirs["/usr/src/linux/"]; !ok {
   146  		t.Errorf("Dir not created: /usr/src/linux")
   147  	}
   148  }
   149  
   150  func TestMkdirAllFirstExistsNoFile(t *testing.T) {
   151  	fs := &mkdirFS{
   152  		Filesystem: Dummy(errors.New("Not implemented")),
   153  		dirs:       make(map[string]os.FileInfo),
   154  	}
   155  	// Make dir
   156  	fs.dirs["/usr"] = DumFileInfo{IName: "usr", IDir: true}
   157  	fs.dirs["/usr/src"] = DumFileInfo{IName: "src", IDir: false}
   158  
   159  	err := MkdirAll(fs, "/usr/src/linux/linux-4.10", 0777)
   160  	if err == nil {
   161  		t.Fatalf("Mkdir failed")
   162  	}
   163  }
   164  
   165  type rmFileinfo struct {
   166  	DumFileInfo
   167  	subfiles []*rmFileinfo
   168  	parent   *rmFileinfo
   169  }
   170  
   171  type rmFS struct {
   172  	Filesystem
   173  	files map[string]*rmFileinfo
   174  }
   175  
   176  func (fs *rmFS) ReadDir(path string) ([]os.FileInfo, error) {
   177  	if fi, ok := fs.files[path]; ok {
   178  		if fi.IsDir() {
   179  			s := make([]os.FileInfo, len(fi.subfiles))
   180  			for i, sf := range fi.subfiles {
   181  				s[i] = sf
   182  			}
   183  			for _, sf := range s {
   184  				if sf == nil {
   185  					panic("sf in readdir nil")
   186  				}
   187  			}
   188  			return s, nil
   189  		}
   190  		return nil, ErrNotDirectory
   191  	}
   192  
   193  	return nil, os.ErrNotExist
   194  }
   195  
   196  func findRmFileInfoIndex(s []*rmFileinfo, needle *rmFileinfo) int {
   197  	for i, fi := range s {
   198  		if fi == needle {
   199  			return i
   200  		}
   201  	}
   202  	return -1
   203  }
   204  
   205  func (fs *rmFS) Remove(name string) error {
   206  	if fi, ok := fs.files[name]; ok {
   207  		if fi.IsDir() && len(fi.subfiles) > 0 {
   208  			return ErrIsDirectory // Not empty
   209  		}
   210  
   211  		// remove references
   212  		delete(fs.files, name)
   213  		if fi.parent != nil {
   214  			if i := findRmFileInfoIndex(fi.parent.subfiles, fi); i >= 0 {
   215  				fi.parent.subfiles = append(fi.parent.subfiles[:i], fi.parent.subfiles[i+1:]...)
   216  			}
   217  		}
   218  		return nil
   219  	}
   220  
   221  	return &os.PathError{Op: "remove", Path: name, Err: os.ErrNotExist}
   222  }
   223  
   224  func TestRemoveAll(t *testing.T) {
   225  	fs := &rmFS{
   226  		Filesystem: Dummy(errors.New("Not implemented")),
   227  		files:      make(map[string]*rmFileinfo),
   228  	}
   229  
   230  	fiTmpFile := &rmFileinfo{
   231  		DumFileInfo: DumFileInfo{
   232  			IName: "file",
   233  			IDir:  false,
   234  		},
   235  	}
   236  
   237  	fiTmp := &rmFileinfo{
   238  		DumFileInfo: DumFileInfo{
   239  			IName: "tmp",
   240  			IDir:  true,
   241  		},
   242  		subfiles: []*rmFileinfo{
   243  			fiTmpFile,
   244  		},
   245  	}
   246  
   247  	fiRoot := &rmFileinfo{
   248  		DumFileInfo: DumFileInfo{
   249  			IName: "/",
   250  			IDir:  true,
   251  		},
   252  		subfiles: []*rmFileinfo{
   253  			fiTmp,
   254  		},
   255  	}
   256  	fs.files["/tmp/file"] = fiTmpFile
   257  	fiTmpFile.parent = fiTmp
   258  	fs.files["/tmp"] = fiTmp
   259  	fiTmp.parent = fiRoot
   260  	fs.files["/"] = fiRoot
   261  
   262  	fiTmpFile.Name()
   263  	err := RemoveAll(fs, "/tmp")
   264  	if err != nil {
   265  		t.Errorf("Unexpected error remove all: %s", err)
   266  	}
   267  
   268  	if _, ok := fs.files["/tmp/file"]; ok {
   269  		t.Errorf("/tmp/file was not removed")
   270  	}
   271  
   272  	if _, ok := fs.files["/tmp"]; ok {
   273  		t.Errorf("/tmp was not removed")
   274  	}
   275  
   276  	if _, ok := fs.files["/"]; !ok {
   277  		t.Errorf("/ was removed")
   278  	}
   279  }