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