github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/beacon/light/request/server_test.go (about)

     1  package request
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/ethereum/go-ethereum/common/mclock"
     7  )
     8  
     9  const (
    10  	testRequest  = "Life, the Universe, and Everything"
    11  	testResponse = 42
    12  )
    13  
    14  var testEventType = &EventType{Name: "testEvent"}
    15  
    16  func TestServerEvents(t *testing.T) {
    17  	rs := &testRequestServer{}
    18  	clock := &mclock.Simulated{}
    19  	srv := NewServer(rs, clock)
    20  	var lastEventType *EventType
    21  	srv.subscribe(func(event Event) { lastEventType = event.Type })
    22  	evTypeName := func(evType *EventType) string {
    23  		if evType == nil {
    24  			return "none"
    25  		}
    26  		return evType.Name
    27  	}
    28  	expEvent := func(expType *EventType) {
    29  		if lastEventType != expType {
    30  			t.Errorf("Wrong event type (expected %s, got %s)", evTypeName(expType), evTypeName(lastEventType))
    31  		}
    32  		lastEventType = nil
    33  	}
    34  	// user events should simply be passed through
    35  	rs.eventCb(Event{Type: testEventType})
    36  	expEvent(testEventType)
    37  	// send request, soft timeout, then valid response
    38  	srv.sendRequest(testRequest)
    39  	clock.WaitForTimers(1)
    40  	clock.Run(softRequestTimeout)
    41  	expEvent(EvTimeout)
    42  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
    43  	expEvent(EvResponse)
    44  	// send request, hard timeout (response after hard timeout should be ignored)
    45  	srv.sendRequest(testRequest)
    46  	clock.WaitForTimers(1)
    47  	clock.Run(softRequestTimeout)
    48  	expEvent(EvTimeout)
    49  	clock.WaitForTimers(1)
    50  	clock.Run(hardRequestTimeout)
    51  	expEvent(EvFail)
    52  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
    53  	expEvent(nil)
    54  }
    55  
    56  func TestServerParallel(t *testing.T) {
    57  	rs := &testRequestServer{}
    58  	srv := NewServer(rs, &mclock.Simulated{})
    59  	srv.subscribe(func(event Event) {})
    60  
    61  	expSend := func(expSent int) {
    62  		var sent int
    63  		for sent <= expSent {
    64  			if !srv.canRequestNow() {
    65  				break
    66  			}
    67  			sent++
    68  			srv.sendRequest(testRequest)
    69  		}
    70  		if sent != expSent {
    71  			t.Errorf("Wrong number of parallel requests accepted (expected %d, got %d)", expSent, sent)
    72  		}
    73  	}
    74  	// max out parallel allowance
    75  	expSend(defaultParallelLimit)
    76  	// 1 answered, should accept 1 more
    77  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
    78  	expSend(1)
    79  	// 2 answered, should accept 2 more
    80  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 2, Request: testRequest, Response: testResponse}})
    81  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 3, Request: testRequest, Response: testResponse}})
    82  	expSend(2)
    83  	// failed request, should decrease allowance and not accept more
    84  	rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 4, Request: testRequest}})
    85  	expSend(0)
    86  	srv.unsubscribe()
    87  }
    88  
    89  func TestServerFail(t *testing.T) {
    90  	rs := &testRequestServer{}
    91  	clock := &mclock.Simulated{}
    92  	srv := NewServer(rs, clock)
    93  	srv.subscribe(func(event Event) {})
    94  	expCanRequest := func(expCanRequest bool) {
    95  		if canRequest := srv.canRequestNow(); canRequest != expCanRequest {
    96  			t.Errorf("Wrong result for canRequestNow (expected %v, got %v)", expCanRequest, canRequest)
    97  		}
    98  	}
    99  	// timed out request
   100  	expCanRequest(true)
   101  	srv.sendRequest(testRequest)
   102  	clock.WaitForTimers(1)
   103  	expCanRequest(true)
   104  	clock.Run(softRequestTimeout)
   105  	expCanRequest(false) // cannot request when there is a timed out request
   106  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
   107  	expCanRequest(true)
   108  	// explicit server.Fail
   109  	srv.fail("")
   110  	clock.WaitForTimers(1)
   111  	expCanRequest(false) // cannot request for a while after a failure
   112  	clock.Run(minFailureDelay)
   113  	expCanRequest(true)
   114  	// request returned with EvFail
   115  	srv.sendRequest(testRequest)
   116  	rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 2, Request: testRequest}})
   117  	clock.WaitForTimers(1)
   118  	expCanRequest(false) // EvFail should also start failure delay
   119  	clock.Run(minFailureDelay)
   120  	expCanRequest(false) // second failure delay is longer, should still be disabled
   121  	clock.Run(minFailureDelay)
   122  	expCanRequest(true)
   123  	srv.unsubscribe()
   124  }
   125  
   126  func TestServerEventRateLimit(t *testing.T) {
   127  	rs := &testRequestServer{}
   128  	clock := &mclock.Simulated{}
   129  	srv := NewServer(rs, clock)
   130  	var eventCount int
   131  	srv.subscribe(func(event Event) {
   132  		if !event.IsRequestEvent() {
   133  			eventCount++
   134  		}
   135  	})
   136  	expEvents := func(send, expAllowed int) {
   137  		eventCount = 0
   138  		for sent := 0; sent < send; sent++ {
   139  			rs.eventCb(Event{Type: testEventType})
   140  		}
   141  		if eventCount != expAllowed {
   142  			t.Errorf("Wrong number of server events passing rate limitation (sent %d, expected %d, got %d)", send, expAllowed, eventCount)
   143  		}
   144  	}
   145  	expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
   146  	clock.Run(maxServerEventRate)
   147  	expEvents(5, 1)
   148  	clock.Run(maxServerEventRate * maxServerEventBuffer * 2)
   149  	expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
   150  }
   151  
   152  type testRequestServer struct {
   153  	eventCb func(Event)
   154  }
   155  
   156  func (rs *testRequestServer) Name() string                  { return "" }
   157  func (rs *testRequestServer) Subscribe(eventCb func(Event)) { rs.eventCb = eventCb }
   158  func (rs *testRequestServer) SendRequest(ID, Request)       {}
   159  func (rs *testRequestServer) Unsubscribe()                  {}