1
2
3
4
5
6
7
8
9
10
11
12
13 package db
14
15 import (
16 "context"
17
18 "gitlab.com/flimzy/testy"
19
20 "github.com/go-kivik/kivik/v4"
21 "github.com/go-kivik/kivik/v4/kiviktest/kt"
22 )
23
24 func init() {
25 kt.Register("BulkDocs", bulkDocs)
26 }
27
28 func bulkDocs(ctx *kt.Context) {
29 ctx.RunRW(func(ctx *kt.Context) {
30 ctx.RunAdmin(func(ctx *kt.Context) {
31 testBulkDocs(ctx, ctx.Admin)
32 })
33 ctx.RunNoAuth(func(ctx *kt.Context) {
34 testBulkDocs(ctx, ctx.NoAuth)
35 })
36 })
37 }
38
39 func testBulkDocs(ctx *kt.Context, client *kivik.Client) {
40 ctx.Parallel()
41 dbname := ctx.TestDB()
42 adb := ctx.Admin.DB(dbname, ctx.Options("db"))
43 if err := adb.Err(); err != nil {
44 ctx.Fatalf("Failed to connect to db as admin: %s", err)
45 }
46 db := client.DB(dbname, ctx.Options("db"))
47 if err := db.Err(); err != nil {
48 ctx.Fatalf("Failed to connect to db: %s", err)
49 }
50 ctx.Run("group", func(ctx *kt.Context) {
51 ctx.Run("Create", func(ctx *kt.Context) {
52 ctx.Parallel()
53 doc := map[string]string{
54 "name": "Robert",
55 }
56 var updates []kivik.BulkResult
57 err := kt.Retry(func() error {
58 var err error
59 updates, err = db.BulkDocs(context.Background(), []interface{}{doc})
60 return err
61 })
62 if !ctx.IsExpectedSuccess(err) {
63 return
64 }
65 for _, update := range updates {
66 if update.Error != nil {
67 ctx.Errorf("Bulk create failed: %s", update.Error)
68 }
69 }
70 if err != nil {
71 ctx.Errorf("Iteration error: %s", err)
72 }
73 })
74 ctx.Run("Update", func(ctx *kt.Context) {
75 ctx.Parallel()
76 doc := map[string]string{
77 "_id": ctx.TestDBName(),
78 "name": "Alice",
79 }
80 rev, err := adb.Put(context.Background(), doc["_id"], doc)
81 if err != nil {
82 ctx.Fatalf("Failed to create doc: %s", err)
83 }
84 doc["_rev"] = rev
85 var updates []kivik.BulkResult
86 err = kt.Retry(func() error {
87 var err error
88 updates, err = db.BulkDocs(context.Background(), []interface{}{doc})
89 return err
90 })
91 if !ctx.IsExpectedSuccess(err) {
92 return
93 }
94 for _, update := range updates {
95 if update.Error != nil {
96 ctx.Errorf("Bulk delete failed: %s", update.Error)
97 }
98 }
99 if err != nil {
100 ctx.Errorf("Iteration error: %s", err)
101 }
102 })
103 ctx.Run("Delete", func(ctx *kt.Context) {
104 ctx.Parallel()
105 id := ctx.TestDBName()
106 doc := map[string]interface{}{
107 "_id": id,
108 "name": "Alice",
109 }
110 rev, err := adb.Put(context.Background(), id, doc)
111 if err != nil {
112 ctx.Fatalf("Failed to create doc: %s", err)
113 }
114 doc["_rev"] = rev
115 doc["_deleted"] = true
116 var updates []kivik.BulkResult
117 err = kt.Retry(func() error {
118 var err error
119 updates, err = db.BulkDocs(context.Background(), []interface{}{doc})
120 return err
121 })
122 if !ctx.IsExpectedSuccess(err) {
123 return
124 }
125 for _, update := range updates {
126 if update.Error != nil {
127 ctx.Errorf("Bulk update failed: %s", update.Error)
128 }
129 }
130 if err != nil {
131 ctx.Errorf("Iteration error: %s", err)
132 }
133 })
134 ctx.Run("Mix", func(ctx *kt.Context) {
135 ctx.Parallel()
136
137 doc0 := map[string]string{
138 "name": "Fred",
139 }
140
141 id1 := ctx.TestDBName()
142 doc1 := map[string]interface{}{
143 "_id": id1,
144 "name": "Robert",
145 }
146
147 rev1, err := adb.Put(context.Background(), id1, doc1)
148 if err != nil {
149 ctx.Fatalf("Failed to create doc1: %s", err)
150 }
151 doc1["_rev"] = rev1
152
153 id2 := ctx.TestDBName()
154 doc2 := map[string]interface{}{
155 "_id": id2,
156 "name": "Alice",
157 }
158 rev2, err := adb.Put(context.Background(), id2, doc2)
159 if err != nil {
160 ctx.Fatalf("Failed to create doc2: %s", err)
161 }
162 doc2["_rev"] = rev2
163 doc2["_deleted"] = true
164
165 id3 := ctx.TestDBName()
166 doc3 := map[string]string{
167 "_id": id3,
168 }
169 _, err = adb.Put(context.Background(), id3, doc3)
170 if err != nil {
171 ctx.Fatalf("Failed to create doc2: %s", err)
172 }
173
174 var updates []kivik.BulkResult
175
176 err = kt.Retry(func() error {
177 var err error
178 updates, err = db.BulkDocs(context.Background(), []interface{}{doc0, doc1, doc2, doc3})
179 return err
180 })
181 if !ctx.IsExpectedSuccess(err) {
182 return
183 }
184 if err != nil {
185 ctx.Errorf("Iteration error: %s", err)
186 }
187 for _, update := range updates {
188 var testName string
189 switch update.ID {
190 case id3:
191 testName = "Conflict"
192 case id1:
193 testName = "Update"
194 case id2:
195 testName = "Delete"
196 default:
197 testName = "Create"
198 }
199 ctx.Run(testName, func(ctx *kt.Context) {
200 ctx.CheckError(update.Error)
201 })
202 }
203 })
204 ctx.Run("NonJSON", func(ctx *kt.Context) {
205 const age = 32
206 ctx.Parallel()
207 id1 := ctx.TestDBName()
208 id2 := ctx.TestDBName()
209 docs := []interface{}{
210 struct {
211 ID string `json:"_id"`
212 Name string `json:"name"`
213 }{ID: id1, Name: "Robert"},
214 struct {
215 ID string `json:"_id"`
216 Name string `json:"name"`
217 Age int `json:"the_age"`
218 }{ID: id2, Name: "Alice", Age: age},
219 }
220 var updates []kivik.BulkResult
221 err := kt.Retry(func() error {
222 var err error
223 updates, err = db.BulkDocs(context.Background(), docs)
224 return err
225 })
226 if !ctx.IsExpectedSuccess(err) {
227 return
228 }
229 if err != nil {
230 ctx.Errorf("Iteration error: %s", err)
231 }
232 for _, update := range updates {
233 if e := update.Error; e != nil {
234 ctx.Errorf("Bulk create failed: %s", e)
235 }
236 }
237 ctx.Run("Retrieve", func(ctx *kt.Context) {
238 var result map[string]interface{}
239 if err = db.Get(context.Background(), id2).ScanDoc(&result); err != nil {
240 ctx.Fatalf("failed to scan bulk-inserted document: %s", err)
241 }
242 expected := map[string]interface{}{
243 "_id": id2,
244 "name": "Alice",
245 "the_age": age,
246 "_rev": result["_rev"],
247 }
248 if d := testy.DiffAsJSON(expected, result); d != nil {
249 ctx.Errorf("Retrieved document differs:\n%s\n", d)
250 }
251 })
252 })
253 })
254 }
255
View as plain text