carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "errors"
6 "sync"
7
8 "github.com/carlosframework/platform/internal/release"
9)
10
11// hookStore is the recording store the lifecycle tests drive failures
12// through. failPut and failDelete map a key to how many more times it fails
13// (a negative count fails forever); onDelete runs before each Delete, which is
14// how a test observes the row at the moment a marker is removed; onGet runs
15// before each Get.
16type hookStore struct {
17 release.Store
18 mu sync.Mutex
19 failPut map[string]int
20 failDelete map[string]int
21 onDelete func(key string)
22 // onGet runs before each Get: how a test changes the bucket between two
23 // reads of one request (Task 8's ErrNotTrashed test).
24 onGet func(key string)
25 deletes []string
26}
27
28func (h *hookStore) Get(ctx context.Context, key string) ([]byte, string, error) {
29 if h.onGet != nil {
30 h.onGet(key)
31 }
32 return h.Store.Get(ctx, key)
33}
34
35func (h *hookStore) fails(m map[string]int, key string) bool {
36 h.mu.Lock()
37 defer h.mu.Unlock()
38 n, ok := m[key]
39 if !ok || n == 0 {
40 return false
41 }
42 if n > 0 {
43 m[key] = n - 1
44 }
45 return true
46}
47
48func (h *hookStore) Put(ctx context.Context, key string, body []byte, ifMatch string) (string, error) {
49 if h.fails(h.failPut, key) {
50 return "", errors.New("hookStore: put refused")
51 }
52 return h.Store.Put(ctx, key, body, ifMatch)
53}
54
55func (h *hookStore) Delete(ctx context.Context, key string) error {
56 if h.onDelete != nil {
57 h.onDelete(key)
58 }
59 if h.fails(h.failDelete, key) {
60 return errors.New("hookStore: delete refused")
61 }
62 h.mu.Lock()
63 h.deletes = append(h.deletes, key)
64 h.mu.Unlock()
65 return h.Store.Delete(ctx, key)
66}
67