github.com/celestiaorg/celestia-node@v0.15.0-beta.1/share/getters/utils_test.go (about) 1 package getters 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func Test_ErrorContains(t *testing.T) { 15 err1 := errors.New("1") 16 err2 := errors.New("2") 17 18 w1 := func(err error) error { 19 return fmt.Errorf("wrap1: %w", err) 20 } 21 w2 := func(err error) error { 22 return fmt.Errorf("wrap1: %w", err) 23 } 24 25 type args struct { 26 err error 27 target error 28 } 29 tests := []struct { 30 name string 31 args args 32 want bool 33 }{ 34 {"nil err", 35 args{ 36 err: nil, 37 target: err1, 38 }, 39 false, 40 }, 41 {"nil target", 42 args{ 43 err: err1, 44 target: nil, 45 }, 46 true, 47 }, 48 {"errors.Is true", 49 args{ 50 err: w1(err1), 51 target: err1, 52 }, 53 true, 54 }, 55 {"errors.Is false", 56 args{ 57 err: w1(err1), 58 target: err2, 59 }, 60 false, 61 }, 62 {"same wrap but different base error", 63 args{ 64 err: w1(err1), 65 target: w1(err2), 66 }, 67 false, 68 }, 69 {"both wrapped true", 70 args{ 71 err: w1(err1), 72 target: w2(err1), 73 }, 74 true, 75 }, 76 {"both wrapped false", 77 args{ 78 err: w1(err1), 79 target: w2(err2), 80 }, 81 false, 82 }, 83 {"multierr first in slice", 84 args{ 85 err: errors.Join(w1(err1), w2(err2)), 86 target: w2(err1), 87 }, 88 true, 89 }, 90 {"multierr second in slice", 91 args{ 92 err: errors.Join(w1(err1), w2(err2)), 93 target: w1(err2), 94 }, 95 true, 96 }, 97 } 98 for _, tt := range tests { 99 t.Run(tt.name, func(t *testing.T) { 100 assert.Equalf(t, 101 tt.want, 102 ErrorContains(tt.args.err, tt.args.target), 103 "ErrorContains(%v, %v)", tt.args.err, tt.args.target) 104 }) 105 } 106 } 107 108 func Test_ctxWithSplitTimeout(t *testing.T) { 109 type args struct { 110 ctxTimeout time.Duration 111 splitFactor []int 112 minTimeout time.Duration 113 } 114 tests := []struct { 115 name string 116 args args 117 want time.Duration 118 }{ 119 { 120 name: "ctxTimeout > minTimeout, splitFactor <= 0", 121 args: args{ 122 ctxTimeout: 3 * time.Minute, 123 splitFactor: []int{-1, 0}, 124 minTimeout: time.Minute, 125 }, 126 want: time.Minute, 127 }, 128 { 129 name: "ctxTimeout > minTimeout, splitFactor = 1", 130 args: args{ 131 ctxTimeout: 3 * time.Minute, 132 splitFactor: []int{1}, 133 minTimeout: time.Minute, 134 }, 135 want: 3 * time.Minute, 136 }, 137 { 138 name: "ctxTimeout > minTimeout, splitFactor = 2", 139 args: args{ 140 ctxTimeout: 3 * time.Minute, 141 splitFactor: []int{2}, 142 minTimeout: time.Minute, 143 }, 144 want: 3 * time.Minute / 2, 145 }, 146 { 147 name: "ctxTimeout > minTimeout, resulted timeout limited by minTimeout", 148 args: args{ 149 ctxTimeout: 3 * time.Minute, 150 splitFactor: []int{3, 4, 5}, 151 minTimeout: time.Minute, 152 }, 153 want: time.Minute, 154 }, 155 { 156 name: "ctxTimeout < minTimeout", 157 args: args{ 158 ctxTimeout: time.Minute, 159 splitFactor: []int{-1, 0, 1, 2, 3}, 160 minTimeout: 2 * time.Minute, 161 }, 162 want: time.Minute, 163 }, 164 { 165 name: "minTimeout = 0, splitFactor <= 1", 166 args: args{ 167 ctxTimeout: time.Minute, 168 splitFactor: []int{-1, 0, 1}, 169 minTimeout: 0, 170 }, 171 want: time.Minute, 172 }, 173 { 174 name: "minTimeout = 0, splitFactor > 1", 175 args: args{ 176 ctxTimeout: time.Minute, 177 splitFactor: []int{2}, 178 minTimeout: 0, 179 }, 180 want: time.Minute / 2, 181 }, 182 { 183 name: "no context timeout", 184 args: args{ 185 ctxTimeout: 0, 186 splitFactor: []int{-1, 0, 1, 2}, 187 minTimeout: time.Minute, 188 }, 189 want: time.Minute, 190 }, 191 { 192 name: "no context timeout, minTimeout = 0", 193 args: args{ 194 ctxTimeout: 0, 195 splitFactor: []int{-1, 0, 1, 2}, 196 minTimeout: 0, 197 }, 198 want: 0, 199 }, 200 } 201 for _, tt := range tests { 202 t.Run(tt.name, func(t *testing.T) { 203 for _, sf := range tt.args.splitFactor { 204 ctx, cancel := context.WithCancel(context.Background()) 205 // add timeout if original context should have it 206 if tt.args.ctxTimeout > 0 { 207 ctx, cancel = context.WithTimeout(ctx, tt.args.ctxTimeout) 208 } 209 t.Cleanup(cancel) 210 got, _ := ctxWithSplitTimeout(ctx, sf, tt.args.minTimeout) 211 dl, ok := got.Deadline() 212 // in case no deadline is found in ctx or not expected to be found, check both cases apply at the 213 // same time 214 if !ok || tt.want == 0 { 215 require.False(t, ok) 216 require.Equal(t, tt.want, time.Duration(0)) 217 continue 218 } 219 d := time.Until(dl) 220 require.True(t, d <= tt.want+time.Second) 221 require.True(t, d >= tt.want-time.Second) 222 } 223 }) 224 } 225 }