github.com/jotfs/jot@v0.2.0/client_test.go (about) 1 package jot 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "fmt" 8 "io" 9 "math/rand" 10 "net/http" 11 "os" 12 "testing" 13 "time" 14 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func TestNew(t *testing.T) { 19 // New 20 _, err := New("https://localhost:8000", http.DefaultClient, nil) 21 assert.NoError(t, err) 22 23 // New with options 24 client, err := New("http://example.com", http.DefaultClient, &Options{ 25 Compression: CompressNone, 26 CacheDir: "/var/log", 27 }) 28 assert.NoError(t, err) 29 assert.Equal(t, CompressNone, client.mode) 30 assert.Equal(t, "/var/log", client.cacheDir) 31 32 // Error if endpoint string is empty 33 client, err = New("", http.DefaultClient, nil) 34 assert.Error(t, err) 35 assert.Nil(t, client) 36 } 37 38 func TestUpload(t *testing.T) { 39 client := testClient(t) 40 defer clearFiles(t, client) 41 42 // Upload data 43 data := randBytes(130*miB, 7456) 44 _, err := client.Upload(bytes.NewReader(data), "data.txt") 45 assert.NoError(t, err) 46 47 // Upload empty data 48 ctx := context.Background() 49 _, err = client.UploadWithContext(ctx, bytes.NewReader(nil), "data2.txt", CompressNone) 50 assert.NoError(t, err) 51 } 52 53 func TestDownload(t *testing.T) { 54 client := testClient(t) 55 defer clearFiles(t, client) 56 57 // Upload data (none & zstd compression) and check download matches original data 58 data1 := randBytes(10*miB, 2854) 59 for _, mode := range []CompressMode{CompressNone, CompressZstd} { 60 s1 := uploadTestFile(t, client, data1, "data1.txt", mode) 61 62 msg := fmt.Sprintf("mode = %d", mode) 63 var buf bytes.Buffer 64 err := client.Download(s1, &buf) 65 assert.NoError(t, err, msg) 66 assert.Equal(t, data1, buf.Bytes(), msg) 67 } 68 69 // Download file which doesn't exist -- should get ErrNotFound 70 var buf bytes.Buffer 71 err := client.Download(FileID{}, &buf) 72 assert.Equal(t, ErrNotFound, err) 73 74 } 75 76 func TestList(t *testing.T) { 77 client := testClient(t) 78 defer clearFiles(t, client) 79 80 data1 := randBytes(2*kiB, 6332) 81 data2 := randBytes(12*miB, 83) 82 data3 := randBytes(10*miB, 9832) 83 s1 := uploadTestFile(t, client, data1, "data1.txt", CompressNone) 84 s2 := uploadTestFile(t, client, data2, "files/data2.txt", CompressZstd) 85 s3 := uploadTestFile(t, client, data3, "files/data3.txt", CompressNone) 86 87 // We don't know the CreatedAt value here so leave it at zero for each 88 info1 := FileInfo{Name: "/data1.txt", Size: uint64(len(data1)), FileID: s1} 89 info2 := FileInfo{Name: "/files/data2.txt", Size: uint64(len(data2)), FileID: s2} 90 info3 := FileInfo{Name: "/files/data3.txt", Size: uint64(len(data3)), FileID: s3} 91 92 runIt := func(it FileIterator) ([]FileInfo, error) { 93 files := make([]FileInfo, 0) 94 for { 95 file, err := it.Next() 96 if err == io.EOF { 97 break 98 } 99 if err != nil { 100 return nil, err 101 } 102 // Zero the CreatedAt field so we can match it with the expected values 103 file.CreatedAt = time.Time{} 104 files = append(files, file) 105 } 106 return files, nil 107 } 108 109 // List 110 it := client.List("/", nil) 111 files, err := runIt(it) 112 assert.NoError(t, err) 113 assert.Equal(t, []FileInfo{info3, info2, info1}, files) 114 115 // List ascending 116 it = client.List("/", &ListOpts{Ascending: true}) 117 files, err = runIt(it) 118 assert.NoError(t, err) 119 assert.Equal(t, []FileInfo{info1, info2, info3}, files) 120 121 // List filter 122 it = client.List("/", &ListOpts{Exclude: "/files/*", Include: "/files/data2.txt"}) 123 files, err = runIt(it) 124 assert.NoError(t, err) 125 assert.Equal(t, []FileInfo{info2, info1}, files) 126 127 // List -- no matches 128 it = client.List("/invalid/", nil) 129 files, err = runIt(it) 130 assert.NoError(t, err) 131 assert.Equal(t, []FileInfo{}, files) 132 133 // Head 134 it = client.Head("data1.txt", nil) 135 files, err = runIt(it) 136 assert.NoError(t, err) 137 assert.Equal(t, []FileInfo{info1}, files) 138 139 // Head -- no matches 140 it = client.Head("does-not-exist", nil) 141 files, err = runIt(it) 142 assert.NoError(t, err) 143 assert.Equal(t, []FileInfo{}, files) 144 } 145 146 func TestCopy(t *testing.T) { 147 client := testClient(t) 148 defer clearFiles(t, client) 149 150 data1 := randBytes(13*miB, 5343) 151 s1 := uploadTestFile(t, client, data1, "data1.txt", CompressNone) 152 153 // Copy 154 s2, err := client.Copy(s1, "data/data2.txt") 155 assert.NoError(t, err) 156 157 // Should be able to get file 158 var buf bytes.Buffer 159 err = client.Download(s2, &buf) 160 assert.NoError(t, err) 161 assert.Equal(t, data1, buf.Bytes()) 162 163 // Copy does not exist 164 _, err = client.Copy(FileID{}, "abc") 165 assert.Equal(t, ErrNotFound, err) 166 } 167 168 func TestMergeErrors(t *testing.T) { 169 err1 := errors.New("1") 170 err2 := errors.New("2") 171 172 tests := []struct { 173 e error 174 minor error 175 output error 176 }{ 177 {err1, nil, err1}, 178 {nil, err2, err2}, 179 {nil, nil, nil}, 180 } 181 182 for i, test := range tests { 183 assert.Equal(t, test.output, mergeErrors(test.e, test.minor), i) 184 } 185 186 // Check wrapping 187 err := mergeErrors(err1, err2) 188 assert.Equal(t, err1, errors.Unwrap(err)) 189 } 190 191 func uploadTestFile(t *testing.T, client *Client, data []byte, name string, mode CompressMode) FileID { 192 ctx := context.Background() 193 s, err := client.UploadWithContext(ctx, bytes.NewReader(data), name, mode) 194 if err != nil { 195 t.Fatal(err) 196 } 197 return s 198 } 199 200 func clearFiles(t *testing.T, client *Client) { 201 it := client.List("/", nil) 202 for { 203 file, err := it.Next() 204 if err == io.EOF { 205 break 206 } 207 if err != nil { 208 t.Fatal(err) 209 } 210 if err = client.Delete(file.FileID); err != nil { 211 t.Fatal(err) 212 } 213 } 214 } 215 216 func testClient(t *testing.T) *Client { 217 client, err := New("http://localhost:6777", http.DefaultClient, nil) 218 if err != nil { 219 t.Fatal(err) 220 } 221 return client 222 } 223 224 func randBytes(n int, seed int64) []byte { 225 b := make([]byte, n) 226 rand.Seed(seed) 227 rand.Read(b) 228 return b 229 } 230 231 func BenchmarkUpload(b *testing.B) { 232 client, err := New("http://localhost:6777", http.DefaultClient, nil) 233 if err != nil { 234 b.Fatal(err) 235 } 236 237 ctx := context.Background() 238 f, err := os.Open("random.txt") 239 if err != nil { 240 b.Fatal(err) 241 } 242 _, err = client.UploadWithContext(ctx, f, "random.txt", CompressNone) 243 if err != nil { 244 b.Fatal(err) 245 } 246 }