github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/swarm/api/client/client_test.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package client 13 14 import ( 15 "bytes" 16 "io/ioutil" 17 "os" 18 "path/filepath" 19 "reflect" 20 "sort" 21 "testing" 22 23 "github.com/Sberex/go-sberex/swarm/api" 24 "github.com/Sberex/go-sberex/swarm/testutil" 25 ) 26 27 // TestClientUploadDownloadRaw test uploading and downloading raw data to swarm 28 func TestClientUploadDownloadRaw(t *testing.T) { 29 srv := testutil.NewTestSwarmServer(t) 30 defer srv.Close() 31 32 client := NewClient(srv.URL) 33 34 // upload some raw data 35 data := []byte("foo123") 36 hash, err := client.UploadRaw(bytes.NewReader(data), int64(len(data))) 37 if err != nil { 38 t.Fatal(err) 39 } 40 41 // check we can download the same data 42 res, err := client.DownloadRaw(hash) 43 if err != nil { 44 t.Fatal(err) 45 } 46 defer res.Close() 47 gotData, err := ioutil.ReadAll(res) 48 if err != nil { 49 t.Fatal(err) 50 } 51 if !bytes.Equal(gotData, data) { 52 t.Fatalf("expected downloaded data to be %q, got %q", data, gotData) 53 } 54 } 55 56 // TestClientUploadDownloadFiles test uploading and downloading files to swarm 57 // manifests 58 func TestClientUploadDownloadFiles(t *testing.T) { 59 srv := testutil.NewTestSwarmServer(t) 60 defer srv.Close() 61 62 client := NewClient(srv.URL) 63 upload := func(manifest, path string, data []byte) string { 64 file := &File{ 65 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 66 ManifestEntry: api.ManifestEntry{ 67 Path: path, 68 ContentType: "text/plain", 69 Size: int64(len(data)), 70 }, 71 } 72 hash, err := client.Upload(file, manifest) 73 if err != nil { 74 t.Fatal(err) 75 } 76 return hash 77 } 78 checkDownload := func(manifest, path string, expected []byte) { 79 file, err := client.Download(manifest, path) 80 if err != nil { 81 t.Fatal(err) 82 } 83 defer file.Close() 84 if file.Size != int64(len(expected)) { 85 t.Fatalf("expected downloaded file to be %d bytes, got %d", len(expected), file.Size) 86 } 87 if file.ContentType != "text/plain" { 88 t.Fatalf("expected downloaded file to have type %q, got %q", "text/plain", file.ContentType) 89 } 90 data, err := ioutil.ReadAll(file) 91 if err != nil { 92 t.Fatal(err) 93 } 94 if !bytes.Equal(data, expected) { 95 t.Fatalf("expected downloaded data to be %q, got %q", expected, data) 96 } 97 } 98 99 // upload a file to the root of a manifest 100 rootData := []byte("some-data") 101 rootHash := upload("", "", rootData) 102 103 // check we can download the root file 104 checkDownload(rootHash, "", rootData) 105 106 // upload another file to the same manifest 107 otherData := []byte("some-other-data") 108 newHash := upload(rootHash, "some/other/path", otherData) 109 110 // check we can download both files from the new manifest 111 checkDownload(newHash, "", rootData) 112 checkDownload(newHash, "some/other/path", otherData) 113 114 // replace the root file with different data 115 newHash = upload(newHash, "", otherData) 116 117 // check both files have the other data 118 checkDownload(newHash, "", otherData) 119 checkDownload(newHash, "some/other/path", otherData) 120 } 121 122 var testDirFiles = []string{ 123 "file1.txt", 124 "file2.txt", 125 "dir1/file3.txt", 126 "dir1/file4.txt", 127 "dir2/file5.txt", 128 "dir2/dir3/file6.txt", 129 "dir2/dir4/file7.txt", 130 "dir2/dir4/file8.txt", 131 } 132 133 func newTestDirectory(t *testing.T) string { 134 dir, err := ioutil.TempDir("", "swarm-client-test") 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 for _, file := range testDirFiles { 140 path := filepath.Join(dir, file) 141 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 142 os.RemoveAll(dir) 143 t.Fatalf("error creating dir for %s: %s", path, err) 144 } 145 if err := ioutil.WriteFile(path, []byte(file), 0644); err != nil { 146 os.RemoveAll(dir) 147 t.Fatalf("error writing file %s: %s", path, err) 148 } 149 } 150 151 return dir 152 } 153 154 // TestClientUploadDownloadDirectory tests uploading and downloading a 155 // directory of files to a swarm manifest 156 func TestClientUploadDownloadDirectory(t *testing.T) { 157 srv := testutil.NewTestSwarmServer(t) 158 defer srv.Close() 159 160 dir := newTestDirectory(t) 161 defer os.RemoveAll(dir) 162 163 // upload the directory 164 client := NewClient(srv.URL) 165 defaultPath := filepath.Join(dir, testDirFiles[0]) 166 hash, err := client.UploadDirectory(dir, defaultPath, "") 167 if err != nil { 168 t.Fatalf("error uploading directory: %s", err) 169 } 170 171 // check we can download the individual files 172 checkDownloadFile := func(path string, expected []byte) { 173 file, err := client.Download(hash, path) 174 if err != nil { 175 t.Fatal(err) 176 } 177 defer file.Close() 178 data, err := ioutil.ReadAll(file) 179 if err != nil { 180 t.Fatal(err) 181 } 182 if !bytes.Equal(data, expected) { 183 t.Fatalf("expected data to be %q, got %q", expected, data) 184 } 185 } 186 for _, file := range testDirFiles { 187 checkDownloadFile(file, []byte(file)) 188 } 189 190 // check we can download the default path 191 checkDownloadFile("", []byte(testDirFiles[0])) 192 193 // check we can download the directory 194 tmp, err := ioutil.TempDir("", "swarm-client-test") 195 if err != nil { 196 t.Fatal(err) 197 } 198 defer os.RemoveAll(tmp) 199 if err := client.DownloadDirectory(hash, "", tmp); err != nil { 200 t.Fatal(err) 201 } 202 for _, file := range testDirFiles { 203 data, err := ioutil.ReadFile(filepath.Join(tmp, file)) 204 if err != nil { 205 t.Fatal(err) 206 } 207 if !bytes.Equal(data, []byte(file)) { 208 t.Fatalf("expected data to be %q, got %q", file, data) 209 } 210 } 211 } 212 213 // TestClientFileList tests listing files in a swarm manifest 214 func TestClientFileList(t *testing.T) { 215 srv := testutil.NewTestSwarmServer(t) 216 defer srv.Close() 217 218 dir := newTestDirectory(t) 219 defer os.RemoveAll(dir) 220 221 client := NewClient(srv.URL) 222 hash, err := client.UploadDirectory(dir, "", "") 223 if err != nil { 224 t.Fatalf("error uploading directory: %s", err) 225 } 226 227 ls := func(prefix string) []string { 228 list, err := client.List(hash, prefix) 229 if err != nil { 230 t.Fatal(err) 231 } 232 paths := make([]string, 0, len(list.CommonPrefixes)+len(list.Entries)) 233 paths = append(paths, list.CommonPrefixes...) 234 for _, entry := range list.Entries { 235 paths = append(paths, entry.Path) 236 } 237 sort.Strings(paths) 238 return paths 239 } 240 241 tests := map[string][]string{ 242 "": {"dir1/", "dir2/", "file1.txt", "file2.txt"}, 243 "file": {"file1.txt", "file2.txt"}, 244 "file1": {"file1.txt"}, 245 "file2.txt": {"file2.txt"}, 246 "file12": {}, 247 "dir": {"dir1/", "dir2/"}, 248 "dir1": {"dir1/"}, 249 "dir1/": {"dir1/file3.txt", "dir1/file4.txt"}, 250 "dir1/file": {"dir1/file3.txt", "dir1/file4.txt"}, 251 "dir1/file3.txt": {"dir1/file3.txt"}, 252 "dir1/file34": {}, 253 "dir2/": {"dir2/dir3/", "dir2/dir4/", "dir2/file5.txt"}, 254 "dir2/file": {"dir2/file5.txt"}, 255 "dir2/dir": {"dir2/dir3/", "dir2/dir4/"}, 256 "dir2/dir3/": {"dir2/dir3/file6.txt"}, 257 "dir2/dir4/": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 258 "dir2/dir4/file": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 259 "dir2/dir4/file7.txt": {"dir2/dir4/file7.txt"}, 260 "dir2/dir4/file78": {}, 261 } 262 for prefix, expected := range tests { 263 actual := ls(prefix) 264 if !reflect.DeepEqual(actual, expected) { 265 t.Fatalf("expected prefix %q to return %v, got %v", prefix, expected, actual) 266 } 267 } 268 } 269 270 // TestClientMultipartUpload tests uploading files to swarm using a multipart 271 // upload 272 func TestClientMultipartUpload(t *testing.T) { 273 srv := testutil.NewTestSwarmServer(t) 274 defer srv.Close() 275 276 // define an uploader which uploads testDirFiles with some data 277 data := []byte("some-data") 278 uploader := UploaderFunc(func(upload UploadFn) error { 279 for _, name := range testDirFiles { 280 file := &File{ 281 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 282 ManifestEntry: api.ManifestEntry{ 283 Path: name, 284 ContentType: "text/plain", 285 Size: int64(len(data)), 286 }, 287 } 288 if err := upload(file); err != nil { 289 return err 290 } 291 } 292 return nil 293 }) 294 295 // upload the files as a multipart upload 296 client := NewClient(srv.URL) 297 hash, err := client.MultipartUpload("", uploader) 298 if err != nil { 299 t.Fatal(err) 300 } 301 302 // check we can download the individual files 303 checkDownloadFile := func(path string) { 304 file, err := client.Download(hash, path) 305 if err != nil { 306 t.Fatal(err) 307 } 308 defer file.Close() 309 gotData, err := ioutil.ReadAll(file) 310 if err != nil { 311 t.Fatal(err) 312 } 313 if !bytes.Equal(gotData, data) { 314 t.Fatalf("expected data to be %q, got %q", data, gotData) 315 } 316 } 317 for _, file := range testDirFiles { 318 checkDownloadFile(file) 319 } 320 }