github.com/ethereum/go-ethereum@v1.16.1/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  	srv.unsubscribe()
    55  }
    56  
    57  func TestServerParallel(t *testing.T) {
    58  	rs := &testRequestServer{}
    59  	srv := NewServer(rs, &mclock.Simulated{})
    60  	srv.subscribe(func(event Event) {})
    61  
    62  	expSend := func(expSent int) {
    63  		var sent int
    64  		for sent <= expSent {
    65  			if !srv.canRequestNow() {
    66  				break
    67  			}
    68  			sent++
    69  			srv.sendRequest(testRequest)
    70  		}
    71  		if sent != expSent {
    72  			t.Errorf("Wrong number of parallel requests accepted (expected %d, got %d)", expSent, sent)
    73  		}
    74  	}
    75  	// max out parallel allowance
    76  	expSend(defaultParallelLimit)
    77  	// 1 answered, should accept 1 more
    78  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
    79  	expSend(1)
    80  	// 2 answered, should accept 2 more
    81  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 2, Request: testRequest, Response: testResponse}})
    82  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 3, Request: testRequest, Response: testResponse}})
    83  	expSend(2)
    84  	// failed request, should decrease allowance and not accept more
    85  	rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 4, Request: testRequest}})
    86  	expSend(0)
    87  	srv.unsubscribe()
    88  }
    89  
    90  func TestServerFail(t *testing.T) {
    91  	rs := &testRequestServer{}
    92  	clock := &mclock.Simulated{}
    93  	srv := NewServer(rs, clock)
    94  	srv.subscribe(func(event Event) {})
    95  	expCanRequest := func(expCanRequest bool) {
    96  		if canRequest := srv.canRequestNow(); canRequest != expCanRequest {
    97  			t.Errorf("Wrong result for canRequestNow (expected %v, got %v)", expCanRequest, canRequest)
    98  		}
    99  	}
   100  	// timed out request
   101  	expCanRequest(true)
   102  	srv.sendRequest(testRequest)
   103  	clock.WaitForTimers(1)
   104  	expCanRequest(true)
   105  	clock.Run(softRequestTimeout)
   106  	expCanRequest(false) // cannot request when there is a timed out request
   107  	rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
   108  	expCanRequest(true)
   109  	// explicit server.Fail
   110  	srv.fail("")
   111  	clock.WaitForTimers(1)
   112  	expCanRequest(false) // cannot request for a while after a failure
   113  	clock.Run(minFailureDelay)
   114  	expCanRequest(true)
   115  	// request returned with EvFail
   116  	srv.sendRequest(testRequest)
   117  	rs.eventCb(Event{Type: EvFail, Data: RequestResponse{ID: 2, Request: testRequest}})
   118  	clock.WaitForTimers(1)
   119  	expCanRequest(false) // EvFail should also start failure delay
   120  	clock.Run(minFailureDelay)
   121  	expCanRequest(false) // second failure delay is longer, should still be disabled
   122  	clock.Run(minFailureDelay)
   123  	expCanRequest(true)
   124  	srv.unsubscribe()
   125  }
   126  
   127  func TestServerEventRateLimit(t *testing.T) {
   128  	rs := &testRequestServer{}
   129  	clock := &mclock.Simulated{}
   130  	srv := NewServer(rs, clock)
   131  	var eventCount int
   132  	srv.subscribe(func(event Event) {
   133  		eventCount++
   134  	})
   135  	expEvents := func(send, expAllowed int) {
   136  		eventCount = 0
   137  		for sent := 0; sent < send; sent++ {
   138  			rs.eventCb(Event{Type: testEventType})
   139  		}
   140  		if eventCount != expAllowed {
   141  			t.Errorf("Wrong number of server events passing rate limitation (sent %d, expected %d, got %d)", send, expAllowed, eventCount)
   142  		}
   143  	}
   144  	expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
   145  	clock.Run(maxServerEventRate)
   146  	expEvents(5, 1)
   147  	clock.Run(maxServerEventRate * maxServerEventBuffer * 2)
   148  	expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
   149  	srv.unsubscribe()
   150  }
   151  
   152  func TestServerUnsubscribe(t *testing.T) {
   153  	rs := &testRequestServer{}
   154  	clock := &mclock.Simulated{}
   155  	srv := NewServer(rs, clock)
   156  	var eventCount int
   157  	srv.subscribe(func(event Event) {
   158  		eventCount++
   159  	})
   160  	eventCb := rs.eventCb
   161  	eventCb(Event{Type: testEventType})
   162  	if eventCount != 1 {
   163  		t.Errorf("Server event callback not called before unsubscribe")
   164  	}
   165  	srv.unsubscribe()
   166  	if rs.eventCb != nil {
   167  		t.Errorf("Server event callback not removed after unsubscribe")
   168  	}
   169  	eventCb(Event{Type: testEventType})
   170  	if eventCount != 1 {
   171  		t.Errorf("Server event callback called after unsubscribe")
   172  	}
   173  }
   174  
   175  type testRequestServer struct {
   176  	eventCb func(Event)
   177  }
   178  
   179  func (rs *testRequestServer) Name() string                  { return "" }
   180  func (rs *testRequestServer) Subscribe(eventCb func(Event)) { rs.eventCb = eventCb }
   181  func (rs *testRequestServer) SendRequest(ID, Request)       {}
   182  func (rs *testRequestServer) Unsubscribe()                  { rs.eventCb = nil }