github.com/go-kivik/kivik/v4@v4.3.2/kiviktest/db/bulk.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 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) { // nolint: gocyclo 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 }