github.com/micro/go-micro/v2@v2.9.1/service_test.go (about)

     1  package micro
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"sync"
     7  	"testing"
     8  
     9  	"github.com/micro/go-micro/v2/client"
    10  	proto "github.com/micro/go-micro/v2/debug/service/proto"
    11  	"github.com/micro/go-micro/v2/registry/memory"
    12  	"github.com/micro/go-micro/v2/util/test"
    13  )
    14  
    15  func testShutdown(wg *sync.WaitGroup, cancel func()) {
    16  	// add 1
    17  	wg.Add(1)
    18  	// shutdown the service
    19  	cancel()
    20  	// wait for stop
    21  	wg.Wait()
    22  }
    23  
    24  func testService(ctx context.Context, wg *sync.WaitGroup, name string) Service {
    25  	// add self
    26  	wg.Add(1)
    27  
    28  	r := memory.NewRegistry(memory.Services(test.Data))
    29  
    30  	// create service
    31  	return NewService(
    32  		Name(name),
    33  		Context(ctx),
    34  		Registry(r),
    35  		AfterStart(func() error {
    36  			wg.Done()
    37  			return nil
    38  		}),
    39  		AfterStop(func() error {
    40  			wg.Done()
    41  			return nil
    42  		}),
    43  	)
    44  }
    45  
    46  func testRequest(ctx context.Context, c client.Client, name string) error {
    47  	// test call debug
    48  	req := c.NewRequest(
    49  		name,
    50  		"Debug.Health",
    51  		new(proto.HealthRequest),
    52  	)
    53  
    54  	rsp := new(proto.HealthResponse)
    55  
    56  	err := c.Call(context.TODO(), req, rsp)
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	if rsp.Status != "ok" {
    62  		return errors.New("service response: " + rsp.Status)
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  // TestService tests running and calling a service
    69  func TestService(t *testing.T) {
    70  	// waitgroup for server start
    71  	var wg sync.WaitGroup
    72  
    73  	// cancellation context
    74  	ctx, cancel := context.WithCancel(context.Background())
    75  
    76  	// start test server
    77  	service := testService(ctx, &wg, "test.service")
    78  
    79  	go func() {
    80  		// wait for service to start
    81  		wg.Wait()
    82  
    83  		// make a test call
    84  		if err := testRequest(ctx, service.Client(), "test.service"); err != nil {
    85  			t.Fatal(err)
    86  		}
    87  
    88  		// shutdown the service
    89  		testShutdown(&wg, cancel)
    90  	}()
    91  
    92  	// start service
    93  	if err := service.Run(); err != nil {
    94  		t.Fatal(err)
    95  	}
    96  }
    97  
    98  func benchmarkService(b *testing.B, n int, name string) {
    99  	// stop the timer
   100  	b.StopTimer()
   101  
   102  	// waitgroup for server start
   103  	var wg sync.WaitGroup
   104  
   105  	// cancellation context
   106  	ctx, cancel := context.WithCancel(context.Background())
   107  
   108  	// create test server
   109  	service := testService(ctx, &wg, name)
   110  
   111  	// start the server
   112  	go func() {
   113  		if err := service.Run(); err != nil {
   114  			b.Fatal(err)
   115  		}
   116  	}()
   117  
   118  	// wait for service to start
   119  	wg.Wait()
   120  
   121  	// make a test call to warm the cache
   122  	for i := 0; i < 10; i++ {
   123  		if err := testRequest(ctx, service.Client(), name); err != nil {
   124  			b.Fatal(err)
   125  		}
   126  	}
   127  
   128  	// start the timer
   129  	b.StartTimer()
   130  
   131  	// number of iterations
   132  	for i := 0; i < b.N; i++ {
   133  		// for concurrency
   134  		for j := 0; j < n; j++ {
   135  			wg.Add(1)
   136  
   137  			go func() {
   138  				err := testRequest(ctx, service.Client(), name)
   139  				wg.Done()
   140  				if err != nil {
   141  					b.Fatal(err)
   142  				}
   143  			}()
   144  		}
   145  
   146  		// wait for test completion
   147  		wg.Wait()
   148  	}
   149  
   150  	// stop the timer
   151  	b.StopTimer()
   152  
   153  	// shutdown service
   154  	testShutdown(&wg, cancel)
   155  }
   156  
   157  func BenchmarkService1(b *testing.B) {
   158  	benchmarkService(b, 1, "test.service.1")
   159  }
   160  
   161  func BenchmarkService8(b *testing.B) {
   162  	benchmarkService(b, 8, "test.service.8")
   163  }
   164  
   165  func BenchmarkService16(b *testing.B) {
   166  	benchmarkService(b, 16, "test.service.16")
   167  }
   168  
   169  func BenchmarkService32(b *testing.B) {
   170  	benchmarkService(b, 32, "test.service.32")
   171  }
   172  
   173  func BenchmarkService64(b *testing.B) {
   174  	benchmarkService(b, 64, "test.service.64")
   175  }