github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/cmd/swarm/upload_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU 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 // go-ethereum 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 General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 "io/ioutil" 24 "net/http" 25 "os" 26 "path" 27 "path/filepath" 28 "runtime" 29 "strings" 30 "testing" 31 "time" 32 33 "github.com/ethereum/go-ethereum/log" 34 swarmapi "github.com/ethereum/go-ethereum/swarm/api/client" 35 "github.com/ethereum/go-ethereum/swarm/testutil" 36 "github.com/mattn/go-colorable" 37 ) 38 39 func init() { 40 log.PrintOrigins(true) 41 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 42 } 43 44 func TestSwarmUp(t *testing.T) { 45 if runtime.GOOS == "windows" { 46 t.Skip() 47 } 48 49 cluster := newTestCluster(t, clusterSize) 50 defer cluster.Shutdown() 51 52 cases := []struct { 53 name string 54 f func(t *testing.T, cluster *testCluster) 55 }{ 56 {"NoEncryption", testNoEncryption}, 57 {"Encrypted", testEncrypted}, 58 {"RecursiveNoEncryption", testRecursiveNoEncryption}, 59 {"RecursiveEncrypted", testRecursiveEncrypted}, 60 {"DefaultPathAll", testDefaultPathAll}, 61 } 62 63 for _, tc := range cases { 64 t.Run(tc.name, func(t *testing.T) { 65 tc.f(t, cluster) 66 }) 67 } 68 } 69 70 // testNoEncryption tests that running 'swarm up' makes the resulting file 71 // available from all nodes via the HTTP API 72 func testNoEncryption(t *testing.T, cluster *testCluster) { 73 testDefault(t, cluster, false) 74 } 75 76 // testEncrypted tests that running 'swarm up --encrypted' makes the resulting file 77 // available from all nodes via the HTTP API 78 func testEncrypted(t *testing.T, cluster *testCluster) { 79 testDefault(t, cluster, true) 80 } 81 82 func testRecursiveNoEncryption(t *testing.T, cluster *testCluster) { 83 testRecursive(t, cluster, false) 84 } 85 86 func testRecursiveEncrypted(t *testing.T, cluster *testCluster) { 87 testRecursive(t, cluster, true) 88 } 89 90 func testDefault(t *testing.T, cluster *testCluster, toEncrypt bool) { 91 tmpFileName := testutil.TempFileWithContent(t, data) 92 defer os.Remove(tmpFileName) 93 94 // write data to file 95 hashRegexp := `[a-f\d]{64}` 96 flags := []string{ 97 "--bzzapi", cluster.Nodes[0].URL, 98 "up", 99 tmpFileName} 100 if toEncrypt { 101 hashRegexp = `[a-f\d]{128}` 102 flags = []string{ 103 "--bzzapi", cluster.Nodes[0].URL, 104 "up", 105 "--encrypt", 106 tmpFileName} 107 } 108 // upload the file with 'swarm up' and expect a hash 109 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 110 up := runSwarm(t, flags...) 111 _, matches := up.ExpectRegexp(hashRegexp) 112 up.ExpectExit() 113 hash := matches[0] 114 log.Info("file uploaded", "hash", hash) 115 116 // get the file from the HTTP API of each node 117 for _, node := range cluster.Nodes { 118 log.Info("getting file from node", "node", node.Name) 119 120 res, err := http.Get(node.URL + "/bzz:/" + hash) 121 if err != nil { 122 t.Fatal(err) 123 } 124 defer res.Body.Close() 125 126 reply, err := ioutil.ReadAll(res.Body) 127 if err != nil { 128 t.Fatal(err) 129 } 130 if res.StatusCode != 200 { 131 t.Fatalf("expected HTTP status 200, got %s", res.Status) 132 } 133 if string(reply) != data { 134 t.Fatalf("expected HTTP body %q, got %q", data, reply) 135 } 136 log.Debug("verifying uploaded file using `swarm down`") 137 //try to get the content with `swarm down` 138 tmpDownload, err := ioutil.TempDir("", "swarm-test") 139 tmpDownload = path.Join(tmpDownload, "tmpfile.tmp") 140 if err != nil { 141 t.Fatal(err) 142 } 143 defer os.RemoveAll(tmpDownload) 144 145 bzzLocator := "bzz:/" + hash 146 flags = []string{ 147 "--bzzapi", cluster.Nodes[0].URL, 148 "down", 149 bzzLocator, 150 tmpDownload, 151 } 152 153 down := runSwarm(t, flags...) 154 down.ExpectExit() 155 156 fi, err := os.Stat(tmpDownload) 157 if err != nil { 158 t.Fatalf("could not stat path: %v", err) 159 } 160 161 switch mode := fi.Mode(); { 162 case mode.IsRegular(): 163 downloadedBytes, err := ioutil.ReadFile(tmpDownload) 164 if err != nil { 165 t.Fatalf("had an error reading the downloaded file: %v", err) 166 } 167 if !bytes.Equal(downloadedBytes, bytes.NewBufferString(data).Bytes()) { 168 t.Fatalf("retrieved data and posted data not equal!") 169 } 170 171 default: 172 t.Fatalf("expected to download regular file, got %s", fi.Mode()) 173 } 174 } 175 176 timeout := time.Duration(2 * time.Second) 177 httpClient := http.Client{ 178 Timeout: timeout, 179 } 180 181 // try to squeeze a timeout by getting an non-existent hash from each node 182 for _, node := range cluster.Nodes { 183 _, err := httpClient.Get(node.URL + "/bzz:/1023e8bae0f70be7d7b5f74343088ba408a218254391490c85ae16278e230340") 184 // we're speeding up the timeout here since netstore has a 60 seconds timeout on a request 185 if err != nil && !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") { 186 t.Fatal(err) 187 } 188 // this is disabled since it takes 60s due to netstore timeout 189 // if res.StatusCode != 404 { 190 // t.Fatalf("expected HTTP status 404, got %s", res.Status) 191 // } 192 } 193 } 194 195 func testRecursive(t *testing.T, cluster *testCluster, toEncrypt bool) { 196 tmpUploadDir, err := ioutil.TempDir("", "swarm-test") 197 if err != nil { 198 t.Fatal(err) 199 } 200 defer os.RemoveAll(tmpUploadDir) 201 // create tmp files 202 for _, path := range []string{"tmp1", "tmp2"} { 203 if err := ioutil.WriteFile(filepath.Join(tmpUploadDir, path), bytes.NewBufferString(data).Bytes(), 0644); err != nil { 204 t.Fatal(err) 205 } 206 } 207 208 hashRegexp := `[a-f\d]{64}` 209 flags := []string{ 210 "--bzzapi", cluster.Nodes[0].URL, 211 "--recursive", 212 "up", 213 tmpUploadDir} 214 if toEncrypt { 215 hashRegexp = `[a-f\d]{128}` 216 flags = []string{ 217 "--bzzapi", cluster.Nodes[0].URL, 218 "--recursive", 219 "up", 220 "--encrypt", 221 tmpUploadDir} 222 } 223 // upload the file with 'swarm up' and expect a hash 224 log.Info(fmt.Sprintf("uploading file with 'swarm up'")) 225 up := runSwarm(t, flags...) 226 _, matches := up.ExpectRegexp(hashRegexp) 227 up.ExpectExit() 228 hash := matches[0] 229 log.Info("dir uploaded", "hash", hash) 230 231 // get the file from the HTTP API of each node 232 for _, node := range cluster.Nodes { 233 log.Info("getting file from node", "node", node.Name) 234 //try to get the content with `swarm down` 235 tmpDownload, err := ioutil.TempDir("", "swarm-test") 236 if err != nil { 237 t.Fatal(err) 238 } 239 defer os.RemoveAll(tmpDownload) 240 bzzLocator := "bzz:/" + hash 241 flagss := []string{ 242 "--bzzapi", cluster.Nodes[0].URL, 243 "down", 244 "--recursive", 245 bzzLocator, 246 tmpDownload, 247 } 248 249 fmt.Println("downloading from swarm with recursive") 250 down := runSwarm(t, flagss...) 251 down.ExpectExit() 252 253 files, err := ioutil.ReadDir(tmpDownload) 254 for _, v := range files { 255 fi, err := os.Stat(path.Join(tmpDownload, v.Name())) 256 if err != nil { 257 t.Fatalf("got an error: %v", err) 258 } 259 260 switch mode := fi.Mode(); { 261 case mode.IsRegular(): 262 if file, err := swarmapi.Open(path.Join(tmpDownload, v.Name())); err != nil { 263 t.Fatalf("encountered an error opening the file returned from the CLI: %v", err) 264 } else { 265 ff := make([]byte, len(data)) 266 io.ReadFull(file, ff) 267 buf := bytes.NewBufferString(data) 268 269 if !bytes.Equal(ff, buf.Bytes()) { 270 t.Fatalf("retrieved data and posted data not equal!") 271 } 272 } 273 default: 274 t.Fatalf("this shouldnt happen") 275 } 276 } 277 if err != nil { 278 t.Fatalf("could not list files at: %v", files) 279 } 280 } 281 } 282 283 // testDefaultPathAll tests swarm recursive upload with relative and absolute 284 // default paths and with encryption. 285 func testDefaultPathAll(t *testing.T, cluster *testCluster) { 286 testDefaultPath(t, cluster, false, false) 287 testDefaultPath(t, cluster, false, true) 288 testDefaultPath(t, cluster, true, false) 289 testDefaultPath(t, cluster, true, true) 290 } 291 292 func testDefaultPath(t *testing.T, cluster *testCluster, toEncrypt bool, absDefaultPath bool) { 293 tmp, err := ioutil.TempDir("", "swarm-defaultpath-test") 294 if err != nil { 295 t.Fatal(err) 296 } 297 defer os.RemoveAll(tmp) 298 299 err = ioutil.WriteFile(filepath.Join(tmp, "index.html"), []byte("<h1>Test</h1>"), 0666) 300 if err != nil { 301 t.Fatal(err) 302 } 303 err = ioutil.WriteFile(filepath.Join(tmp, "robots.txt"), []byte("Disallow: /"), 0666) 304 if err != nil { 305 t.Fatal(err) 306 } 307 308 defaultPath := "index.html" 309 if absDefaultPath { 310 defaultPath = filepath.Join(tmp, defaultPath) 311 } 312 313 args := []string{ 314 "--bzzapi", 315 cluster.Nodes[0].URL, 316 "--recursive", 317 "--defaultpath", 318 defaultPath, 319 "up", 320 tmp, 321 } 322 if toEncrypt { 323 args = append(args, "--encrypt") 324 } 325 326 up := runSwarm(t, args...) 327 hashRegexp := `[a-f\d]{64,128}` 328 _, matches := up.ExpectRegexp(hashRegexp) 329 up.ExpectExit() 330 hash := matches[0] 331 332 client := swarmapi.NewClient(cluster.Nodes[0].URL) 333 334 m, isEncrypted, err := client.DownloadManifest(hash) 335 if err != nil { 336 t.Fatal(err) 337 } 338 339 if toEncrypt != isEncrypted { 340 t.Error("downloaded manifest is not encrypted") 341 } 342 343 var found bool 344 var entriesCount int 345 for _, e := range m.Entries { 346 entriesCount++ 347 if e.Path == "" { 348 found = true 349 } 350 } 351 352 if !found { 353 t.Error("manifest default entry was not found") 354 } 355 356 if entriesCount != 3 { 357 t.Errorf("manifest contains %v entries, expected %v", entriesCount, 3) 358 } 359 }