trpc.group/trpc-go/trpc-go@v1.0.2/server/server_unix_test.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 //go:build !windows 15 // +build !windows 16 17 package server_test 18 19 import ( 20 "fmt" 21 "net" 22 "os" 23 "testing" 24 "time" 25 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 29 trpc "trpc.group/trpc-go/trpc-go" 30 "trpc.group/trpc-go/trpc-go/admin" 31 "trpc.group/trpc-go/trpc-go/log" 32 "trpc.group/trpc-go/trpc-go/server" 33 "trpc.group/trpc-go/trpc-go/transport" 34 ) 35 36 func TestStartNewProcess(t *testing.T) { 37 // If the process is started by graceful restart, 38 // exit here in case of infinite loop. 39 if len(os.Getenv(transport.EnvGraceRestart)) > 0 { 40 t.SkipNow() 41 } 42 s := &server.Server{} 43 cfg := &trpc.Config{} 44 cfg.Server.Admin.IP = "127.0.0.1" 45 cfg.Server.Admin.Port = 9028 46 opts := []admin.Option{ 47 admin.WithVersion(trpc.Version()), 48 admin.WithAddr(fmt.Sprintf("%s:%d", cfg.Server.Admin.IP, cfg.Server.Admin.Port)), 49 admin.WithTLS(cfg.Server.Admin.EnableTLS), 50 } 51 52 adminService := admin.NewServer(opts...) 53 s.AddService(admin.ServiceName, adminService) 54 55 service := server.New(server.WithAddress("127.0.0.1:9080"), 56 server.WithNetwork("tcp"), 57 server.WithProtocol("trpc"), 58 server.WithServiceName("trpc.test.helloworld.Greeter1")) 59 60 s.AddService("trpc.test.helloworld.Greeter1", service) 61 err := s.Register(nil, nil) 62 assert.NotNil(t, err) 63 64 impl := &GreeterServerImpl{} 65 err = s.Register(&GreeterServerServiceDesc, impl) 66 assert.Nil(t, err) 67 go func() { 68 var netOpError *net.OpError 69 assert.ErrorAs( 70 t, 71 s.Serve(), 72 &netOpError, 73 `it is normal to have "use of closed network connection" error during hot restart`, 74 ) 75 }() 76 time.Sleep(time.Second * 1) 77 78 log.Info(os.Environ()) 79 // The environment variable is not set for parent process. 80 // It will be set by the child process started by graceful restart. 81 if os.Getenv(transport.EnvGraceRestart) == "" { 82 fpid := os.Getpid() 83 // graceful restart 84 cpid, err := s.StartNewProcess("-test.run=Test[^StartNewProcess$]") 85 assert.Nil(t, err) 86 assert.NotEqual(t, fpid, cpid) 87 t.Logf("fpid:%v, cpid:%v", fpid, cpid) 88 } 89 // Sleep 10s, let the parent process rewrite test coverage. The child process will exit quickly. 90 time.Sleep(time.Second * 10) 91 err = s.Close(nil) 92 assert.Nil(t, err) 93 } 94 95 func TestCloseOldListenerDuringHotRestart(t *testing.T) { 96 // If the process is started by graceful restart, 97 // exit here in case of infinite loop. 98 if len(os.Getenv(transport.EnvGraceRestart)) > 0 { 99 t.SkipNow() 100 } 101 s := &server.Server{} 102 ln, err := net.Listen("tcp", "127.0.0.1:0") 103 require.Nil(t, err) 104 service := server.New( 105 server.WithNetwork("tcp"), 106 server.WithProtocol("trpc"), 107 server.WithServiceName("trpc.test.helloworld.Greeter1"), 108 server.WithListener(ln), 109 ) 110 111 s.AddService("trpc.test.helloworld.Greeter1", service) 112 err = s.Register(&GreeterServerServiceDesc, &GreeterServerImpl{}) 113 go func() { 114 err = s.Serve() 115 assert.Nil(t, err) 116 }() 117 time.Sleep(time.Second) 118 119 log.Info(os.Environ()) 120 // The environment variable is not set for parent process. 121 // It will be set by the child process started by graceful restart. 122 if os.Getenv(transport.EnvGraceRestart) == "" { 123 fpid := os.Getpid() 124 // Graceful restart 125 cpid, err := s.StartNewProcess("-test.run=^TestCloseOldListenerDuringHotRestart$") 126 require.Nil(t, err) 127 require.NotEqual(t, fpid, cpid) 128 t.Logf("fpid:%v, cpid:%v", fpid, cpid) 129 time.Sleep(time.Second) 130 // Child will not be up in this test case, so trying to connect won't work. 131 _, err = net.Dial("tcp", ln.Addr().String()) 132 t.Logf("dial err: %+v", err) 133 require.NotNil(t, err) 134 } 135 // Sleep 1s, let the parent process rewrite test coverage. The child process will exit quickly. 136 time.Sleep(time.Second) 137 err = s.Close(nil) 138 require.Nil(t, err) 139 }