github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/testing/scenarios/metrics_test.go (about)

     1  package scenarios
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"testing"
     9  
    10  	"github.com/xtls/xray-core/app/metrics"
    11  	"github.com/xtls/xray-core/app/proxyman"
    12  	"github.com/xtls/xray-core/app/router"
    13  	"github.com/xtls/xray-core/common"
    14  	"github.com/xtls/xray-core/common/net"
    15  	"github.com/xtls/xray-core/common/serial"
    16  	"github.com/xtls/xray-core/core"
    17  	"github.com/xtls/xray-core/proxy/dokodemo"
    18  	"github.com/xtls/xray-core/proxy/freedom"
    19  	"github.com/xtls/xray-core/testing/servers/tcp"
    20  )
    21  
    22  const expectedMessage = "goroutine profile: total"
    23  
    24  func TestMetrics(t *testing.T) {
    25  	tcpServer := tcp.Server{
    26  		MsgProcessor: xor,
    27  	}
    28  	dest, err := tcpServer.Start()
    29  	common.Must(err)
    30  	defer tcpServer.Close()
    31  
    32  	metricsPort := tcp.PickPort()
    33  	clientConfig := &core.Config{
    34  		App: []*serial.TypedMessage{
    35  			serial.ToTypedMessage(&metrics.Config{
    36  				Tag: "metrics_out",
    37  			}),
    38  			serial.ToTypedMessage(&router.Config{
    39  				Rule: []*router.RoutingRule{
    40  					{
    41  						InboundTag: []string{"metrics_in"},
    42  						TargetTag: &router.RoutingRule_Tag{
    43  							Tag: "metrics_out",
    44  						},
    45  					},
    46  				},
    47  			}),
    48  		},
    49  		Inbound: []*core.InboundHandlerConfig{
    50  			{
    51  				Tag: "metrics_in",
    52  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    53  					PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(metricsPort)}},
    54  					Listen:   net.NewIPOrDomain(net.LocalHostIP),
    55  				}),
    56  				ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
    57  					Address:  net.NewIPOrDomain(dest.Address),
    58  					Port:     uint32(dest.Port),
    59  					Networks: []net.Network{net.Network_TCP},
    60  				}),
    61  			},
    62  		},
    63  		Outbound: []*core.OutboundHandlerConfig{
    64  			{
    65  				Tag:           "default-outbound",
    66  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
    67  			},
    68  		},
    69  	}
    70  
    71  	servers, err := InitializeServerConfigs(clientConfig)
    72  	common.Must(err)
    73  	defer CloseAllServers(servers)
    74  
    75  	resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/debug/pprof/goroutine?debug=1", metricsPort))
    76  	common.Must(err)
    77  	if resp == nil {
    78  		t.Error("unexpected pprof nil response")
    79  	}
    80  	if resp.StatusCode != http.StatusOK {
    81  		t.Error("unexpected pprof status code")
    82  	}
    83  	body, err := io.ReadAll(resp.Body)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	if string(body)[0:len(expectedMessage)] != expectedMessage {
    88  		t.Error("unexpected response body from pprof handler")
    89  	}
    90  
    91  	resp2, err2 := http.Get(fmt.Sprintf("http://127.0.0.1:%d/debug/vars", metricsPort))
    92  	common.Must(err2)
    93  	if resp2 == nil {
    94  		t.Error("unexpected expvars nil response")
    95  	}
    96  	if resp2.StatusCode != http.StatusOK {
    97  		t.Error("unexpected expvars status code")
    98  	}
    99  	body2, err2 := io.ReadAll(resp2.Body)
   100  	if err2 != nil {
   101  		t.Fatal(err2)
   102  	}
   103  	var json2 map[string]interface{}
   104  	if json.Unmarshal(body2, &json2) != nil {
   105  		t.Error("unexpected response body from expvars handler")
   106  	}
   107  }