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 }