carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package rootparticipation
2
3import (
4 "context"
5 "errors"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/rootstate"
9)
10
11type transactionTestStore struct {
12 rootstate.Store
13 held bool
14 locks int
15}
16
17func (s *transactionTestStore) Lock(context.Context, string) (func(), error) {
18 if s.held {
19 return nil, ErrUnavailable
20 }
21 s.held = true
22 s.locks++
23 return func() { s.held = false }, nil
24}
25func TestPlan14ParticipationTransactionScope(t *testing.T) {
26 s := &transactionTestStore{}
27 l := Ledger{State: s}
28 var stale context.Context
29 if err := l.WithTransaction(t.Context(), func(ctx context.Context) error {
30 stale = ctx
31 held, ok, err := TransactionLedger(ctx)
32 if err != nil || !ok || held.State != s || !s.held {
33 t.Fatal("missing held ledger", err)
34 }
35 foreign := Ledger{State: &transactionTestStore{}}
36 if err := foreign.WithTransaction(ctx, func(context.Context) error { t.Fatal("foreign token accepted"); return nil }); !errors.Is(err, ErrUnavailable) {
37 t.Fatal(err)
38 }
39 return l.WithTransaction(ctx, func(context.Context) error { return nil })
40 }); err != nil {
41 t.Fatal(err)
42 }
43 if s.held || s.locks != 1 {
44 t.Fatal("nested lock or leak", s)
45 }
46 if _, _, err := TransactionLedger(stale); !errors.Is(err, ErrUnavailable) {
47 t.Fatal("stale token accepted", err)
48 }
49 if err := l.WithTransaction(stale, func(context.Context) error { t.Fatal("stale token reused"); return nil }); !errors.Is(err, ErrUnavailable) {
50 t.Fatal(err)
51 }
52 sentinel := errors.New("effect")
53 if err := l.WithTransaction(t.Context(), func(context.Context) error { return sentinel }); !errors.Is(err, sentinel) || s.held {
54 t.Fatal("error lost or lock leaked", err)
55 }
56}
57