...

Source file src/github.com/sirupsen/logrus/hook_test.go

Documentation: github.com/sirupsen/logrus

     1  package logrus_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"sync"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	. "github.com/sirupsen/logrus"
    14  	"github.com/sirupsen/logrus/hooks/test"
    15  	. "github.com/sirupsen/logrus/internal/testutils"
    16  )
    17  
    18  type TestHook struct {
    19  	Fired bool
    20  }
    21  
    22  func (hook *TestHook) Fire(entry *Entry) error {
    23  	hook.Fired = true
    24  	return nil
    25  }
    26  
    27  func (hook *TestHook) Levels() []Level {
    28  	return []Level{
    29  		TraceLevel,
    30  		DebugLevel,
    31  		InfoLevel,
    32  		WarnLevel,
    33  		ErrorLevel,
    34  		FatalLevel,
    35  		PanicLevel,
    36  	}
    37  }
    38  
    39  func TestHookFires(t *testing.T) {
    40  	hook := new(TestHook)
    41  
    42  	LogAndAssertJSON(t, func(log *Logger) {
    43  		log.Hooks.Add(hook)
    44  		assert.Equal(t, hook.Fired, false)
    45  
    46  		log.Print("test")
    47  	}, func(fields Fields) {
    48  		assert.Equal(t, hook.Fired, true)
    49  	})
    50  }
    51  
    52  type ModifyHook struct {
    53  }
    54  
    55  func (hook *ModifyHook) Fire(entry *Entry) error {
    56  	entry.Data["wow"] = "whale"
    57  	return nil
    58  }
    59  
    60  func (hook *ModifyHook) Levels() []Level {
    61  	return []Level{
    62  		TraceLevel,
    63  		DebugLevel,
    64  		InfoLevel,
    65  		WarnLevel,
    66  		ErrorLevel,
    67  		FatalLevel,
    68  		PanicLevel,
    69  	}
    70  }
    71  
    72  func TestHookCanModifyEntry(t *testing.T) {
    73  	hook := new(ModifyHook)
    74  
    75  	LogAndAssertJSON(t, func(log *Logger) {
    76  		log.Hooks.Add(hook)
    77  		log.WithField("wow", "elephant").Print("test")
    78  	}, func(fields Fields) {
    79  		assert.Equal(t, fields["wow"], "whale")
    80  	})
    81  }
    82  
    83  func TestCanFireMultipleHooks(t *testing.T) {
    84  	hook1 := new(ModifyHook)
    85  	hook2 := new(TestHook)
    86  
    87  	LogAndAssertJSON(t, func(log *Logger) {
    88  		log.Hooks.Add(hook1)
    89  		log.Hooks.Add(hook2)
    90  
    91  		log.WithField("wow", "elephant").Print("test")
    92  	}, func(fields Fields) {
    93  		assert.Equal(t, fields["wow"], "whale")
    94  		assert.Equal(t, hook2.Fired, true)
    95  	})
    96  }
    97  
    98  type SingleLevelModifyHook struct {
    99  	ModifyHook
   100  }
   101  
   102  func (h *SingleLevelModifyHook) Levels() []Level {
   103  	return []Level{InfoLevel}
   104  }
   105  
   106  func TestHookEntryIsPristine(t *testing.T) {
   107  	l := New()
   108  	b := &bytes.Buffer{}
   109  	l.Formatter = &JSONFormatter{}
   110  	l.Out = b
   111  	l.AddHook(&SingleLevelModifyHook{})
   112  
   113  	l.Error("error message")
   114  	data := map[string]string{}
   115  	err := json.Unmarshal(b.Bytes(), &data)
   116  	require.NoError(t, err)
   117  	_, ok := data["wow"]
   118  	require.False(t, ok)
   119  	b.Reset()
   120  
   121  	l.Info("error message")
   122  	data = map[string]string{}
   123  	err = json.Unmarshal(b.Bytes(), &data)
   124  	require.NoError(t, err)
   125  	_, ok = data["wow"]
   126  	require.True(t, ok)
   127  	b.Reset()
   128  
   129  	l.Error("error message")
   130  	data = map[string]string{}
   131  	err = json.Unmarshal(b.Bytes(), &data)
   132  	require.NoError(t, err)
   133  	_, ok = data["wow"]
   134  	require.False(t, ok)
   135  	b.Reset()
   136  }
   137  
   138  type ErrorHook struct {
   139  	Fired bool
   140  }
   141  
   142  func (hook *ErrorHook) Fire(entry *Entry) error {
   143  	hook.Fired = true
   144  	return nil
   145  }
   146  
   147  func (hook *ErrorHook) Levels() []Level {
   148  	return []Level{
   149  		ErrorLevel,
   150  	}
   151  }
   152  
   153  func TestErrorHookShouldntFireOnInfo(t *testing.T) {
   154  	hook := new(ErrorHook)
   155  
   156  	LogAndAssertJSON(t, func(log *Logger) {
   157  		log.Hooks.Add(hook)
   158  		log.Info("test")
   159  	}, func(fields Fields) {
   160  		assert.Equal(t, hook.Fired, false)
   161  	})
   162  }
   163  
   164  func TestErrorHookShouldFireOnError(t *testing.T) {
   165  	hook := new(ErrorHook)
   166  
   167  	LogAndAssertJSON(t, func(log *Logger) {
   168  		log.Hooks.Add(hook)
   169  		log.Error("test")
   170  	}, func(fields Fields) {
   171  		assert.Equal(t, hook.Fired, true)
   172  	})
   173  }
   174  
   175  func TestAddHookRace(t *testing.T) {
   176  	var wg sync.WaitGroup
   177  	wg.Add(2)
   178  	hook := new(ErrorHook)
   179  	LogAndAssertJSON(t, func(log *Logger) {
   180  		go func() {
   181  			defer wg.Done()
   182  			log.AddHook(hook)
   183  		}()
   184  		go func() {
   185  			defer wg.Done()
   186  			log.Error("test")
   187  		}()
   188  		wg.Wait()
   189  	}, func(fields Fields) {
   190  		// the line may have been logged
   191  		// before the hook was added, so we can't
   192  		// actually assert on the hook
   193  	})
   194  }
   195  
   196  func TestAddHookRace2(t *testing.T) {
   197  	t.Parallel()
   198  
   199  	for i := 0; i < 3; i++ {
   200  		testname := fmt.Sprintf("Test %d", i)
   201  		t.Run(testname, func(t *testing.T) {
   202  			t.Parallel()
   203  
   204  			_ = test.NewGlobal()
   205  			Info(testname)
   206  		})
   207  	}
   208  }
   209  
   210  type HookCallFunc struct {
   211  	F func()
   212  }
   213  
   214  func (h *HookCallFunc) Levels() []Level {
   215  	return AllLevels
   216  }
   217  
   218  func (h *HookCallFunc) Fire(e *Entry) error {
   219  	h.F()
   220  	return nil
   221  }
   222  
   223  func TestHookFireOrder(t *testing.T) {
   224  	checkers := []string{}
   225  	h := LevelHooks{}
   226  	h.Add(&HookCallFunc{F: func() { checkers = append(checkers, "first hook") }})
   227  	h.Add(&HookCallFunc{F: func() { checkers = append(checkers, "second hook") }})
   228  	h.Add(&HookCallFunc{F: func() { checkers = append(checkers, "third hook") }})
   229  
   230  	if err := h.Fire(InfoLevel, &Entry{}); err != nil {
   231  		t.Error("unexpected error:", err)
   232  	}
   233  	require.Equal(t, []string{"first hook", "second hook", "third hook"}, checkers)
   234  }
   235  

View as plain text