oras.land/oras-go/v2@v2.5.1-0.20240520045656-aef90e4d04c4/internal/fs/tarfs/tarfs_test.go (about)

     1  /*
     2  Copyright The ORAS Authors.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7  http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package tarfs
    17  
    18  import (
    19  	"bytes"
    20  	"errors"
    21  	"io"
    22  	"io/fs"
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	"oras.land/oras-go/v2/errdef"
    27  )
    28  
    29  /*
    30  testdata/test.tar contains:
    31  
    32  	foobar
    33  	foobar_link
    34  	foobar_symlink
    35  	dir/
    36  		hello
    37  		subdir/
    38  			world
    39  */
    40  func TestTarFS_Open_Success(t *testing.T) {
    41  	testFiles := map[string][]byte{
    42  		"foobar":           []byte("foobar"),
    43  		"dir/hello":        []byte("hello"),
    44  		"dir/subdir/world": []byte("world"),
    45  	}
    46  	tarPath := "testdata/test.tar"
    47  	tfs, err := New(tarPath)
    48  	if err != nil {
    49  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
    50  	}
    51  	tarPathAbs, err := filepath.Abs(tarPath)
    52  	if err != nil {
    53  		t.Fatal("error calling filepath.Abs(), error =", err)
    54  	}
    55  	if tfs.path != tarPathAbs {
    56  		t.Fatalf("TarFS.path = %s, want %s", tfs.path, tarPathAbs)
    57  	}
    58  
    59  	for name, data := range testFiles {
    60  		f, err := tfs.Open(name)
    61  		if err != nil {
    62  			t.Fatalf("TarFS.Open(%s) error = %v, wantErr %v", name, err, nil)
    63  			continue
    64  		}
    65  
    66  		got, err := io.ReadAll(f)
    67  		if err != nil {
    68  			t.Fatalf("failed to read %s: %v", name, err)
    69  		}
    70  		if err = f.Close(); err != nil {
    71  			t.Errorf("TarFS.Open(%s).Close() error = %v", name, err)
    72  		}
    73  		if want := data; !bytes.Equal(got, want) {
    74  			t.Errorf("TarFS.Open(%s) = %v, want %v", name, string(got), string(want))
    75  		}
    76  	}
    77  }
    78  
    79  func TestTarFS_Open_MoreThanOnce(t *testing.T) {
    80  	tfs, err := New("testdata/test.tar")
    81  	if err != nil {
    82  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
    83  	}
    84  
    85  	name := "foobar"
    86  	data := []byte("foobar")
    87  	// open once
    88  	f1, err := tfs.Open(name)
    89  	if err != nil {
    90  		t.Fatalf("1st: TarFS.Open(%s) error = %v, wantErr %v", name, err, nil)
    91  	}
    92  
    93  	got, err := io.ReadAll(f1)
    94  	if err != nil {
    95  		t.Fatalf("1st: failed to read %s: %v", name, err)
    96  	}
    97  	if want := data; !bytes.Equal(got, want) {
    98  		t.Errorf("1st: TarFS.Open(%s) = %v, want %v", name, string(got), string(want))
    99  	}
   100  
   101  	// open twice
   102  	f2, err := tfs.Open(name)
   103  	if err != nil {
   104  		t.Fatalf("2nd: TarFS.Open(%s) error = %v, wantErr %v", name, err, nil)
   105  	}
   106  	got, err = io.ReadAll(f2)
   107  	if err != nil {
   108  		t.Fatalf("2nd: failed to read %s: %v", name, err)
   109  	}
   110  	if want := data; !bytes.Equal(got, want) {
   111  		t.Errorf("2nd: TarFS.Open(%s) = %v, want %v", name, string(got), string(want))
   112  	}
   113  
   114  	// close
   115  	if err = f1.Close(); err != nil {
   116  		t.Errorf("1st TarFS.Open(%s).Close() error = %v", name, err)
   117  	}
   118  	if err = f2.Close(); err != nil {
   119  		t.Errorf("2nd TarFS.Open(%s).Close() error = %v", name, err)
   120  	}
   121  }
   122  
   123  func TestTarFS_Open_NotExist(t *testing.T) {
   124  	testFiles := []string{
   125  		"dir/foo",
   126  		"subdir/bar",
   127  		"barfoo",
   128  	}
   129  	tfs, err := New("testdata/test.tar")
   130  	if err != nil {
   131  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   132  	}
   133  	for _, name := range testFiles {
   134  		_, err := tfs.Open(name)
   135  		if want := fs.ErrNotExist; !errors.Is(err, want) {
   136  			t.Errorf("TarFS.Open(%s) error = %v, wantErr %v", name, err, want)
   137  		}
   138  	}
   139  }
   140  
   141  func TestTarFS_Open_InvalidPath(t *testing.T) {
   142  	testFiles := []string{
   143  		"dir/",
   144  		"subdir/",
   145  		"dir/subdir/",
   146  	}
   147  	tfs, err := New("testdata/test.tar")
   148  	if err != nil {
   149  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   150  	}
   151  	for _, name := range testFiles {
   152  		_, err := tfs.Open(name)
   153  		if want := fs.ErrInvalid; !errors.Is(err, want) {
   154  			t.Errorf("TarFS.Open(%s) error = %v, wantErr %v", name, err, want)
   155  		}
   156  	}
   157  }
   158  
   159  func TestTarFS_Open_Unsupported(t *testing.T) {
   160  	testFiles := []string{
   161  		"foobar_link",
   162  		"foobar_symlink",
   163  	}
   164  	tfs, err := New("testdata/test.tar")
   165  	if err != nil {
   166  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   167  	}
   168  	for _, name := range testFiles {
   169  		_, err := tfs.Open(name)
   170  		if want := errdef.ErrUnsupported; !errors.Is(err, want) {
   171  			t.Errorf("TarFS.Open(%s) error = %v, wantErr %v", name, err, want)
   172  		}
   173  	}
   174  }
   175  
   176  func TestTarFS_Stat(t *testing.T) {
   177  	tfs, err := New("testdata/test.tar")
   178  	if err != nil {
   179  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   180  	}
   181  
   182  	name := "foobar"
   183  	fi, err := tfs.Stat(name)
   184  	if err != nil {
   185  		t.Fatal("Stat() error =", err)
   186  	}
   187  	if got, want := fi.Name(), "foobar"; got != want {
   188  		t.Errorf("Stat().want() = %v, want %v", got, want)
   189  	}
   190  	if got, want := fi.Size(), int64(6); got != want {
   191  		t.Errorf("Stat().Size() = %v, want %v", got, want)
   192  	}
   193  
   194  	name = "dir/hello"
   195  	fi, err = tfs.Stat(name)
   196  	if err != nil {
   197  		t.Fatal("Stat() error =", err)
   198  	}
   199  	if got, want := fi.Name(), "hello"; got != want {
   200  		t.Errorf("Stat().want() = %v, want %v", got, want)
   201  	}
   202  	if got, want := fi.Size(), int64(5); got != want {
   203  		t.Errorf("Stat().Size() = %v, want %v", got, want)
   204  	}
   205  
   206  	name = "dir/subdir/world"
   207  	fi, err = tfs.Stat(name)
   208  	if err != nil {
   209  		t.Fatal("Stat() error =", err)
   210  	}
   211  	if got, want := fi.Name(), "world"; got != want {
   212  		t.Errorf("Stat().want() = %v, want %v", got, want)
   213  	}
   214  	if got, want := fi.Size(), int64(5); got != want {
   215  		t.Errorf("Stat().Size() = %v, want %v", got, want)
   216  	}
   217  }
   218  
   219  func TestTarFS_Stat_NotExist(t *testing.T) {
   220  	testFiles := []string{
   221  		"dir/foo",
   222  		"subdir/bar",
   223  		"barfoo",
   224  	}
   225  	tfs, err := New("testdata/test.tar")
   226  	if err != nil {
   227  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   228  	}
   229  	for _, name := range testFiles {
   230  		_, err := tfs.Stat(name)
   231  		if want := fs.ErrNotExist; !errors.Is(err, want) {
   232  			t.Errorf("TarFS.Stat(%s) error = %v, wantErr %v", name, err, want)
   233  		}
   234  	}
   235  }
   236  
   237  func TestTarFS_Stat_InvalidPath(t *testing.T) {
   238  	testFiles := []string{
   239  		"dir/",
   240  		"subdir/",
   241  		"dir/subdir/",
   242  	}
   243  	tfs, err := New("testdata/test.tar")
   244  	if err != nil {
   245  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   246  	}
   247  	for _, name := range testFiles {
   248  		_, err := tfs.Stat(name)
   249  		if want := fs.ErrInvalid; !errors.Is(err, want) {
   250  			t.Errorf("TarFS.Stat(%s) error = %v, wantErr %v", name, err, want)
   251  		}
   252  	}
   253  }
   254  
   255  func TestTarFS_Stat_Unsupported(t *testing.T) {
   256  	testFiles := []string{
   257  		"foobar_link",
   258  		"foobar_symlink",
   259  	}
   260  	tfs, err := New("testdata/test.tar")
   261  	if err != nil {
   262  		t.Fatalf("New() error = %v, wantErr %v", err, nil)
   263  	}
   264  	for _, name := range testFiles {
   265  		_, err := tfs.Stat(name)
   266  		if want := errdef.ErrUnsupported; !errors.Is(err, want) {
   267  			t.Errorf("TarFS.Stat(%s) error = %v, wantErr %v", name, err, want)
   268  		}
   269  	}
   270  }