2021-07-06 12:12:19 +02:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
2021-10-30 20:24:40 +02:00
|
|
|
"io"
|
2021-07-06 12:12:19 +02:00
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2024-06-04 22:40:43 +02:00
|
|
|
"go-micro.dev/v5/registry"
|
2021-07-06 12:12:19 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestService(t *testing.T) {
|
|
|
|
var (
|
|
|
|
beforeStartCalled bool
|
|
|
|
afterStartCalled bool
|
|
|
|
beforeStopCalled bool
|
|
|
|
afterStopCalled bool
|
|
|
|
str = `<html><body><h1>Hello World</h1></body></html>`
|
|
|
|
fn = func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, str) }
|
|
|
|
reg = registry.NewMemoryRegistry()
|
|
|
|
)
|
|
|
|
|
|
|
|
beforeStart := func() error {
|
|
|
|
beforeStartCalled = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
afterStart := func() error {
|
|
|
|
afterStartCalled = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeStop := func() error {
|
|
|
|
beforeStopCalled = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
afterStop := func() error {
|
|
|
|
afterStopCalled = true
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
service := NewService(
|
|
|
|
Name("go.micro.web.test"),
|
|
|
|
Registry(reg),
|
|
|
|
BeforeStart(beforeStart),
|
|
|
|
AfterStart(afterStart),
|
|
|
|
BeforeStop(beforeStop),
|
|
|
|
AfterStop(afterStop),
|
|
|
|
)
|
|
|
|
|
|
|
|
service.HandleFunc("/", fn)
|
|
|
|
|
|
|
|
errCh := make(chan error, 1)
|
|
|
|
go func() {
|
|
|
|
errCh <- service.Run()
|
|
|
|
close(errCh)
|
|
|
|
}()
|
|
|
|
|
|
|
|
var s []*registry.Service
|
|
|
|
|
|
|
|
eventually(func() bool {
|
|
|
|
var err error
|
|
|
|
s, err = reg.GetService("go.micro.web.test")
|
|
|
|
return err == nil
|
|
|
|
}, t.Fatal)
|
|
|
|
|
|
|
|
if have, want := len(s), 1; have != want {
|
|
|
|
t.Fatalf("Expected %d but got %d services", want, have)
|
|
|
|
}
|
|
|
|
|
|
|
|
rsp, err := http.Get(fmt.Sprintf("http://%s", s[0].Nodes[0].Address))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer rsp.Body.Close()
|
|
|
|
|
2021-10-30 20:24:40 +02:00
|
|
|
b, err := io.ReadAll(rsp.Body)
|
2021-07-06 12:12:19 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if string(b) != str {
|
|
|
|
t.Errorf("Expected %s got %s", str, string(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
callbackTests := []struct {
|
|
|
|
subject string
|
|
|
|
have interface{}
|
|
|
|
}{
|
|
|
|
{"beforeStartCalled", beforeStartCalled},
|
|
|
|
{"afterStartCalled", afterStartCalled},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range callbackTests {
|
|
|
|
if tt.have != true {
|
|
|
|
t.Errorf("unexpected %s: want true, have false", tt.subject)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err := <-errCh:
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("service.Run():%v", err)
|
|
|
|
}
|
|
|
|
case <-time.After(time.Duration(time.Second)):
|
|
|
|
if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
|
|
|
|
t.Logf("service.Run() survived a client request without an error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ch := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(ch, syscall.SIGTERM)
|
|
|
|
p, _ := os.FindProcess(os.Getpid())
|
|
|
|
p.Signal(syscall.SIGTERM)
|
|
|
|
|
|
|
|
<-ch
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err := <-errCh:
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("service.Run():%v", err)
|
|
|
|
} else {
|
|
|
|
if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
|
|
|
|
t.Log("service.Run() nil return on syscall.SIGTERM")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case <-time.After(time.Duration(time.Second)):
|
|
|
|
if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
|
|
|
|
t.Logf("service.Run() survived a client request without an error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
eventually(func() bool {
|
|
|
|
_, err := reg.GetService("go.micro.web.test")
|
|
|
|
return err == registry.ErrNotFound
|
|
|
|
}, t.Error)
|
|
|
|
|
|
|
|
callbackTests = []struct {
|
|
|
|
subject string
|
|
|
|
have interface{}
|
|
|
|
}{
|
|
|
|
{"beforeStopCalled", beforeStopCalled},
|
|
|
|
{"afterStopCalled", afterStopCalled},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range callbackTests {
|
|
|
|
if tt.have != true {
|
|
|
|
t.Errorf("unexpected %s: want true, have false", tt.subject)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestOptions(t *testing.T) {
|
|
|
|
var (
|
|
|
|
name = "service-name"
|
|
|
|
id = "service-id"
|
|
|
|
version = "service-version"
|
|
|
|
address = "service-addr:8080"
|
|
|
|
advertise = "service-adv:8080"
|
|
|
|
reg = registry.NewMemoryRegistry()
|
|
|
|
registerTTL = 123 * time.Second
|
|
|
|
registerInterval = 456 * time.Second
|
|
|
|
handler = http.NewServeMux()
|
|
|
|
metadata = map[string]string{"key": "val"}
|
|
|
|
secure = true
|
|
|
|
)
|
|
|
|
|
|
|
|
service := NewService(
|
|
|
|
Name(name),
|
|
|
|
Id(id),
|
|
|
|
Version(version),
|
|
|
|
Address(address),
|
|
|
|
Advertise(advertise),
|
|
|
|
Registry(reg),
|
|
|
|
RegisterTTL(registerTTL),
|
|
|
|
RegisterInterval(registerInterval),
|
|
|
|
Handler(handler),
|
|
|
|
Metadata(metadata),
|
|
|
|
Secure(secure),
|
|
|
|
)
|
|
|
|
|
|
|
|
opts := service.Options()
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
subject string
|
|
|
|
want interface{}
|
|
|
|
have interface{}
|
|
|
|
}{
|
|
|
|
{"name", name, opts.Name},
|
|
|
|
{"version", version, opts.Version},
|
|
|
|
{"id", id, opts.Id},
|
|
|
|
{"address", address, opts.Address},
|
|
|
|
{"advertise", advertise, opts.Advertise},
|
|
|
|
{"registry", reg, opts.Registry},
|
|
|
|
{"registerTTL", registerTTL, opts.RegisterTTL},
|
|
|
|
{"registerInterval", registerInterval, opts.RegisterInterval},
|
|
|
|
{"handler", handler, opts.Handler},
|
|
|
|
{"metadata", metadata["key"], opts.Metadata["key"]},
|
|
|
|
{"secure", secure, opts.Secure},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
if tc.want != tc.have {
|
|
|
|
t.Errorf("unexpected %s: want %v, have %v", tc.subject, tc.want, tc.have)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func eventually(pass func() bool, fail func(...interface{})) {
|
|
|
|
tick := time.NewTicker(10 * time.Millisecond)
|
|
|
|
defer tick.Stop()
|
|
|
|
|
|
|
|
timeout := time.After(time.Second)
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-timeout:
|
|
|
|
fail("timed out")
|
|
|
|
return
|
|
|
|
case <-tick.C:
|
|
|
|
if pass() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTLS(t *testing.T) {
|
|
|
|
var (
|
|
|
|
str = `<html><body><h1>Hello World</h1></body></html>`
|
|
|
|
fn = func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, str) }
|
|
|
|
secure = true
|
|
|
|
reg = registry.NewMemoryRegistry()
|
|
|
|
)
|
|
|
|
|
|
|
|
service := NewService(
|
|
|
|
Name("go.micro.web.test"),
|
|
|
|
Secure(secure),
|
|
|
|
Registry(reg),
|
|
|
|
)
|
|
|
|
|
|
|
|
service.HandleFunc("/", fn)
|
|
|
|
|
|
|
|
errCh := make(chan error, 1)
|
|
|
|
go func() {
|
|
|
|
errCh <- service.Run()
|
|
|
|
close(errCh)
|
|
|
|
}()
|
|
|
|
|
|
|
|
var s []*registry.Service
|
|
|
|
|
|
|
|
eventually(func() bool {
|
|
|
|
var err error
|
|
|
|
s, err = reg.GetService("go.micro.web.test")
|
|
|
|
return err == nil
|
|
|
|
}, t.Fatal)
|
|
|
|
|
|
|
|
if have, want := len(s), 1; have != want {
|
|
|
|
t.Fatalf("Expected %d but got %d services", want, have)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr := &http.Transport{
|
|
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
|
|
}
|
|
|
|
client := &http.Client{Transport: tr}
|
|
|
|
rsp, err := client.Get(fmt.Sprintf("https://%s", s[0].Nodes[0].Address))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer rsp.Body.Close()
|
|
|
|
|
2021-10-30 20:24:40 +02:00
|
|
|
b, err := io.ReadAll(rsp.Body)
|
2021-07-06 12:12:19 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if string(b) != str {
|
|
|
|
t.Errorf("Expected %s got %s", str, string(b))
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err := <-errCh:
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("service.Run():%v", err)
|
|
|
|
}
|
|
|
|
case <-time.After(time.Duration(time.Second)):
|
|
|
|
if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
|
|
|
|
t.Logf("service.Run() survived a client request without an error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|