tariff/wrapper_test.go
Rama master · réplica de lectura del repositorio original.
package tariff
import (
"context"
"errors"
"sync"
"testing"
"time"
"github.com/evcc-io/evcc/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// retryTariff fails instantiation on demand
type retryTariff struct {
mu sync.Mutex
err error
calls int
}
// created returns the number of creation attempts
func (t *retryTariff) created() int {
t.mu.Lock()
defer t.mu.Unlock()
return t.calls
}
func (t *retryTariff) setErr(err error) {
t.mu.Lock()
defer t.mu.Unlock()
t.err = err
}
func (t *retryTariff) Rates() (api.Rates, error) {
t.mu.Lock()
defer t.mu.Unlock()
if t.err != nil {
return nil, t.err
}
now := time.Now().Truncate(SlotDuration)
return api.Rates{{Start: now, End: now.Add(SlotDuration), Value: 1}}, nil
}
func (t *retryTariff) Type() api.TariffType {
return api.TariffTypePriceForecast
}
var retryable = new(retryTariff)
func init() {
registry.AddCtx("test-retry", func(context.Context, map[string]any) (api.Tariff, error) {
retryable.mu.Lock()
retryable.calls++
retryable.mu.Unlock()
if _, err := retryable.Rates(); err != nil {
return nil, err
}
return retryable, nil
})
}
func TestWrapperRetry(t *testing.T) {
retryable.setErr(errors.New("unavailable"))
_, err := NewFromConfig(context.TODO(), "test-retry", nil)
require.Error(t, err)
res := NewWrapper(context.TODO(), "test-retry", nil, err)
w := res.(*Wrapper)
// creation has just failed: no immediate retry
assert.False(t, w.retriedAt.IsZero())
created := retryable.created()
_, err = res.Rates()
require.ErrorContains(t, err, "tariff not available")
assert.Equal(t, api.TariffType(0), res.Type())
assert.Equal(t, created, retryable.created())
// tariff becomes available but retry interval not elapsed: still unavailable
retryable.setErr(nil)
_, err = res.Rates()
require.Error(t, err)
// retry interval elapsed: next call creates the tariff
w.mu.Lock()
w.retriedAt = time.Time{}
w.mu.Unlock()
rr, err := res.Rates()
require.NoError(t, err)
assert.Len(t, rr, 1)
assert.Equal(t, api.TariffTypePriceForecast, res.Type())
// tariff fails at runtime: error passed through, no re-creation
retryable.setErr(api.ErrOutdated)
_, err = res.Rates()
require.ErrorIs(t, err, api.ErrOutdated)
assert.Same(t, retryable, w.tariff)
}