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 }