Files
orbit/examples/task-outbox/internal/outbox/store_test.go

65 lines
2.2 KiB
Go

package outbox
import (
"bytes"
"context"
"encoding/json"
"errors"
"testing"
"time"
orbit "git.yuntuo.hk/k2safe/orbit/sdk/go"
)
func testID(t *testing.T) string {
t.Helper()
id, err := orbit.NewEventMessageID()
if err != nil {
t.Fatal(err)
}
return id
}
func testRequest(queue string) orbit.SubmitTaskRequest {
return orbit.SubmitTaskRequest{QueueID: queue, Handler: "object.prepare", HandlerVersion: "v1", PayloadVersion: "v1", Payload: json.RawMessage(`{"sequence":9007199254740993,"ref":"objects/test"}`), TaskTimeoutMS: 60000}
}
func TestFrozenDocumentAndFailureClassification(t *testing.T) {
s := &Store{namespace: testID(t), queue: testID(t)}
in := testRequest(s.queue)
in.TaskTimeoutMS = 0
in.DelayMS = 1500
raw, err := s.document(in)
if err != nil {
t.Fatal(err)
}
var frozen orbit.SubmitTaskRequest
if json.Unmarshal(raw, &frozen) != nil || frozen.TaskTimeoutMS != 86400000 || frozen.DelayMS != 1500 || frozen.AvailableAt != nil || frozen.Retry.MaxAttempts != 1 || frozen.Retry.AttemptTimeoutMS != 30000 || !bytes.Contains(frozen.Payload, []byte("9007199254740993")) {
t.Fatal("frozen defaults or precision changed")
}
in.QueueID = testID(t)
if _, err = s.document(in); !errors.Is(err, ErrInvalid) {
t.Fatal("cross queue request frozen")
}
in = testRequest(s.queue)
in.BusinessKey = "operation-\xff"
if _, err = s.document(in); !errors.Is(err, ErrInvalid) {
t.Fatal("invalid UTF-8 was silently rewritten")
}
for _, test := range []struct {
err error
state, code string
}{
{context.DeadlineExceeded, "PENDING", "UNCONFIRMED"},
{&orbit.APIError{StatusCode: 503, Code: "UNAVAILABLE"}, "PENDING", "UNCONFIRMED"},
{&orbit.APIError{StatusCode: 429, RetryAfter: 30 * time.Second}, "PENDING", "BACKPRESSURE"},
{&orbit.APIError{StatusCode: 403}, "REVIEW", "AUTHORIZATION"},
{&orbit.APIError{StatusCode: 409, Code: "IDEMPOTENCY_CONFLICT"}, "REVIEW", "IDEMPOTENCY_CONFLICT"},
{&orbit.HTTPError{StatusCode: 302}, "REVIEW", "HTTP_REJECTED"},
{&orbit.HTTPError{StatusCode: 502}, "PENDING", "UNCONFIRMED"},
} {
state, code, delay := classify(test.err, 100)
if state != test.state || code != test.code || delay < time.Second || delay > time.Hour {
t.Fatal(state, code, delay)
}
}
}