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