github.com/alexdevranger/node-1.8.27@v0.0.0-20221128213301-aa5841e41d2d/cmd/swarm/global-store/global_store_test.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of go-dubxcoin.
     3  //
     4  // go-dubxcoin 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  	"context"
    21  	"io/ioutil"
    22  	"net"
    23  	"net/http"
    24  	"os"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/alexdevranger/node-1.8.27/common"
    29  	"github.com/alexdevranger/node-1.8.27/rpc"
    30  	mockRPC "github.com/alexdevranger/node-1.8.27/swarm/storage/mock/rpc"
    31  )
    32  
    33  // TestHTTP_InMemory tests in-memory global store that exposes
    34  // HTTP server.
    35  func TestHTTP_InMemory(t *testing.T) {
    36  	testHTTP(t, true)
    37  }
    38  
    39  // TestHTTP_Database tests global store with persisted database
    40  // that exposes HTTP server.
    41  func TestHTTP_Database(t *testing.T) {
    42  	dir, err := ioutil.TempDir("", "swarm-global-store-")
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	defer os.RemoveAll(dir)
    47  
    48  	// create a fresh global store
    49  	testHTTP(t, true, "--dir", dir)
    50  
    51  	// check if data saved by the previous global store instance
    52  	testHTTP(t, false, "--dir", dir)
    53  }
    54  
    55  // testWebsocket starts global store binary with HTTP server
    56  // and validates that it can store and retrieve data.
    57  // If put is false, no data will be stored, only retrieved,
    58  // giving the possibility to check if data is present in the
    59  // storage directory.
    60  func testHTTP(t *testing.T, put bool, args ...string) {
    61  	addr := findFreeTCPAddress(t)
    62  	testCmd := runGlobalStore(t, append([]string{"http", "--addr", addr}, args...)...)
    63  	defer testCmd.Interrupt()
    64  
    65  	client, err := rpc.DialHTTP("http://" + addr)
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  
    70  	// wait until global store process is started as
    71  	// rpc.DialHTTP is actually not connecting
    72  	for i := 0; i < 1000; i++ {
    73  		_, err = http.DefaultClient.Get("http://" + addr)
    74  		if err == nil {
    75  			break
    76  		}
    77  		time.Sleep(10 * time.Millisecond)
    78  	}
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  
    83  	store := mockRPC.NewGlobalStore(client)
    84  	defer store.Close()
    85  
    86  	node := store.NewNodeStore(common.HexToAddress("123abc"))
    87  
    88  	wantKey := "key"
    89  	wantValue := "value"
    90  
    91  	if put {
    92  		err = node.Put([]byte(wantKey), []byte(wantValue))
    93  		if err != nil {
    94  			t.Fatal(err)
    95  		}
    96  	}
    97  
    98  	gotValue, err := node.Get([]byte(wantKey))
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	if string(gotValue) != wantValue {
   104  		t.Errorf("got value %s for key %s, want %s", string(gotValue), wantKey, wantValue)
   105  	}
   106  }
   107  
   108  // TestWebsocket_InMemory tests in-memory global store that exposes
   109  // WebSocket server.
   110  func TestWebsocket_InMemory(t *testing.T) {
   111  	testWebsocket(t, true)
   112  }
   113  
   114  // TestWebsocket_Database tests global store with persisted database
   115  // that exposes HTTP server.
   116  func TestWebsocket_Database(t *testing.T) {
   117  	dir, err := ioutil.TempDir("", "swarm-global-store-")
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  	defer os.RemoveAll(dir)
   122  
   123  	// create a fresh global store
   124  	testWebsocket(t, true, "--dir", dir)
   125  
   126  	// check if data saved by the previous global store instance
   127  	testWebsocket(t, false, "--dir", dir)
   128  }
   129  
   130  // testWebsocket starts global store binary with WebSocket server
   131  // and validates that it can store and retrieve data.
   132  // If put is false, no data will be stored, only retrieved,
   133  // giving the possibility to check if data is present in the
   134  // storage directory.
   135  func testWebsocket(t *testing.T, put bool, args ...string) {
   136  	addr := findFreeTCPAddress(t)
   137  	testCmd := runGlobalStore(t, append([]string{"ws", "--addr", addr}, args...)...)
   138  	defer testCmd.Interrupt()
   139  
   140  	var client *rpc.Client
   141  	var err error
   142  	// wait until global store process is started
   143  	for i := 0; i < 1000; i++ {
   144  		client, err = rpc.DialWebsocket(context.Background(), "ws://"+addr, "")
   145  		if err == nil {
   146  			break
   147  		}
   148  		time.Sleep(10 * time.Millisecond)
   149  	}
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  
   154  	store := mockRPC.NewGlobalStore(client)
   155  	defer store.Close()
   156  
   157  	node := store.NewNodeStore(common.HexToAddress("123abc"))
   158  
   159  	wantKey := "key"
   160  	wantValue := "value"
   161  
   162  	if put {
   163  		err = node.Put([]byte(wantKey), []byte(wantValue))
   164  		if err != nil {
   165  			t.Fatal(err)
   166  		}
   167  	}
   168  
   169  	gotValue, err := node.Get([]byte(wantKey))
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	if string(gotValue) != wantValue {
   175  		t.Errorf("got value %s for key %s, want %s", string(gotValue), wantKey, wantValue)
   176  	}
   177  }
   178  
   179  // findFreeTCPAddress returns a local address (IP:Port) to which
   180  // global store can listen on.
   181  func findFreeTCPAddress(t *testing.T) (addr string) {
   182  	t.Helper()
   183  
   184  	listener, err := net.Listen("tcp", "")
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  	defer listener.Close()
   189  
   190  	return listener.Addr().String()
   191  }