This repository has been archived by the owner on Mar 31, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 80
/
transaction_test.go
85 lines (73 loc) · 1.7 KB
/
transaction_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package firego
import (
"encoding/base64"
"net/http"
"net/http/httptest"
"strconv"
"sync/atomic"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type aBool struct {
addr *int32
}
func (a *aBool) set(v bool) {
val := int32(0)
if v {
val = 1
}
atomic.StoreInt32(a.addr, val)
}
func (a *aBool) val() bool {
v := atomic.LoadInt32(a.addr)
if v == 1 {
return true
}
return false
}
func newABool() *aBool {
return &aBool{
addr: new(int32),
}
}
func TestTransaction(t *testing.T) {
storedVal := newABool()
hitConflict := newABool()
fbCounter := new(int64)
atomic.StoreInt64(fbCounter, 1)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
counter := atomic.LoadInt64(fbCounter)
val := strconv.FormatInt(counter, 10)
valBytes := []byte(val)
etag := base64.StdEncoding.EncodeToString(valBytes)
if req.Method == http.MethodGet {
w.Header().Set("Etag", etag)
w.Write(valBytes)
return
}
if req.Header.Get("if-match") != etag {
hitConflict.set(true)
w.Header().Set("Etag", etag)
w.WriteHeader(http.StatusConflict)
w.Write(valBytes)
return
}
storedVal.set(true)
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
fb := New(server.URL, nil)
err := fb.Transaction(func(currentSnapshot interface{}) (interface{}, error) {
counter, ok := currentSnapshot.(float64)
require.True(t, ok, "counter is not of type float64")
if !hitConflict.val() {
// set some random value so that we can test out the conflict logic
atomic.StoreInt64(fbCounter, 123)
}
return counter + 1, nil
})
assert.NoError(t, err)
assert.True(t, storedVal.val())
assert.True(t, hitConflict.val())
}