github.com/annwntech/go-micro/v2@v2.9.5/web/service_test.go (about) 1 package web 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "os/signal" 10 "syscall" 11 "testing" 12 "time" 13 14 "github.com/annwntech/go-micro/v2/registry" 15 "github.com/annwntech/go-micro/v2/registry/memory" 16 ) 17 18 func TestService(t *testing.T) { 19 var ( 20 beforeStartCalled bool 21 afterStartCalled bool 22 beforeStopCalled bool 23 afterStopCalled bool 24 str = `<html><body><h1>Hello World</h1></body></html>` 25 fn = func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, str) } 26 reg = memory.NewRegistry() 27 ) 28 29 beforeStart := func() error { 30 beforeStartCalled = true 31 return nil 32 } 33 34 afterStart := func() error { 35 afterStartCalled = true 36 return nil 37 } 38 39 beforeStop := func() error { 40 beforeStopCalled = true 41 return nil 42 } 43 44 afterStop := func() error { 45 afterStopCalled = true 46 return nil 47 } 48 49 service := NewService( 50 Name("go.micro.web.test"), 51 Registry(reg), 52 BeforeStart(beforeStart), 53 AfterStart(afterStart), 54 BeforeStop(beforeStop), 55 AfterStop(afterStop), 56 ) 57 58 service.HandleFunc("/", fn) 59 60 errCh := make(chan error, 1) 61 go func() { 62 errCh <- service.Run() 63 close(errCh) 64 }() 65 66 var s []*registry.Service 67 68 eventually(func() bool { 69 var err error 70 s, err = reg.GetService("go.micro.web.test") 71 return err == nil 72 }, t.Fatal) 73 74 if have, want := len(s), 1; have != want { 75 t.Fatalf("Expected %d but got %d services", want, have) 76 } 77 78 rsp, err := http.Get(fmt.Sprintf("http://%s", s[0].Nodes[0].Address)) 79 if err != nil { 80 t.Fatal(err) 81 } 82 defer rsp.Body.Close() 83 84 b, err := ioutil.ReadAll(rsp.Body) 85 if err != nil { 86 t.Fatal(err) 87 } 88 89 if string(b) != str { 90 t.Errorf("Expected %s got %s", str, string(b)) 91 } 92 93 callbackTests := []struct { 94 subject string 95 have interface{} 96 }{ 97 {"beforeStartCalled", beforeStartCalled}, 98 {"afterStartCalled", afterStartCalled}, 99 } 100 101 for _, tt := range callbackTests { 102 if tt.have != true { 103 t.Errorf("unexpected %s: want true, have false", tt.subject) 104 } 105 } 106 107 select { 108 case err := <-errCh: 109 if err != nil { 110 t.Fatalf("service.Run():%v", err) 111 } 112 case <-time.After(time.Duration(time.Second)): 113 if len(os.Getenv("IN_TRAVIS_CI")) == 0 { 114 t.Logf("service.Run() survived a client request without an error") 115 } 116 } 117 118 ch := make(chan os.Signal, 1) 119 signal.Notify(ch, syscall.SIGTERM) 120 p, _ := os.FindProcess(os.Getpid()) 121 p.Signal(syscall.SIGTERM) 122 123 <-ch 124 125 select { 126 case err := <-errCh: 127 if err != nil { 128 t.Fatalf("service.Run():%v", err) 129 } else { 130 if len(os.Getenv("IN_TRAVIS_CI")) == 0 { 131 t.Log("service.Run() nil return on syscall.SIGTERM") 132 } 133 } 134 case <-time.After(time.Duration(time.Second)): 135 if len(os.Getenv("IN_TRAVIS_CI")) == 0 { 136 t.Logf("service.Run() survived a client request without an error") 137 } 138 } 139 140 eventually(func() bool { 141 _, err := reg.GetService("go.micro.web.test") 142 return err == registry.ErrNotFound 143 }, t.Error) 144 145 callbackTests = []struct { 146 subject string 147 have interface{} 148 }{ 149 {"beforeStopCalled", beforeStopCalled}, 150 {"afterStopCalled", afterStopCalled}, 151 } 152 153 for _, tt := range callbackTests { 154 if tt.have != true { 155 t.Errorf("unexpected %s: want true, have false", tt.subject) 156 } 157 } 158 159 } 160 161 func TestOptions(t *testing.T) { 162 var ( 163 name = "service-name" 164 id = "service-id" 165 version = "service-version" 166 address = "service-addr:8080" 167 advertise = "service-adv:8080" 168 reg = memory.NewRegistry() 169 registerTTL = 123 * time.Second 170 registerInterval = 456 * time.Second 171 handler = http.NewServeMux() 172 metadata = map[string]string{"key": "val"} 173 secure = true 174 ) 175 176 service := NewService( 177 Name(name), 178 Id(id), 179 Version(version), 180 Address(address), 181 Advertise(advertise), 182 Registry(reg), 183 RegisterTTL(registerTTL), 184 RegisterInterval(registerInterval), 185 Handler(handler), 186 Metadata(metadata), 187 Secure(secure), 188 ) 189 190 opts := service.Options() 191 192 tests := []struct { 193 subject string 194 want interface{} 195 have interface{} 196 }{ 197 {"name", name, opts.Name}, 198 {"version", version, opts.Version}, 199 {"id", id, opts.Id}, 200 {"address", address, opts.Address}, 201 {"advertise", advertise, opts.Advertise}, 202 {"registry", reg, opts.Registry}, 203 {"registerTTL", registerTTL, opts.RegisterTTL}, 204 {"registerInterval", registerInterval, opts.RegisterInterval}, 205 {"handler", handler, opts.Handler}, 206 {"metadata", metadata["key"], opts.Metadata["key"]}, 207 {"secure", secure, opts.Secure}, 208 } 209 210 for _, tc := range tests { 211 if tc.want != tc.have { 212 t.Errorf("unexpected %s: want %v, have %v", tc.subject, tc.want, tc.have) 213 } 214 } 215 } 216 217 func eventually(pass func() bool, fail func(...interface{})) { 218 tick := time.NewTicker(10 * time.Millisecond) 219 defer tick.Stop() 220 221 timeout := time.After(time.Second) 222 223 for { 224 select { 225 case <-timeout: 226 fail("timed out") 227 return 228 case <-tick.C: 229 if pass() { 230 return 231 } 232 } 233 } 234 } 235 236 func TestTLS(t *testing.T) { 237 var ( 238 str = `<html><body><h1>Hello World</h1></body></html>` 239 fn = func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, str) } 240 secure = true 241 reg = memory.NewRegistry() 242 ) 243 244 service := NewService( 245 Name("go.micro.web.test"), 246 Secure(secure), 247 Registry(reg), 248 ) 249 250 service.HandleFunc("/", fn) 251 252 errCh := make(chan error, 1) 253 go func() { 254 errCh <- service.Run() 255 close(errCh) 256 }() 257 258 var s []*registry.Service 259 260 eventually(func() bool { 261 var err error 262 s, err = reg.GetService("go.micro.web.test") 263 return err == nil 264 }, t.Fatal) 265 266 if have, want := len(s), 1; have != want { 267 t.Fatalf("Expected %d but got %d services", want, have) 268 } 269 270 tr := &http.Transport{ 271 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 272 } 273 client := &http.Client{Transport: tr} 274 rsp, err := client.Get(fmt.Sprintf("https://%s", s[0].Nodes[0].Address)) 275 if err != nil { 276 t.Fatal(err) 277 } 278 defer rsp.Body.Close() 279 280 b, err := ioutil.ReadAll(rsp.Body) 281 if err != nil { 282 t.Fatal(err) 283 } 284 285 if string(b) != str { 286 t.Errorf("Expected %s got %s", str, string(b)) 287 } 288 289 select { 290 case err := <-errCh: 291 if err != nil { 292 t.Fatalf("service.Run():%v", err) 293 } 294 case <-time.After(time.Duration(time.Second)): 295 if len(os.Getenv("IN_TRAVIS_CI")) == 0 { 296 t.Logf("service.Run() survived a client request without an error") 297 } 298 } 299 300 }