gitee.com/h79/goutils@v1.22.10/common/archive/zip/zip_test.go (about)

     1  package zip
     2  
     3  import (
     4  	"archive/zip"
     5  	"bytes"
     6  	"gitee.com/h79/goutils/common/file/config"
     7  	"io"
     8  	"io/fs"
     9  	"os"
    10  	"path/filepath"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestZipFile(t *testing.T) {
    18  	tmp := t.TempDir()
    19  	f, err := os.Create(filepath.Join(tmp, "test.zip"))
    20  	require.NoError(t, err)
    21  	defer f.Close() // nolint: errcheck
    22  	archive := New(f)
    23  	defer archive.Close() // nolint: errcheck
    24  
    25  	require.Error(t, archive.Add(config.File{
    26  		Source:      "../testdata/nope.txt",
    27  		Destination: "nope.txt",
    28  	}))
    29  	require.NoError(t, archive.Add(config.File{
    30  		Source:      "../testdata/foo.txt",
    31  		Destination: "foo.txt",
    32  	}))
    33  	require.NoError(t, archive.Add(config.File{
    34  		Source:      "../testdata/sub1",
    35  		Destination: "sub1",
    36  	}))
    37  	require.NoError(t, archive.Add(config.File{
    38  		Source:      "../testdata/sub1/sub3",
    39  		Destination: "sub1/sub3",
    40  	}))
    41  	require.NoError(t, archive.Add(config.File{
    42  		Source:      "../testdata/sub1/bar.txt",
    43  		Destination: "sub1/bar.txt",
    44  	}))
    45  	require.NoError(t, archive.Add(config.File{
    46  		Source:      "../testdata/sub1/executable",
    47  		Destination: "sub1/executable",
    48  	}))
    49  	require.NoError(t, archive.Add(config.File{
    50  		Source:      "../testdata/sub1/sub2",
    51  		Destination: "sub1/sub2",
    52  	}))
    53  	require.NoError(t, archive.Add(config.File{
    54  		Source:      "../testdata/sub1/sub2/foo.txt",
    55  		Destination: "sub1/sub2/foo.txt",
    56  	}))
    57  	require.NoError(t, archive.Add(config.File{
    58  		Source:      "../testdata/regular.txt",
    59  		Destination: "regular.txt",
    60  	}))
    61  	require.NoError(t, archive.Add(config.File{
    62  		Source:      "../testdata/link.txt",
    63  		Destination: "link.txt",
    64  	}))
    65  
    66  	require.ErrorIs(t, archive.Add(config.File{
    67  		Source:      "../testdata/regular.txt",
    68  		Destination: "link.txt",
    69  	}), fs.ErrExist)
    70  
    71  	require.NoError(t, archive.Close())
    72  	require.Error(t, archive.Add(config.File{
    73  		Source:      "tar.go",
    74  		Destination: "tar.go",
    75  	}))
    76  	require.NoError(t, f.Close())
    77  
    78  	f, err = os.Open(f.Name())
    79  	require.NoError(t, err)
    80  	defer f.Close() // nolint: errcheck
    81  
    82  	info, err := f.Stat()
    83  	require.NoError(t, err)
    84  	require.Truef(t, info.Size() < 10000, "archived file should be smaller than %d", info.Size())
    85  
    86  	r, err := zip.NewReader(f, info.Size())
    87  	require.NoError(t, err)
    88  
    89  	paths := make([]string, len(r.File))
    90  	for i, zf := range r.File {
    91  		paths[i] = zf.Name
    92  		if zf.Name == "sub1/executable" {
    93  			ex := zf.Mode()&0o111 != 0
    94  			require.True(t, ex, "expected executable permissions, got %s", zf.Mode())
    95  		}
    96  		if zf.Name == "link.txt" {
    97  			require.True(t, zf.FileInfo().Mode()&os.ModeSymlink != 0)
    98  			rc, err := zf.Open()
    99  			require.NoError(t, err)
   100  			var link bytes.Buffer
   101  			_, err = io.Copy(&link, rc)
   102  			require.NoError(t, err)
   103  			rc.Close()
   104  			require.Equal(t, link.String(), "regular.txt")
   105  		}
   106  	}
   107  	require.Equal(t, []string{
   108  		"foo.txt",
   109  		"sub1/",
   110  		"sub1/sub3/",
   111  		"sub1/bar.txt",
   112  		"sub1/executable",
   113  		"sub1/sub2/",
   114  		"sub1/sub2/foo.txt",
   115  		"regular.txt",
   116  		"link.txt",
   117  	}, paths)
   118  }
   119  
   120  func TestZipFileInfo(t *testing.T) {
   121  	now := time.Now().Truncate(time.Second)
   122  	f, err := os.Create(filepath.Join(t.TempDir(), "test.zip"))
   123  	require.NoError(t, err)
   124  	defer f.Close() // nolint: errcheck
   125  	archive := New(f)
   126  	defer archive.Close() // nolint: errcheck
   127  
   128  	require.NoError(t, archive.Add(config.File{
   129  		Source:      "../testdata/foo.txt",
   130  		Destination: "nope.txt",
   131  		Info: config.FileInfo{
   132  			Mode:        0o755,
   133  			Owner:       "carlos",
   134  			Group:       "root",
   135  			ParsedMTime: now,
   136  		},
   137  	}))
   138  
   139  	require.NoError(t, archive.Close())
   140  	require.NoError(t, f.Close())
   141  
   142  	f, err = os.Open(f.Name())
   143  	require.NoError(t, err)
   144  	defer f.Close() // nolint: errcheck
   145  
   146  	info, err := f.Stat()
   147  	require.NoError(t, err)
   148  
   149  	r, err := zip.NewReader(f, info.Size())
   150  	require.NoError(t, err)
   151  
   152  	require.Len(t, r.File, 1)
   153  	for _, next := range r.File {
   154  		require.Equal(t, "nope.txt", next.Name)
   155  		require.Equal(t, now.Unix(), next.Modified.Unix())
   156  		require.Equal(t, fs.FileMode(0o755), next.FileInfo().Mode())
   157  	}
   158  }
   159  
   160  func TestTarInvalidLink(t *testing.T) {
   161  	archive := New(io.Discard)
   162  	defer archive.Close() // nolint: errcheck
   163  
   164  	require.NoError(t, archive.Add(config.File{
   165  		Source:      "../testdata/badlink.txt",
   166  		Destination: "badlink.txt",
   167  	}))
   168  }
   169  
   170  // TODO: add copying test