github.com/GuanceCloud/cliutils@v1.1.21/logger/tcpudp_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package logger
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"net"
    12  	"net/url"
    13  	"testing"
    14  	"time"
    15  
    16  	tu "github.com/GuanceCloud/cliutils/testutil"
    17  )
    18  
    19  type listener interface {
    20  	Close() error
    21  }
    22  
    23  var stopListenMsg = "__stop_server"
    24  
    25  func serve(t *testing.T,
    26  	expectLogCnt int,
    27  	proto string,
    28  	listen string,
    29  	ch chan interface{},
    30  ) (listener, error) {
    31  	t.Helper()
    32  	switch proto {
    33  	case "udp":
    34  		l, err := net.ListenPacket("udp", listen)
    35  		if err != nil {
    36  			t.Logf("net.ListenPacket: %s", err)
    37  			return nil, err
    38  		}
    39  
    40  		go func() {
    41  			readBuf := make([]byte, 1024)
    42  			lines := []string{}
    43  			for {
    44  				n, _, err := l.ReadFrom(readBuf)
    45  				if err != nil {
    46  					t.Error(err)
    47  					ch <- nil
    48  					return
    49  				}
    50  
    51  				if bytes.Contains(readBuf, []byte(stopListenMsg)) {
    52  					for _, line := range lines {
    53  						t.Logf("log data: %s", line)
    54  					}
    55  
    56  					tu.Equals(t, expectLogCnt, len(lines))
    57  					ch <- nil
    58  					return
    59  				} else {
    60  					t.Logf("get log data: %s", string(readBuf[:n]))
    61  					lines = append(lines, string(readBuf[:n]))
    62  				}
    63  			}
    64  		}()
    65  		return l, nil
    66  
    67  	case "tcp":
    68  		l, err := net.Listen("tcp", listen)
    69  		if err != nil {
    70  			return nil, err
    71  		}
    72  
    73  		t.Logf("listen to %s ok", listen)
    74  
    75  		go func() {
    76  			for {
    77  				conn, err := l.Accept()
    78  				if err != nil {
    79  					t.Logf("l.Accept: %s", err)
    80  					ch <- nil
    81  					return
    82  				}
    83  
    84  				go func(c net.Conn) {
    85  					lines := []string{}
    86  					readBuf := make([]byte, 1024)
    87  					defer c.Close()
    88  
    89  					for {
    90  						n, err := c.Read(readBuf)
    91  						if err != nil {
    92  							t.Error(err)
    93  						}
    94  
    95  						if bytes.Contains(readBuf, []byte(stopListenMsg)) {
    96  							for _, line := range lines {
    97  								t.Logf("log data: %s", line)
    98  							}
    99  
   100  							tu.Equals(t, expectLogCnt, len(lines))
   101  							return
   102  						} else {
   103  							t.Logf("get log data: %s", string(readBuf[:n]))
   104  							lines = append(lines, string(readBuf[:n]))
   105  						}
   106  					}
   107  				}(conn)
   108  			}
   109  		}()
   110  
   111  		return l, nil
   112  	}
   113  
   114  	return nil, fmt.Errorf("should not been here")
   115  }
   116  
   117  func TestRemoteLogger(t *testing.T) {
   118  	cases := []struct {
   119  		name         string
   120  		file         string
   121  		level        string
   122  		options      int
   123  		logs         [][2]string
   124  		expectLogCnt int
   125  		ch           chan interface{}
   126  		fail         bool
   127  	}{
   128  		{
   129  			name:    "tcp-logger-server",
   130  			file:    "tcp://0.0.0.0:12345",
   131  			options: OPT_DEFAULT,
   132  			level:   DEBUG,
   133  			logs: [][2]string{
   134  				{DEBUG, "this is debug msg"},
   135  				{INFO, "this is info msg"},
   136  			},
   137  			expectLogCnt: 2,
   138  			ch:           make(chan interface{}),
   139  		},
   140  
   141  		{
   142  			name:    "udp-logger-server",
   143  			file:    "udp://0.0.0.0:12345",
   144  			options: OPT_DEFAULT,
   145  			level:   DEBUG,
   146  			logs: [][2]string{
   147  				{DEBUG, "this is debug msg"},
   148  				{INFO, "this is info msg"},
   149  			},
   150  			expectLogCnt: 2,
   151  			ch:           make(chan interface{}),
   152  		},
   153  
   154  		{
   155  			name:    "udp-logger-server-with-color-log",
   156  			file:    "udp://0.0.0.0:12345",
   157  			options: OPT_DEFAULT | OPT_COLOR,
   158  			level:   DEBUG,
   159  			logs: [][2]string{
   160  				{DEBUG, "this is debug msg"},
   161  				{INFO, "this is info msg"},
   162  			},
   163  			expectLogCnt: 2,
   164  			ch:           make(chan interface{}),
   165  		},
   166  
   167  		{
   168  			name:    "invalid-remote-logger",
   169  			file:    "http://0.0.0.0:12345",
   170  			options: OPT_DEFAULT | OPT_COLOR,
   171  			fail:    true,
   172  		},
   173  	}
   174  
   175  	for _, tc := range cases {
   176  		t.Run(tc.name, func(t *testing.T) {
   177  			u, err := url.Parse(tc.file)
   178  			if err != nil {
   179  				t.Error(err)
   180  			}
   181  
   182  			var listen listener
   183  
   184  			switch u.Scheme {
   185  			case "tcp", "udp":
   186  				listen, err = serve(t, tc.expectLogCnt, u.Scheme, u.Host, tc.ch)
   187  				if err != nil {
   188  					t.Error(err)
   189  				}
   190  				time.Sleep(time.Second) // wait server ok
   191  			default:
   192  				t.Logf("invalid schema")
   193  				return
   194  			}
   195  
   196  			rs, err := newRemoteSync(u.Scheme, u.Host)
   197  			if err != nil {
   198  				t.Error(err)
   199  			}
   200  
   201  			rl, err := newCustomizeRootLogger(tc.level, tc.options, rs)
   202  			root = rl
   203  
   204  			if err != nil {
   205  				t.Error(err)
   206  			}
   207  
   208  			l := SLogger(tc.name)
   209  
   210  			for _, arr := range tc.logs {
   211  				if len(arr) != 2 {
   212  					t.Error("expect length 2")
   213  				}
   214  
   215  				switch arr[0] {
   216  				case DEBUG:
   217  					l.Debugf("-> %s", arr[1])
   218  				case INFO:
   219  					l.Infof("-> %s", arr[1])
   220  				}
   221  
   222  				time.Sleep(time.Millisecond * 10)
   223  			}
   224  
   225  			// end of log message: shutdown server
   226  			l.Info(stopListenMsg)
   227  			time.Sleep(time.Millisecond * 10) // wait server receive ok
   228  
   229  			listen.Close()
   230  			<-tc.ch
   231  		})
   232  	}
   233  }