github.com/TeaOSLab/EdgeNode@v1.3.8/internal/nodes/http_access_log_queue_test.go (about)

     1  // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
     2  
     3  package nodes_test
     4  
     5  import (
     6  	"bytes"
     7  	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
     8  	"github.com/TeaOSLab/EdgeNode/internal/nodes"
     9  	"github.com/TeaOSLab/EdgeNode/internal/rpc"
    10  	"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
    11  	_ "github.com/iwind/TeaGo/bootstrap"
    12  	"google.golang.org/grpc/status"
    13  	"reflect"
    14  	"runtime"
    15  	"runtime/debug"
    16  	"strconv"
    17  	"strings"
    18  	"testing"
    19  	"time"
    20  	"unicode/utf8"
    21  )
    22  
    23  func TestHTTPAccessLogQueue_Push(t *testing.T) {
    24  	// 发送到API
    25  	client, err := rpc.SharedRPC()
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	var requestId = 1_000_000
    31  
    32  	var utf8Bytes = []byte{}
    33  	for i := 0; i < 254; i++ {
    34  		utf8Bytes = append(utf8Bytes, uint8(i))
    35  	}
    36  
    37  	//bytes = []byte("真不错")
    38  
    39  	var accessLog = &pb.HTTPAccessLog{
    40  		ServerId:    23,
    41  		RequestId:   strconv.FormatInt(time.Now().Unix(), 10) + strconv.Itoa(requestId) + strconv.FormatInt(1, 10),
    42  		NodeId:      48,
    43  		Host:        "www.hello.com",
    44  		RequestURI:  string(utf8Bytes),
    45  		RequestPath: string(utf8Bytes),
    46  		Timestamp:   time.Now().Unix(),
    47  		Cookie:      map[string]string{"test": string(utf8Bytes)},
    48  
    49  		Header: map[string]*pb.Strings{
    50  			"test": {Values: []string{string(utf8Bytes)}},
    51  		},
    52  	}
    53  
    54  	new(nodes.HTTPAccessLogQueue).ToValidUTF8(accessLog)
    55  
    56  	//	logs.PrintAsJSON(accessLog)
    57  
    58  	//t.Log(strings.ToValidUTF8(string(utf8Bytes), ""))
    59  	_, err = client.HTTPAccessLogRPC.CreateHTTPAccessLogs(client.Context(), &pb.CreateHTTPAccessLogsRequest{HttpAccessLogs: []*pb.HTTPAccessLog{
    60  		accessLog,
    61  	}})
    62  	if err != nil {
    63  		// 这里只是为了重现错误
    64  		t.Logf("%#v, %s", err, err.Error())
    65  
    66  		statusErr, ok := status.FromError(err)
    67  		if ok {
    68  			t.Logf("%#v", statusErr)
    69  		}
    70  		return
    71  	}
    72  	t.Log("ok")
    73  }
    74  
    75  func TestHTTPAccessLogQueue_Push2(t *testing.T) {
    76  	var utf8Bytes = []byte{}
    77  	for i := 0; i < 254; i++ {
    78  		utf8Bytes = append(utf8Bytes, uint8(i))
    79  	}
    80  
    81  	var accessLog = &pb.HTTPAccessLog{
    82  		ServerId:    23,
    83  		RequestId:   strconv.FormatInt(time.Now().Unix(), 10) + strconv.Itoa(1) + strconv.FormatInt(1, 10),
    84  		NodeId:      48,
    85  		Host:        "www.hello.com",
    86  		RequestURI:  string(utf8Bytes),
    87  		RequestPath: string(utf8Bytes),
    88  		Timestamp:   time.Now().Unix(),
    89  	}
    90  	var v = reflect.Indirect(reflect.ValueOf(accessLog))
    91  	var countFields = v.NumField()
    92  	for i := 0; i < countFields; i++ {
    93  		var field = v.Field(i)
    94  		if field.Kind() == reflect.String {
    95  			field.SetString(strings.ToValidUTF8(field.String(), ""))
    96  		}
    97  	}
    98  
    99  	client, err := rpc.SharedRPC()
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	_, err = client.HTTPAccessLogRPC.CreateHTTPAccessLogs(client.Context(), &pb.CreateHTTPAccessLogsRequest{HttpAccessLogs: []*pb.HTTPAccessLog{
   104  		accessLog,
   105  	}})
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	t.Log("ok")
   110  }
   111  
   112  func TestHTTPAccessLogQueue_Memory(t *testing.T) {
   113  	if !testutils.IsSingleTesting() {
   114  		return
   115  	}
   116  
   117  	testutils.StartMemoryStats(t)
   118  
   119  	debug.SetGCPercent(10)
   120  
   121  	var accessLogs = []*pb.HTTPAccessLog{}
   122  	for i := 0; i < 20_000; i++ {
   123  		accessLogs = append(accessLogs, &pb.HTTPAccessLog{
   124  			RequestPath: "https://goedge.cn/hello/world",
   125  		})
   126  	}
   127  
   128  	runtime.GC()
   129  	_ = accessLogs
   130  
   131  	// will not release automatically
   132  	func() {
   133  		var accessLogs1 = []*pb.HTTPAccessLog{}
   134  		for i := 0; i < 2_000_000; i++ {
   135  			accessLogs1 = append(accessLogs1, &pb.HTTPAccessLog{
   136  				RequestPath: "https://goedge.cn/hello/world",
   137  			})
   138  		}
   139  		_ = accessLogs1
   140  	}()
   141  
   142  	time.Sleep(5 * time.Second)
   143  }
   144  
   145  func TestUTF8_IsValid(t *testing.T) {
   146  	t.Log(utf8.ValidString("abc"))
   147  
   148  	var noneUTF8Bytes = []byte{}
   149  	for i := 0; i < 254; i++ {
   150  		noneUTF8Bytes = append(noneUTF8Bytes, uint8(i))
   151  	}
   152  	t.Log(utf8.ValidString(string(noneUTF8Bytes)))
   153  }
   154  
   155  func BenchmarkHTTPAccessLogQueue_ToValidUTF8(b *testing.B) {
   156  	runtime.GOMAXPROCS(1)
   157  
   158  	var utf8Bytes = []byte{}
   159  	for i := 0; i < 254; i++ {
   160  		utf8Bytes = append(utf8Bytes, uint8(i))
   161  	}
   162  
   163  	for i := 0; i < b.N; i++ {
   164  		_ = bytes.ToValidUTF8(utf8Bytes, nil)
   165  	}
   166  }
   167  
   168  func BenchmarkHTTPAccessLogQueue_ToValidUTF8String(b *testing.B) {
   169  	runtime.GOMAXPROCS(1)
   170  
   171  	var utf8Bytes = []byte{}
   172  	for i := 0; i < 254; i++ {
   173  		utf8Bytes = append(utf8Bytes, uint8(i))
   174  	}
   175  
   176  	var s = string(utf8Bytes)
   177  	for i := 0; i < b.N; i++ {
   178  		_ = strings.ToValidUTF8(s, "")
   179  	}
   180  }
   181  
   182  func BenchmarkAppendAccessLogs(b *testing.B) {
   183  	b.ReportAllocs()
   184  
   185  	var stat1 = &runtime.MemStats{}
   186  	runtime.ReadMemStats(stat1)
   187  
   188  	const count = 20000
   189  	var a = make([]*pb.HTTPAccessLog, 0, count)
   190  	for i := 0; i < b.N; i++ {
   191  		a = append(a, &pb.HTTPAccessLog{
   192  			RequestPath: "/hello/world",
   193  			Host:        "example.com",
   194  			RequestBody: bytes.Repeat([]byte{'A'}, 1024),
   195  		})
   196  		if len(a) == count {
   197  			a = make([]*pb.HTTPAccessLog, 0, count)
   198  		}
   199  	}
   200  
   201  	_ = len(a)
   202  
   203  	var stat2 = &runtime.MemStats{}
   204  	runtime.ReadMemStats(stat2)
   205  	b.Log((stat2.TotalAlloc-stat1.TotalAlloc)>>20, "MB")
   206  }
   207  
   208  func BenchmarkAppendAccessLogs2(b *testing.B) {
   209  	b.ReportAllocs()
   210  
   211  	var stat1 = &runtime.MemStats{}
   212  	runtime.ReadMemStats(stat1)
   213  
   214  	const count = 20000
   215  	var a = []*pb.HTTPAccessLog{}
   216  	for i := 0; i < b.N; i++ {
   217  		a = append(a, &pb.HTTPAccessLog{
   218  			RequestPath: "/hello/world",
   219  			Host:        "example.com",
   220  			RequestBody: bytes.Repeat([]byte{'A'}, 1024),
   221  		})
   222  		if len(a) == count {
   223  			a = []*pb.HTTPAccessLog{}
   224  		}
   225  	}
   226  
   227  	_ = len(a)
   228  
   229  	var stat2 = &runtime.MemStats{}
   230  	runtime.ReadMemStats(stat2)
   231  	b.Log((stat2.TotalAlloc-stat1.TotalAlloc)>>20, "MB")
   232  }