Browse Source

Merge pull request #7222 from gyuho/manual

client: add GetVersion method
Gyu-Ho Lee 9 years ago
parent
commit
0fea49f8fa
2 changed files with 62 additions and 0 deletions
  1. 33 0
      client/client.go
  2. 29 0
      client/client_test.go

+ 33 - 0
client/client.go

@@ -15,6 +15,7 @@
 package client
 
 import (
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io/ioutil"
@@ -27,6 +28,8 @@ import (
 	"sync"
 	"time"
 
+	"github.com/coreos/etcd/version"
+
 	"golang.org/x/net/context"
 )
 
@@ -201,6 +204,9 @@ type Client interface {
 	// returned
 	SetEndpoints(eps []string) error
 
+	// GetVersion retrieves the current etcd server and cluster version
+	GetVersion(ctx context.Context) (*version.Versions, error)
+
 	httpClient
 }
 
@@ -477,6 +483,33 @@ func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration
 	}
 }
 
+func (c *httpClusterClient) GetVersion(ctx context.Context) (*version.Versions, error) {
+	act := &getAction{Prefix: "/version"}
+
+	resp, body, err := c.Do(ctx, act)
+	if err != nil {
+		return nil, err
+	}
+
+	switch resp.StatusCode {
+	case http.StatusOK:
+		if len(body) == 0 {
+			return nil, ErrEmptyBody
+		}
+		var vresp version.Versions
+		if err := json.Unmarshal(body, &vresp); err != nil {
+			return nil, ErrInvalidJSON
+		}
+		return &vresp, nil
+	default:
+		var etcdErr Error
+		if err := json.Unmarshal(body, &etcdErr); err != nil {
+			return nil, ErrInvalidJSON
+		}
+		return nil, etcdErr
+	}
+}
+
 type roundTripResponse struct {
 	resp *http.Response
 	err  error

+ 29 - 0
client/client_test.go

@@ -28,6 +28,7 @@ import (
 	"time"
 
 	"github.com/coreos/etcd/pkg/testutil"
+	"github.com/coreos/etcd/version"
 	"golang.org/x/net/context"
 )
 
@@ -860,6 +861,34 @@ func TestHTTPClusterClientAutoSyncFail(t *testing.T) {
 	}
 }
 
+func TestHTTPClusterClientGetVersion(t *testing.T) {
+	body := []byte(`{"etcdserver":"2.3.2","etcdcluster":"2.3.0"}`)
+	cf := newStaticHTTPClientFactory([]staticHTTPResponse{
+		{
+			resp: http.Response{StatusCode: http.StatusOK, Header: http.Header{"Content-Length": []string{"44"}}},
+			body: body,
+		},
+	})
+
+	hc := &httpClusterClient{
+		clientFactory: cf,
+		rand:          rand.New(rand.NewSource(0)),
+	}
+	err := hc.SetEndpoints([]string{"http://127.0.0.1:4003", "http://127.0.0.1:2379", "http://127.0.0.1:4001", "http://127.0.0.1:4002"})
+	if err != nil {
+		t.Fatalf("unexpected error during setup: %#v", err)
+	}
+
+	actual, err := hc.GetVersion(context.Background())
+	if err != nil {
+		t.Errorf("non-nil error: %#v", err)
+	}
+	expected := version.Versions{Server: "2.3.2", Cluster: "2.3.0"}
+	if !reflect.DeepEqual(&expected, actual) {
+		t.Errorf("incorrect Response: want=%#v got=%#v", expected, actual)
+	}
+}
+
 // TestHTTPClusterClientSyncPinEndpoint tests that Sync() pins the endpoint when
 // it gets the exactly same member list as before.
 func TestHTTPClusterClientSyncPinEndpoint(t *testing.T) {