Skip to content

Commit

Permalink
Merge pull request #241 from go-kivik/membership-v3
Browse files Browse the repository at this point in the history
Add /_membership support
  • Loading branch information
flimzy authored Jul 10, 2020
2 parents 2e585b6 + 3e5c1be commit 680f35a
Show file tree
Hide file tree
Showing 15 changed files with 165 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ variables:

linter:
stage: test
image: golangci/golangci-lint:v1.26
image: golangci/golangci-lint:v1.28
script:
- go mod download
- golangci-lint run ./...
Expand Down
6 changes: 4 additions & 2 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ type rawCookie struct {
next http.RoundTripper
}

var _ Authenticator = &rawCookie{}
var _ http.RoundTripper = &rawCookie{}
var (
_ Authenticator = &rawCookie{}
_ http.RoundTripper = &rawCookie{}
)

func (a *rawCookie) auth(_ context.Context, c *client) error {
if c.Client.Client.Transport != nil {
Expand Down
13 changes: 7 additions & 6 deletions chttp/chttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package chttp
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -18,7 +19,7 @@ import (
"gitlab.com/flimzy/testy"
"golang.org/x/net/publicsuffix"

"github.com/go-kivik/kivik/v3/errors"
"github.com/go-kivik/kivik/v3"
)

var defaultUA = func() string {
Expand Down Expand Up @@ -689,7 +690,7 @@ func TestDoReq(t *testing.T) {
name: "body error",
method: "PUT",
path: "foo",
client: newTestClient(nil, errors.Status(http.StatusBadRequest, "bad request")),
client: newTestClient(nil, &kivik.Error{HTTPStatus: http.StatusBadRequest, Message: "bad request"}),
status: http.StatusBadRequest,
err: `Put "?http://example.com/foo"?: bad request`,
},
Expand Down Expand Up @@ -796,7 +797,7 @@ func TestDoReq(t *testing.T) {
name: "couchdb mounted below root",
client: newCustomClient("http://foo.com/dbroot/", func(r *http.Request) (*http.Response, error) {
if r.URL.Path != "/dbroot/foo" {
return nil, errors.Errorf("Unexpected path: %s", r.URL.Path)
return nil, fmt.Errorf("Unexpected path: %s", r.URL.Path)
}
return &http.Response{}, nil
}),
Expand All @@ -807,7 +808,7 @@ func TestDoReq(t *testing.T) {
name: "user agent",
client: newCustomClient("http://foo.com/", func(r *http.Request) (*http.Response, error) {
if ua := r.UserAgent(); ua != defaultUA {
return nil, errors.Errorf("Unexpected User Agent: %s", ua)
return nil, fmt.Errorf("Unexpected User Agent: %s", ua)
}
return &http.Response{}, nil
}),
Expand Down Expand Up @@ -971,7 +972,7 @@ func TestNetError(t *testing.T) {
input: &url.Error{
Op: "Get",
URL: "http://foo.com/",
Err: errors.Status(http.StatusBadRequest, "some error"),
Err: &kivik.Error{HTTPStatus: http.StatusBadRequest, Message: "some error"},
},
status: http.StatusBadRequest,
err: `Get "?http://foo.com/"?: some error`,
Expand All @@ -985,7 +986,7 @@ func TestNetError(t *testing.T) {
},
{
name: "other error with embedded status",
input: errors.Status(http.StatusBadRequest, "bad req"),
input: &kivik.Error{HTTPStatus: http.StatusBadRequest, Message: "bad req"},
status: http.StatusBadRequest,
curlStatus: 0,
err: "bad req",
Expand Down
7 changes: 7 additions & 0 deletions cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"

"github.com/go-kivik/couchdb/v3/chttp"
"github.com/go-kivik/kivik/v3/driver"
)

func (c *client) ClusterStatus(ctx context.Context, opts map[string]interface{}) (string, error) {
Expand All @@ -26,3 +27,9 @@ func (c *client) ClusterSetup(ctx context.Context, action interface{}) error {
_, err := c.DoError(ctx, http.MethodPost, "/_cluster_setup", options)
return err
}

func (c *client) Membership(ctx context.Context) (*driver.ClusterMembership, error) {
result := new(driver.ClusterMembership)
_, err := c.DoJSON(ctx, http.MethodGet, "/_membership", nil, &result)
return result, err
}
55 changes: 54 additions & 1 deletion cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

"gitlab.com/flimzy/testy"

kivik "github.com/go-kivik/kivik/v3"
"github.com/go-kivik/kivik/v3"
"github.com/go-kivik/kivik/v3/driver"
)

const optionEnsureDBsExist = "ensure_dbs_exist"
Expand Down Expand Up @@ -173,3 +174,55 @@ func TestClusterSetup(t *testing.T) {
testy.StatusErrorRE(t, test.err, test.status, err)
})
}

func TestMembership(t *testing.T) {
type tt struct {
client *client
want *driver.ClusterMembership
status int
err string
}

tests := testy.NewTable()
tests.Add("network error", tt{
client: newTestClient(nil, errors.New("network error")),
status: http.StatusBadGateway,
err: `Get "?http://example.com/_membership"?: network error`,
})
tests.Add("success 2.3.1", func(t *testing.T) interface{} {
return tt{
client: newTestClient(&http.Response{
StatusCode: http.StatusOK,
Header: http.Header{
"Cache-Control": []string{"must-revalidate"},
"Content-Length": []string{"382"},
"Content-Type": []string{"application/json"},
"Date": []string{"Fri, 10 Jul 2020 13:12:10 GMT"},
"Server": []string{"CouchDB/2.3.1 (Erlang OTP/19)"},
},
Body: ioutil.NopCloser(strings.NewReader(`{"all_nodes":["couchdb@b2c-couchdb-0.b2c-couchdb.b2c.svc.cluster.local","couchdb@b2c-couchdb-1.b2c-couchdb.b2c.svc.cluster.local","couchdb@b2c-couchdb-2.b2c-couchdb.b2c.svc.cluster.local"],"cluster_nodes":["couchdb@b2c-couchdb-0.b2c-couchdb.b2c.svc.cluster.local","couchdb@b2c-couchdb-1.b2c-couchdb.b2c.svc.cluster.local","couchdb@b2c-couchdb-2.b2c-couchdb.b2c.svc.cluster.local"]}
`)),
}, nil),
want: &driver.ClusterMembership{
AllNodes: []string{
"couchdb@b2c-couchdb-0.b2c-couchdb.b2c.svc.cluster.local",
"couchdb@b2c-couchdb-1.b2c-couchdb.b2c.svc.cluster.local",
"couchdb@b2c-couchdb-2.b2c-couchdb.b2c.svc.cluster.local",
},
ClusterNodes: []string{
"couchdb@b2c-couchdb-0.b2c-couchdb.b2c.svc.cluster.local",
"couchdb@b2c-couchdb-1.b2c-couchdb.b2c.svc.cluster.local",
"couchdb@b2c-couchdb-2.b2c-couchdb.b2c.svc.cluster.local",
},
},
}
})

tests.Run(t, func(t *testing.T, tt tt) {
got, err := tt.client.Membership(context.Background())
testy.StatusErrorRE(t, tt.err, tt.status, err)
if d := testy.DiffInterface(tt.want, got); d != nil {
t.Error(d)
}
})
}
6 changes: 4 additions & 2 deletions couchdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ type client struct {
sdMU sync.Mutex
}

var _ driver.Client = &client{}
var _ driver.DBUpdater = &client{}
var (
_ driver.Client = &client{}
_ driver.DBUpdater = &client{}
)

// NewClient establishes a new connection to a CouchDB server instance. If
// auth credentials are included in the URL, they are used to authenticate using
Expand Down
12 changes: 7 additions & 5 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ type db struct {
dbName string
}

var _ driver.DB = &db{}
var _ driver.OptsFinder = &db{}
var _ driver.MetaGetter = &db{}
var _ driver.AttachmentMetaGetter = &db{}
var _ driver.PartitionedDB = &db{}
var (
_ driver.DB = &db{}
_ driver.OptsFinder = &db{}
_ driver.MetaGetter = &db{}
_ driver.AttachmentMetaGetter = &db{}
_ driver.PartitionedDB = &db{}
)

func (d *db) path(path string) string {
url, err := url.Parse(d.dbName + "/" + strings.TrimPrefix(path, "/"))
Expand Down
13 changes: 9 additions & 4 deletions find_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,13 @@ func TestUnmarshalQueryPlan(t *testing.T) {
{
name: "complex field list",
input: `{"dbname":"foo", "fields":[{"foo":"asc"},{"bar":"desc"}]}`,
expected: &queryPlan{DBName: "foo",
Fields: []interface{}{map[string]interface{}{"foo": "asc"},
map[string]interface{}{"bar": "desc"}}},
expected: &queryPlan{
DBName: "foo",
Fields: []interface{}{
map[string]interface{}{"foo": "asc"},
map[string]interface{}{"bar": "desc"},
},
},
},
{
name: "invalid bare string",
Expand Down Expand Up @@ -251,7 +255,8 @@ func TestGetIndexes(t *testing.T) {
Type: "json",
Definition: map[string]interface{}{
"fields": []interface{}{
map[string]interface{}{"foo": "asc"}},
map[string]interface{}{"foo": "asc"},
},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/go-kivik/couchdb/v3
go 1.13

require (
github.com/go-kivik/kivik/v3 v3.1.1
github.com/go-kivik/kivik/v3 v3.2.0
github.com/go-kivik/kiviktest/v3 v3.0.2
github.com/gopherjs/gopherjs v0.0.0-20200209144316-f9cef593def5
github.com/pkg/errors v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/flimzy/diff v0.1.5/go.mod h1:lFJtC7SPsK0EroDmGTSrdtWKAxOk3rO+q+e04LL0
github.com/flimzy/testy v0.1.17-0.20190521133342-95b386c3ece6 h1:uw6StVCll2vXdHJMAiKvhfAwcwBYD6d9dgWOIdHMku8=
github.com/flimzy/testy v0.1.17-0.20190521133342-95b386c3ece6/go.mod h1:3szguN8NXqgq9bt9Gu8TQVj698PJWmyx/VY1frwwKrM=
github.com/go-kivik/kivik/v3 v3.0.1/go.mod h1:7tmQDvkta/pcijpUjLMsQ9HJUELiKD5zm6jQ3Gb9cxE=
github.com/go-kivik/kivik/v3 v3.1.1 h1:Rz111JKpj+4hIcQyn2dZvASJWoPQNT2wpSsbN2muwk4=
github.com/go-kivik/kivik/v3 v3.1.1/go.mod h1:chqVuHKAU9j2C7qL0cAH2FCO26oL+0B4aIBeCRMnLa8=
github.com/go-kivik/kivik/v3 v3.2.0 h1:YQ6j89DrQwNdMdpWioObEP+pYTSAtF58HomS5ROfKc0=
github.com/go-kivik/kivik/v3 v3.2.0/go.mod h1:chqVuHKAU9j2C7qL0cAH2FCO26oL+0B4aIBeCRMnLa8=
github.com/go-kivik/kiviktest/v3 v3.0.2 h1:+n90Nopbrzf/tqoXu4xqAMXk1+191vLrvakBdiz7r3Y=
github.com/go-kivik/kiviktest/v3 v3.0.2/go.mod h1:sqsz3M2sJxTxAUdOj+2SU21y4phcpYc0FJIn+hbf1D0=
github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
Expand Down
3 changes: 2 additions & 1 deletion test/couchdb21.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func registerSuiteCouch21() {
"GetIndexes/NoAuth/_global_changes.status": http.StatusUnauthorized,
"GetIndexes/NoAuth/chicken.status": http.StatusNotFound,
"GetIndexes/NoAuth/_duck.status": http.StatusUnauthorized,
"GetIndexes/RW.indexes": []kivik.Index{kt.AllDocsIndex,
"GetIndexes/RW.indexes": []kivik.Index{
kt.AllDocsIndex,
{
DesignDoc: "_design/foo",
Name: "bar",
Expand Down
3 changes: 2 additions & 1 deletion test/couchdb22.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func registerSuiteCouch22() {
"GetIndexes/NoAuth/_global_changes.status": http.StatusUnauthorized,
"GetIndexes/NoAuth/chicken.status": http.StatusNotFound,
"GetIndexes/NoAuth/_duck.status": http.StatusUnauthorized,
"GetIndexes/RW.indexes": []kivik.Index{kt.AllDocsIndex,
"GetIndexes/RW.indexes": []kivik.Index{
kt.AllDocsIndex,
{
DesignDoc: "_design/foo",
Name: "bar",
Expand Down
3 changes: 2 additions & 1 deletion test/couchdb23.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func registerSuiteCouch23() {
"GetIndexes/NoAuth/_global_changes.status": http.StatusUnauthorized,
"GetIndexes/NoAuth/chicken.status": http.StatusNotFound,
"GetIndexes/NoAuth/_duck.status": http.StatusUnauthorized,
"GetIndexes/RW.indexes": []kivik.Index{kt.AllDocsIndex,
"GetIndexes/RW.indexes": []kivik.Index{
kt.AllDocsIndex,
{
DesignDoc: "_design/foo",
Name: "bar",
Expand Down
3 changes: 2 additions & 1 deletion test/couchdb30.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ func registerSuiteCouch30() {
"GetIndexes/NoAuth/_duck.status": http.StatusUnauthorized,
"GetIndexes/NoAuth/_replicator.status": http.StatusUnauthorized,
"GetIndexes/NoAuth/_users.status": http.StatusUnauthorized,
"GetIndexes/RW.indexes": []kivik.Index{kt.AllDocsIndex,
"GetIndexes/RW.indexes": []kivik.Index{
kt.AllDocsIndex,
{
DesignDoc: "_design/foo",
Name: "bar",
Expand Down
Loading

0 comments on commit 680f35a

Please sign in to comment.