MCPcopy Create free account
hub / github.com/erpc/erpc / TestSharedVariableTimeoutHandling

Function TestSharedVariableTimeoutHandling

data/shared_state_variable_test.go:989–1197  ·  view source on GitHub ↗

TestSharedVariableTimeoutHandling verifies that when the remote backend is down, the shared variable operations fail fast and leave enough time for the actual operation.

(t *testing.T)

Source from the content-addressed store, hash-verified

987// TestSharedVariableTimeoutHandling verifies that when the remote backend is down,
988// the shared variable operations fail fast and leave enough time for the actual operation.
989func TestSharedVariableTimeoutHandling(t *testing.T) {
990 t.Run("operations respect timeout when remote is down", func(t *testing.T) {
991 ctx, cancel := context.WithCancel(context.Background())
992 defer cancel()
993
994 // Create a connector that simulates a broken Redis connection
995 connector := NewMockConnector("broken")
996 registry := &sharedStateRegistry{
997 appCtx: ctx,
998 logger: &log.Logger,
999 clusterKey: "test",
1000 connector: connector,
1001 fallbackTimeout: 1 * time.Second,
1002 lockTtl: 30 * time.Second,
1003 lockMaxWait: 200 * time.Millisecond,
1004 updateMaxWait: 200 * time.Millisecond,
1005 initializer: util.NewInitializer(ctx, &log.Logger, nil),
1006 }
1007
1008 // Setup mock to simulate timeout on Lock
1009 connector.On("Lock", mock.Anything, mock.Anything, mock.Anything).
1010 Run(func(args mock.Arguments) {
1011 ctx := args.Get(0).(context.Context)
1012 // Wait for context to timeout
1013 <-ctx.Done()
1014 }).
1015 Return(nil, context.DeadlineExceeded)
1016
1017 // Background push publishes best-effort for fast propagation.
1018 connector.On("PublishCounterInt64", mock.Anything, "test/timeout-counter", mock.Anything).Return(nil).Maybe()
1019
1020 // Setup mock for Get to return not found initially
1021 connector.On("Get", mock.Anything, ConnectorMainIndex, "test/timeout-counter", "value", nil).
1022 Return(nil, common.NewErrRecordNotFound("test/timeout-counter", "value", "mock"))
1023
1024 // Setup mock for WatchCounterInt64
1025 updates := make(chan CounterInt64State, 10)
1026 cleanup := func() { close(updates) }
1027 connector.On("WatchCounterInt64", mock.Anything, "test/timeout-counter").
1028 Return(updates, cleanup, nil)
1029
1030 // Get a counter variable
1031 counter := registry.GetCounterInt64("timeout-counter", 100).(*counterInt64)
1032 time.Sleep(100 * time.Millisecond) // Allow initialization
1033
1034 // Test TryUpdateIfStale with a parent context that has enough time for lock wait + operations
1035 operationCtx, operationCancel := context.WithTimeout(ctx, 3*time.Second)
1036 defer operationCancel()
1037
1038 executionCount := atomic.Int32{}
1039 start := time.Now()
1040
1041 value, err := counter.TryUpdateIfStale(operationCtx, 100*time.Millisecond, func(ctx context.Context) (int64, error) {
1042 executionCount.Add(1)
1043 // This simulates the actual operation (e.g., fetching block number)
1044 select {
1045 case <-ctx.Done():
1046 return 0, ctx.Err()

Callers

nothing calls this directly

Calls 15

GetCounterInt64Method · 0.95
ValidateMethod · 0.95
NewInitializerFunction · 0.92
DurationTypeAlias · 0.92
NewMockConnectorFunction · 0.85
LoadMethod · 0.80
processNewValueMethod · 0.80
RunMethod · 0.65
GetMethod · 0.65
TryUpdateIfStaleMethod · 0.65
AddMethod · 0.65
TryUpdateMethod · 0.65

Tested by

no test coverage detected