package alamo import ( "context" "errors" "testing" "testing/synctest" "time" "github.com/stretchr/testify/require" ) func TestGatewaySharesSixSecondRequestStartInterval(t *testing.T) { synctest.Test(t, func(t *testing.T) { client := &fakeGateway{states: []State{testState()}} gateway := &gateway{client: client} _, err := gateway.status(t.Context()) require.NoError(t, err) _, err = gateway.action(t.Context(), testMAC, Action{}) require.NoError(t, err) _, err = gateway.status(t.Context()) require.NoError(t, err) require.Len(t, client.starts, 3) require.Equal(t, 6*time.Second, client.starts[1].Sub(client.starts[0])) require.Equal(t, 6*time.Second, client.starts[2].Sub(client.starts[1])) }) } func TestGatewayDoesNotSpendAnotherIntervalAfterSlowRequests(t *testing.T) { synctest.Test(t, func(t *testing.T) { client := &fakeGateway{ states: []State{testState()}, delay: 4 * time.Second, } gateway := &gateway{client: client} _, err := gateway.status(t.Context()) require.NoError(t, err) _, err = gateway.status(t.Context()) require.NoError(t, err) require.Equal(t, 6*time.Second, client.starts[1].Sub(client.starts[0])) }) } func TestGatewayExpiryAndCancellationStopRateWaitWithoutIO(t *testing.T) { synctest.Test(t, func(t *testing.T) { client := &fakeGateway{states: []State{testState()}} gateway := &gateway{client: client} _, err := gateway.status(t.Context()) require.NoError(t, err) ctx, cancel := context.WithTimeout(t.Context(), time.Second) defer cancel() _, err = gateway.action(ctx, testMAC, Action{}) require.ErrorIs(t, err, context.DeadlineExceeded) ctx, cancel = context.WithCancel(t.Context()) cancel() _, err = gateway.status(ctx) require.ErrorIs(t, err, context.Canceled) require.Len(t, client.starts, 1) }) } func TestGatewayBoundsFakeClientOperationsAndReturnsFailures(t *testing.T) { synctest.Test(t, func(t *testing.T) { client := &fakeGateway{delay: time.Minute} gateway := &gateway{client: client} _, err := gateway.status(t.Context()) require.ErrorIs(t, err, context.DeadlineExceeded) _, err = gateway.action(t.Context(), testMAC, Action{}) require.ErrorIs(t, err, context.DeadlineExceeded) client.delay = 0 client.err = errors.New("gateway unavailable") _, err = gateway.status(t.Context()) require.ErrorIs(t, err, client.err) _, err = gateway.action(t.Context(), testMAC, Action{}) require.ErrorIs(t, err, client.err) }) } func TestGatewayDoesNotStartAtTheExactCommandDeadline(t *testing.T) { synctest.Test(t, func(t *testing.T) { client := &fakeGateway{states: []State{testState()}} gateway := &gateway{client: client} _, err := gateway.status(t.Context()) require.NoError(t, err) ctx, cancel := context.WithTimeout(t.Context(), 6*time.Second) defer cancel() _, err = gateway.action(ctx, testMAC, Action{}) require.ErrorIs(t, err, context.DeadlineExceeded) require.Len(t, client.starts, 1) }) }