| @@ -1,4 +1,4 @@ | |||||||
| # Go Micro [](https://godoc.org/github.com/micro/go-micro) [](https://travis-ci.org/micro/go-micro) | # Go Micro [](https://godoc.org/github.com/micro/go-micro) [](https://travis-ci.org/micro/go-micro) [](https://goreportcard.com/report/github.com/micro/go-micro) | ||||||
|  |  | ||||||
| Go Micro is a pluggable RPC based microservice library which provides the fundamental building blocks for writing distributed applications. It is part of the [Micro](https://github.com/micro/micro) toolkit. It supports Proto-RPC and JSON-RPC as the request/response protocol out of the box and defaults to Consul for discovery. | Go Micro is a pluggable RPC based microservice library which provides the fundamental building blocks for writing distributed applications. It is part of the [Micro](https://github.com/micro/micro) toolkit. It supports Proto-RPC and JSON-RPC as the request/response protocol out of the box and defaults to Consul for discovery. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								broker/http_broker_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								broker/http_broker_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | package broker | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/micro/go-micro/registry/mock" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestBroker(t *testing.T) { | ||||||
|  | 	m := mock.NewRegistry() | ||||||
|  | 	b := NewBroker([]string{}, Registry(m)) | ||||||
|  |  | ||||||
|  | 	if err := b.Init(); err != nil { | ||||||
|  | 		t.Errorf("Unexpected init error: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := b.Connect(); err != nil { | ||||||
|  | 		t.Errorf("Unexpected connect error: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	msg := &Message{ | ||||||
|  | 		Header: map[string]string{ | ||||||
|  | 			"Content-Type": "application/json", | ||||||
|  | 		}, | ||||||
|  | 		Body: []byte(`{"message": "Hello World"}`), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	done := make(chan bool) | ||||||
|  |  | ||||||
|  | 	sub, err := b.Subscribe("test", func(p Publication) error { | ||||||
|  | 		m := p.Message() | ||||||
|  | 		t.Logf("Received message %+v", m) | ||||||
|  |  | ||||||
|  | 		if string(m.Body) != string(msg.Body) { | ||||||
|  | 			t.Errorf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		close(done) | ||||||
|  | 		return nil | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Errorf("Unexpected subscribe error: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := b.Publish("test", msg); err != nil { | ||||||
|  | 		t.Errorf("Unexpected publish error: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	<-done | ||||||
|  | 	sub.Unsubscribe() | ||||||
|  |  | ||||||
|  | 	if err := b.Disconnect(); err != nil { | ||||||
|  | 		t.Errorf("Unexpected disconnect error: %v", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								metadata/metadata_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								metadata/metadata_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | package metadata | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"golang.org/x/net/context" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMetadataContext(t *testing.T) { | ||||||
|  | 	md := Metadata{ | ||||||
|  | 		"foo": "bar", | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx := NewContext(context.TODO(), md) | ||||||
|  |  | ||||||
|  | 	emd, ok := FromContext(ctx) | ||||||
|  | 	if !ok { | ||||||
|  | 		t.Errorf("Unexpected error retrieving metadata, got %t", ok) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if emd["foo"] != md["foo"] { | ||||||
|  | 		t.Errorf("Expected key: %s val: %s, got key: %s val: %s", "foo", md["foo"], "foo", emd["foo"]) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if i := len(emd); i != 1 { | ||||||
|  | 		t.Errorf("Expected metadata length 1 got %d", i) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								registry/mock/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								registry/mock/helper.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | package mock | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/micro/go-micro/registry" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func addNodes(old, neu []*registry.Node) []*registry.Node { | ||||||
|  | 	for _, n := range neu { | ||||||
|  | 		var seen bool | ||||||
|  | 		for i, o := range old { | ||||||
|  | 			if o.Id == n.Id { | ||||||
|  | 				seen = true | ||||||
|  | 				old[i] = n | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if !seen { | ||||||
|  | 			old = append(old, n) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return old | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func addServices(old, neu []*registry.Service) []*registry.Service { | ||||||
|  | 	for _, s := range neu { | ||||||
|  | 		var seen bool | ||||||
|  | 		for i, o := range old { | ||||||
|  | 			if o.Version == s.Version { | ||||||
|  | 				s.Nodes = addNodes(o.Nodes, s.Nodes) | ||||||
|  | 				seen = true | ||||||
|  | 				old[i] = s | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if !seen { | ||||||
|  | 			old = append(old, s) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return old | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func delNodes(old, del []*registry.Node) []*registry.Node { | ||||||
|  | 	var nodes []*registry.Node | ||||||
|  | 	for _, o := range old { | ||||||
|  | 		var rem bool | ||||||
|  | 		for _, n := range del { | ||||||
|  | 			if o.Id == n.Id { | ||||||
|  | 				rem = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if !rem { | ||||||
|  | 			nodes = append(nodes, o) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nodes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func delServices(old, del []*registry.Service) []*registry.Service { | ||||||
|  | 	var services []*registry.Service | ||||||
|  | 	for i, o := range old { | ||||||
|  | 		var rem bool | ||||||
|  | 		for _, s := range del { | ||||||
|  | 			if o.Version == s.Version { | ||||||
|  | 				old[i].Nodes = delNodes(o.Nodes, s.Nodes) | ||||||
|  | 				if len(old[i].Nodes) == 0 { | ||||||
|  | 					rem = true | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if !rem { | ||||||
|  | 			services = append(services, o) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return services | ||||||
|  | } | ||||||
							
								
								
									
										78
									
								
								registry/mock/helper_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								registry/mock/helper_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | package mock | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/micro/go-micro/registry" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestDelServices(t *testing.T) { | ||||||
|  | 	services := []*registry.Service{ | ||||||
|  | 		{ | ||||||
|  | 			Name:    "foo", | ||||||
|  | 			Version: "1.0.0", | ||||||
|  | 			Nodes: []*registry.Node{ | ||||||
|  | 				{ | ||||||
|  | 					Id:      "foo-123", | ||||||
|  | 					Address: "localhost", | ||||||
|  | 					Port:    9999, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			Name:    "foo", | ||||||
|  | 			Version: "1.0.0", | ||||||
|  | 			Nodes: []*registry.Node{ | ||||||
|  | 				{ | ||||||
|  | 					Id:      "foo-123", | ||||||
|  | 					Address: "localhost", | ||||||
|  | 					Port:    6666, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	servs := delServices([]*registry.Service{services[0]}, []*registry.Service{services[1]}) | ||||||
|  | 	if i := len(servs); i > 0 { | ||||||
|  | 		t.Errorf("Expected 0 nodes, got %d: %+v", i, servs) | ||||||
|  | 	} | ||||||
|  | 	t.Logf("Services %+v", servs) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestDelNodes(t *testing.T) { | ||||||
|  | 	services := []*registry.Service{ | ||||||
|  | 		{ | ||||||
|  | 			Name:    "foo", | ||||||
|  | 			Version: "1.0.0", | ||||||
|  | 			Nodes: []*registry.Node{ | ||||||
|  | 				{ | ||||||
|  | 					Id:      "foo-123", | ||||||
|  | 					Address: "localhost", | ||||||
|  | 					Port:    9999, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Id:      "foo-321", | ||||||
|  | 					Address: "localhost", | ||||||
|  | 					Port:    6666, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			Name:    "foo", | ||||||
|  | 			Version: "1.0.0", | ||||||
|  | 			Nodes: []*registry.Node{ | ||||||
|  | 				{ | ||||||
|  | 					Id:      "foo-123", | ||||||
|  | 					Address: "localhost", | ||||||
|  | 					Port:    6666, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	nodes := delNodes(services[0].Nodes, services[1].Nodes) | ||||||
|  | 	if i := len(nodes); i != 1 { | ||||||
|  | 		t.Errorf("Expected only 1 node, got %d: %+v", i, nodes) | ||||||
|  | 	} | ||||||
|  | 	t.Logf("Nodes %+v", nodes) | ||||||
|  | } | ||||||
| @@ -8,48 +8,54 @@ type MockRegistry struct { | |||||||
| 	Services map[string][]*registry.Service | 	Services map[string][]*registry.Service | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MockRegistry) init() { | var ( | ||||||
| 	// add some mock data | 	mockData = map[string][]*registry.Service{ | ||||||
| 	m.Services["foo"] = []*registry.Service{ | 		"foo": []*registry.Service{ | ||||||
| 		{ | 			{ | ||||||
| 			Name:    "foo", | 				Name:    "foo", | ||||||
| 			Version: "1.0.0", | 				Version: "1.0.0", | ||||||
| 			Nodes: []*registry.Node{ | 				Nodes: []*registry.Node{ | ||||||
| 				{ | 					{ | ||||||
| 					Id:      "foo-1.0.0-123", | 						Id:      "foo-1.0.0-123", | ||||||
| 					Address: "localhost", | 						Address: "localhost", | ||||||
| 					Port:    9999, | 						Port:    9999, | ||||||
| 				}, | 					}, | ||||||
| 				{ | 					{ | ||||||
| 					Id:      "foo-1.0.0-321", | 						Id:      "foo-1.0.0-321", | ||||||
| 					Address: "localhost", | 						Address: "localhost", | ||||||
| 					Port:    9999, | 						Port:    9999, | ||||||
|  | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 			{ | ||||||
| 		{ | 				Name:    "foo", | ||||||
| 			Name:    "foo", | 				Version: "1.0.1", | ||||||
| 			Version: "1.0.1", | 				Nodes: []*registry.Node{ | ||||||
| 			Nodes: []*registry.Node{ | 					{ | ||||||
| 				{ | 						Id:      "foo-1.0.1-321", | ||||||
| 					Id:      "foo-1.0.1-321", | 						Address: "localhost", | ||||||
| 					Address: "localhost", | 						Port:    6666, | ||||||
| 					Port:    6666, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 			{ | ||||||
| 		{ | 				Name:    "foo", | ||||||
| 			Name:    "foo", | 				Version: "1.0.3", | ||||||
| 			Version: "1.0.3", | 				Nodes: []*registry.Node{ | ||||||
| 			Nodes: []*registry.Node{ | 					{ | ||||||
| 				{ | 						Id:      "foo-1.0.3-345", | ||||||
| 					Id:      "foo-1.0.3-345", | 						Address: "localhost", | ||||||
| 					Address: "localhost", | 						Port:    8888, | ||||||
| 					Port:    8888, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func (m *MockRegistry) init() { | ||||||
|  | 	// add some mock data | ||||||
|  | 	m.Services = mockData | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MockRegistry) GetService(service string) ([]*registry.Service, error) { | func (m *MockRegistry) GetService(service string) ([]*registry.Service, error) { | ||||||
| @@ -70,10 +76,14 @@ func (m *MockRegistry) ListServices() ([]*registry.Service, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MockRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error { | func (m *MockRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error { | ||||||
|  | 	services := addServices(m.Services[s.Name], []*registry.Service{s}) | ||||||
|  | 	m.Services[s.Name] = services | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MockRegistry) Deregister(s *registry.Service) error { | func (m *MockRegistry) Deregister(s *registry.Service) error { | ||||||
|  | 	services := delServices(m.Services[s.Name], []*registry.Service{s}) | ||||||
|  | 	m.Services[s.Name] = services | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										138
									
								
								registry/mock/mock_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								registry/mock/mock_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | |||||||
|  | package mock | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/micro/go-micro/registry" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	testData = map[string][]*registry.Service{ | ||||||
|  | 		"foo": []*registry.Service{ | ||||||
|  | 			{ | ||||||
|  | 				Name:    "foo", | ||||||
|  | 				Version: "1.0.0", | ||||||
|  | 				Nodes: []*registry.Node{ | ||||||
|  | 					{ | ||||||
|  | 						Id:      "foo-1.0.0-123", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    9999, | ||||||
|  | 					}, | ||||||
|  | 					{ | ||||||
|  | 						Id:      "foo-1.0.0-321", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    9999, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Name:    "foo", | ||||||
|  | 				Version: "1.0.1", | ||||||
|  | 				Nodes: []*registry.Node{ | ||||||
|  | 					{ | ||||||
|  | 						Id:      "foo-1.0.1-321", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    6666, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Name:    "foo", | ||||||
|  | 				Version: "1.0.3", | ||||||
|  | 				Nodes: []*registry.Node{ | ||||||
|  | 					{ | ||||||
|  | 						Id:      "foo-1.0.3-345", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    8888, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		"bar": []*registry.Service{ | ||||||
|  | 			{ | ||||||
|  | 				Name:    "bar", | ||||||
|  | 				Version: "default", | ||||||
|  | 				Nodes: []*registry.Node{ | ||||||
|  | 					{ | ||||||
|  | 						Id:      "bar-1.0.0-123", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    9999, | ||||||
|  | 					}, | ||||||
|  | 					{ | ||||||
|  | 						Id:      "bar-1.0.0-321", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    9999, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Name:    "bar", | ||||||
|  | 				Version: "latest", | ||||||
|  | 				Nodes: []*registry.Node{ | ||||||
|  | 					{ | ||||||
|  | 						Id:      "bar-1.0.1-321", | ||||||
|  | 						Address: "localhost", | ||||||
|  | 						Port:    6666, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMockRegistry(t *testing.T) { | ||||||
|  | 	m := NewRegistry() | ||||||
|  |  | ||||||
|  | 	fn := func(k string, v []*registry.Service) { | ||||||
|  | 		services, err := m.GetService(k) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Unexpected error getting service %s: %v", k, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(services) != len(v) { | ||||||
|  | 			t.Errorf("Expected %d services for %s, got %d", len(v), k, len(services)) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, service := range v { | ||||||
|  | 			var seen bool | ||||||
|  | 			for _, s := range services { | ||||||
|  | 				if s.Version == service.Version { | ||||||
|  | 					seen = true | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if !seen { | ||||||
|  | 				t.Errorf("expected to find version %s", service.Version) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// test existing mock data | ||||||
|  | 	for k, v := range mockData { | ||||||
|  | 		fn(k, v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// register data | ||||||
|  | 	for _, v := range testData { | ||||||
|  | 		for _, service := range v { | ||||||
|  | 			if err := m.Register(service); err != nil { | ||||||
|  | 				t.Errorf("Unexpected register error: %v", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// using test data | ||||||
|  | 	for k, v := range testData { | ||||||
|  |  | ||||||
|  | 		fn(k, v) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// deregister | ||||||
|  | 	for _, v := range testData { | ||||||
|  | 		for _, service := range v { | ||||||
|  | 			if err := m.Deregister(service); err != nil { | ||||||
|  | 				t.Errorf("Unexpected deregister error: %v", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -7,7 +7,17 @@ import ( | |||||||
| 	"github.com/micro/go-micro/transport" | 	"github.com/micro/go-micro/transport" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestHTTPTransport_PortRange(t *testing.T) { | func expectedPort(t *testing.T, expected string, lsn transport.Listener) { | ||||||
|  | 	parts := strings.Split(lsn.Addr(), ":") | ||||||
|  | 	port := parts[len(parts)-1] | ||||||
|  |  | ||||||
|  | 	if port != expected { | ||||||
|  | 		lsn.Close() | ||||||
|  | 		t.Errorf("Expected address to be `%s`, got `%s`", expected, port) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestHTTPTransportPortRange(t *testing.T) { | ||||||
| 	tp := transport.NewTransport([]string{}) | 	tp := transport.NewTransport([]string{}) | ||||||
|  |  | ||||||
| 	lsn1, err := tp.Listen(":44444-44448") | 	lsn1, err := tp.Listen(":44444-44448") | ||||||
| @@ -32,12 +42,70 @@ func TestHTTPTransport_PortRange(t *testing.T) { | |||||||
| 	lsn2.Close() | 	lsn2.Close() | ||||||
| } | } | ||||||
|  |  | ||||||
| func expectedPort(t *testing.T, expected string, lsn transport.Listener) { | func TestHTTPTransportCommunication(t *testing.T) { | ||||||
| 	parts := strings.Split(lsn.Addr(), ":") | 	tr := transport.NewTransport([]string{}) | ||||||
| 	port := parts[len(parts)-1] |  | ||||||
|  |  | ||||||
| 	if port != expected { | 	l, err := tr.Listen(":0") | ||||||
| 		lsn.Close() | 	if err != nil { | ||||||
| 		t.Errorf("Expected address to be `%s`, got `%s`", expected, port) | 		t.Errorf("Unexpected listen err: %v", err) | ||||||
| 	} | 	} | ||||||
|  | 	defer l.Close() | ||||||
|  |  | ||||||
|  | 	fn := func(sock transport.Socket) { | ||||||
|  | 		defer sock.Close() | ||||||
|  |  | ||||||
|  | 		for { | ||||||
|  | 			var m transport.Message | ||||||
|  | 			if err := sock.Recv(&m); err != nil { | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			t.Logf("Successfully received %+v", m) | ||||||
|  |  | ||||||
|  | 			if err := sock.Send(&m); err != nil { | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	done := make(chan bool) | ||||||
|  |  | ||||||
|  | 	go func() { | ||||||
|  | 		if err := l.Accept(fn); err != nil { | ||||||
|  | 			select { | ||||||
|  | 			case <-done: | ||||||
|  | 			default: | ||||||
|  | 				t.Errorf("Unexpected accept err: %v", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	c, err := tr.Dial(l.Addr()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Errorf("Unexpected dial err: %v", err) | ||||||
|  | 	} | ||||||
|  | 	defer c.Close() | ||||||
|  |  | ||||||
|  | 	m := transport.Message{ | ||||||
|  | 		Header: map[string]string{ | ||||||
|  | 			"Content-Type": "application/json", | ||||||
|  | 		}, | ||||||
|  | 		Body: []byte(`{"message": "Hello World"}`), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := c.Send(&m); err != nil { | ||||||
|  | 		t.Errorf("Unexpected send err: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var rm transport.Message | ||||||
|  |  | ||||||
|  | 	if err := c.Recv(&rm); err != nil { | ||||||
|  | 		t.Errorf("Unexpected recv err: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if string(rm.Body) != string(m.Body) { | ||||||
|  | 		t.Errorf("Expected %v, got %v", m.Body, rm.Body) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	close(done) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user