Files
zeekayandHanzo Dev 8ee8950230 Go 1.27.1, and the code it can say more simply
The module declares go 1.27.1 and the adapter image follows. go fix
applied the modernizers and left ptrString and ptrBool with no callers,
so they are gone; omitzero is not applied, since it changes what the
JSON says.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 19:52:31 -07:00

141 lines
3.4 KiB
Go

package extras
import (
"log"
"net/http"
"os"
"testing"
"time"
insights "github.com/hanzoai/insights-go"
"github.com/orian/flakyhttp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRetryBehavior(t *testing.T) {
tests := []struct {
name string
failCount int // 0 = always fail, N = fail N times then succeed
requestCount int
disableRetry bool // if true, RetryAfter returns -1
expectSuccess bool
retryAfter func(i int) time.Duration
forceClose bool
}{
{
name: "NoRetry_DropsMessage",
failCount: 0, // always fail
requestCount: 1,
disableRetry: true,
expectSuccess: false,
},
{
name: "AllRetriesFail_DropsMessage",
failCount: 0, // always fail, will exhaust all 10 retries
requestCount: 10,
disableRetry: false,
expectSuccess: false,
},
{
name: "QuitDuringRetry_DropsMessage",
failCount: 1, // always fail, will exhaust all 10 retries
requestCount: 1,
disableRetry: false,
expectSuccess: false,
retryAfter: func(i int) time.Duration {
return time.Minute
},
forceClose: true,
},
{
name: "SuccessOnLastRetry",
failCount: 9, // fail 9 times, succeed on 10th (last retry)
requestCount: 10,
disableRetry: false,
expectSuccess: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
server := flakyhttp.NewServer(flakyhttp.Config{
Scenario: flakyhttp.ScenarioNoResponse,
FailCount: tc.failCount,
})
url, err := server.Start()
require.NoError(t, err)
defer server.Close()
callback := newTestCallback(t)
config := insights.Config{
Endpoint: url,
Transport: &timeoutTransport{
rt: http.DefaultTransport,
timeout: 1 * time.Second,
},
Interval: 1 * time.Millisecond,
BatchSize: 1,
Logger: insights.StdLogger(log.New(os.Stderr, "[insights] ", log.LstdFlags), true),
Callback: callback,
RetryAfter: func(i int) time.Duration { return time.Millisecond },
}
if tc.disableRetry {
config.MaxRetries = new(0)
}
if tc.retryAfter != nil {
config.RetryAfter = tc.retryAfter
}
client, err := insights.NewWithConfig("test-api-key", config)
require.NoError(t, err)
err = client.Enqueue(insights.Capture{
DistinctId: "user1",
Event: "test_event",
})
require.NoError(t, err)
if tc.forceClose {
time.Sleep(10 * time.Millisecond)
client.Close()
}
// Wait for callback
select {
case <-callback.successChan:
if !tc.expectSuccess {
require.Fail(t, "Expected failure but got success")
}
t.Log("Event delivered successfully")
case err := <-callback.failureChan:
if tc.expectSuccess {
require.Fail(t, "Expected success but got failure: %v", err)
}
t.Logf("Event dropped as expected: %v", err)
case <-time.After(5 * time.Second):
require.Fail(t, "Timeout waiting for callback")
}
if !tc.forceClose {
client.Close()
}
success, failure := callback.GetCounts()
assert.Equal(t, tc.requestCount, server.RequestCount())
assert.Equal(t, 1, success+failure, "Expected 1 callback")
if tc.expectSuccess {
assert.Equal(t, 1, success, "Expected 1 success")
assert.Equal(t, 0, failure, "Expected 0 failures")
} else {
assert.Equal(t, 0, success, "Expected 0 success")
assert.Equal(t, 1, failure, "Expected 1 failure")
}
})
}
}