From 3da927759a88da388151e08efdc4e972020654f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=B7=E9=9B=A8?= <99347745@qq.com> Date: Fri, 22 Oct 2021 15:57:18 +0800 Subject: [PATCH] test: add transport http test (#1579) * test: add transport http test * fix lient * add client * add http test --- transport/http/binding/bind_test.go | 94 +++++++++++++++ transport/http/binding/encode_test.go | 9 ++ transport/http/client_test.go | 42 +++++++ transport/http/context_test.go | 167 ++++++++++++++++++++++++++ transport/http/router_test.go | 6 + transport/http/transport_test.go | 8 ++ 6 files changed, 326 insertions(+) create mode 100644 transport/http/binding/bind_test.go diff --git a/transport/http/binding/bind_test.go b/transport/http/binding/bind_test.go new file mode 100644 index 000000000..dae7faa8d --- /dev/null +++ b/transport/http/binding/bind_test.go @@ -0,0 +1,94 @@ +package binding + +import ( + "net/http" + "net/url" + "reflect" + "testing" +) + +func TestBindQuery(t *testing.T) { + type TestBind struct { + Name string `json:"name"` + URL string `json:"url"` + } + p1 := TestBind{} + type args struct { + vars url.Values + target interface{} + } + tests := []struct { + name string + args args + wantErr bool + want interface{} + }{ + { + name: "test", + args: args{ + vars: map[string][]string{"name": {"kratos"}, "url": {"https://go-kratos.dev/"}}, + target: &p1, + }, + wantErr: false, + want: TestBind{"kratos", "https://go-kratos.dev/"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := BindQuery(tt.args.vars, tt.args.target); (err != nil) != tt.wantErr { + t.Errorf("BindQuery() error = %v, wantErr %v", err, tt.wantErr) + } + if reflect.DeepEqual(tt.args.target, tt.want) { + t.Errorf("BindQuery() target = %v, want %v", tt.args.target, tt.want) + } + }) + } +} + +func TestBindForm(t *testing.T) { + type TestBind struct { + Name string `json:"name"` + URL string `json:"url"` + } + p1 := TestBind{} + type args struct { + req *http.Request + target interface{} + } + tests := []struct { + name string + args args + wantErr bool + want interface{} + }{ + { + name: "error not nil", + args: args{ + req: &http.Request{Method: "POST"}, + target: &p1, + }, + wantErr: true, + want: nil, + }, + { + name: "error is nil", + args: args{ + req: &http.Request{Form: map[string][]string{"name": {"kratos"}, "url": {"https://go-kratos.dev/"}}}, + target: &p1, + }, + wantErr: false, + want: TestBind{"kratos", "https://go-kratos.dev/"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := BindForm(tt.args.req, tt.args.target) + if (err != nil) != tt.wantErr { + t.Errorf("BindForm() error = %v, wantErr %v", err, tt.wantErr) + } + if err != nil && reflect.DeepEqual(tt.args.target, tt.want) { + t.Errorf("BindQuery() target = %v, want %v", tt.args.target, tt.want) + } + }) + } +} diff --git a/transport/http/binding/encode_test.go b/transport/http/binding/encode_test.go index 9cba7bc9f..5cf574364 100644 --- a/transport/http/binding/encode_test.go +++ b/transport/http/binding/encode_test.go @@ -37,4 +37,13 @@ func TestProtoPath(t *testing.T) { if url != `http://helloworld.Greeter/helloworld/test/sub/{sub.name33}` { t.Fatalf("proto path not expected!actual: %s ", url) } + + url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub", &binding.HelloRequest{ + Name: "go", + Sub: &binding.Sub{Name: "kratos"}, + }, true) + fmt.Println(url) + if url != `http://helloworld.Greeter/helloworld/go/sub?sub.naming=kratos` { + t.Fatalf("proto path not expected!actual: %s ", url) + } } diff --git a/transport/http/client_test.go b/transport/http/client_test.go index 0a2872c5d..3d9445e06 100644 --- a/transport/http/client_test.go +++ b/transport/http/client_test.go @@ -111,9 +111,19 @@ func (*mockDiscovery) GetService(ctx context.Context, serviceName string) ([]*re } func (*mockDiscovery) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) { + return &mockWatcher{}, nil +} + +type mockWatcher struct{} + +func (*mockWatcher) Next() ([]*registry.ServiceInstance, error) { return nil, nil } +func (*mockWatcher) Stop() error { + return nil +} + func TestWithDiscovery(t *testing.T) { ov := &mockDiscovery{} o := WithDiscovery(ov) @@ -203,3 +213,35 @@ func TestCodecForResponse(t *testing.T) { c := CodecForResponse(resp) assert.Equal(t, "xml", c.Name()) } + +func TestNewClient(t *testing.T) { + _, err := NewClient(context.Background(), WithEndpoint("127.0.0.1:8888")) + if err != nil { + t.Error(err) + } + _, err = NewClient(context.Background(), WithEndpoint("127.0.0.1:9999"), WithTLSConfig(&tls.Config{ServerName: "www.kratos.com", RootCAs: nil})) + if err != nil { + t.Error(err) + } + client, err := NewClient(context.Background(), WithDiscovery(&mockDiscovery{}), WithEndpoint("discovery:///go-kratos")) + if err != nil { + t.Error(err) + } + _, err = NewClient(context.Background(), WithDiscovery(&mockDiscovery{}), WithEndpoint("discovery:///go-kratos")) + if err != nil { + t.Error(err) + } + _, err = NewClient(context.Background(), WithDiscovery(&mockDiscovery{}), WithEndpoint("127.0.0.1:8888")) + if err != nil { + t.Error(err) + } + _, err = NewClient(context.Background(), WithDiscovery(&mockDiscovery{}), WithEndpoint("https://go-kratos.dev/")) + if err == nil { + t.Error("err should not be equal to nil") + } + + err = client.Invoke(context.Background(), "POST", "/go", map[string]string{"name": "kratos"}, nil, EmptyCallOption{}) + if err == nil { + t.Error("err should not be equal to nil") + } +} diff --git a/transport/http/context_test.go b/transport/http/context_test.go index d02cfda64..07ec8c03e 100644 --- a/transport/http/context_test.go +++ b/transport/http/context_test.go @@ -1 +1,168 @@ package http + +import ( + "bytes" + "context" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestContextHeader(t *testing.T) { + w := wrapper{ + router: nil, + req: &http.Request{Header: map[string][]string{"name": {"kratos"}}}, + res: nil, + w: responseWriter{}, + } + h := w.Header() + assert.Equal(t, h, http.Header{"name": {"kratos"}}) +} + +func TestContextForm(t *testing.T) { + w := wrapper{ + router: nil, + req: &http.Request{Header: map[string][]string{"name": {"kratos"}}, Method: "POST"}, + res: nil, + w: responseWriter{}, + } + form := w.Form() + assert.Equal(t, form, url.Values{}) + + w = wrapper{ + router: nil, + req: &http.Request{Form: map[string][]string{"name": {"kratos"}}}, + res: nil, + w: responseWriter{}, + } + form = w.Form() + assert.Equal(t, form, url.Values{"name": []string{"kratos"}}) +} + +func TestContextQuery(t *testing.T) { + w := wrapper{ + router: nil, + req: &http.Request{URL: &url.URL{Scheme: "https", Host: "github.com", Path: "go-kratos/kratos", RawQuery: "page=1"}, Method: "POST"}, + res: nil, + w: responseWriter{}, + } + q := w.Query() + assert.Equal(t, q, url.Values{"page": []string{"1"}}) +} + +func TestContextRequest(t *testing.T) { + req := &http.Request{Method: "POST"} + w := wrapper{ + router: nil, + req: req, + res: nil, + w: responseWriter{}, + } + res := w.Request() + assert.Equal(t, res, req) +} + +func TestContextResponse(t *testing.T) { + res := httptest.NewRecorder() + w := wrapper{ + router: &Router{srv: &Server{enc: DefaultResponseEncoder}}, + req: &http.Request{Method: "POST"}, + res: res, + w: responseWriter{200, res}, + } + assert.Equal(t, w.Response(), res) + err := w.Returns(map[string]string{}, nil) + assert.Nil(t, err) +} + +func TestContextBindQuery(t *testing.T) { + w := wrapper{ + router: nil, + req: &http.Request{URL: &url.URL{Scheme: "https", Host: "go-kratos-dev", RawQuery: "page=2"}}, + res: nil, + w: responseWriter{}, + } + type BindQuery struct { + Page int `json:"page"` + } + b := BindQuery{} + err := w.BindQuery(&b) + assert.Nil(t, err) + assert.Equal(t, b, BindQuery{Page: 2}) +} + +func TestContextBindForm(t *testing.T) { + w := wrapper{ + router: nil, + req: &http.Request{URL: &url.URL{Scheme: "https", Host: "go-kratos-dev"}, Form: map[string][]string{"page": {"2"}}}, + res: nil, + w: responseWriter{}, + } + type BindForm struct { + Page int `json:"page"` + } + b := BindForm{} + err := w.BindForm(&b) + assert.Nil(t, err) + assert.Equal(t, b, BindForm{Page: 2}) +} + +func TestContextResponseReturn(t *testing.T) { + writer := httptest.NewRecorder() + w := wrapper{ + router: nil, + req: nil, + res: writer, + w: responseWriter{}, + } + err := w.JSON(200, "success") + assert.Nil(t, err) + err = w.XML(200, "success") + assert.Nil(t, err) + err = w.String(200, "success") + assert.Nil(t, err) + err = w.Blob(200, "blob", []byte("success")) + assert.Nil(t, err) + err = w.Stream(200, "stream", bytes.NewBuffer([]byte("success"))) + assert.Nil(t, err) +} + +func TestContextCtx(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + req := &http.Request{Method: "POST"} + req = req.WithContext(ctx) + w := wrapper{ + router: &Router{srv: &Server{enc: DefaultResponseEncoder}}, + req: req, + res: nil, + w: responseWriter{}, + } + _, ok := w.Deadline() + assert.Equal(t, ok, true) + done := w.Done() + assert.NotNil(t, done) + err := w.Err() + assert.Nil(t, err) + v := w.Value("test") + assert.Nil(t, v) + + w = wrapper{ + router: &Router{srv: &Server{enc: DefaultResponseEncoder}}, + req: nil, + res: nil, + w: responseWriter{}, + } + _, ok = w.Deadline() + assert.Equal(t, ok, false) + done = w.Done() + assert.Nil(t, done) + err = w.Err() + assert.NotNil(t, err) + v = w.Value("test") + assert.Nil(t, v) +} diff --git a/transport/http/router_test.go b/transport/http/router_test.go index cc9f0a0b7..53507ed3c 100644 --- a/transport/http/router_test.go +++ b/transport/http/router_test.go @@ -184,4 +184,10 @@ func TestHandle(t *testing.T) { return nil } r.GET("/get", h) + r.HEAD("/head", h) + r.PATCH("/patch", h) + r.DELETE("/delete", h) + r.CONNECT("/connect", h) + r.OPTIONS("/options", h) + r.TRACE("/trace", h) } diff --git a/transport/http/transport_test.go b/transport/http/transport_test.go index 50da37d45..ed2de92ff 100644 --- a/transport/http/transport_test.go +++ b/transport/http/transport_test.go @@ -1,6 +1,7 @@ package http import ( + "context" "net/http" "testing" @@ -57,3 +58,10 @@ func TestHeaderCarrier_Keys(t *testing.T) { v.Set("bcc", "2") assert.ElementsMatch(t, []string{"Abb", "Bcc"}, v.Keys()) } + +func TestSetOperation(t *testing.T) { + tr := &Transport{} + ctx := transport.NewServerContext(context.Background(), tr) + SetOperation(ctx, "kratos") + assert.Equal(t, tr.operation, "kratos") +}