gitee.com/h79/goutils@v1.22.10/common/archive/tar/tar_test.go (about)

     1  package tar
     2  
     3  import (
     4  	"archive/tar"
     5  	"gitee.com/h79/goutils/common/file/config"
     6  	"io"
     7  	"io/fs"
     8  	"os"
     9  	"path/filepath"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestTarFile(t *testing.T) {
    17  	tmp := t.TempDir()
    18  	f, err := os.Create(filepath.Join(tmp, "test.tar"))
    19  	require.NoError(t, err)
    20  	defer f.Close() // nolint: errcheck
    21  	archive := New(f)
    22  	defer archive.Close() // nolint: errcheck
    23  
    24  	require.Error(t, archive.Add(config.File{
    25  		Source:      "../testdata/nope.txt",
    26  		Destination: "nope.txt",
    27  	}))
    28  	require.NoError(t, archive.Add(config.File{
    29  		Source:      "../testdata/foo.txt",
    30  		Destination: "foo.txt",
    31  	}))
    32  	require.NoError(t, archive.Add(config.File{
    33  		Source:      "../testdata/sub1",
    34  		Destination: "sub1",
    35  	}))
    36  	require.NoError(t, archive.Add(config.File{
    37  		Source:      "../testdata/sub1/bar.txt",
    38  		Destination: "sub1/bar.txt",
    39  	}))
    40  	require.NoError(t, archive.Add(config.File{
    41  		Source:      "../testdata/sub1/executable",
    42  		Destination: "sub1/executable",
    43  	}))
    44  	require.NoError(t, archive.Add(config.File{
    45  		Source:      "../testdata/sub1/sub2",
    46  		Destination: "sub1/sub2",
    47  	}))
    48  	require.NoError(t, archive.Add(config.File{
    49  		Source:      "../testdata/sub1/sub2/subfoo.txt",
    50  		Destination: "sub1/sub2/subfoo.txt",
    51  	}))
    52  	require.NoError(t, archive.Add(config.File{
    53  		Source:      "../testdata/regular.txt",
    54  		Destination: "regular.txt",
    55  	}))
    56  	require.NoError(t, archive.Add(config.File{
    57  		Source:      "../testdata/link.txt",
    58  		Destination: "link.txt",
    59  	}))
    60  
    61  	require.ErrorIs(t, archive.Add(config.File{
    62  		Source:      "../testdata/regular.txt",
    63  		Destination: "link.txt",
    64  	}), fs.ErrExist)
    65  
    66  	require.NoError(t, archive.Close())
    67  	require.Error(t, archive.Add(config.File{
    68  		Source:      "tar.go",
    69  		Destination: "tar.go",
    70  	}))
    71  	require.NoError(t, f.Close())
    72  
    73  	f, err = os.Open(f.Name())
    74  	require.NoError(t, err)
    75  	defer f.Close() // nolint: errcheck
    76  
    77  	info, err := f.Stat()
    78  	require.NoError(t, err)
    79  	require.Truef(t, info.Size() < 10000, "archived file should be smaller than %d", info.Size())
    80  
    81  	var paths []string
    82  	r := tar.NewReader(f)
    83  	for {
    84  		next, err := r.Next()
    85  		if err == io.EOF {
    86  			break
    87  		}
    88  		require.NoError(t, err)
    89  		paths = append(paths, next.Name)
    90  		if next.Name == "sub1/executable" {
    91  			ex := next.FileInfo().Mode()&0o111 != 0
    92  			require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode())
    93  		}
    94  		if next.Name == "link.txt" {
    95  			require.Equal(t, next.Linkname, "regular.txt")
    96  		}
    97  	}
    98  	require.Equal(t, []string{
    99  		"foo.txt",
   100  		"sub1",
   101  		"sub1/bar.txt",
   102  		"sub1/executable",
   103  		"sub1/sub2",
   104  		"sub1/sub2/subfoo.txt",
   105  		"regular.txt",
   106  		"link.txt",
   107  	}, paths)
   108  }
   109  
   110  func TestTarFileInfo(t *testing.T) {
   111  	now := time.Now().Truncate(time.Second)
   112  	f, err := os.Create(filepath.Join(t.TempDir(), "test.tar"))
   113  	require.NoError(t, err)
   114  	defer f.Close() // nolint: errcheck
   115  	archive := New(f)
   116  	defer archive.Close() // nolint: errcheck
   117  
   118  	require.NoError(t, archive.Add(config.File{
   119  		Source:      "../testdata/foo.txt",
   120  		Destination: "nope.txt",
   121  		Info: config.FileInfo{
   122  			Mode:        0o755,
   123  			Owner:       "carlos",
   124  			Group:       "root",
   125  			ParsedMTime: now,
   126  		},
   127  	}))
   128  
   129  	require.NoError(t, archive.Close())
   130  	require.NoError(t, f.Close())
   131  
   132  	f, err = os.Open(f.Name())
   133  	require.NoError(t, err)
   134  	defer f.Close() // nolint: errcheck
   135  
   136  	var found int
   137  	r := tar.NewReader(f)
   138  	for {
   139  		next, err := r.Next()
   140  		if err == io.EOF {
   141  			break
   142  		}
   143  		require.NoError(t, err)
   144  
   145  		found++
   146  		require.Equal(t, "nope.txt", next.Name)
   147  		require.Equal(t, now, next.ModTime)
   148  		require.Equal(t, fs.FileMode(0o755), next.FileInfo().Mode())
   149  		require.Equal(t, "carlos", next.Uname)
   150  		require.Equal(t, 0, next.Uid)
   151  		require.Equal(t, "root", next.Gname)
   152  		require.Equal(t, 0, next.Gid)
   153  	}
   154  	require.Equal(t, 1, found)
   155  }
   156  
   157  func TestTarInvalidLink(t *testing.T) {
   158  	archive := New(io.Discard)
   159  	defer archive.Close() // nolint: errcheck
   160  
   161  	require.NoError(t, archive.Add(config.File{
   162  		Source:      "../testdata/badlink.txt",
   163  		Destination: "badlink.txt",
   164  	}))
   165  }
   166  
   167  func TestCopying(t *testing.T) {
   168  	f1, err := os.Create(filepath.Join(t.TempDir(), "1.tar"))
   169  	require.NoError(t, err)
   170  	f2, err := os.Create(filepath.Join(t.TempDir(), "2.tar"))
   171  	require.NoError(t, err)
   172  
   173  	t1 := New(f1)
   174  	require.NoError(t, t1.Add(config.File{
   175  		Source:      "../testdata/foo.txt",
   176  		Destination: "foo.txt",
   177  	}))
   178  	require.NoError(t, t1.Add(config.File{
   179  		Source:      "../testdata/foo.txt",
   180  		Destination: "ملف.txt",
   181  	}))
   182  	require.NoError(t, t1.Close())
   183  	require.NoError(t, f1.Close())
   184  
   185  	f1, err = os.Open(f1.Name())
   186  	require.NoError(t, err)
   187  
   188  	t2, err := Copying(f1, f2)
   189  	require.NoError(t, err)
   190  	require.NoError(t, t2.Add(config.File{
   191  		Source:      "../testdata/sub1/executable",
   192  		Destination: "executable",
   193  	}))
   194  	require.NoError(t, t2.Add(config.File{
   195  		Source:      "../testdata/sub1/executable",
   196  		Destination: "ملف.exe",
   197  	}))
   198  	require.NoError(t, t2.Close())
   199  	require.NoError(t, f2.Close())
   200  	require.NoError(t, f1.Close())
   201  
   202  }