carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "errors"
6 "os"
7 "sync"
8 "testing"
9 "time"
10
11 "github.com/carlosframework/platform/internal/rootstate"
12)
13
14type exclusionDisk struct {
15 rootstate.Store
16 mu sync.Mutex
17}
18
19func (d *exclusionDisk) Lock(ctx context.Context, name string) (func(), error) {
20 d.mu.Lock()
21 return d.mu.Unlock, nil
22}
23func (d *exclusionDisk) Close() error { return nil }
24
25func TestPlan14ReleaseExclusionToken(t *testing.T) {
26 disk := &exclusionDisk{}
27 a := &ReleaseExclusion{Open: func() (rootstate.Store, error) { return disk, nil }}
28 b := &ReleaseExclusion{Open: a.Open}
29 if !errors.Is(a.Check(t.Context()), os.ErrPermission) {
30 t.Fatal("missing token accepted")
31 }
32 var stale context.Context
33 if err := a.With(t.Context(), func(ctx context.Context) error {
34 stale = ctx
35 if err := a.Check(ctx); err != nil {
36 t.Fatal(err)
37 }
38 if !errors.Is(b.Check(ctx), os.ErrPermission) {
39 t.Fatal("foreign token accepted")
40 }
41 if !errors.Is(b.With(ctx, func(context.Context) error { t.Fatal("foreign nested lock"); return nil }), os.ErrPermission) {
42 t.Fatal("foreign nesting accepted")
43 }
44 return a.With(ctx, func(nested context.Context) error { return a.Check(nested) })
45 }); err != nil {
46 t.Fatal(err)
47 }
48 if !errors.Is(a.Check(stale), os.ErrPermission) {
49 t.Fatal("stale token accepted")
50 }
51 if !errors.Is(a.With(stale, func(context.Context) error { t.Fatal("stale reused"); return nil }), os.ErrPermission) {
52 t.Fatal("stale context reacquired")
53 }
54}
55
56type deadlineExclusionDisk struct {
57 rootstate.Store
58 wait bool
59}
60
61func (d deadlineExclusionDisk) Lock(ctx context.Context, name string) (func(), error) {
62 if _, ok := ctx.Deadline(); !ok {
63 return nil, os.ErrPermission
64 }
65 if d.wait {
66 <-ctx.Done()
67 return nil, ctx.Err()
68 }
69 return func() {}, nil
70}
71func (d deadlineExclusionDisk) Close() error { return nil }
72func TestPlan14ReleaseExclusionWaitBudget(t *testing.T) {
73 for _, wait := range []bool{false, true} {
74 x := &ReleaseExclusion{Wait: 10 * time.Millisecond, Open: func() (rootstate.Store, error) { return deadlineExclusionDisk{wait: wait}, nil }}
75 called := false
76 err := x.With(t.Context(), func(ctx context.Context) error { called = true; time.Sleep(20 * time.Millisecond); return x.Check(ctx) })
77 if wait {
78 if !errors.Is(err, context.DeadlineExceeded) || called {
79 t.Fatal("unbounded wait", err, called)
80 }
81 } else if err != nil || !called {
82 t.Fatal("wait budget leaked into effect", err, called)
83 }
84 }
85}
86