github.com/memikequinn/go-ethereum@v1.6.6-0.20170621145815-58a1e13e6dd7/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 "github.com/ethereum/go-ethereum/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 != file.ContentType { 93 t.Fatalf("expected downloaded file to have type %q, got %q", file.ContentType, 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 for _, prefix := range list.CommonPrefixes { 239 paths = append(paths, prefix) 240 } 241 for _, entry := range list.Entries { 242 paths = append(paths, entry.Path) 243 } 244 sort.Strings(paths) 245 return paths 246 } 247 248 tests := map[string][]string{ 249 "": []string{"dir1/", "dir2/", "file1.txt", "file2.txt"}, 250 "file": []string{"file1.txt", "file2.txt"}, 251 "file1": []string{"file1.txt"}, 252 "file2.txt": []string{"file2.txt"}, 253 "file12": []string{}, 254 "dir": []string{"dir1/", "dir2/"}, 255 "dir1": []string{"dir1/"}, 256 "dir1/": []string{"dir1/file3.txt", "dir1/file4.txt"}, 257 "dir1/file": []string{"dir1/file3.txt", "dir1/file4.txt"}, 258 "dir1/file3.txt": []string{"dir1/file3.txt"}, 259 "dir1/file34": []string{}, 260 "dir2/": []string{"dir2/dir3/", "dir2/dir4/", "dir2/file5.txt"}, 261 "dir2/file": []string{"dir2/file5.txt"}, 262 "dir2/dir": []string{"dir2/dir3/", "dir2/dir4/"}, 263 "dir2/dir3/": []string{"dir2/dir3/file6.txt"}, 264 "dir2/dir4/": []string{"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 265 "dir2/dir4/file": []string{"dir2/dir4/file7.txt", "dir2/dir4/file8.txt"}, 266 "dir2/dir4/file7.txt": []string{"dir2/dir4/file7.txt"}, 267 "dir2/dir4/file78": []string{}, 268 } 269 for prefix, expected := range tests { 270 actual := ls(prefix) 271 if !reflect.DeepEqual(actual, expected) { 272 t.Fatalf("expected prefix %q to return %v, got %v", prefix, expected, actual) 273 } 274 } 275 } 276 277 // TestClientMultipartUpload tests uploading files to swarm using a multipart 278 // upload 279 func TestClientMultipartUpload(t *testing.T) { 280 srv := testutil.NewTestSwarmServer(t) 281 defer srv.Close() 282 283 // define an uploader which uploads testDirFiles with some data 284 data := []byte("some-data") 285 uploader := UploaderFunc(func(upload UploadFn) error { 286 for _, name := range testDirFiles { 287 file := &File{ 288 ReadCloser: ioutil.NopCloser(bytes.NewReader(data)), 289 ManifestEntry: api.ManifestEntry{ 290 Path: name, 291 ContentType: "text/plain", 292 Size: int64(len(data)), 293 }, 294 } 295 if err := upload(file); err != nil { 296 return err 297 } 298 } 299 return nil 300 }) 301 302 // upload the files as a multipart upload 303 client := NewClient(srv.URL) 304 hash, err := client.MultipartUpload("", uploader) 305 if err != nil { 306 t.Fatal(err) 307 } 308 309 // check we can download the individual files 310 checkDownloadFile := func(path string) { 311 file, err := client.Download(hash, path) 312 if err != nil { 313 t.Fatal(err) 314 } 315 defer file.Close() 316 gotData, err := ioutil.ReadAll(file) 317 if err != nil { 318 t.Fatal(err) 319 } 320 if !bytes.Equal(gotData, data) { 321 t.Fatalf("expected data to be %q, got %q", data, gotData) 322 } 323 } 324 for _, file := range testDirFiles { 325 checkDownloadFile(file) 326 } 327 }