...

Source file src/github.com/spf13/afero/tarfs/tarfs_test.go

Documentation: github.com/spf13/afero/tarfs

     1  // Most of the tests are stolen from the zipfs implementation
     2  package tarfs
     3  
     4  import (
     5  	"archive/tar"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  	"path/filepath"
    11  	"reflect"
    12  	"strings"
    13  	"syscall"
    14  	"testing"
    15  
    16  	"github.com/spf13/afero"
    17  )
    18  
    19  var files = []struct {
    20  	name        string
    21  	exists      bool
    22  	isdir       bool
    23  	size        int64
    24  	content     string
    25  	contentAt4k string
    26  }{
    27  	{"/", true, true, 0, "", ""},
    28  	{"/sub", true, true, 0, "", ""},
    29  	{"/sub/testDir2", true, true, 0, "", ""},
    30  	{"/sub/testDir2/testFile", true, false, 8192, "cccccccc", "ccccdddd"},
    31  	{"/testFile", true, false, 8192, "aaaaaaaa", "aaaabbbb"},
    32  	{"/testDir1/testFile", true, false, 8192, "bbbbbbbb", "bbbbcccc"},
    33  
    34  	{"/nonExisting", false, false, 0, "", ""},
    35  }
    36  
    37  var dirs = []struct {
    38  	name     string
    39  	children []string
    40  }{
    41  	{"/", []string{"sub", "testDir1", "testFile"}},
    42  	{"/sub", []string{"testDir2"}},
    43  	{"/sub/testDir2", []string{"testFile"}},
    44  	{"/testDir1", []string{"testFile"}},
    45  }
    46  
    47  var afs *afero.Afero
    48  
    49  func TestMain(m *testing.M) {
    50  	tf, err := os.Open("testdata/t.tar")
    51  	if err != nil {
    52  		fmt.Print(err)
    53  		os.Exit(1)
    54  	}
    55  
    56  	tfs := New(tar.NewReader(tf))
    57  	afs = &afero.Afero{Fs: tfs}
    58  
    59  	// Check that an empty reader does not panic.
    60  	_ = New(tar.NewReader(strings.NewReader("")))
    61  	os.Exit(m.Run())
    62  }
    63  
    64  func TestFsOpen(t *testing.T) {
    65  	for _, f := range files {
    66  		file, err := afs.Open(f.name)
    67  		if (err == nil) != f.exists {
    68  			t.Errorf("%v exists = %v, but got err = %v", f.name, f.exists, err)
    69  		}
    70  
    71  		if !f.exists {
    72  			continue
    73  		}
    74  		if err != nil {
    75  			t.Fatalf("%v: %v", f.name, err)
    76  		}
    77  
    78  		if file.Name() != filepath.FromSlash(f.name) {
    79  			t.Errorf("Name(), got %v, expected %v", file.Name(), filepath.FromSlash(f.name))
    80  		}
    81  
    82  		s, err := file.Stat()
    83  		if err != nil {
    84  			t.Fatalf("stat %v: got error '%v'", file.Name(), err)
    85  		}
    86  
    87  		if isdir := s.IsDir(); isdir != f.isdir {
    88  			t.Errorf("%v directory, got: %v, expected: %v", file.Name(), isdir, f.isdir)
    89  		}
    90  
    91  		if size := s.Size(); size != f.size {
    92  			t.Errorf("%v size, got: %v, expected: %v", file.Name(), size, f.size)
    93  		}
    94  	}
    95  }
    96  
    97  func TestRead(t *testing.T) {
    98  	for _, f := range files {
    99  		if !f.exists {
   100  			continue
   101  		}
   102  
   103  		file, err := afs.Open(f.name)
   104  		if err != nil {
   105  			t.Fatalf("opening %v: %v", f.name, err)
   106  		}
   107  
   108  		buf := make([]byte, 8)
   109  		n, err := file.Read(buf)
   110  		if err != nil {
   111  			if f.isdir && (err != syscall.EISDIR) {
   112  				t.Errorf("%v got error %v, expected EISDIR", f.name, err)
   113  			} else if !f.isdir {
   114  				t.Errorf("%v: %v", f.name, err)
   115  			}
   116  		} else if n != 8 {
   117  			t.Errorf("%v: got %d read bytes, expected 8", f.name, n)
   118  		} else if string(buf) != f.content {
   119  			t.Errorf("%v: got <%s>, expected <%s>", f.name, f.content, string(buf))
   120  		}
   121  
   122  	}
   123  }
   124  
   125  func TestReadAt(t *testing.T) {
   126  	for _, f := range files {
   127  		if !f.exists {
   128  			continue
   129  		}
   130  
   131  		file, err := afs.Open(f.name)
   132  		if err != nil {
   133  			t.Fatalf("opening %v: %v", f.name, err)
   134  		}
   135  
   136  		buf := make([]byte, 8)
   137  		n, err := file.ReadAt(buf, 4092)
   138  		if err != nil {
   139  			if f.isdir && (err != syscall.EISDIR) {
   140  				t.Errorf("%v got error %v, expected EISDIR", f.name, err)
   141  			} else if !f.isdir {
   142  				t.Errorf("%v: %v", f.name, err)
   143  			}
   144  		} else if n != 8 {
   145  			t.Errorf("%v: got %d read bytes, expected 8", f.name, n)
   146  		} else if string(buf) != f.contentAt4k {
   147  			t.Errorf("%v: got <%s>, expected <%s>", f.name, f.contentAt4k, string(buf))
   148  		}
   149  
   150  	}
   151  }
   152  
   153  func TestSeek(t *testing.T) {
   154  	for _, f := range files {
   155  		if !f.exists {
   156  			continue
   157  		}
   158  
   159  		file, err := afs.Open(f.name)
   160  		if err != nil {
   161  			t.Fatalf("opening %v: %v", f.name, err)
   162  		}
   163  
   164  		tests := []struct {
   165  			offin  int64
   166  			whence int
   167  			offout int64
   168  		}{
   169  			{0, io.SeekStart, 0},
   170  			{10, io.SeekStart, 10},
   171  			{1, io.SeekCurrent, 11},
   172  			{10, io.SeekCurrent, 21},
   173  			{0, io.SeekEnd, f.size},
   174  			{-1, io.SeekEnd, f.size - 1},
   175  		}
   176  
   177  		for _, s := range tests {
   178  			n, err := file.Seek(s.offin, s.whence)
   179  			if err != nil {
   180  				if f.isdir && err == syscall.EISDIR {
   181  					continue
   182  				}
   183  
   184  				t.Errorf("%v: %v", f.name, err)
   185  			}
   186  
   187  			if n != s.offout {
   188  				t.Errorf("%v: (off: %v, whence: %v): got %v, expected %v", f.name, s.offin, s.whence, n, s.offout)
   189  			}
   190  		}
   191  
   192  	}
   193  }
   194  
   195  func TestName(t *testing.T) {
   196  	for _, f := range files {
   197  		if !f.exists {
   198  			continue
   199  		}
   200  
   201  		file, err := afs.Open(f.name)
   202  		if err != nil {
   203  			t.Fatalf("opening %v: %v", f.name, err)
   204  		}
   205  
   206  		n := file.Name()
   207  		if n != filepath.FromSlash(f.name) {
   208  			t.Errorf("got: %v, expected: %v", n, filepath.FromSlash(f.name))
   209  		}
   210  
   211  	}
   212  }
   213  
   214  func TestClose(t *testing.T) {
   215  	for _, f := range files {
   216  		if !f.exists {
   217  			continue
   218  		}
   219  
   220  		file, err := afs.Open(f.name)
   221  		if err != nil {
   222  			t.Fatalf("opening %v: %v", f.name, err)
   223  		}
   224  
   225  		err = file.Close()
   226  		if err != nil {
   227  			t.Errorf("%v: %v", f.name, err)
   228  		}
   229  
   230  		err = file.Close()
   231  		if err == nil {
   232  			t.Errorf("%v: closing twice should return an error", f.name)
   233  		}
   234  
   235  		buf := make([]byte, 8)
   236  		n, err := file.Read(buf)
   237  		if n != 0 || err == nil {
   238  			t.Errorf("%v: could read from a closed file", f.name)
   239  		}
   240  
   241  		n, err = file.ReadAt(buf, 256)
   242  		if n != 0 || err == nil {
   243  			t.Errorf("%v: could readAt from a closed file", f.name)
   244  		}
   245  
   246  		off, err := file.Seek(0, io.SeekStart)
   247  		if off != 0 || err == nil {
   248  			t.Errorf("%v: could seek from a closed file", f.name)
   249  		}
   250  	}
   251  }
   252  
   253  func TestOpenFile(t *testing.T) {
   254  	for _, f := range files {
   255  		file, err := afs.OpenFile(f.name, os.O_RDONLY, 0o400)
   256  		if !f.exists {
   257  			if !errors.Is(err, syscall.ENOENT) {
   258  				t.Errorf("%v: got %v, expected%v", f.name, err, syscall.ENOENT)
   259  			}
   260  
   261  			continue
   262  		}
   263  
   264  		if err != nil {
   265  			t.Fatalf("%v: %v", f.name, err)
   266  		}
   267  		file.Close()
   268  
   269  		_, err = afs.OpenFile(f.name, os.O_CREATE, 0o600)
   270  		if !errors.Is(err, syscall.EPERM) {
   271  			t.Errorf("%v: open for write: got %v, expected %v", f.name, err, syscall.EPERM)
   272  		}
   273  
   274  	}
   275  }
   276  
   277  func TestFsStat(t *testing.T) {
   278  	for _, f := range files {
   279  		fi, err := afs.Stat(f.name)
   280  		if !f.exists {
   281  			if !errors.Is(err, syscall.ENOENT) {
   282  				t.Errorf("%v: got %v, expected%v", f.name, err, syscall.ENOENT)
   283  			}
   284  
   285  			continue
   286  		}
   287  
   288  		if err != nil {
   289  			t.Fatalf("stat %v: got error '%v'", f.name, err)
   290  		}
   291  
   292  		if isdir := fi.IsDir(); isdir != f.isdir {
   293  			t.Errorf("%v directory, got: %v, expected: %v", f.name, isdir, f.isdir)
   294  		}
   295  
   296  		if size := fi.Size(); size != f.size {
   297  			t.Errorf("%v size, got: %v, expected: %v", f.name, size, f.size)
   298  		}
   299  	}
   300  }
   301  
   302  func TestReaddir(t *testing.T) {
   303  	for _, d := range dirs {
   304  		dir, err := afs.Open(d.name)
   305  		if err != nil {
   306  			t.Fatal(err)
   307  		}
   308  
   309  		fi, err := dir.Readdir(0)
   310  		if err != nil {
   311  			t.Fatal(err)
   312  		}
   313  		var names []string
   314  		for _, f := range fi {
   315  			names = append(names, f.Name())
   316  		}
   317  
   318  		if !reflect.DeepEqual(names, d.children) {
   319  			t.Errorf("%v: children, got '%v', expected '%v'", d.name, names, d.children)
   320  		}
   321  
   322  		fi, err = dir.Readdir(1)
   323  		if err != nil {
   324  			t.Fatal(err)
   325  		}
   326  
   327  		names = []string{}
   328  		for _, f := range fi {
   329  			names = append(names, f.Name())
   330  		}
   331  
   332  		if !reflect.DeepEqual(names, d.children[0:1]) {
   333  			t.Errorf("%v: children, got '%v', expected '%v'", d.name, names, d.children[0:1])
   334  		}
   335  	}
   336  
   337  	dir, err := afs.Open("/testFile")
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  
   342  	_, err = dir.Readdir(-1)
   343  	if err != syscall.ENOTDIR {
   344  		t.Fatal("Expected error")
   345  	}
   346  }
   347  
   348  func TestReaddirnames(t *testing.T) {
   349  	for _, d := range dirs {
   350  		dir, err := afs.Open(d.name)
   351  		if err != nil {
   352  			t.Fatal(err)
   353  		}
   354  
   355  		names, err := dir.Readdirnames(0)
   356  		if err != nil {
   357  			t.Fatal(err)
   358  		}
   359  
   360  		if !reflect.DeepEqual(names, d.children) {
   361  			t.Errorf("%v: children, got '%v', expected '%v'", d.name, names, d.children)
   362  		}
   363  
   364  		names, err = dir.Readdirnames(1)
   365  		if err != nil {
   366  			t.Fatal(err)
   367  		}
   368  
   369  		if !reflect.DeepEqual(names, d.children[0:1]) {
   370  			t.Errorf("%v: children, got '%v', expected '%v'", d.name, names, d.children[0:1])
   371  		}
   372  	}
   373  
   374  	dir, err := afs.Open("/testFile")
   375  	if err != nil {
   376  		t.Fatal(err)
   377  	}
   378  
   379  	_, err = dir.Readdir(-1)
   380  	if err != syscall.ENOTDIR {
   381  		t.Fatal("Expected error")
   382  	}
   383  }
   384  
   385  func TestGlob(t *testing.T) {
   386  	for _, s := range []struct {
   387  		glob    string
   388  		entries []string
   389  	}{
   390  		{filepath.FromSlash("/*"), []string{filepath.FromSlash("/sub"), filepath.FromSlash("/testDir1"), filepath.FromSlash("/testFile")}},
   391  		{filepath.FromSlash("*"), []string{filepath.FromSlash("sub"), filepath.FromSlash("testDir1"), filepath.FromSlash("testFile")}},
   392  		{filepath.FromSlash("sub/*"), []string{filepath.FromSlash("sub/testDir2")}},
   393  		{filepath.FromSlash("sub/testDir2/*"), []string{filepath.FromSlash("sub/testDir2/testFile")}},
   394  		{filepath.FromSlash("testDir1/*"), []string{filepath.FromSlash("testDir1/testFile")}},
   395  	} {
   396  		entries, err := afero.Glob(afs.Fs, s.glob)
   397  		if err != nil {
   398  			t.Error(err)
   399  		}
   400  		if reflect.DeepEqual(entries, s.entries) {
   401  			t.Logf("glob: %s: glob ok", s.glob)
   402  		} else {
   403  			t.Errorf("glob: %s: got %#v, expected %#v", s.glob, entries, s.entries)
   404  		}
   405  	}
   406  }
   407  

View as plain text