1
0
mirror of https://github.com/go-micro/go-micro.git synced 2024-11-24 08:02:32 +02:00

add benchmarks

This commit is contained in:
Asim Aslam 2019-01-16 18:54:43 +00:00
parent e2e426b90c
commit 7b89b36e37

View File

@ -2,65 +2,179 @@ package micro
import (
"context"
"errors"
"sync"
"testing"
glog "github.com/go-log/log"
"github.com/micro/go-log"
"github.com/micro/go-micro/client"
"github.com/micro/go-micro/registry/memory"
proto "github.com/micro/go-micro/server/debug/proto"
)
func TestService(t *testing.T) {
var wg sync.WaitGroup
func testShutdown(wg *sync.WaitGroup, cancel func()) {
// add 1
wg.Add(1)
// shutdown the service
cancel()
// wait for stop
wg.Wait()
}
// cancellation context
ctx, cancel := context.WithCancel(context.Background())
func testService(ctx context.Context, wg *sync.WaitGroup, name string) Service {
// set no op logger
log.SetLogger(glog.DefaultLogger)
// add self
wg.Add(1)
r := memory.NewRegistry()
r.(*memory.Registry).Setup()
// create service
service := NewService(
Name("test.service"),
return NewService(
Name(name),
Context(ctx),
Registry(r),
AfterStart(func() error {
wg.Done()
return nil
}),
AfterStop(func() error {
wg.Done()
return nil
}),
)
}
func testRequest(ctx context.Context, c client.Client, name string) error {
// test call debug
req := c.NewRequest(
name,
"Debug.Health",
new(proto.HealthRequest),
)
// we can't test service.Init as it parses the command line
// service.Init()
rsp := new(proto.HealthResponse)
err := c.Call(context.TODO(), req, rsp)
if err != nil {
return err
}
if rsp.Status != "ok" {
return errors.New("service response: " + rsp.Status)
}
return nil
}
// TestService tests running and calling a service
func TestService(t *testing.T) {
// waitgroup for server start
var wg sync.WaitGroup
// cancellation context
ctx, cancel := context.WithCancel(context.Background())
// start test server
service := testService(ctx, &wg, "test.service")
// run service
go func() {
// wait for start
// wait for service to start
wg.Wait()
// test call debug
req := service.Client().NewRequest(
"test.service",
"Debug.Health",
new(proto.HealthRequest),
)
rsp := new(proto.HealthResponse)
err := service.Client().Call(context.TODO(), req, rsp)
if err != nil {
// make a test call
if err := testRequest(ctx, service.Client(), "test.service"); err != nil {
t.Fatal(err)
}
if rsp.Status != "ok" {
t.Fatalf("service response: %s", rsp.Status)
}
// shutdown the service
cancel()
testShutdown(&wg, cancel)
}()
// start service
if err := service.Run(); err != nil {
t.Fatal(err)
}
}
func benchmarkService(b *testing.B, n int, name string) {
// stop the timer
b.StopTimer()
// waitgroup for server start
var wg sync.WaitGroup
// cancellation context
ctx, cancel := context.WithCancel(context.Background())
// create test server
service := testService(ctx, &wg, name)
// start the server
go func() {
if err := service.Run(); err != nil {
b.Fatal(err)
}
}()
// wait for service to start
wg.Wait()
// make a test call to warm the cache
for i := 0; i < 10; i++ {
if err := testRequest(ctx, service.Client(), name); err != nil {
b.Fatal(err)
}
}
// start the timer
b.StartTimer()
// number of iterations
for i := 0; i < b.N; i++ {
// for concurrency
for j := 0; j < n; j++ {
wg.Add(1)
go func() {
err := testRequest(ctx, service.Client(), name)
wg.Done()
if err != nil {
b.Fatal(err)
}
}()
}
// wait for test completion
wg.Wait()
}
// stop the timer
b.StopTimer()
// shutdown service
testShutdown(&wg, cancel)
}
func BenchmarkService1(b *testing.B) {
benchmarkService(b, 1, "test.service.1")
}
func BenchmarkService8(b *testing.B) {
benchmarkService(b, 8, "test.service.8")
}
func BenchmarkService16(b *testing.B) {
benchmarkService(b, 16, "test.service.16")
}
func BenchmarkService32(b *testing.B) {
benchmarkService(b, 32, "test.service.32")
}
func BenchmarkService64(b *testing.B) {
benchmarkService(b, 64, "test.service.64")
}