-
Notifications
You must be signed in to change notification settings - Fork 0
/
transaction_test.go
113 lines (97 loc) · 3.03 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package modm
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
type TestCounter struct {
DefaultField `bson:",inline"`
Key string `bson:"key,omitempty" json:"key"`
Count int `bson:"count,omitempty" json:"count"`
}
type TestPaper struct {
DefaultField `bson:",inline"`
Text string `bson:"text,omitempty" json:"text"`
NumberID int `bson:"number_id,omitempty" json:"numberId"`
}
func (u *TestPaper) Uniques() []string {
return []string{"number_id"}
}
type TestDB struct {
DoTransaction DoTransactionFunc
Papers *Repo[*TestPaper]
Counters *Repo[*TestCounter]
}
func TestDoTransaction(t *testing.T) {
database, cleanup := setupTestDatabase(t)
defer cleanup()
db := TestDB{
Papers: NewRepo[*TestPaper](database.Collection("test_papers")),
Counters: NewRepo[*TestCounter](database.Collection("test_counters")),
}
db.DoTransaction = DoTransaction(database.Client())
ctx := context.TODO()
err := db.Papers.EnsureIndexesByModel(ctx, &TestPaper{})
require.NoError(t, err)
_, err = db.Counters.InsertOne(ctx, &TestCounter{Key: "paper", Count: 0})
require.NoError(t, err)
result, err := db.DoTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
paperCounter, err := db.Counters.FindOneAndUpdate(
sessCtx,
&TestCounter{Key: "paper"},
bson.M{"$inc": bson.M{"count": 1}},
)
if err != nil {
return nil, err
}
paper, err := db.Papers.InsertOne(sessCtx, &TestPaper{Text: "go", NumberID: paperCounter.Count})
return paper, err
})
require.NoError(t, err)
paper, ok := result.(*TestPaper)
require.True(t, ok)
assert.Equal(t, 1, paper.NumberID)
result2, err := db.DoTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
paperCounter, err := db.Counters.FindOneAndUpdate(
sessCtx,
&TestCounter{Key: "paper"},
bson.M{"$inc": bson.M{"count": 1}},
)
if err != nil {
return nil, err
}
paper, err := db.Papers.InsertOne(sessCtx, &TestPaper{Text: "go", NumberID: paperCounter.Count})
return paper, err
})
require.NoError(t, err)
paper2, ok := result2.(*TestPaper)
require.True(t, ok)
assert.Equal(t, 2, paper2.NumberID)
_, err = db.Papers.InsertOne(ctx, &TestPaper{Text: "go", NumberID: 2})
require.True(t, mongo.IsDuplicateKeyError(err))
t.Run("Error Case - StartSession", func(t *testing.T) {
mockClient := &mongo.Client{}
// Mock callback function
mockCallback := func(sessCtx context.Context) (interface{}, error) {
return nil, nil
}
result, err := DoTransaction(mockClient)(context.Background(), mockCallback)
assert.Error(t, err)
assert.Nil(t, result)
})
t.Run("Error Case - WithTransaction", func(t *testing.T) {
ctx := context.TODO()
result, err := db.DoTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
paper, err := db.Papers.FindOne(
sessCtx,
&TestPaper{NumberID: 404},
)
return paper, err
})
require.Error(t, err)
assert.Nil(t, result)
})
}