export_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2018 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. // +build !windows
  17. package main
  18. import (
  19. "bytes"
  20. "crypto/md5"
  21. "crypto/rand"
  22. "io"
  23. "io/ioutil"
  24. "net/http"
  25. "os"
  26. "strings"
  27. "testing"
  28. "github.com/ethereum/go-ethereum/swarm"
  29. )
  30. // TestCLISwarmExportImport perform the following test:
  31. // 1. runs swarm node
  32. // 2. uploads a random file
  33. // 3. runs an export of the local datastore
  34. // 4. runs a second swarm node
  35. // 5. imports the exported datastore
  36. // 6. fetches the uploaded random file from the second node
  37. func TestCLISwarmExportImport(t *testing.T) {
  38. cluster := newTestCluster(t, 1)
  39. // generate random 10mb file
  40. f, cleanup := generateRandomFile(t, 10000000)
  41. defer cleanup()
  42. // upload the file with 'swarm up' and expect a hash
  43. up := runSwarm(t, "--bzzapi", cluster.Nodes[0].URL, "up", f.Name())
  44. _, matches := up.ExpectRegexp(`[a-f\d]{64}`)
  45. up.ExpectExit()
  46. hash := matches[0]
  47. var info swarm.Info
  48. if err := cluster.Nodes[0].Client.Call(&info, "bzz_info"); err != nil {
  49. t.Fatal(err)
  50. }
  51. cluster.Stop()
  52. defer cluster.Cleanup()
  53. // generate an export.tar
  54. exportCmd := runSwarm(t, "db", "export", info.Path+"/chunks", info.Path+"/export.tar", strings.TrimPrefix(info.BzzKey, "0x"))
  55. exportCmd.ExpectExit()
  56. // start second cluster
  57. cluster2 := newTestCluster(t, 1)
  58. var info2 swarm.Info
  59. if err := cluster2.Nodes[0].Client.Call(&info2, "bzz_info"); err != nil {
  60. t.Fatal(err)
  61. }
  62. // stop second cluster, so that we close LevelDB
  63. cluster2.Stop()
  64. defer cluster2.Cleanup()
  65. // import the export.tar
  66. importCmd := runSwarm(t, "db", "import", info2.Path+"/chunks", info.Path+"/export.tar", strings.TrimPrefix(info2.BzzKey, "0x"))
  67. importCmd.ExpectExit()
  68. // spin second cluster back up
  69. cluster2.StartExistingNodes(t, 1, strings.TrimPrefix(info2.BzzAccount, "0x"))
  70. // try to fetch imported file
  71. res, err := http.Get(cluster2.Nodes[0].URL + "/bzz:/" + hash)
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. if res.StatusCode != 200 {
  76. t.Fatalf("expected HTTP status %d, got %s", 200, res.Status)
  77. }
  78. // compare downloaded file with the generated random file
  79. mustEqualFiles(t, f, res.Body)
  80. }
  81. func mustEqualFiles(t *testing.T, up io.Reader, down io.Reader) {
  82. h := md5.New()
  83. upLen, err := io.Copy(h, up)
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. upHash := h.Sum(nil)
  88. h.Reset()
  89. downLen, err := io.Copy(h, down)
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. downHash := h.Sum(nil)
  94. if !bytes.Equal(upHash, downHash) || upLen != downLen {
  95. t.Fatalf("downloaded imported file md5=%x (length %v) is not the same as the generated one mp5=%x (length %v)", downHash, downLen, upHash, upLen)
  96. }
  97. }
  98. func generateRandomFile(t *testing.T, size int) (f *os.File, teardown func()) {
  99. // create a tmp file
  100. tmp, err := ioutil.TempFile("", "swarm-test")
  101. if err != nil {
  102. t.Fatal(err)
  103. }
  104. // callback for tmp file cleanup
  105. teardown = func() {
  106. tmp.Close()
  107. os.Remove(tmp.Name())
  108. }
  109. // write 10mb random data to file
  110. buf := make([]byte, 10000000)
  111. _, err = rand.Read(buf)
  112. if err != nil {
  113. t.Fatal(err)
  114. }
  115. ioutil.WriteFile(tmp.Name(), buf, 0755)
  116. return tmp, teardown
  117. }