github.com/gobitfly/go-ethereum@v1.8.12/swarm/api/client/client_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum 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/ethereum/go-ethereum/swarm/api" 29 swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http" 30 "github.com/ethereum/go-ethereum/swarm/testutil" 31 ) 32 33 func serverFunc(api *api.API) testutil.TestServer { 34 return swarmhttp.NewServer(api) 35 } 36 37 // TestClientUploadDownloadRaw test uploading and downloading raw data to swarm 38 func TestClientUploadDownloadRaw(t *testing.T) { 39 testClientUploadDownloadRaw(false, t) 40 } 41 func TestClientUploadDownloadRawEncrypted(t *testing.T) { 42 testClientUploadDownloadRaw(true, t) 43 } 44 45 func testClientUploadDownloadRaw(toEncrypt bool, t *testing.T) { 46 srv := testutil.NewTestSwarmServer(t, serverFunc) 47 defer srv.Close() 48 49 client := NewClient(srv.URL) 50 51 // upload some raw data 52 data := []byte("foo123") 53 hash, err := client.UploadRaw(bytes.NewReader(data), int64(len(data)), toEncrypt) 54 if err != nil { 55 t.Fatal(err) 56 } 57 58 // check we can download the same data 59 res, isEncrypted, err := client.DownloadRaw(hash) 60 if err != nil { 61 t.Fatal(err) 62 } 63 if isEncrypted != toEncrypt { 64 t.Fatalf("Expected encyption status %v got %v", toEncrypt, isEncrypted) 65 } 66 defer res.Close() 67 gotData, err := ioutil.ReadAll(res) 68 if err != nil { 69 t.Fatal(err) 70 } 71 if !bytes.Equal(gotData, data) { 72 t.Fatalf("expected downloaded data to be %q, got %q", data, gotData) 73 } 74 } 75 76 // TestClientUploadDownloadFiles test uploading and downloading files to swarm 77 // manifests 78 func TestClientUploadDownloadFiles(t *testing.T) { 79 testClientUploadDownloadFiles(false, t) 80 } 81 82 func TestClientUploadDownloadFilesEncrypted(t *testing.T) { 83 testClientUploadDownloadFiles(true, t) 84 } 85 86 func testClientUploadDownloadFiles(toEncrypt bool, t *testing.T) { 87 srv := testutil.NewTestSwarmServer(t, serverFunc) 88 defer srv.Close() 89 90 client := NewClient(srv.URL) 91 upload := func(manifest, path string, data []byte) string { 92 file := &File{ 93 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 94 ManifestEntry: api.ManifestEntry{ 95 Path: path, 96 ContentType: "text/plain", 97 Size: int64(len(data)), 98 }, 99 } 100 hash, err := client.Upload(file, manifest, toEncrypt) 101 if err != nil { 102 t.Fatal(err) 103 } 104 return hash 105 } 106 checkDownload := func(manifest, path string, expected []byte) { 107 file, err := client.Download(manifest, path) 108 if err != nil { 109 t.Fatal(err) 110 } 111 defer file.Close() 112 if file.Size != int64(len(expected)) { 113 t.Fatalf("expected downloaded file to be %d bytes, got %d", len(expected), file.Size) 114 } 115 if file.ContentType != "text/plain" { 116 t.Fatalf("expected downloaded file to have type %q, got %q", "text/plain", file.ContentType) 117 } 118 data, err := ioutil.ReadAll(file) 119 if err != nil { 120 t.Fatal(err) 121 } 122 if !bytes.Equal(data, expected) { 123 t.Fatalf("expected downloaded data to be %q, got %q", expected, data) 124 } 125 } 126 127 // upload a file to the root of a manifest 128 rootData := []byte("some-data") 129 rootHash := upload("", "", rootData) 130 131 // check we can download the root file 132 checkDownload(rootHash, "", rootData) 133 134 // upload another file to the same manifest 135 otherData := []byte("some-other-data") 136 newHash := upload(rootHash, "some/other/path", otherData) 137 138 // check we can download both files from the new manifest 139 checkDownload(newHash, "", rootData) 140 checkDownload(newHash, "some/other/path", otherData) 141 142 // replace the root file with different data 143 newHash = upload(newHash, "", otherData) 144 145 // check both files have the other data 146 checkDownload(newHash, "", otherData) 147 checkDownload(newHash, "some/other/path", otherData) 148 } 149 150 var testDirFiles = []string{ 151 "file1.txt", 152 "file2.txt", 153 "dir1/file3.txt", 154 "dir1/file4.txt", 155 "dir2/file5.txt", 156 "dir2/dir3/file6.txt", 157 "dir2/dir4/file7.txt", 158 "dir2/dir4/file8.txt", 159 } 160 161 func newTestDirectory(t *testing.T) string { 162 dir, err := ioutil.TempDir("", "swarm-client-test") 163 if err != nil { 164 t.Fatal(err) 165 } 166 167 for _, file := range testDirFiles { 168 path := filepath.Join(dir, file) 169 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 170 os.RemoveAll(dir) 171 t.Fatalf("error creating dir for %s: %s", path, err) 172 } 173 if err := ioutil.WriteFile(path, []byte(file), 0644); err != nil { 174 os.RemoveAll(dir) 175 t.Fatalf("error writing file %s: %s", path, err) 176 } 177 } 178 179 return dir 180 } 181 182 // TestClientUploadDownloadDirectory tests uploading and downloading a 183 // directory of files to a swarm manifest 184 func TestClientUploadDownloadDirectory(t *testing.T) { 185 srv := testutil.NewTestSwarmServer(t, serverFunc) 186 defer srv.Close() 187 188 dir := newTestDirectory(t) 189 defer os.RemoveAll(dir) 190 191 // upload the directory 192 client := NewClient(srv.URL) 193 defaultPath := filepath.Join(dir, testDirFiles[0]) 194 hash, err := client.UploadDirectory(dir, defaultPath, "", false) 195 if err != nil { 196 t.Fatalf("error uploading directory: %s", err) 197 } 198 199 // check we can download the individual files 200 checkDownloadFile := func(path string, expected []byte) { 201 file, err := client.Download(hash, path) 202 if err != nil { 203 t.Fatal(err) 204 } 205 defer file.Close() 206 data, err := ioutil.ReadAll(file) 207 if err != nil { 208 t.Fatal(err) 209 } 210 if !bytes.Equal(data, expected) { 211 t.Fatalf("expected data to be %q, got %q", expected, data) 212 } 213 } 214 for _, file := range testDirFiles { 215 checkDownloadFile(file, []byte(file)) 216 } 217 218 // check we can download the default path 219 checkDownloadFile("", []byte(testDirFiles[0])) 220 221 // check we can download the directory 222 tmp, err := ioutil.TempDir("", "swarm-client-test") 223 if err != nil { 224 t.Fatal(err) 225 } 226 defer os.RemoveAll(tmp) 227 if err := client.DownloadDirectory(hash, "", tmp); err != nil { 228 t.Fatal(err) 229 } 230 for _, file := range testDirFiles { 231 data, err := ioutil.ReadFile(filepath.Join(tmp, file)) 232 if err != nil { 233 t.Fatal(err) 234 } 235 if !bytes.Equal(data, []byte(file)) { 236 t.Fatalf("expected data to be %q, got %q", file, data) 237 } 238 } 239 } 240 241 // TestClientFileList tests listing files in a swarm manifest 242 func TestClientFileList(t *testing.T) { 243 testClientFileList(false, t) 244 } 245 246 func TestClientFileListEncrypted(t *testing.T) { 247 testClientFileList(true, t) 248 } 249 250 func testClientFileList(toEncrypt bool, t *testing.T) { 251 srv := testutil.NewTestSwarmServer(t, serverFunc) 252 defer srv.Close() 253 254 dir := newTestDirectory(t) 255 defer os.RemoveAll(dir) 256 257 client := NewClient(srv.URL) 258 hash, err := client.UploadDirectory(dir, "", "", toEncrypt) 259 if err != nil { 260 t.Fatalf("error uploading directory: %s", err) 261 } 262 263 ls := func(prefix string) []string { 264 list, err := client.List(hash, prefix) 265 if err != nil { 266 t.Fatal(err) 267 } 268 paths := make([]string, 0, len(list.CommonPrefixes)+len(list.Entries)) 269 paths = append(paths, list.CommonPrefixes...) 270 for _, entry := range list.Entries { 271 paths = append(paths, entry.Path) 272 } 273 sort.Strings(paths) 274 return paths 275 } 276 277 tests := map[string][]string{ 278 "": {"dir1/", "dir2/", "file1.txt", "file2.txt"}, 279 "file": {"file1.txt", "file2.txt"}, 280 "file1": {"file1.txt"}, 281 "file2.txt": {"file2.txt"}, 282 "file12": {}, 283 "dir": {"dir1/", "dir2/"}, 284 "dir1": {"dir1/"}, 285 "dir1/": {"dir1/file3.txt", "dir1/file4.txt"}, 286 "dir1/file": {"dir1/file3.txt", "dir1/file4.txt"}, 287 "dir1/file3.txt": {"dir1/file3.txt"}, 288 "dir1/file34": {}, 289 "dir2/": {"dir2/dir3/", "dir2/dir4/", "dir2/file5.txt"}, 290 "dir2/file": {"dir2/file5.txt"}, 291 "dir2/dir": {"dir2/dir3/", "dir2/dir4/"}, 292 "dir2/dir3/": {"dir2/dir3/file6.txt"}, 293 "dir2/dir4/": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 294 "dir2/dir4/file": {"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 295 "dir2/dir4/file7.txt": {"dir2/dir4/file7.txt"}, 296 "dir2/dir4/file78": {}, 297 } 298 for prefix, expected := range tests { 299 actual := ls(prefix) 300 if !reflect.DeepEqual(actual, expected) { 301 t.Fatalf("expected prefix %q to return %v, got %v", prefix, expected, actual) 302 } 303 } 304 } 305 306 // TestClientMultipartUpload tests uploading files to swarm using a multipart 307 // upload 308 func TestClientMultipartUpload(t *testing.T) { 309 srv := testutil.NewTestSwarmServer(t, serverFunc) 310 defer srv.Close() 311 312 // define an uploader which uploads testDirFiles with some data 313 data := []byte("some-data") 314 uploader := UploaderFunc(func(upload UploadFn) error { 315 for _, name := range testDirFiles { 316 file := &File{ 317 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 318 ManifestEntry: api.ManifestEntry{ 319 Path: name, 320 ContentType: "text/plain", 321 Size: int64(len(data)), 322 }, 323 } 324 if err := upload(file); err != nil { 325 return err 326 } 327 } 328 return nil 329 }) 330 331 // upload the files as a multipart upload 332 client := NewClient(srv.URL) 333 hash, err := client.MultipartUpload("", uploader) 334 if err != nil { 335 t.Fatal(err) 336 } 337 338 // check we can download the individual files 339 checkDownloadFile := func(path string) { 340 file, err := client.Download(hash, path) 341 if err != nil { 342 t.Fatal(err) 343 } 344 defer file.Close() 345 gotData, err := ioutil.ReadAll(file) 346 if err != nil { 347 t.Fatal(err) 348 } 349 if !bytes.Equal(gotData, data) { 350 t.Fatalf("expected data to be %q, got %q", data, gotData) 351 } 352 } 353 for _, file := range testDirFiles { 354 checkDownloadFile(file) 355 } 356 }