github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/errors_timestamp_test.go (about)

     1  package grip
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/mongodb/grip/level"
    10  	"github.com/mongodb/grip/message"
    11  	"github.com/pkg/errors"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestTimestampError(t *testing.T) {
    17  	t.Run("ErrorFinder", func(t *testing.T) {
    18  		ts, ok := ErrorTimeFinder(nil)
    19  		assert.False(t, ok)
    20  		assert.Zero(t, ts)
    21  
    22  		ts, ok = ErrorTimeFinder(newTimeStampError(nil))
    23  		assert.False(t, ok)
    24  		assert.Zero(t, ts)
    25  
    26  		ts, ok = ErrorTimeFinder(newTimeStampError(errors.New("hello")))
    27  		assert.True(t, ok)
    28  		assert.NotZero(t, ts)
    29  
    30  		ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack((errors.New("hello"))), "world"))
    31  		assert.False(t, ok)
    32  		assert.Zero(t, ts)
    33  
    34  		ts, ok = ErrorTimeFinder(errors.WithStack(newTimeStampError(errors.New("hello"))))
    35  		assert.True(t, ok)
    36  		assert.NotZero(t, ts)
    37  
    38  		ts, ok = ErrorTimeFinder(errors.WithStack(newTimeStampError(nil)))
    39  		assert.False(t, ok)
    40  		assert.Zero(t, ts)
    41  
    42  		ts, ok = ErrorTimeFinder(newTimeStampError(errors.WithStack(errors.New("hello"))))
    43  		assert.True(t, ok)
    44  		assert.NotZero(t, ts)
    45  
    46  		ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack(newTimeStampError(errors.New("hello"))), "world"))
    47  		assert.True(t, ok)
    48  		assert.NotZero(t, ts)
    49  	})
    50  	t.Run("Wrap", func(t *testing.T) {
    51  		t.Run("WithTimestamp", func(t *testing.T) {
    52  			ts, ok := ErrorTimeFinder(nil)
    53  			assert.False(t, ok)
    54  			assert.Zero(t, ts)
    55  
    56  			ts, ok = ErrorTimeFinder(WrapErrorTime(nil))
    57  			assert.False(t, ok)
    58  			assert.Zero(t, ts)
    59  
    60  			ts, ok = ErrorTimeFinder(WrapErrorTime(errors.New("hello")))
    61  			assert.True(t, ok)
    62  			assert.NotZero(t, ts)
    63  
    64  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTime(errors.New("hello"))))
    65  			assert.True(t, ok)
    66  			assert.NotZero(t, ts)
    67  
    68  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTime(nil)))
    69  			assert.False(t, ok)
    70  			assert.Zero(t, ts)
    71  
    72  			ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack(WrapErrorTime(errors.New("hello"))), "world"))
    73  			assert.True(t, ok)
    74  			assert.NotZero(t, ts)
    75  		})
    76  		t.Run("WithTimestampMessage", func(t *testing.T) {
    77  			ts, ok := ErrorTimeFinder(nil)
    78  			assert.False(t, ok)
    79  			assert.Zero(t, ts)
    80  
    81  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessage(nil, "earth"))
    82  			assert.False(t, ok)
    83  			assert.Zero(t, ts)
    84  
    85  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessage(errors.New("hello"), "earth"))
    86  			assert.True(t, ok)
    87  			assert.NotZero(t, ts)
    88  
    89  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessage(errors.New("hello"), "earth")))
    90  			assert.True(t, ok)
    91  			assert.NotZero(t, ts)
    92  
    93  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessage(nil, "earth")))
    94  			assert.False(t, ok)
    95  			assert.Zero(t, ts)
    96  
    97  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessage(errors.WithStack(errors.New("hello")), "earth"))
    98  			assert.True(t, ok)
    99  			assert.NotZero(t, ts)
   100  
   101  			ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack(WrapErrorTimeMessage(errors.New("hello"), "earth")), "world"))
   102  			assert.True(t, ok)
   103  			assert.NotZero(t, ts)
   104  		})
   105  		t.Run("WithTimestampMessageFormatEmpty", func(t *testing.T) {
   106  			ts, ok := ErrorTimeFinder(nil)
   107  			assert.False(t, ok)
   108  			assert.Zero(t, ts)
   109  
   110  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(nil, "earth"))
   111  			assert.False(t, ok)
   112  			assert.Zero(t, ts)
   113  
   114  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(errors.New("hello"), "earth"))
   115  			assert.True(t, ok)
   116  			assert.NotZero(t, ts)
   117  
   118  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessagef(errors.New("hello"), "earth")))
   119  			assert.True(t, ok)
   120  			assert.NotZero(t, ts)
   121  
   122  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessagef(nil, "earth")))
   123  			assert.False(t, ok)
   124  			assert.Zero(t, ts)
   125  
   126  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(errors.WithStack(errors.New("hello")), "earth"))
   127  			assert.True(t, ok)
   128  			assert.NotZero(t, ts)
   129  
   130  			ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack(WrapErrorTimeMessagef(errors.New("hello"), "earth")), "world"))
   131  			assert.True(t, ok)
   132  			assert.NotZero(t, ts)
   133  		})
   134  		t.Run("WrapWithTimestampMessageFormat", func(t *testing.T) {
   135  			ts, ok := ErrorTimeFinder(nil)
   136  			assert.False(t, ok)
   137  			assert.Zero(t, ts)
   138  
   139  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(nil, "earth-%s", "lings"))
   140  			assert.False(t, ok)
   141  			assert.Zero(t, ts)
   142  
   143  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(errors.New("hello"), "earth-%s", "lings"))
   144  			assert.True(t, ok)
   145  			assert.NotZero(t, ts)
   146  
   147  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessagef(errors.New("hello"), "earth-%s", "lings")))
   148  			assert.True(t, ok)
   149  			assert.NotZero(t, ts)
   150  
   151  			ts, ok = ErrorTimeFinder(errors.WithStack(WrapErrorTimeMessagef(nil, "earth-%s", "lings")))
   152  			assert.False(t, ok)
   153  			assert.Zero(t, ts)
   154  
   155  			ts, ok = ErrorTimeFinder(WrapErrorTimeMessagef(errors.WithStack(errors.New("hello")), "earth-%s", "lings"))
   156  			assert.True(t, ok)
   157  			assert.NotZero(t, ts)
   158  
   159  			ts, ok = ErrorTimeFinder(errors.Wrap(errors.WithStack(WrapErrorTimeMessagef(errors.New("hello"), "earth-%s", "lings")), "world"))
   160  			assert.True(t, ok)
   161  			assert.NotZero(t, ts)
   162  		})
   163  	})
   164  	t.Run("Interfaces", func(t *testing.T) {
   165  		t.Run("Cause", func(t *testing.T) {
   166  			we := WrapErrorTime(errors.New("hello"))
   167  			assert.Equal(t, "hello", we.(errorCauser).Cause().Error())
   168  		})
   169  		t.Run("FormattingBasic", func(t *testing.T) {
   170  			err := &timestampError{
   171  				time: time.Now(),
   172  				err:  errors.New("hello world"),
   173  			}
   174  			assert.Contains(t, err.Error(), err.time.Format(time.RFC3339))
   175  			assert.Contains(t, err.Error(), "hello world")
   176  		})
   177  		t.Run("FormattingStrong", func(t *testing.T) {
   178  			err := &timestampError{
   179  				time: time.Now(),
   180  				err:  errors.New("hello world"),
   181  			}
   182  			assert.Contains(t, fmt.Sprintf("%+v", err), err.time.Format(time.RFC3339))
   183  			assert.Contains(t, fmt.Sprintf("%+v", err), "hello world")
   184  			assert.Contains(t, fmt.Sprintf("%q", err), err.time.Format(time.RFC3339))
   185  			assert.Contains(t, fmt.Sprintf("%q", err), "hello world")
   186  			assert.Contains(t, fmt.Sprintf("%s", err), err.time.Format(time.RFC3339)) // nolint
   187  			assert.Contains(t, fmt.Sprintf("%s", err), "hello world")                 // nolint
   188  		})
   189  		t.Run("Composer", func(t *testing.T) {
   190  			assert.Implements(t, (*message.Composer)(nil), &timestampError{})
   191  			t.Run("Nil", func(t *testing.T) {
   192  				err := &timestampError{}
   193  				assert.False(t, err.Loggable())
   194  				assert.Zero(t, err.String())
   195  				assert.NoError(t, err.Annotate("foo", "bar"))
   196  			})
   197  			t.Run("Loggable", func(t *testing.T) {
   198  				msg, ok := WrapErrorTime(errors.New("hello world")).(message.Composer)
   199  				require.True(t, ok)
   200  
   201  				assert.True(t, msg.Loggable())
   202  				assert.Equal(t, "hello world", msg.String())
   203  			})
   204  			t.Run("Annotate", func(t *testing.T) {
   205  				msg, ok := WrapErrorTime(errors.New("hello world")).(message.Composer)
   206  				require.True(t, ok)
   207  				assert.NoError(t, msg.Annotate("foo", "bar"))
   208  				assert.Error(t, msg.Annotate("foo", "bar"))
   209  				assert.NoError(t, msg.Annotate("bar", "bar"))
   210  			})
   211  			t.Run("RawJSON", func(t *testing.T) {
   212  				msg, ok := WrapErrorTime(errors.New("hello world")).(message.Composer)
   213  				require.True(t, ok)
   214  
   215  				for i := 0; i < 10; i++ {
   216  					_, err := json.Marshal(msg.Raw())
   217  					require.NoError(t, err)
   218  				}
   219  			})
   220  			t.Run("Levels", func(t *testing.T) {
   221  				err := &timestampError{}
   222  				require.Error(t, err.SetPriority(1000))
   223  				require.NoError(t, err.SetPriority(level.Debug))
   224  				require.Equal(t, level.Debug, err.Priority())
   225  
   226  				require.Error(t, err.SetPriority(1000))
   227  				require.Equal(t, level.Debug, err.Priority())
   228  
   229  				require.NoError(t, err.SetPriority(level.Alert))
   230  				require.Equal(t, level.Alert, err.Priority())
   231  			})
   232  		})
   233  	})
   234  }