mirror of
				https://github.com/optim-enterprises-bv/Xray-core.git
				synced 2025-11-04 12:37:49 +00:00 
			
		
		
		
	Add statistics in conn testing
Occasional error is observed when we execute long test Print time and memory for better troubleshooting in the future Co-authored-by: Jebbs <qjebbs@gmail.com>
This commit is contained in:
		
							
								
								
									
										100
									
								
								common/units/bytesize.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								common/units/bytesize.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
package units
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errInvalidSize = errors.New("invalid size")
 | 
			
		||||
	errInvalidUnit = errors.New("invalid or unsupported unit")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ByteSize is the size of bytes
 | 
			
		||||
type ByteSize uint64
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_ = iota
 | 
			
		||||
	// KB = 1KB
 | 
			
		||||
	KB ByteSize = 1 << (10 * iota)
 | 
			
		||||
	// MB = 1MB
 | 
			
		||||
	MB
 | 
			
		||||
	// GB = 1GB
 | 
			
		||||
	GB
 | 
			
		||||
	// TB = 1TB
 | 
			
		||||
	TB
 | 
			
		||||
	// PB = 1PB
 | 
			
		||||
	PB
 | 
			
		||||
	// EB = 1EB
 | 
			
		||||
	EB
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (b ByteSize) String() string {
 | 
			
		||||
	unit := ""
 | 
			
		||||
	value := float64(0)
 | 
			
		||||
	switch {
 | 
			
		||||
	case b == 0:
 | 
			
		||||
		return "0"
 | 
			
		||||
	case b < KB:
 | 
			
		||||
		unit = "B"
 | 
			
		||||
		value = float64(b)
 | 
			
		||||
	case b < MB:
 | 
			
		||||
		unit = "KB"
 | 
			
		||||
		value = float64(b) / float64(KB)
 | 
			
		||||
	case b < GB:
 | 
			
		||||
		unit = "MB"
 | 
			
		||||
		value = float64(b) / float64(MB)
 | 
			
		||||
	case b < TB:
 | 
			
		||||
		unit = "GB"
 | 
			
		||||
		value = float64(b) / float64(GB)
 | 
			
		||||
	case b < PB:
 | 
			
		||||
		unit = "TB"
 | 
			
		||||
		value = float64(b) / float64(TB)
 | 
			
		||||
	case b < EB:
 | 
			
		||||
		unit = "PB"
 | 
			
		||||
		value = float64(b) / float64(PB)
 | 
			
		||||
	default:
 | 
			
		||||
		unit = "EB"
 | 
			
		||||
		value = float64(b) / float64(EB)
 | 
			
		||||
	}
 | 
			
		||||
	result := strconv.FormatFloat(value, 'f', 2, 64)
 | 
			
		||||
	result = strings.TrimSuffix(result, ".0")
 | 
			
		||||
	return result + unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse parses ByteSize from string
 | 
			
		||||
func (b *ByteSize) Parse(s string) error {
 | 
			
		||||
	s = strings.TrimSpace(s)
 | 
			
		||||
	s = strings.ToUpper(s)
 | 
			
		||||
	i := strings.IndexFunc(s, unicode.IsLetter)
 | 
			
		||||
	if i == -1 {
 | 
			
		||||
		return errInvalidUnit
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bytesString, multiple := s[:i], s[i:]
 | 
			
		||||
	bytes, err := strconv.ParseFloat(bytesString, 64)
 | 
			
		||||
	if err != nil || bytes <= 0 {
 | 
			
		||||
		return errInvalidSize
 | 
			
		||||
	}
 | 
			
		||||
	switch multiple {
 | 
			
		||||
	case "B":
 | 
			
		||||
		*b = ByteSize(bytes)
 | 
			
		||||
	case "K", "KB", "KIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(KB))
 | 
			
		||||
	case "M", "MB", "MIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(MB))
 | 
			
		||||
	case "G", "GB", "GIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(GB))
 | 
			
		||||
	case "T", "TB", "TIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(TB))
 | 
			
		||||
	case "P", "PB", "PIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(PB))
 | 
			
		||||
	case "E", "EB", "EIB":
 | 
			
		||||
		*b = ByteSize(bytes * float64(EB))
 | 
			
		||||
	default:
 | 
			
		||||
		return errInvalidUnit
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								common/units/bytesize_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								common/units/bytesize_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
package units_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/xtls/xray-core/common/units"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestByteSizes(t *testing.T) {
 | 
			
		||||
	size := units.ByteSize(0)
 | 
			
		||||
	assertSizeString(t, size, "0")
 | 
			
		||||
	size++
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00B"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00KB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00MB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00GB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00TB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00PB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
	size <<= 10
 | 
			
		||||
	assertSizeValue(t,
 | 
			
		||||
		assertSizeString(t, size, "1.00EB"),
 | 
			
		||||
		size,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func assertSizeValue(t *testing.T, size string, expected units.ByteSize) {
 | 
			
		||||
	actual := units.ByteSize(0)
 | 
			
		||||
	err := actual.Parse(size)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
	}
 | 
			
		||||
	if actual != expected {
 | 
			
		||||
		t.Errorf("expect %s, but got %s", expected, actual)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func assertSizeString(t *testing.T, size units.ByteSize, expected string) string {
 | 
			
		||||
	actual := size.String()
 | 
			
		||||
	if actual != expected {
 | 
			
		||||
		t.Errorf("expect %s, but got %s", expected, actual)
 | 
			
		||||
	}
 | 
			
		||||
	return expected
 | 
			
		||||
}
 | 
			
		||||
@@ -23,6 +23,7 @@ import (
 | 
			
		||||
	"github.com/xtls/xray-core/common/net"
 | 
			
		||||
	"github.com/xtls/xray-core/common/retry"
 | 
			
		||||
	"github.com/xtls/xray-core/common/serial"
 | 
			
		||||
	"github.com/xtls/xray-core/common/units"
 | 
			
		||||
	core "github.com/xtls/xray-core/core"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -198,7 +199,18 @@ func testUDPConn(port net.Port, payloadSize int, timeout time.Duration) func() e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func testTCPConn2(conn net.Conn, payloadSize int, timeout time.Duration) func() error {
 | 
			
		||||
	return func() error {
 | 
			
		||||
	return func() (err1 error) {
 | 
			
		||||
		start := time.Now()
 | 
			
		||||
		defer func() {
 | 
			
		||||
			var m runtime.MemStats
 | 
			
		||||
			runtime.ReadMemStats(&m)
 | 
			
		||||
			// For info on each, see: https://golang.org/pkg/runtime/#MemStats
 | 
			
		||||
			fmt.Println("testConn finishes:", time.Since(start).Milliseconds(), "ms\t",
 | 
			
		||||
				err1, "\tAlloc =", units.ByteSize(m.Alloc).String(),
 | 
			
		||||
				"\tTotalAlloc =", units.ByteSize(m.TotalAlloc).String(),
 | 
			
		||||
				"\tSys =", units.ByteSize(m.Sys).String(),
 | 
			
		||||
				"\tNumGC =", m.NumGC)
 | 
			
		||||
		}()
 | 
			
		||||
		payload := make([]byte, payloadSize)
 | 
			
		||||
		common.Must2(rand.Read(payload))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user