github.com/badrootd/celestia-core@v0.0.0-20240305091328-aa4207a4b25d/light/provider/http/http_test.go (about)

     1  package http_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/badrootd/celestia-core/abci/example/kvstore"
    14  	"github.com/badrootd/celestia-core/light/provider"
    15  	lighthttp "github.com/badrootd/celestia-core/light/provider/http"
    16  	rpcclient "github.com/badrootd/celestia-core/rpc/client"
    17  	rpchttp "github.com/badrootd/celestia-core/rpc/client/http"
    18  	ctypes "github.com/badrootd/celestia-core/rpc/core/types"
    19  	rpctest "github.com/badrootd/celestia-core/rpc/test"
    20  	"github.com/badrootd/celestia-core/types"
    21  )
    22  
    23  func TestNewProvider(t *testing.T) {
    24  	c, err := lighthttp.New("chain-test", "192.168.0.1:26657")
    25  	require.NoError(t, err)
    26  	require.Equal(t, fmt.Sprintf("%s", c), "http{http://192.168.0.1:26657}")
    27  
    28  	c, err = lighthttp.New("chain-test", "http://153.200.0.1:26657")
    29  	require.NoError(t, err)
    30  	require.Equal(t, fmt.Sprintf("%s", c), "http{http://153.200.0.1:26657}")
    31  
    32  	c, err = lighthttp.New("chain-test", "153.200.0.1")
    33  	require.NoError(t, err)
    34  	require.Equal(t, fmt.Sprintf("%s", c), "http{http://153.200.0.1}")
    35  }
    36  
    37  func TestProvider(t *testing.T) {
    38  	app := kvstore.NewApplication()
    39  	app.RetainBlocks = 10
    40  	node := rpctest.StartTendermint(app)
    41  
    42  	cfg := rpctest.GetConfig()
    43  	defer os.RemoveAll(cfg.RootDir)
    44  	rpcAddr := cfg.RPC.ListenAddress
    45  	genDoc, err := types.GenesisDocFromFile(cfg.GenesisFile())
    46  	require.NoError(t, err)
    47  	chainID := genDoc.ChainID
    48  
    49  	c, err := rpchttp.New(rpcAddr, "/websocket")
    50  	require.NoError(t, err)
    51  
    52  	p := lighthttp.NewWithClient(chainID, c)
    53  	require.NotNil(t, p)
    54  
    55  	// let it produce some blocks
    56  	err = rpcclient.WaitForHeight(c, 10, nil)
    57  	require.NoError(t, err)
    58  
    59  	// let's get the highest block
    60  	lb, err := p.LightBlock(context.Background(), 0)
    61  	require.NoError(t, err)
    62  	require.NotNil(t, lb)
    63  	assert.True(t, lb.Height < 1000)
    64  
    65  	// let's check this is valid somehow
    66  	assert.Nil(t, lb.ValidateBasic(chainID))
    67  
    68  	// historical queries now work :)
    69  	lower := lb.Height - 3
    70  	lb, err = p.LightBlock(context.Background(), lower)
    71  	require.NoError(t, err)
    72  	assert.Equal(t, lower, lb.Height)
    73  
    74  	// fetching missing heights (both future and pruned) should return appropriate errors
    75  	lb, err = p.LightBlock(context.Background(), 1000)
    76  	require.Error(t, err)
    77  	require.Nil(t, lb)
    78  	assert.Equal(t, provider.ErrHeightTooHigh, err)
    79  
    80  	_, err = p.LightBlock(context.Background(), 1)
    81  	require.Error(t, err)
    82  	require.Nil(t, lb)
    83  	assert.Equal(t, provider.ErrLightBlockNotFound, err)
    84  
    85  	// fetching with the context cancelled
    86  	ctx, cancel := context.WithCancel(context.Background())
    87  	cancel()
    88  	_, err = p.LightBlock(ctx, lower+3)
    89  	require.Error(t, err)
    90  	require.Equal(t, context.Canceled, err)
    91  
    92  	// fetching with the deadline exceeded (a mock RPC client is used to simulate this)
    93  	c2, err := newMockHTTP(rpcAddr)
    94  	require.NoError(t, err)
    95  	p2 := lighthttp.NewWithClient(chainID, c2)
    96  	_, err = p2.LightBlock(context.Background(), 0)
    97  	require.Error(t, err)
    98  	require.Equal(t, context.DeadlineExceeded, err)
    99  
   100  	// stop the full node and check that a no response error is returned
   101  	rpctest.StopTendermint(node)
   102  	time.Sleep(10 * time.Second)
   103  	lb, err = p.LightBlock(context.Background(), lower+2)
   104  	// we should see a connection refused
   105  	require.Error(t, err)
   106  	require.Contains(t, err.Error(), "connection refused")
   107  	require.Nil(t, lb)
   108  }
   109  
   110  type mockHTTP struct {
   111  	*rpchttp.HTTP
   112  }
   113  
   114  func newMockHTTP(remote string) (*mockHTTP, error) {
   115  	c, err := rpchttp.New(remote, "/websocket")
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	return &mockHTTP{c}, nil
   120  }
   121  
   122  func (m *mockHTTP) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
   123  	return nil, fmt.Errorf("post failed: %w", context.DeadlineExceeded)
   124  }