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