|
@@ -16,6 +16,7 @@ package rafthttp
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"errors"
|
|
"errors"
|
|
|
|
|
+ "io"
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
"net/http"
|
|
|
"sync"
|
|
"sync"
|
|
@@ -25,6 +26,7 @@ import (
|
|
|
"github.com/coreos/etcd/pkg/testutil"
|
|
"github.com/coreos/etcd/pkg/testutil"
|
|
|
"github.com/coreos/etcd/pkg/types"
|
|
"github.com/coreos/etcd/pkg/types"
|
|
|
"github.com/coreos/etcd/raft/raftpb"
|
|
"github.com/coreos/etcd/raft/raftpb"
|
|
|
|
|
+ "github.com/coreos/etcd/version"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// TestPipelineSend tests that pipeline could send data using roundtripper
|
|
// TestPipelineSend tests that pipeline could send data using roundtripper
|
|
@@ -33,7 +35,7 @@ func TestPipelineSend(t *testing.T) {
|
|
|
tr := &roundTripperRecorder{}
|
|
tr := &roundTripperRecorder{}
|
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
|
fs := &stats.FollowerStats{}
|
|
fs := &stats.FollowerStats{}
|
|
|
- p := newPipeline(tr, picker, types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
+ p := newPipeline(tr, picker, types.ID(2), types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
|
p.msgc <- raftpb.Message{Type: raftpb.MsgApp}
|
|
p.msgc <- raftpb.Message{Type: raftpb.MsgApp}
|
|
|
p.stop()
|
|
p.stop()
|
|
@@ -52,7 +54,7 @@ func TestPipelineExceedMaximalServing(t *testing.T) {
|
|
|
tr := newRoundTripperBlocker()
|
|
tr := newRoundTripperBlocker()
|
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
|
fs := &stats.FollowerStats{}
|
|
fs := &stats.FollowerStats{}
|
|
|
- p := newPipeline(tr, picker, types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
+ p := newPipeline(tr, picker, types.ID(2), types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
|
// keep the sender busy and make the buffer full
|
|
// keep the sender busy and make the buffer full
|
|
|
// nothing can go out as we block the sender
|
|
// nothing can go out as we block the sender
|
|
@@ -92,7 +94,7 @@ func TestPipelineExceedMaximalServing(t *testing.T) {
|
|
|
func TestPipelineSendFailed(t *testing.T) {
|
|
func TestPipelineSendFailed(t *testing.T) {
|
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
|
fs := &stats.FollowerStats{}
|
|
fs := &stats.FollowerStats{}
|
|
|
- p := newPipeline(newRespRoundTripper(0, errors.New("blah")), picker, types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
+ p := newPipeline(newRespRoundTripper(0, errors.New("blah")), picker, types.ID(2), types.ID(1), types.ID(1), fs, &fakeRaft{}, nil)
|
|
|
|
|
|
|
|
p.msgc <- raftpb.Message{Type: raftpb.MsgApp}
|
|
p.msgc <- raftpb.Message{Type: raftpb.MsgApp}
|
|
|
p.stop()
|
|
p.stop()
|
|
@@ -107,7 +109,7 @@ func TestPipelineSendFailed(t *testing.T) {
|
|
|
func TestPipelinePost(t *testing.T) {
|
|
func TestPipelinePost(t *testing.T) {
|
|
|
tr := &roundTripperRecorder{}
|
|
tr := &roundTripperRecorder{}
|
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
picker := mustNewURLPicker(t, []string{"http://localhost:2380"})
|
|
|
- p := newPipeline(tr, picker, types.ID(1), types.ID(1), nil, &fakeRaft{}, nil)
|
|
|
|
|
|
|
+ p := newPipeline(tr, picker, types.ID(2), types.ID(1), types.ID(1), nil, &fakeRaft{}, nil)
|
|
|
if err := p.post([]byte("some data")); err != nil {
|
|
if err := p.post([]byte("some data")); err != nil {
|
|
|
t.Fatalf("unexpect post error: %v", err)
|
|
t.Fatalf("unexpect post error: %v", err)
|
|
|
}
|
|
}
|
|
@@ -122,6 +124,12 @@ func TestPipelinePost(t *testing.T) {
|
|
|
if g := tr.Request().Header.Get("Content-Type"); g != "application/protobuf" {
|
|
if g := tr.Request().Header.Get("Content-Type"); g != "application/protobuf" {
|
|
|
t.Errorf("content type = %s, want %s", g, "application/protobuf")
|
|
t.Errorf("content type = %s, want %s", g, "application/protobuf")
|
|
|
}
|
|
}
|
|
|
|
|
+ if g := tr.Request().Header.Get("X-Server-Version"); g != version.Version {
|
|
|
|
|
+ t.Errorf("version = %s, want %s", g, version.Version)
|
|
|
|
|
+ }
|
|
|
|
|
+ if g := tr.Request().Header.Get("X-Min-Cluster-Version"); g != version.MinClusterVersion {
|
|
|
|
|
+ t.Errorf("min version = %s, want %s", g, version.MinClusterVersion)
|
|
|
|
|
+ }
|
|
|
if g := tr.Request().Header.Get("X-Etcd-Cluster-ID"); g != "1" {
|
|
if g := tr.Request().Header.Get("X-Etcd-Cluster-ID"); g != "1" {
|
|
|
t.Errorf("cluster id = %s, want %s", g, "1")
|
|
t.Errorf("cluster id = %s, want %s", g, "1")
|
|
|
}
|
|
}
|
|
@@ -148,7 +156,7 @@ func TestPipelinePostBad(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
for i, tt := range tests {
|
|
for i, tt := range tests {
|
|
|
picker := mustNewURLPicker(t, []string{tt.u})
|
|
picker := mustNewURLPicker(t, []string{tt.u})
|
|
|
- p := newPipeline(newRespRoundTripper(tt.code, tt.err), picker, types.ID(1), types.ID(1), nil, &fakeRaft{}, make(chan error))
|
|
|
|
|
|
|
+ p := newPipeline(newRespRoundTripper(tt.code, tt.err), picker, types.ID(2), types.ID(1), types.ID(1), nil, &fakeRaft{}, make(chan error))
|
|
|
err := p.post([]byte("some data"))
|
|
err := p.post([]byte("some data"))
|
|
|
p.stop()
|
|
p.stop()
|
|
|
|
|
|
|
@@ -169,7 +177,7 @@ func TestPipelinePostErrorc(t *testing.T) {
|
|
|
for i, tt := range tests {
|
|
for i, tt := range tests {
|
|
|
picker := mustNewURLPicker(t, []string{tt.u})
|
|
picker := mustNewURLPicker(t, []string{tt.u})
|
|
|
errorc := make(chan error, 1)
|
|
errorc := make(chan error, 1)
|
|
|
- p := newPipeline(newRespRoundTripper(tt.code, tt.err), picker, types.ID(1), types.ID(1), nil, &fakeRaft{}, errorc)
|
|
|
|
|
|
|
+ p := newPipeline(newRespRoundTripper(tt.code, tt.err), picker, types.ID(2), types.ID(1), types.ID(1), nil, &fakeRaft{}, errorc)
|
|
|
p.post([]byte("some data"))
|
|
p.post([]byte("some data"))
|
|
|
p.stop()
|
|
p.stop()
|
|
|
select {
|
|
select {
|
|
@@ -227,5 +235,5 @@ func (t *roundTripperRecorder) Request() *http.Request {
|
|
|
|
|
|
|
|
type nopReadCloser struct{}
|
|
type nopReadCloser struct{}
|
|
|
|
|
|
|
|
-func (n *nopReadCloser) Read(p []byte) (int, error) { return 0, nil }
|
|
|
|
|
|
|
+func (n *nopReadCloser) Read(p []byte) (int, error) { return 0, io.EOF }
|
|
|
func (n *nopReadCloser) Close() error { return nil }
|
|
func (n *nopReadCloser) Close() error { return nil }
|