...

Source file src/github.com/go-kivik/kivik/v4/kiviktest/db/bulk.go

Documentation: github.com/go-kivik/kivik/v4/kiviktest/db

     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  }
   255  

View as plain text