github.com/go-kivik/kivik/v4@v4.3.2/cluster_test.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 kivik
    14  
    15  import (
    16  	"context"
    17  	"errors"
    18  	"net/http"
    19  	"testing"
    20  
    21  	"gitlab.com/flimzy/testy"
    22  
    23  	"github.com/go-kivik/kivik/v4/driver"
    24  	internal "github.com/go-kivik/kivik/v4/int/errors"
    25  	"github.com/go-kivik/kivik/v4/int/mock"
    26  )
    27  
    28  func TestClusterStatus(t *testing.T) {
    29  	type tst struct {
    30  		client   driver.Client
    31  		closed   bool
    32  		options  Option
    33  		expected string
    34  		status   int
    35  		err      string
    36  	}
    37  	tests := testy.NewTable()
    38  	tests.Add("driver doesn't implement Cluster interface", tst{
    39  		client: &mock.Client{},
    40  		status: http.StatusNotImplemented,
    41  		err:    "kivik: driver does not support cluster operations",
    42  	})
    43  	tests.Add("client error", tst{
    44  		client: &mock.Cluster{
    45  			ClusterStatusFunc: func(context.Context, driver.Options) (string, error) {
    46  				return "", errors.New("client error")
    47  			},
    48  		},
    49  		status: http.StatusInternalServerError,
    50  		err:    "client error",
    51  	})
    52  	tests.Add("success", tst{
    53  		client: &mock.Cluster{
    54  			ClusterStatusFunc: func(context.Context, driver.Options) (string, error) {
    55  				return "cluster_finished", nil
    56  			},
    57  		},
    58  		expected: "cluster_finished",
    59  	})
    60  	tests.Add("client closed", tst{
    61  		client: &mock.Cluster{},
    62  		closed: true,
    63  		status: http.StatusServiceUnavailable,
    64  		err:    "kivik: client closed",
    65  	})
    66  
    67  	tests.Run(t, func(t *testing.T, test tst) {
    68  		c := &Client{
    69  			driverClient: test.client,
    70  			closed:       test.closed,
    71  		}
    72  		result, err := c.ClusterStatus(context.Background(), test.options)
    73  		if d := internal.StatusErrorDiff(test.err, test.status, err); d != "" {
    74  			t.Error(d)
    75  		}
    76  		if result != test.expected {
    77  			t.Errorf("Unexpected status:\nExpected: %s\n  Actual: %s\n", test.expected, result)
    78  		}
    79  	})
    80  }
    81  
    82  func TestClusterSetup(t *testing.T) {
    83  	type tst struct {
    84  		client driver.Client
    85  		closed bool
    86  		action interface{}
    87  		status int
    88  		err    string
    89  	}
    90  
    91  	tests := testy.NewTable()
    92  	tests.Add("driver doesn't implement Cluster interface", tst{
    93  		client: &mock.Client{},
    94  		status: http.StatusNotImplemented,
    95  		err:    "kivik: driver does not support cluster operations",
    96  	})
    97  	tests.Add("client error", tst{
    98  		client: &mock.Cluster{
    99  			ClusterSetupFunc: func(context.Context, interface{}) error {
   100  				return errors.New("client error")
   101  			},
   102  		},
   103  		status: http.StatusInternalServerError,
   104  		err:    "client error",
   105  	})
   106  	tests.Add("success", tst{
   107  		client: &mock.Cluster{
   108  			ClusterSetupFunc: func(context.Context, interface{}) error {
   109  				return nil
   110  			},
   111  		},
   112  	})
   113  	tests.Add("client closed", tst{
   114  		client: &mock.Cluster{},
   115  		closed: true,
   116  		status: http.StatusServiceUnavailable,
   117  		err:    "kivik: client closed",
   118  	})
   119  
   120  	tests.Run(t, func(t *testing.T, test tst) {
   121  		c := &Client{
   122  			driverClient: test.client,
   123  			closed:       test.closed,
   124  		}
   125  		err := c.ClusterSetup(context.Background(), test.action)
   126  		if d := internal.StatusErrorDiff(test.err, test.status, err); d != "" {
   127  			t.Error(d)
   128  		}
   129  	})
   130  }
   131  
   132  func TestMembership(t *testing.T) {
   133  	type tt struct {
   134  		client driver.Client
   135  		closed bool
   136  		want   *ClusterMembership
   137  		status int
   138  		err    string
   139  	}
   140  
   141  	tests := testy.NewTable()
   142  	tests.Add("driver doesn't implement Cluster interface", tt{
   143  		client: &mock.Client{},
   144  		status: http.StatusNotImplemented,
   145  		err:    "kivik: driver does not support cluster operations",
   146  	})
   147  	tests.Add("client error", tt{
   148  		client: &mock.Cluster{
   149  			MembershipFunc: func(context.Context) (*driver.ClusterMembership, error) {
   150  				return nil, errors.New("client error")
   151  			},
   152  		},
   153  		status: http.StatusInternalServerError,
   154  		err:    "client error",
   155  	})
   156  	tests.Add("success", tt{
   157  		client: &mock.Cluster{
   158  			MembershipFunc: func(context.Context) (*driver.ClusterMembership, error) {
   159  				return &driver.ClusterMembership{
   160  					AllNodes:     []string{"one", "two", "three"},
   161  					ClusterNodes: []string{"one", "two"},
   162  				}, nil
   163  			},
   164  		},
   165  		want: &ClusterMembership{
   166  			AllNodes:     []string{"one", "two", "three"},
   167  			ClusterNodes: []string{"one", "two"},
   168  		},
   169  	})
   170  	tests.Add("client closed", tt{
   171  		client: &mock.Cluster{},
   172  		closed: true,
   173  		status: http.StatusServiceUnavailable,
   174  		err:    "kivik: client closed",
   175  	})
   176  
   177  	tests.Run(t, func(t *testing.T, tt tt) {
   178  		c := &Client{
   179  			driverClient: tt.client,
   180  			closed:       tt.closed,
   181  		}
   182  		got, err := c.Membership(context.Background())
   183  		if d := internal.StatusErrorDiff(tt.err, tt.status, err); d != "" {
   184  			t.Error(d)
   185  		}
   186  		if err != nil {
   187  			return
   188  		}
   189  		if d := testy.DiffInterface(tt.want, got); d != nil {
   190  			t.Error(d)
   191  		}
   192  	})
   193  }