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  }