...

Source file src/github.com/go-kivik/kivik/v4/kiviktest/db/explain.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("Explain", explain)
    26  }
    27  
    28  func explain(ctx *kt.Context) {
    29  	ctx.RunAdmin(func(ctx *kt.Context) {
    30  		testExplain(ctx, ctx.Admin)
    31  	})
    32  	ctx.RunNoAuth(func(ctx *kt.Context) {
    33  		testExplain(ctx, ctx.NoAuth)
    34  	})
    35  	ctx.RunRW(func(ctx *kt.Context) {
    36  		testExplainRW(ctx)
    37  	})
    38  }
    39  
    40  func testExplainRW(ctx *kt.Context) {
    41  	if ctx.Admin == nil {
    42  		// Can't do anything here without admin access
    43  		return
    44  	}
    45  	dbName := ctx.TestDB()
    46  	ctx.Run("group", func(ctx *kt.Context) {
    47  		ctx.RunAdmin(func(ctx *kt.Context) {
    48  			doExplainTest(ctx, ctx.Admin, dbName)
    49  		})
    50  		ctx.RunNoAuth(func(ctx *kt.Context) {
    51  			doExplainTest(ctx, ctx.NoAuth, dbName)
    52  		})
    53  	})
    54  }
    55  
    56  func testExplain(ctx *kt.Context, client *kivik.Client) {
    57  	if !ctx.IsSet("databases") {
    58  		ctx.Errorf("databases not set; Did you configure this test?")
    59  		return
    60  	}
    61  	for _, dbName := range ctx.StringSlice("databases") {
    62  		func(dbName string) {
    63  			ctx.Run(dbName, func(ctx *kt.Context) {
    64  				doExplainTest(ctx, client, dbName)
    65  			})
    66  		}(dbName)
    67  	}
    68  }
    69  
    70  func doExplainTest(ctx *kt.Context, client *kivik.Client, dbName string) {
    71  	const limit = 25
    72  	ctx.Parallel()
    73  	db := client.DB(dbName, ctx.Options("db"))
    74  	// Errors may be deferred here, so only return if we actually get
    75  	// an error.
    76  	if err := db.Err(); err != nil && !ctx.IsExpectedSuccess(err) {
    77  		return
    78  	}
    79  
    80  	var plan *kivik.QueryPlan
    81  	err := kt.Retry(func() error {
    82  		var e error
    83  		plan, e = db.Explain(context.Background(), `{"selector":{"_id":{"$gt":null}}}`)
    84  		return e
    85  	})
    86  	if !ctx.IsExpectedSuccess(err) {
    87  		return
    88  	}
    89  	expected := new(kivik.QueryPlan)
    90  	if e, ok := ctx.Interface("plan").(*kivik.QueryPlan); ok {
    91  		*expected = *e // Make a shallow copy
    92  	} else {
    93  		expected = &kivik.QueryPlan{
    94  			Index: map[string]interface{}{
    95  				"ddoc": nil,
    96  				"name": "_all_docs",
    97  				"type": "special",
    98  				"def":  map[string]interface{}{"fields": []interface{}{map[string]string{"_id": "asc"}}},
    99  			},
   100  			Selector: map[string]interface{}{"_id": map[string]interface{}{"$gt": nil}},
   101  			Options: map[string]interface{}{
   102  				"bookmark":  "nil",
   103  				"conflicts": false,
   104  				"fields":    "all_fields",
   105  				"limit":     limit,
   106  				"r":         []int{49},
   107  				"skip":      0,
   108  				"sort":      map[string]interface{}{},
   109  				"use_index": []interface{}{},
   110  			},
   111  			Limit: limit,
   112  			Range: map[string]interface{}{
   113  				"start_key": nil,
   114  				"end_key":   "\xef\xbf\xbd",
   115  			},
   116  		}
   117  	}
   118  	expected.DBName = dbName
   119  	if d := testy.DiffAsJSON(expected, plan); d != nil {
   120  		ctx.Errorf("Unexpected plan returned:\n%s\n", d)
   121  	}
   122  }
   123  

View as plain text