github.com/codingfuture/orig-energi3@v0.8.4/cmd/swarm/global-store/global_store_test.go (about) 1 // Copyright 2019 The Energi Core Authors 2 // Copyright 2018 The go-ethereum Authors 3 // This file is part of Energi Core. 4 // 5 // Energi Core is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Energi Core is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Energi Core. If not, see <http://www.gnu.org/licenses/>. 17 18 package main 19 20 import ( 21 "context" 22 "io/ioutil" 23 "net" 24 "net/http" 25 "os" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/rpc" 31 mockRPC "github.com/ethereum/go-ethereum/swarm/storage/mock/rpc" 32 ) 33 34 // TestHTTP_InMemory tests in-memory global store that exposes 35 // HTTP server. 36 func TestHTTP_InMemory(t *testing.T) { 37 testHTTP(t, true) 38 } 39 40 // TestHTTP_Database tests global store with persisted database 41 // that exposes HTTP server. 42 func TestHTTP_Database(t *testing.T) { 43 dir, err := ioutil.TempDir("", "swarm-global-store-") 44 if err != nil { 45 t.Fatal(err) 46 } 47 defer os.RemoveAll(dir) 48 49 // create a fresh global store 50 testHTTP(t, true, "--dir", dir) 51 52 // check if data saved by the previous global store instance 53 testHTTP(t, false, "--dir", dir) 54 } 55 56 // testWebsocket starts global store binary with HTTP server 57 // and validates that it can store and retrieve data. 58 // If put is false, no data will be stored, only retrieved, 59 // giving the possibility to check if data is present in the 60 // storage directory. 61 func testHTTP(t *testing.T, put bool, args ...string) { 62 addr := findFreeTCPAddress(t) 63 testCmd := runGlobalStore(t, append([]string{"http", "--addr", addr}, args...)...) 64 defer testCmd.Interrupt() 65 66 client, err := rpc.DialHTTP("http://" + addr) 67 if err != nil { 68 t.Fatal(err) 69 } 70 71 // wait until global store process is started as 72 // rpc.DialHTTP is actually not connecting 73 for i := 0; i < 1000; i++ { 74 _, err = http.DefaultClient.Get("http://" + addr) 75 if err == nil { 76 break 77 } 78 time.Sleep(10 * time.Millisecond) 79 } 80 if err != nil { 81 t.Fatal(err) 82 } 83 84 store := mockRPC.NewGlobalStore(client) 85 defer store.Close() 86 87 node := store.NewNodeStore(common.HexToAddress("123abc")) 88 89 wantKey := "key" 90 wantValue := "value" 91 92 if put { 93 err = node.Put([]byte(wantKey), []byte(wantValue)) 94 if err != nil { 95 t.Fatal(err) 96 } 97 } 98 99 gotValue, err := node.Get([]byte(wantKey)) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 if string(gotValue) != wantValue { 105 t.Errorf("got value %s for key %s, want %s", string(gotValue), wantKey, wantValue) 106 } 107 } 108 109 // TestWebsocket_InMemory tests in-memory global store that exposes 110 // WebSocket server. 111 func TestWebsocket_InMemory(t *testing.T) { 112 testWebsocket(t, true) 113 } 114 115 // TestWebsocket_Database tests global store with persisted database 116 // that exposes HTTP server. 117 func TestWebsocket_Database(t *testing.T) { 118 dir, err := ioutil.TempDir("", "swarm-global-store-") 119 if err != nil { 120 t.Fatal(err) 121 } 122 defer os.RemoveAll(dir) 123 124 // create a fresh global store 125 testWebsocket(t, true, "--dir", dir) 126 127 // check if data saved by the previous global store instance 128 testWebsocket(t, false, "--dir", dir) 129 } 130 131 // testWebsocket starts global store binary with WebSocket server 132 // and validates that it can store and retrieve data. 133 // If put is false, no data will be stored, only retrieved, 134 // giving the possibility to check if data is present in the 135 // storage directory. 136 func testWebsocket(t *testing.T, put bool, args ...string) { 137 addr := findFreeTCPAddress(t) 138 testCmd := runGlobalStore(t, append([]string{"ws", "--addr", addr}, args...)...) 139 defer testCmd.Interrupt() 140 141 var client *rpc.Client 142 var err error 143 // wait until global store process is started 144 for i := 0; i < 1000; i++ { 145 client, err = rpc.DialWebsocket(context.Background(), "ws://"+addr, "") 146 if err == nil { 147 break 148 } 149 time.Sleep(10 * time.Millisecond) 150 } 151 if err != nil { 152 t.Fatal(err) 153 } 154 155 store := mockRPC.NewGlobalStore(client) 156 defer store.Close() 157 158 node := store.NewNodeStore(common.HexToAddress("123abc")) 159 160 wantKey := "key" 161 wantValue := "value" 162 163 if put { 164 err = node.Put([]byte(wantKey), []byte(wantValue)) 165 if err != nil { 166 t.Fatal(err) 167 } 168 } 169 170 gotValue, err := node.Get([]byte(wantKey)) 171 if err != nil { 172 t.Fatal(err) 173 } 174 175 if string(gotValue) != wantValue { 176 t.Errorf("got value %s for key %s, want %s", string(gotValue), wantKey, wantValue) 177 } 178 } 179 180 // findFreeTCPAddress returns a local address (IP:Port) to which 181 // global store can listen on. 182 func findFreeTCPAddress(t *testing.T) (addr string) { 183 t.Helper() 184 185 listener, err := net.Listen("tcp", "") 186 if err != nil { 187 t.Fatal(err) 188 } 189 defer listener.Close() 190 191 return listener.Addr().String() 192 }