Example #1
0
func TestService(t *testing.T) {
	str := `<html><body><h1>Hello World</h1></body></html>`

	fn := func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, str)
	}

	reg := mock.NewRegistry()

	service := NewService(
		Name("go.micro.web.test"),
		Registry(reg),
	)

	service.HandleFunc("/", fn)

	go func() {
		if err := service.Run(); err != nil {
			t.Fatal(err)
		}
	}()

	var s []*registry.Service

	eventually(func() bool {
		var err error
		s, err = reg.GetService("go.micro.web.test")
		return err == nil
	}, t.Fatal)

	if have, want := len(s), 1; have != want {
		t.Fatalf("Expected %d but got %d services", want, have)
	}

	rsp, err := http.Get(fmt.Sprintf("http://%s:%d", s[0].Nodes[0].Address, s[0].Nodes[0].Port))
	if err != nil {
		t.Fatal(err)
	}
	defer rsp.Body.Close()

	b, err := ioutil.ReadAll(rsp.Body)
	if err != nil {
		t.Fatal(err)
	}

	if string(b) != str {
		t.Errorf("Expected %s got %s", str, string(b))
	}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM)

	syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
	<-ch

	eventually(func() bool {
		_, err := reg.GetService("go.micro.web.test")
		return err == registry.ErrNotFound
	}, t.Error)
}
Example #2
0
func TestLabelSelector(t *testing.T) {
	counts := map[string]int{}

	r := mock.NewRegistry()
	r.Register(&registry.Service{
		Name:    "bar",
		Version: "latest",
		Nodes: []*registry.Node{
			&registry.Node{
				Id: "1",
				Metadata: map[string]string{
					"key1": "val1",
				},
			},
			&registry.Node{
				Id: "2",
				Metadata: map[string]string{
					"key2": "val2",
				},
			},
		},
	})

	r.Register(&registry.Service{
		Name:    "bar",
		Version: "1.0.0",
		Nodes: []*registry.Node{
			&registry.Node{
				Id: "3",
				Metadata: map[string]string{
					"key1": "val1",
				},
			},
			&registry.Node{
				Id: "4",
			},
		},
	})

	ls := NewSelector(
		selector.Registry(r),
		Label("key2", "val2"),
		Label("key1", "val1"),
	)

	next, err := ls.Select("bar")
	if err != nil {
		t.Errorf("Unexpected error calling ls select: %v", err)
	}

	for i := 0; i < 100; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		counts[node.Id]++
	}

	t.Logf("Label Select Counts %v", counts)
}
Example #3
0
func TestBreaker(t *testing.T) {
	// setup
	r := mock.NewRegistry()
	s := selector.NewSelector(selector.Registry(r))

	c := client.NewClient(
		// set the selector
		client.Selector(s),
		// add the breaker wrapper
		client.Wrap(NewClientWrapper()),
	)

	req := c.NewJsonRequest("test.service", "Test.Method", map[string]string{
		"foo": "bar",
	})

	var rsp map[string]interface{}

	// Force to point of trip
	for i := 0; i < (hystrix.DefaultVolumeThreshold * 2); i++ {
		c.Call(context.TODO(), req, rsp)
	}

	err := c.Call(context.TODO(), req, rsp)
	if err == nil {
		t.Error("Expecting tripped breaker, got nil error")
	}

	if err.Error() != "hystrix: circuit open" {
		t.Errorf("Expecting tripped breaker, got %v", err)
	}
}
Example #4
0
func sub(be *testing.B, c int) {
	be.StopTimer()
	m := mock.NewRegistry()
	b := NewBroker(Registry(m))
	topic := uuid.NewUUID().String()

	if err := b.Init(); err != nil {
		be.Fatalf("Unexpected init error: %v", err)
	}

	if err := b.Connect(); err != nil {
		be.Fatalf("Unexpected connect error: %v", err)
	}

	msg := &Message{
		Header: map[string]string{
			"Content-Type": "application/json",
		},
		Body: []byte(`{"message": "Hello World"}`),
	}

	var subs []Subscriber
	done := make(chan bool, c)

	for i := 0; i < c; i++ {
		sub, err := b.Subscribe(topic, func(p Publication) error {
			done <- true
			m := p.Message()

			if string(m.Body) != string(msg.Body) {
				be.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
			}

			return nil
		}, Queue("shared"))
		if err != nil {
			be.Fatalf("Unexpected subscribe error: %v", err)
		}
		subs = append(subs, sub)
	}

	for i := 0; i < be.N; i++ {
		be.StartTimer()
		if err := b.Publish(topic, msg); err != nil {
			be.Fatalf("Unexpected publish error: %v", err)
		}
		<-done
		be.StopTimer()
	}

	for _, sub := range subs {
		sub.Unsubscribe()
	}

	if err := b.Disconnect(); err != nil {
		be.Fatalf("Unexpected disconnect error: %v", err)
	}
}
Example #5
0
func TestConcurrentSubBroker(t *testing.T) {
	m := mock.NewRegistry()
	b := NewBroker(Registry(m))

	if err := b.Init(); err != nil {
		t.Fatalf("Unexpected init error: %v", err)
	}

	if err := b.Connect(); err != nil {
		t.Fatalf("Unexpected connect error: %v", err)
	}

	msg := &Message{
		Header: map[string]string{
			"Content-Type": "application/json",
		},
		Body: []byte(`{"message": "Hello World"}`),
	}

	var subs []Subscriber
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		sub, err := b.Subscribe("test", func(p Publication) error {
			defer wg.Done()

			m := p.Message()

			if string(m.Body) != string(msg.Body) {
				t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
			}

			return nil
		})
		if err != nil {
			t.Fatalf("Unexpected subscribe error: %v", err)
		}

		wg.Add(1)
		subs = append(subs, sub)
	}

	if err := b.Publish("test", msg); err != nil {
		t.Fatalf("Unexpected publish error: %v", err)
	}

	wg.Wait()

	for _, sub := range subs {
		sub.Unsubscribe()
	}

	if err := b.Disconnect(); err != nil {
		t.Fatalf("Unexpected disconnect error: %v", err)
	}
}
Example #6
0
func TestGRPCClient(t *testing.T) {
	l, err := net.Listen("tcp", ":0")
	if err != nil {
		t.Fatalf("failed to listen: %v", err)
	}
	defer l.Close()

	s := grpc.NewServer()
	pb.RegisterGreeterServer(s, &greeterServer{})

	go s.Serve(l)
	defer s.Stop()

	parts := strings.Split(l.Addr().String(), ":")
	port, _ := strconv.Atoi(parts[len(parts)-1])
	addr := strings.Join(parts[:len(parts)-1], ":")

	r := mock.NewRegistry()
	r.Register(&registry.Service{
		Name:    "test",
		Version: "test",
		Nodes: []*registry.Node{
			&registry.Node{
				Id:      "test-1",
				Address: addr,
				Port:    port,
			},
		},
	})

	se := selector.NewSelector(
		selector.Registry(r),
	)

	c := NewClient(
		client.Registry(r),
		client.Selector(se),
	)

	req := c.NewRequest("test", "/helloworld.Greeter/SayHello", &pb.HelloRequest{
		Name: "John",
	})

	rsp := pb.HelloReply{}

	err = c.Call(context.TODO(), req, &rsp)
	if err != nil {
		t.Fatal(err)
	}

	if rsp.Message != "Hello John" {
		t.Fatalf("Got unexpected response %v", rsp.Message)
	}
}
Example #7
0
func TestOptions(t *testing.T) {
	var (
		name             = "service-name"
		id               = "service-id"
		version          = "service-version"
		address          = "service-addr"
		advertise        = "service-adv"
		reg              = mock.NewRegistry()
		registerTTL      = 123 * time.Second
		registerInterval = 456 * time.Second
		handler          = http.NewServeMux()
		metadata         = map[string]string{"key": "val"}
	)

	service := NewService(
		Name(name),
		Id(id),
		Version(version),
		Address(address),
		Advertise(advertise),
		Registry(reg),
		RegisterTTL(registerTTL),
		RegisterInterval(registerInterval),
		Handler(handler),
		Metadata(metadata),
	)

	opts := service.Options()

	tests := []struct {
		subject string
		want    interface{}
		have    interface{}
	}{
		{"name", name, opts.Name},
		{"version", version, opts.Version},
		{"id", id, opts.Id},
		{"address", address, opts.Address},
		{"advertise", advertise, opts.Advertise},
		{"registry", reg, registry.DefaultRegistry},
		{"registerTTL", registerTTL, opts.RegisterTTL},
		{"registerInterval", registerInterval, opts.RegisterInterval},
		{"handler", handler, opts.Handler},
		{"metadata", metadata["key"], opts.Metadata["key"]},
	}

	for _, tc := range tests {
		if tc.want != tc.have {
			t.Errorf("unexpected %s: want %v, have %v", tc.subject, tc.want, tc.have)
		}
	}
}
Example #8
0
func TestGRPCServer(t *testing.T) {
	r := mock.NewRegistry()
	s := NewServer(
		server.Name("foo"),
		server.Registry(r),
	)

	pb.RegisterSayHandler(s, &sayServer{})

	if err := s.Start(); err != nil {
		t.Fatalf("failed to start: %v", err)
	}

	if err := s.Register(); err != nil {
		t.Fatalf("failed to register: %v", err)
	}

	// check registration
	services, err := r.GetService("foo")
	if err != nil || len(services) == 0 {
		t.Fatal("failed to get service: %v # %d", err, len(services))
	}

	defer func() {
		if err := s.Deregister(); err != nil {
			t.Fatalf("failed to deregister: %v", err)
		}

		if err := s.Stop(); err != nil {
			t.Fatalf("failed to stop: %v", err)
		}
	}()

	cc, err := grpc.Dial(s.Options().Address, grpc.WithInsecure())
	if err != nil {
		t.Fatal("failed to dial server: %v", err)
	}

	rsp := pb.Response{}

	if err := grpc.Invoke(context.Background(), "Say.Hello", &pb.Request{Name: "John"}, &rsp, cc); err != nil {
		t.Fatal("error calling server: %v", err)
	}

	if rsp.Msg != "Hello John" {
		t.Fatalf("Got unexpected response %v", rsp.Msg)
	}
}
Example #9
0
func TestBroker(t *testing.T) {
	m := mock.NewRegistry()
	b := NewBroker(Registry(m))

	if err := b.Init(); err != nil {
		t.Fatalf("Unexpected init error: %v", err)
	}

	if err := b.Connect(); err != nil {
		t.Fatalf("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()

		if string(m.Body) != string(msg.Body) {
			t.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
		}

		close(done)
		return nil
	})
	if err != nil {
		t.Fatalf("Unexpected subscribe error: %v", err)
	}

	if err := b.Publish("test", msg); err != nil {
		t.Fatalf("Unexpected publish error: %v", err)
	}

	<-done
	sub.Unsubscribe()

	if err := b.Disconnect(); err != nil {
		t.Fatalf("Unexpected disconnect error: %v", err)
	}
}
Example #10
0
func TestDefaultSelector(t *testing.T) {
	counts := map[string]int{}

	rs := newDefaultSelector(Registry(mock.NewRegistry()))

	next, err := rs.Select("foo")
	if err != nil {
		t.Errorf("Unexpected error calling default select: %v", err)
	}

	for i := 0; i < 100; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		counts[node.Id]++
	}

	t.Logf("Default Counts %v", counts)
}
Example #11
0
func TestCacheSelector(t *testing.T) {
	counts := map[string]int{}

	cache := NewSelector(selector.Registry(mock.NewRegistry()))

	next, err := cache.Select("foo")
	if err != nil {
		t.Errorf("Unexpected error calling cache select: %v", err)
	}

	for i := 0; i < 100; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		counts[node.Id]++
	}

	t.Logf("Cache Counts %v", counts)
}
func TestRoundRobinSelector(t *testing.T) {
	counts := map[string]int{}

	rr := &roundRobinSelector{
		so: selector.Options{
			Registry: mock.NewRegistry(),
		},
	}

	next, err := rr.Select("foo")
	if err != nil {
		t.Errorf("Unexpected error calling rr select: %v", err)
	}

	for i := 0; i < 100; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		counts[node.Id]++
	}

	t.Logf("Round Robin Counts %v", counts)
}
func TestBlackListSelector(t *testing.T) {
	counts := map[string]int{}

	bl := &blackListSelector{
		so: selector.Options{
			Registry: mock.NewRegistry(),
		},
		ttl:  2,
		bl:   make(map[string]blackListNode),
		exit: make(chan bool),
	}

	go bl.run()
	defer bl.Close()

	next, err := bl.Select("foo")
	if err != nil {
		t.Errorf("Unexpected error calling bl select: %v", err)
	}

	for i := 0; i < 100; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		counts[node.Id]++
	}

	t.Logf("BlackList Counts %v", counts)

	// test blacklisting
	for i := 0; i < 4; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Expected node err, got err: %v", err)
		}
		bl.Mark("foo", node, errors.New("blacklist"))
	}
	if node, err := next(); err != selector.ErrNoneAvailable {
		t.Errorf("Expected none available err, got node %v err %v", node, err)
	}
	time.Sleep(time.Second * time.Duration(bl.ttl) * 2)
	if _, err := next(); err != nil {
		t.Errorf("Unexpected err %v", err)
	}

	// test resetting
	for i := 0; i < 4; i++ {
		node, err := next()
		if err != nil {
			t.Errorf("Unexpected err: %v", err)
		}
		bl.Mark("foo", node, errors.New("blacklist"))
	}
	if node, err := next(); err != selector.ErrNoneAvailable {
		t.Errorf("Expected none available err, got node %v err %v", node, err)
	}
	bl.Reset("foo")
	if _, err := next(); err != nil {
		t.Errorf("Unexpected err %v", err)
	}
}
Example #14
0
func TestProxyHandler(t *testing.T) {
	r := rmock.NewRegistry()

	cmd.DefaultCmd = cmd.NewCmd(cmd.Registry(&r))

	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer l.Close()

	parts := strings.Split(l.Addr().String(), ":")

	var host string
	var port int

	host = parts[0]
	port, _ = strconv.Atoi(parts[1])

	s := &registry.Service{
		Name: "go.micro.api.test",
		Nodes: []*registry.Node{
			&registry.Node{
				Id:      "1",
				Address: host,
				Port:    port,
			},
		},
	}

	r.Register(s)
	defer r.Deregister(s)

	// setup the test handler
	m := http.NewServeMux()
	m.HandleFunc("/test/foo", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`you got served`))
	})

	// start http test serve
	go http.Serve(l, m)

	// create new request and writer
	w := httptest.NewRecorder()
	req, err := http.NewRequest("POST", "/test/foo", nil)
	if err != nil {
		t.Fatal(err)
	}

	// initialise the handler
	p := Proxy("go.micro.api", false)

	// execute the handler
	p.ServeHTTP(w, req)

	if w.Code != 200 {
		t.Fatalf("Expected 200 response got %d %s", w.Code, w.Body.String())
	}

	if w.Body.String() != "you got served" {
		t.Fatal("Expected body: you got served. Got: %s", w.Body.String())
	}
}
Example #15
0
func TestBlackList(t *testing.T) {
	return

	r := mock.NewRegistry()

	r.Register(&registry.Service{
		Name: "test",
		Nodes: []*registry.Node{
			&registry.Node{
				Id:      "test-1",
				Address: "localhost",
				Port:    10001,
			},
			&registry.Node{
				Id:      "test-2",
				Address: "localhost",
				Port:    10002,
			},
			&registry.Node{
				Id:      "test-3",
				Address: "localhost",
				Port:    10002,
			},
		},
	})

	rs := newSelector(selector.Registry(r))

	next, err := rs.Select("test")
	if err != nil {
		t.Fatal(err)
	}

	node, err := next()
	if err != nil {
		t.Fatal(err)
	}

	for i := 0; i < 4; i++ {
		rs.Mark("test", node, errors.New("error"))
	}

	next, err = rs.Select("test")
	if err != nil {
		t.Fatal(err)
	}

	// still expecting 2 nodes
	seen := make(map[string]bool)

	for i := 0; i < 10; i++ {
		node, err = next()
		if err != nil {
			t.Fatal(err)
		}
		seen[node.Id] = true
	}

	if len(seen) != 2 {
		t.Fatalf("Expected seen to be 2 %+v", seen)
	}

	// blacklist all of it
	for i := 0; i < 20; i++ {
		node, err = next()
		if err != nil {
			t.Fatal(err)
		}
		rs.Mark("test", node, errors.New("error"))
	}

	next, err = rs.Select("test")
	if err != selector.ErrNoneAvailable {
		t.Fatalf("Expected %v got %v", selector.ErrNoneAvailable, err)
	}

}
Example #16
0
func TestHTTPServer(t *testing.T) {
	reg := mock.NewRegistry()

	// create server
	srv := NewServer(server.Registry(reg))

	// create server mux
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`hello world`))
	})

	// create handler
	hd := srv.NewHandler(mux)

	// register handler
	if err := srv.Handle(hd); err != nil {
		t.Fatal(err)
	}

	// start server
	if err := srv.Start(); err != nil {
		t.Fatal(err)
	}

	// register server
	if err := srv.Register(); err != nil {
		t.Fatal(err)
	}

	// lookup server
	service, err := reg.GetService(server.DefaultName)
	if err != nil {
		t.Fatal(err)
	}

	if len(service) != 1 {
		t.Fatalf("Expected 1 service got %d: %+v", len(service), service)
	}

	if len(service[0].Nodes) != 1 {
		t.Fatalf("Expected 1 node got %d: %+v", len(service[0].Nodes), service[0].Nodes)
	}

	// make request
	rsp, err := http.Get(fmt.Sprintf("http://%s:%d", service[0].Nodes[0].Address, service[0].Nodes[0].Port))
	if err != nil {
		t.Fatal(err)
	}
	defer rsp.Body.Close()

	b, err := ioutil.ReadAll(rsp.Body)
	if err != nil {
		t.Fatal(err)
	}

	if s := string(b); s != "hello world" {
		t.Fatalf("Expected response %s, got %s", "hello world", s)
	}

	// deregister server
	if err := srv.Deregister(); err != nil {
		t.Fatal(err)
	}

	// try get service
	service, err = reg.GetService(server.DefaultName)
	if err == nil {
		t.Fatal("Expected %v got %+v", registry.ErrNotFound, service)
	}

	// stop server
	if err := srv.Stop(); err != nil {
		t.Fatal(err)
	}
}
Example #17
0
func pub(be *testing.B, c int) {
	be.StopTimer()
	m := mock.NewRegistry()
	b := NewBroker(Registry(m))
	topic := uuid.NewUUID().String()

	if err := b.Init(); err != nil {
		be.Fatalf("Unexpected init error: %v", err)
	}

	if err := b.Connect(); err != nil {
		be.Fatalf("Unexpected connect error: %v", err)
	}

	msg := &Message{
		Header: map[string]string{
			"Content-Type": "application/json",
		},
		Body: []byte(`{"message": "Hello World"}`),
	}

	done := make(chan bool, c*4)

	sub, err := b.Subscribe(topic, func(p Publication) error {
		done <- true
		m := p.Message()
		if string(m.Body) != string(msg.Body) {
			be.Fatalf("Unexpected msg %s, expected %s", string(m.Body), string(msg.Body))
		}
		return nil
	}, Queue("shared"))
	if err != nil {
		be.Fatalf("Unexpected subscribe error: %v", err)
	}

	var wg sync.WaitGroup
	ch := make(chan int, c*4)
	be.StartTimer()

	for i := 0; i < c; i++ {
		go func() {
			for _ = range ch {
				if err := b.Publish(topic, msg); err != nil {
					be.Fatalf("Unexpected publish error: %v", err)
				}
				select {
				case <-done:
				case <-time.After(time.Second):
				}
				wg.Done()
			}
		}()
	}

	for i := 0; i < be.N; i++ {
		wg.Add(1)
		ch <- i
	}

	wg.Wait()
	be.StopTimer()
	sub.Unsubscribe()
	close(ch)
	close(done)

	if err := b.Disconnect(); err != nil {
		be.Fatalf("Unexpected disconnect error: %v", err)
	}
}
Example #18
0
func TestRPCHandler(t *testing.T) {
	r := rmock.NewRegistry()

	(*cmd.DefaultOptions().Client).Init(
		client.Registry(r),
		client.Selector(selector.NewSelector(selector.Registry(r))),
	)

	(*cmd.DefaultOptions().Server).Init(
		server.Name("test"),
		server.Registry(r),
	)

	(*cmd.DefaultOptions().Server).Handle(
		(*cmd.DefaultOptions().Server).NewHandler(&TestHandler{t, metadata.Metadata{"Foo": "Bar"}}),
	)

	if err := server.Start(); err != nil {
		t.Fatal(err)
	}

	if err := server.Register(); err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()

	request := map[string]string{
		"service": "test",
		"method":  "TestHandler.Exec",
		"request": "{}",
	}

	rb, err := json.Marshal(request)
	if err != nil {
		t.Fatal(err)
	}

	b := bytes.NewBuffer(rb)

	req, err := http.NewRequest("POST", "/rpc", b)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Foo", "Bar")

	RPC(w, req)

	if err := server.Deregister(); err != nil {
		t.Fatal(err)
	}

	if err := server.Stop(); err != nil {
		t.Fatal(err)
	}

	if w.Code != 200 {
		t.Fatalf("Expected 200 response got %d %s", w.Code, w.Body.String())
	}

}