github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/log/logger_test.go (about)

     1  package log
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/sereiner/library/file"
    13  )
    14  
    15  type TestType struct {
    16  	name string
    17  	age  int
    18  }
    19  
    20  // TestDebug 测试记录Debug日志
    21  func TestDebug(t *testing.T) {
    22  	// 清空数据统计
    23  	manager.factory = &testLoggerAppenderFactory{}
    24  	ResultClear()
    25  
    26  	log := New("key1")
    27  
    28  	// 写入字符串
    29  	log.Debug("content1")
    30  
    31  	// 写入nil
    32  	log.Debug(nil)
    33  
    34  	// 写入int
    35  	log.Debug(1)
    36  
    37  	// 写入sliens
    38  	log.Debug(make([]string, 2))
    39  
    40  	// 写入数组
    41  	log.Debug([3]int{1, 2, 3})
    42  
    43  	// 写入结构体
    44  	log.Debug(TestType{name: "test", age: 11})
    45  
    46  	// 日志组件为空
    47  	log = New("")
    48  	log.Debug("hello world")
    49  
    50  	time.Sleep(time.Second * 2)
    51  	// 统计数据是否和预期的一致
    52  	if GetResult("debug") != 6 {
    53  		t.Errorf("test fail except : %d, actual : %d", 6, GetResult("debug"))
    54  	}
    55  
    56  	Close()
    57  	manager, _ = newLoggerManager()
    58  }
    59  
    60  // TestDebug 测试记录Debugf日志【format】
    61  func TestDebugf(t *testing.T) {
    62  	// 清空数据统计
    63  	manager.factory = &testLoggerAppenderFactory{}
    64  	ResultClear()
    65  
    66  	log := New("key1")
    67  	// 参数正确
    68  	log.Debugf("%s %s", "hello", "world")
    69  
    70  	// format 为空字符串
    71  	log.Debugf("", "hello")
    72  
    73  	// format 不包含格式化参数
    74  	log.Debugf("hello", "world")
    75  
    76  	// format 格式化参数过多
    77  	log.Debugf("%s %s %s", "hello", "world")
    78  
    79  	// 内容为nil
    80  	log.Debugf("hello", nil)
    81  
    82  	// 内容和格式化参数类型不匹配
    83  	log.Debugf("%s %d", "hello", "world")
    84  
    85  	// 内容为结构体
    86  	log.Debugf("%+v", TestType{name: "test", age: 11})
    87  
    88  	// 日志组件为空
    89  	log = New("")
    90  	log.Debugf("%s %s", "hello", "world")
    91  
    92  	time.Sleep(time.Second * 2)
    93  	// 统计数据是否和预期的一致
    94  	if GetResult("debug") != 7 {
    95  		t.Errorf("test fail except : %d, actual : %d", 7, GetResult("debug"))
    96  	}
    97  
    98  	Close()
    99  	manager, _ = newLoggerManager()
   100  }
   101  
   102  // TestInfo 测试记录Info日志
   103  func TestInfo(t *testing.T) {
   104  	// 清空数据统计
   105  	manager.factory = &testLoggerAppenderFactory{}
   106  	ResultClear()
   107  
   108  	log := New("key1")
   109  
   110  	// 写入字符串
   111  	log.Info("content1")
   112  	// // 每秒钟写入文件一次
   113  	// time.Sleep(time.Second * 2)
   114  
   115  	// 写入nil
   116  	log.Info(nil)
   117  
   118  	// 写入int
   119  	log.Info(1)
   120  
   121  	// 写入sliens
   122  	log.Info(make([]string, 2))
   123  
   124  	// 写入数组
   125  	log.Info([3]int{1, 2, 3})
   126  
   127  	// 写入结构体
   128  	log.Info(TestType{name: "test", age: 11})
   129  
   130  	// 日志组件为空
   131  	log = New("")
   132  	log.Info("hello world")
   133  
   134  	time.Sleep(time.Second * 2)
   135  	// 统计数据是否和预期的一致
   136  	if GetResult("info") != 6 {
   137  		t.Errorf("test fail except : %d, actual : %d", 6, GetResult("info"))
   138  	}
   139  
   140  	Close()
   141  	manager, _ = newLoggerManager()
   142  }
   143  
   144  // TestInfof 测试记录Info日志【format】
   145  func TestInfof(t *testing.T) {
   146  	// 清空数据统计
   147  	manager.factory = &testLoggerAppenderFactory{}
   148  	ResultClear()
   149  
   150  	log := New("key1")
   151  	// 参数正确
   152  	log.Infof("%s %s", "hello", "world")
   153  
   154  	// format 为空字符串
   155  	log.Infof("", "hello")
   156  
   157  	// format 不包含格式化参数
   158  	log.Infof("hello", "world")
   159  
   160  	// format 格式化参数过多
   161  	log.Infof("%s %s %s", "hello", "world")
   162  
   163  	// 内容为nil
   164  	log.Infof("hello", nil)
   165  
   166  	// 内容和格式化参数类型不匹配
   167  	log.Infof("%s %d", "hello", "world")
   168  
   169  	// 内容为结构体
   170  	log.Infof("%+v", TestType{name: "test", age: 11})
   171  
   172  	// 日志组件为空
   173  	log = New("")
   174  	log.Infof("%s %s", "hello", "world")
   175  
   176  	time.Sleep(time.Second * 2)
   177  	// 统计数据是否和预期的一致
   178  	if GetResult("info") != 7 {
   179  		t.Errorf("test fail except : %d, actual : %d", 7, GetResult("info"))
   180  	}
   181  
   182  	Close()
   183  	manager, _ = newLoggerManager()
   184  }
   185  
   186  // TestError 测试记录Error日志
   187  func TestError(t *testing.T) {
   188  	// 清空数据统计
   189  	manager.factory = &testLoggerAppenderFactory{}
   190  	ResultClear()
   191  
   192  	log := New("key1")
   193  
   194  	// 写入字符串
   195  	log.Error("content1")
   196  
   197  	// 写入nil
   198  	log.Error(nil)
   199  
   200  	// 写入int
   201  	log.Error(1)
   202  
   203  	// 写入sliens
   204  	log.Error(make([]string, 2))
   205  
   206  	// 写入数组
   207  	log.Error([3]int{1, 2, 3})
   208  
   209  	// 写入结构体
   210  	log.Error(TestType{name: "test", age: 11})
   211  
   212  	// 日志组件为空
   213  	log = New("")
   214  	log.Error("hello world")
   215  
   216  	time.Sleep(time.Second * 2)
   217  	// 统计数据是否和预期的一致
   218  	if GetResult("error") != 6 {
   219  		t.Errorf("test fail except : %d, actual : %d", 6, GetResult("error"))
   220  	}
   221  
   222  	Close()
   223  	manager, _ = newLoggerManager()
   224  }
   225  
   226  // TestErrorf 测试记录Error日志【format】
   227  func TestErrorf(t *testing.T) {
   228  	// 清空数据统计
   229  	manager.factory = &testLoggerAppenderFactory{}
   230  	ResultClear()
   231  
   232  	log := New("key1")
   233  	// 参数正确
   234  	log.Errorf("%s %s", "hello", "world")
   235  
   236  	// format 为空字符串
   237  	log.Errorf("", "hello")
   238  
   239  	// format 不包含格式化参数
   240  	log.Errorf("hello", "world")
   241  
   242  	// format 格式化参数过多
   243  	log.Errorf("%s %s %s", "hello", "world")
   244  
   245  	// 内容为nil
   246  	log.Errorf("hello", nil)
   247  
   248  	// 内容为结构体
   249  	log.Errorf("%+v", TestType{name: "test", age: 11})
   250  
   251  	// 内容和格式化参数类型不匹配
   252  	log.Errorf("%s %d", "hello", "world")
   253  
   254  	// 日志组件为空
   255  	log = New("")
   256  	log.Errorf("%s %s", "hello", "world")
   257  
   258  	time.Sleep(time.Second * 2)
   259  	// 统计数据是否和预期的一致
   260  	if GetResult("error") != 7 {
   261  		t.Errorf("test fail except : %d, actual : %d", 7, GetResult("error"))
   262  	}
   263  
   264  	Close()
   265  	manager, _ = newLoggerManager()
   266  }
   267  
   268  // TestWriteToBuffer 测试写入日志的时候,是否漏掉了日志记录,通过测试的testLoggerAppenderFactory来不进行真的日志记录
   269  func TestWriteToBuffer(t *testing.T) {
   270  	manager.factory = &testLoggerAppenderFactory{}
   271  	// 清空结果
   272  	ResultClear()
   273  	totalCount := 10000 * 1
   274  	ch := make(chan int, totalCount)
   275  	lk := sync.WaitGroup{}
   276  
   277  	doWrite := func(ch chan int, lk *sync.WaitGroup) {
   278  		log := New("abc")
   279  	START:
   280  		for {
   281  			select {
   282  			case v, ok := <-ch:
   283  				if ok {
   284  					log.Debug(v)
   285  					log.Info(v)
   286  					log.Error(v)
   287  				} else {
   288  					break START
   289  				}
   290  			}
   291  		}
   292  		lk.Done()
   293  	}
   294  
   295  	for i := 0; i < 100; i++ {
   296  		lk.Add(1)
   297  		go doWrite(ch, &lk)
   298  	}
   299  
   300  	for i := 0; i < totalCount; i++ {
   301  		ch <- i
   302  	}
   303  
   304  	close(ch)
   305  	lk.Wait()
   306  
   307  	time.Sleep(time.Second * 2)
   308  
   309  	Close()
   310  
   311  	for i := 0; i < len(ACCOUNT); i++ {
   312  		fmt.Println(ACCOUNT[i].name, " ", ACCOUNT[i].count)
   313  		if strings.EqualFold(ACCOUNT[i].name, "debug") {
   314  			if ACCOUNT[i].count != totalCount {
   315  				t.Errorf("test fail, actual : %d", ACCOUNT[i].count)
   316  			}
   317  		}
   318  		if strings.EqualFold(ACCOUNT[i].name, "info") {
   319  			if ACCOUNT[i].count != totalCount {
   320  				t.Errorf("test fail, actual : %d", ACCOUNT[i].count)
   321  			}
   322  		}
   323  		// 测试不执行fatal日志记录
   324  		if strings.EqualFold(ACCOUNT[i].name, "fatal") {
   325  			if ACCOUNT[i].count != 0 {
   326  				t.Errorf("test fail, actual : %d", ACCOUNT[i].count)
   327  			}
   328  		}
   329  		if strings.EqualFold(ACCOUNT[i].name, "error") {
   330  			if ACCOUNT[i].count != totalCount {
   331  				t.Errorf("test fail, actual : %d", ACCOUNT[i].count)
   332  			}
   333  		}
   334  	}
   335  
   336  	manager, _ = newLoggerManager()
   337  }
   338  
   339  // TestLoggerToFile 测试输出到文件,并检验日志数量
   340  func TestLoggerToFile(t *testing.T) {
   341  	// 把数据写入文件
   342  	totalAccount := 10000 * 1
   343  	lk := sync.WaitGroup{}
   344  	ch := make(chan int, totalAccount)
   345  	name := "ABC"
   346  
   347  	log := New(name)
   348  
   349  	doWriteToFile := func(ch chan int, lk *sync.WaitGroup) {
   350  	START:
   351  		for {
   352  			select {
   353  			case l, ok := <-ch:
   354  				if ok {
   355  					log.Debug(l)
   356  					log.Info(l)
   357  					log.Error(l)
   358  				} else {
   359  					break START
   360  				}
   361  				lk.Done()
   362  			}
   363  		}
   364  	}
   365  
   366  	for i := 0; i < 100; i++ {
   367  		go doWriteToFile(ch, &lk)
   368  	}
   369  
   370  	for i := 0; i < totalAccount; i++ {
   371  		lk.Add(1)
   372  		ch <- i
   373  	}
   374  	close(ch)
   375  	lk.Wait()
   376  
   377  	time.Sleep(time.Second * 1)
   378  
   379  	Close()
   380  
   381  	// 开始读取文件
   382  	path := fmt.Sprintf("../logs/%s/%d%d%d.log", name, time.Now().Year(), time.Now().Month(), time.Now().Day())
   383  	filePath, _ := file.GetAbs(path)
   384  	data, err := ioutil.ReadFile(filePath)
   385  	if err != nil {
   386  		t.Errorf("test fail : %v", err)
   387  	}
   388  	count := len(strings.Split(string(data), "\n"))
   389  	if count != totalAccount*3+6 {
   390  		t.Errorf("test fail, actual:%d, except:%d", count, totalAccount*3+6)
   391  	}
   392  
   393  	// 删除日志防止下次进行测试的时候数据错误
   394  	os.Remove(filePath)
   395  }
   396  
   397  // TestLoggerToFileCheckOrder 测试写入到文件,然后判断输入的顺序
   398  func TestLoggerToFileCheckOrder(tx *testing.T) {
   399  	// 写入日志到文件
   400  	manager, _ = newLoggerManager()
   401  	logger := GetSession("tofile", "12345678")
   402  	// t, err := time.Parse("2006/01/02 15:04:05", "2016/11/28 16:38:27")
   403  	// if err != nil {
   404  	// 	tx.Errorf("test fail, %+v", err)
   405  	// }
   406  
   407  	// 构建要测试的数据和预期数据
   408  	data := map[string]string{
   409  		// LogEvent{Level: "Debug", Now: t, Name: "tofile", Session: "12345678", Content: "content1", Output: "output1"}: []string{"[d]", "content1"},
   410  		// LogEvent{Level: "Debug", Now: t, Name: "tofile", Session: "12345678", Content: "content2", Output: "output2"}: []string{"[d]", "content2"},
   411  		// LogEvent{Level: "Info", Now: t, Name: "tofile", Session: "12345678", Content: "content3", Output: "output3"}:  []string{"[i]", "content3"},
   412  		// LogEvent{Level: "Fatal", Now: t, Name: "tofile", Session: "12345678", Content: "content4", Output: "output4"}: []string{"[f]", "content4"},
   413  		// LogEvent{Level: "Error", Now: t, Name: "tofile", Session: "12345678", Content: "content5", Output: "output5"}: []string{"[e]", "content5"},
   414  		// LogEvent{Level: "Error", Now: t, Name: "tofile", Session: "12345678", Content: "content6", Output: "output6"}: []string{"[e]", "content6"},
   415  		// LogEvent{Level: "Test", Now: t, Name: "tofile", Session: "12345678", Content: "content7", Output: "output6"}:  []string{"[t]", "content7"},
   416  		"content1": "content1",
   417  		"content2": "content2",
   418  		"content3": "content3",
   419  		"content4": "content4",
   420  		"content5": "content5",
   421  		"content6": "content6",
   422  		"content7": "content7",
   423  	}
   424  
   425  	// 获取日志文件的绝对路径
   426  	filePath, _ := file.GetAbs(fmt.Sprintf("../logs/tofile/%d%d%d.log", time.Now().Year(), time.Now().Month(), time.Now().Day()))
   427  
   428  	// 删除文件,多次测试前面的测试会覆盖掉结果
   429  	os.Remove(filePath)
   430  
   431  	excepts := []string{}
   432  	for event, except := range data {
   433  		// 写内容到buffer
   434  		// manager.Log(event)
   435  		logger.Info(event)
   436  		// 添加预期的结果【测试的时候map顺序不确定】
   437  		// excepts = append(excepts, fmt.Sprintf(`[2016/11/28 16:38:27]%s[12345678] %s`, "12345678", except))
   438  		excepts = append(excepts, fmt.Sprintf(`][i][12345678] %s`, except))
   439  	}
   440  	tx.Log(excepts)
   441  	time.Sleep(time.Second * 11)
   442  
   443  	// 读取文件中的类容
   444  
   445  	// 当前读取文件的行数
   446  	lineNow := 0
   447  
   448  	// 记录匹配的行数
   449  	actual := []int{}
   450  
   451  	// 循环预期结果
   452  	for _, except := range excepts {
   453  		fileData, err := ioutil.ReadFile(filePath)
   454  		if err != nil {
   455  			tx.Errorf("test fail : %v", err)
   456  		}
   457  		for line, lineData := range strings.Split(string(fileData), "\n") {
   458  			// 记录开始位置
   459  			if strings.Contains(lineData, "begin") && lineNow == 0 {
   460  				lineNow = line
   461  			}
   462  
   463  			// 有开始位置,开始匹配
   464  			if line > lineNow {
   465  				if strings.Contains(lineData, except) {
   466  					lineNow = line
   467  					actual = append(actual, line)
   468  				}
   469  			}
   470  		}
   471  	}
   472  
   473  	if len(actual) != len(excepts) {
   474  		tx.Errorf("test fail except: %d, actual: %d", len(excepts), len(actual))
   475  	}
   476  
   477  	tx.Log(actual)
   478  
   479  	// 判断预期结果是否是连续的
   480  	for i := 0; i < len(actual); i++ {
   481  		if i != 0 {
   482  			if actual[i-1]+1 != actual[i] {
   483  				tx.Errorf("test fail, %+v", actual)
   484  				return
   485  			}
   486  		}
   487  	}
   488  }
   489  
   490  // Account 日志记录的对象
   491  type Account struct {
   492  	name  string
   493  	count int
   494  }
   495  
   496  // mutex 保证日志记录是原子操作
   497  var mutex sync.Mutex
   498  
   499  // ACCOUNT 记录日志的结果
   500  var ACCOUNT []*Account
   501  
   502  // SetResult 存放测试结果
   503  func SetResult(name string, n int) {
   504  	for i := 0; i < len(ACCOUNT); i++ {
   505  		if strings.EqualFold(ACCOUNT[i].name, name) {
   506  			mutex.Lock()
   507  			ACCOUNT[i].count = ACCOUNT[i].count + n
   508  			mutex.Unlock()
   509  			return
   510  		}
   511  	}
   512  
   513  	mutex.Lock()
   514  	account := &Account{name: name, count: n}
   515  	ACCOUNT = append(ACCOUNT, account)
   516  	mutex.Unlock()
   517  }
   518  
   519  // GetResult 获取测试结果
   520  func GetResult(name string) int {
   521  	for i := 0; i < len(ACCOUNT); i++ {
   522  		if strings.EqualFold(ACCOUNT[i].name, name) {
   523  			return ACCOUNT[i].count
   524  		}
   525  	}
   526  	return 0
   527  }
   528  
   529  // ResultClear 清空测试结果
   530  func ResultClear() {
   531  	ACCOUNT = []*Account{}
   532  }