go-transaction-manager

Форк
0
794 строки · 19.9 Кб
1
package manager
2

3
import (
4
	"context"
5
	"errors"
6
	"sync"
7
	"testing"
8
	"time"
9

10
	"github.com/golang/mock/gomock"
11
	"github.com/stretchr/testify/assert"
12
	"github.com/stretchr/testify/require"
13

14
	trmcontext "github.com/avito-tech/go-transaction-manager/trm/v2/context"
15
	mock2 "github.com/avito-tech/go-transaction-manager/trm/v2/drivers/mock"
16
	mock_log "github.com/avito-tech/go-transaction-manager/trm/v2/manager/mock"
17
	"github.com/avito-tech/go-transaction-manager/trm/v2/settings"
18

19
	"github.com/avito-tech/go-transaction-manager/trm/v2"
20
)
21

22
func Test_transactionManager_Do(t *testing.T) {
23
	t.Parallel()
24

25
	type fields struct {
26
		factory  trm.TrFactory
27
		settings trm.Settings
28
		log      logger
29
	}
30

31
	type args struct {
32
		ctx            context.Context
33
		settings       trm.Settings
34
		nestedSettings trm.Settings
35
	}
36

37
	ctxManager := trmcontext.DefaultManager
38

39
	emptyFactory := func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
40
		return ctx, nil, nil
41
	}
42

43
	tests := map[string]struct {
44
		args         args
45
		fields       func(t *testing.T, ctrl *gomock.Controller, a args) fields
46
		wantErr      assert.ErrorAssertionFunc
47
		wantEmptyCtx bool
48
	}{
49
		"PropagationRequired_success_commit": {
50
			args: args{
51
				ctx:            context.Background(),
52
				settings:       settings.Must(),
53
				nestedSettings: settings.Must(),
54
			},
55
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
56
				f := fields{
57
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
58
						tx := mock2.NewMockTransaction(ctrl)
59

60
						tx.EXPECT().IsActive().Return(true)
61
						tx.EXPECT().Commit(gomock.Any()).Return(nil)
62

63
						return ctx, tx, nil
64
					},
65
					settings: a.settings,
66
					log:      mock_log.NewMocklogger(ctrl),
67
				}
68

69
				return f
70
			},
71
			wantErr: assert.NoError,
72
		},
73
		"PropagationNested_success_commit": {
74
			args: args{
75
				ctx: context.Background(),
76
				settings: settings.Must(
77
					settings.WithPropagation(trm.PropagationNested),
78
				),
79
				nestedSettings: settings.Must(
80
					settings.WithPropagation(trm.PropagationNested),
81
				),
82
			},
83
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
84
				f := fields{
85
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
86
						txSP := mock2.NewMocktransactionWithSP(ctrl)
87

88
						txSP.EXPECT().IsActive().Return(true).Times(2)
89
						txSP.EXPECT().Begin(gomock.Any(), a.settings).Return(ctx, txSP, nil)
90
						txSP.EXPECT().Commit(gomock.Any()).Return(nil).Times(2)
91

92
						return ctx, txSP, nil
93
					},
94
					settings: a.settings,
95
					log:      mock_log.NewMocklogger(ctrl),
96
				}
97

98
				return f
99
			},
100
			wantErr: assert.NoError,
101
		},
102
		"PropagationsMandatory_success_commit": {
103
			args: args{
104
				ctx: ctxManager.SetByKey(
105
					context.Background(),
106
					settings.DefaultCtxKey,
107
					mock2.NewMockTransaction(nil),
108
				),
109
				settings: settings.Must(),
110
				nestedSettings: settings.Must(
111
					settings.WithPropagation(trm.PropagationsMandatory),
112
				),
113
			},
114
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
115
				f := fields{
116
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
117
						txSP := mock2.NewMocktransactionWithSP(ctrl)
118

119
						txSP.EXPECT().IsActive().Return(true)
120
						txSP.EXPECT().Begin(gomock.Any(), a.settings).Return(txSP, nil)
121
						txSP.EXPECT().Commit(gomock.Any()).Return(nil).Times(2)
122

123
						return ctx, txSP, nil
124
					},
125
					settings: a.settings,
126
					log:      mock_log.NewMocklogger(ctrl),
127
				}
128

129
				return f
130
			},
131
			wantErr: assert.NoError,
132
		},
133
		"PropagationsMandatory_error_without_open_transaction": {
134
			args: args{
135
				ctx: context.Background(),
136
				settings: settings.Must(
137
					settings.WithPropagation(trm.PropagationsMandatory),
138
				),
139
			},
140
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
141
				f := fields{
142
					factory:  emptyFactory,
143
					settings: a.settings,
144
					log:      mock_log.NewMocklogger(ctrl),
145
				}
146

147
				return f
148
			},
149
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
150
				return assert.ErrorIs(t, err, trm.ErrPropagationMandatory)
151
			},
152
		},
153
		"PropagationNever_success": {
154
			args: args{
155
				ctx: context.Background(),
156
				settings: settings.Must(settings.WithPropagation(
157
					trm.PropagationNever,
158
				)),
159
				nestedSettings: settings.Must(settings.WithPropagation(
160
					trm.PropagationNever,
161
				)),
162
			},
163
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
164
				f := fields{
165
					factory:  emptyFactory,
166
					settings: a.settings,
167
					log:      mock_log.NewMocklogger(ctrl),
168
				}
169

170
				return f
171
			},
172
			wantEmptyCtx: true,
173
			wantErr:      assert.NoError,
174
		},
175
		"PropagationNever_error_transaction_is_opened": {
176
			args: args{
177
				ctx:      context.Background(),
178
				settings: settings.Must(),
179
				nestedSettings: settings.Must(settings.WithPropagation(
180
					trm.PropagationNever,
181
				)),
182
			},
183
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
184
				f := fields{
185
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
186
						tx := mock2.NewMockTransaction(ctrl)
187

188
						tx.EXPECT().IsActive().Return(true)
189
						tx.EXPECT().Rollback(gomock.Any()).Return(nil)
190

191
						return ctx, tx, nil
192
					},
193
					settings: a.settings,
194
					log:      mock_log.NewMocklogger(ctrl),
195
				}
196

197
				return f
198
			},
199
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
200
				return assert.ErrorIs(t, err, trm.ErrPropagationNever)
201
			},
202
		},
203
		"PropagationNotSupported_success_commit": {
204
			args: args{
205
				ctx: context.Background(),
206
				settings: settings.Must(
207
					settings.WithPropagation(trm.PropagationNotSupported),
208
				),
209
				nestedSettings: settings.Must(
210
					settings.WithPropagation(trm.PropagationNotSupported),
211
				),
212
			},
213
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
214
				f := fields{
215
					factory:  emptyFactory,
216
					settings: a.settings,
217
					log:      mock_log.NewMocklogger(ctrl),
218
				}
219

220
				return f
221
			},
222
			wantErr:      assert.NoError,
223
			wantEmptyCtx: true,
224
		},
225
		"PropagationNotSupported_nilling_ctx_success_commit": {
226
			args: args{
227
				ctx:      context.Background(),
228
				settings: settings.Must(),
229
				nestedSettings: settings.Must(
230
					settings.WithPropagation(trm.PropagationNotSupported),
231
				),
232
			},
233
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
234
				f := fields{
235
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
236
						txSP := mock2.NewMocktransactionWithSP(ctrl)
237

238
						txSP.EXPECT().IsActive().Return(true)
239
						txSP.EXPECT().Commit(gomock.Any()).Return(nil)
240

241
						return ctx, txSP, nil
242
					},
243
					settings: a.settings,
244
					log:      mock_log.NewMocklogger(ctrl),
245
				}
246

247
				return f
248
			},
249
			wantErr:      assert.NoError,
250
			wantEmptyCtx: true,
251
		},
252
		"PropagationRequiresNew": {
253
			args: args{
254
				ctx: context.Background(),
255
				settings: settings.Must(
256
					settings.WithPropagation(trm.PropagationRequiresNew),
257
				),
258
				nestedSettings: settings.Must(
259
					settings.WithPropagation(trm.PropagationRequiresNew),
260
				),
261
			},
262
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
263
				f := fields{
264
					factory: func() trm.TrFactory {
265
						txSP := mock2.NewMocktransactionWithSP(ctrl)
266

267
						txSP.EXPECT().IsActive().Return(true).Times(2)
268
						txSP.EXPECT().Commit(gomock.Any()).Return(nil).Times(2)
269

270
						return func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
271
							return ctx, txSP, nil
272
						}
273
					}(),
274
					settings: a.settings,
275
					log:      mock_log.NewMocklogger(ctrl),
276
				}
277

278
				return f
279
			},
280
			wantErr: assert.NoError,
281
		},
282
		"PropagationSupports_nil_transaction": {
283
			args: args{
284
				ctx: context.Background(),
285
				settings: settings.Must(
286
					settings.WithPropagation(trm.PropagationSupports),
287
				),
288
				nestedSettings: settings.Must(
289
					settings.WithPropagation(trm.PropagationSupports),
290
				),
291
			},
292
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
293
				f := fields{
294
					factory:  emptyFactory,
295
					settings: a.settings,
296
					log:      mock_log.NewMocklogger(ctrl),
297
				}
298

299
				return f
300
			},
301
			wantErr:      assert.NoError,
302
			wantEmptyCtx: true,
303
		},
304
		"PropagationSupports": {
305
			args: args{
306
				ctx: context.Background(),
307
				settings: settings.Must(
308
					settings.WithPropagation(trm.PropagationRequired),
309
				),
310
				nestedSettings: settings.Must(
311
					settings.WithPropagation(trm.PropagationSupports),
312
				),
313
			},
314
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
315
				f := fields{
316
					factory: func() func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
317
						txSP := mock2.NewMocktransactionWithSP(ctrl)
318

319
						txSP.EXPECT().IsActive().Return(true)
320
						txSP.EXPECT().Commit(gomock.Any()).Return(nil)
321

322
						return func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
323
							return ctx, txSP, nil
324
						}
325
					}(),
326
					settings: a.settings,
327
					log:      mock_log.NewMocklogger(ctrl),
328
				}
329

330
				return f
331
			},
332
			wantErr: assert.NoError,
333
		},
334
	}
335
	for name, tt := range tests {
336
		tt := tt
337
		t.Run(name, func(t *testing.T) {
338
			t.Parallel()
339

340
			ctrl := gomock.NewController(t)
341
			defer ctrl.Finish()
342

343
			f := tt.fields(t, ctrl, tt.args)
344

345
			tr := Must(f.factory, WithLog(f.log), WithSettings(f.settings))
346

347
			err := tr.DoWithSettings(
348
				tt.args.ctx,
349
				tt.args.settings,
350
				func(ctx context.Context) error {
351
					return tr.DoWithSettings(
352
						ctx,
353
						tt.args.nestedSettings,
354
						func(ctx context.Context) error {
355
							if tt.wantEmptyCtx {
356
								require.Nil(t, ctxManager.Default(ctx))
357
							} else {
358
								require.NotNil(t, ctxManager.Default(ctx))
359
							}
360

361
							return nil
362
						},
363
					)
364
				},
365
			)
366

367
			tt.wantErr(t, err)
368
		})
369
	}
370
}
371

372
func Test_transactionManager_Do_Error(t *testing.T) {
373
	t.Parallel()
374

375
	type fields struct {
376
		factory  trm.TrFactory
377
		settings trm.Settings
378
		log      logger
379
	}
380

381
	type args struct {
382
		ctx      context.Context
383
		settings trm.Settings
384
	}
385

386
	testErr := errors.New("error test")
387
	testCommitErr := errors.New("error Commit test")
388
	testRollbackErr := errors.New("error rollback test")
389
	defaultArgs := args{
390
		ctx:      context.Background(),
391
		settings: settings.Must(),
392
	}
393

394
	tests := map[string]struct {
395
		args    args
396
		fields  func(t *testing.T, ctrl *gomock.Controller, a args) fields
397
		ret     error
398
		wantErr assert.ErrorAssertionFunc
399
	}{
400
		//nolint:dupl
401
		"transaction_factory_&_rollback_error": {
402
			args: defaultArgs,
403
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
404
				return fields{
405
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
406
						tx := mock2.NewMockTransaction(ctrl)
407

408
						tx.EXPECT().
409
							IsActive().
410
							Return(true)
411
						tx.EXPECT().
412
							Rollback(gomock.Any()).
413
							Return(testRollbackErr)
414

415
						return ctx, tx, nil
416
					},
417
					settings: a.settings,
418
					log:      mock_log.NewMocklogger(ctrl),
419
				}
420
			},
421
			ret: testErr,
422
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
423
				return assert.ErrorIs(t, err, testErr) &&
424
					assert.ErrorIs(t, err, trm.ErrRollback)
425
			},
426
		},
427
		"skip_rollback_with_error": {
428
			args: defaultArgs,
429
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
430
				return fields{
431
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
432
						tx := mock2.NewMockTransaction(ctrl)
433

434
						tx.EXPECT().
435
							IsActive().
436
							Return(true)
437
						tx.EXPECT().
438
							Commit(gomock.Any())
439

440
						return ctx, tx, nil
441
					},
442
					settings: a.settings,
443
					log:      mock_log.NewMocklogger(ctrl),
444
				}
445
			},
446
			ret: trm.Skippable(testErr),
447
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
448
				return assert.ErrorIs(t, err, testErr) &&
449
					assert.True(t, trm.IsSkippable(err))
450
			},
451
		},
452
		"skip_rollback_with_commit_error": {
453
			args: defaultArgs,
454
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
455
				return fields{
456
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
457
						tx := mock2.NewMockTransaction(ctrl)
458

459
						tx.EXPECT().
460
							IsActive().
461
							Return(true)
462
						tx.EXPECT().
463
							Commit(gomock.Any()).
464
							Return(testCommitErr)
465

466
						return ctx, tx, nil
467
					},
468
					settings: a.settings,
469
					log:      mock_log.NewMocklogger(ctrl),
470
				}
471
			},
472
			ret: trm.Skippable(testErr),
473
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
474
				return assert.ErrorIs(t, err, testErr) &&
475
					assert.ErrorIs(t, err, testCommitErr) &&
476
					assert.ErrorIs(t, err, trm.ErrCommit) &&
477
					assert.False(t, trm.IsSkippable(err))
478
			},
479
		},
480
		//nolint:dupl
481
		"commit_error": {
482
			args: defaultArgs,
483
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
484
				return fields{
485
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
486
						tx := mock2.NewMockTransaction(ctrl)
487

488
						tx.EXPECT().
489
							IsActive().
490
							Return(true)
491
						tx.EXPECT().
492
							Commit(gomock.Any()).
493
							Return(testCommitErr)
494

495
						return ctx, tx, nil
496
					},
497
					settings: a.settings,
498
					log:      mock_log.NewMocklogger(ctrl),
499
				}
500
			},
501
			ret: nil,
502
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
503
				return assert.ErrorIs(t, err, testCommitErr) &&
504
					assert.ErrorIs(t, err, trm.ErrCommit)
505
			},
506
		},
507
		"PropagationNested_err_nested_begin": {
508
			args: args{
509
				ctx: context.Background(),
510
				settings: settings.Must(
511
					settings.WithPropagation(trm.PropagationNested),
512
				),
513
			},
514
			fields: func(_ *testing.T, ctrl *gomock.Controller, a args) fields {
515
				f := fields{
516
					factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
517
						txSP := mock2.NewMocktransactionWithSP(ctrl)
518

519
						txSP.EXPECT().IsActive().Return(true).Times(1)
520
						txSP.EXPECT().Begin(gomock.Any(), a.settings).Return(ctx, nil, testErr)
521
						txSP.EXPECT().Rollback(gomock.Any()).Return(nil).Times(1)
522

523
						return ctx, txSP, nil
524
					},
525
					settings: a.settings,
526
					log:      mock_log.NewMocklogger(ctrl),
527
				}
528

529
				return f
530
			},
531
			wantErr: func(t assert.TestingT, err error, _ ...interface{}) bool {
532
				return assert.ErrorIs(t, err, testErr) &&
533
					assert.ErrorIs(t, err, trm.ErrNestedBegin)
534
			},
535
		},
536
	}
537
	for name, tt := range tests {
538
		tt := tt
539
		t.Run(name, func(t *testing.T) {
540
			t.Parallel()
541

542
			ctrl := gomock.NewController(t)
543
			defer ctrl.Finish()
544

545
			f := tt.fields(t, ctrl, tt.args)
546

547
			tr := Must(f.factory, WithLog(f.log), WithSettings(f.settings))
548

549
			err := tr.DoWithSettings(
550
				tt.args.ctx,
551
				tt.args.settings,
552
				func(ctx context.Context) error {
553
					return tr.Do(
554
						ctx,
555
						func(_ context.Context) error {
556
							return tt.ret
557
						},
558
					)
559
				},
560
			)
561

562
			tt.wantErr(t, err)
563
		})
564
	}
565
}
566

567
func Test_transactionManager_Do_Panic(t *testing.T) {
568
	t.Parallel()
569

570
	ctrl := gomock.NewController(t)
571
	defer ctrl.Finish()
572

573
	testPanic := "panic"
574
	testRollbackErr := errors.New("rollback error")
575

576
	log := mock2.NewLog()
577
	factory := func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
578
		tx := mock2.NewMockTransaction(ctrl)
579

580
		tx.EXPECT().IsActive().Return(true)
581
		tx.EXPECT().Rollback(gomock.Any()).Return(testRollbackErr)
582

583
		return ctx, tx, nil
584
	}
585

586
	m := Must(factory, WithLog(log))
587
	ctxManager := trmcontext.DefaultManager
588

589
	defer func() {
590
		p := recover()
591

592
		assert.Equal(t, testPanic, p)
593
		assert.Equal(t, []string{"rollback error, panic"}, log.Logged)
594
	}()
595

596
	_ = m.Do(context.Background(), func(ctx context.Context) error {
597
		return m.Do(ctx, func(ctx context.Context) error {
598
			assert.NotNil(
599
				t,
600
				ctxManager.Default(ctx),
601
			)
602

603
			panic(testPanic)
604
		})
605
	})
606

607
	assert.NoError(t, errors.New("should not be here"))
608
}
609

610
//nolint:tparallel // there is not t.Cleanup in go 1.13 and less.
611
func Test_transactionManager_Do_ClosedTransaction(t *testing.T) {
612
	t.Parallel()
613

614
	ctrl := gomock.NewController(t)
615
	defer ctrl.Finish()
616

617
	testErr := errors.New("test error")
618

619
	tests := map[string]struct {
620
		ret     error
621
		wantErr require.ErrorAssertionFunc
622
	}{
623
		"without_error": {
624
			ret: nil,
625
			wantErr: func(t require.TestingT, err error, _ ...interface{}) {
626
				require.Equal(t, trm.ErrAlreadyClosed, err)
627
			},
628
		},
629
		"with_error": {
630
			ret: testErr,
631
			wantErr: func(t require.TestingT, err error, _ ...interface{}) {
632
				require.ErrorIs(t, err, testErr)
633
				require.ErrorIs(t, err, trm.ErrAlreadyClosed)
634
			},
635
		},
636
	}
637
	for name, tt := range tests {
638
		tt := tt
639
		t.Run(name, func(t *testing.T) {
640
			t.Parallel()
641

642
			tx := mock2.NewMockTransaction(ctrl)
643
			tx.EXPECT().IsActive().Return(false).MinTimes(2)
644

645
			factory := func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
646
				return ctx, tx, nil
647
			}
648

649
			m := Must(
650
				factory,
651
				WithSettings(settings.Must(settings.WithPropagation(trm.PropagationRequiresNew))),
652
			)
653

654
			err := m.Do(context.Background(), func(ctx context.Context) error {
655
				return m.Do(ctx, func(_ context.Context) error {
656
					return tt.ret
657
				})
658
			})
659

660
			tt.wantErr(t, err)
661
		})
662
	}
663
}
664

665
//nolint:tparallel // there is not t.Cleanup in go 1.13 and less.
666
func Test_transactionManager_Do_Cancel(t *testing.T) {
667
	type fields struct {
668
		settings trm.Settings
669
		factory  trm.TrFactory
670
	}
671

672
	t.Parallel()
673

674
	ctrl := gomock.NewController(t)
675
	defer ctrl.Finish()
676

677
	tests := map[string]struct {
678
		fields  fields
679
		ctx     func(ctx context.Context) (context.Context, context.CancelFunc)
680
		do      func(t *testing.T, ctx context.Context)
681
		wantErr require.ErrorAssertionFunc
682
	}{
683
		"cancel": {
684
			fields: fields{
685
				factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
686
					tr := mock2.NewMockTransaction(ctrl)
687
					tr.EXPECT().IsActive().Return(false)
688

689
					return ctx, tr, nil
690
				},
691
				settings: settings.Must(
692
					settings.WithCancelable(true),
693
					settings.WithPropagation(trm.PropagationRequiresNew),
694
				),
695
			},
696
			ctx: context.WithCancel,
697
			do: func(t *testing.T, ctx context.Context) {
698
				time.Sleep(time.Millisecond)
699

700
				assert.ErrorIs(t, ctx.Err(), context.Canceled)
701
			},
702
			wantErr: func(t require.TestingT, err error, _ ...interface{}) {
703
				assert.ErrorIs(t, err, context.Canceled)
704
			},
705
		},
706
		"timeout": {
707
			fields: fields{
708
				factory: func(ctx context.Context, _ trm.Settings) (context.Context, trm.Transaction, error) {
709
					tr := mock2.NewMockTransaction(ctrl)
710
					tr.EXPECT().IsActive().Return(false)
711

712
					return ctx, tr, nil
713
				},
714
				settings: settings.Must(
715
					settings.WithCancelable(true),
716
					settings.WithTimeout(time.Millisecond),
717
					settings.WithPropagation(trm.PropagationRequiresNew),
718
				),
719
			},
720
			ctx: func(ctx context.Context) (context.Context, context.CancelFunc) {
721
				return ctx, func() {}
722
			},
723
			do: func(t *testing.T, ctx context.Context) {
724
				select {
725
				case <-time.After(time.Second):
726
				case <-ctx.Done():
727
				}
728

729
				assert.ErrorIs(t, ctx.Err(), context.DeadlineExceeded)
730
			},
731
			wantErr: func(t require.TestingT, err error, _ ...interface{}) {
732
				assert.ErrorIs(t, err, context.DeadlineExceeded)
733
			},
734
		},
735
	}
736
	for name, tt := range tests {
737
		tt := tt
738
		t.Run(name, func(t *testing.T) {
739
			t.Parallel()
740

741
			m := Must(
742
				tt.fields.factory,
743
				WithSettings(tt.fields.settings),
744
			)
745

746
			var err error
747

748
			wg := sync.WaitGroup{}
749
			wg.Add(1)
750

751
			ctx, cancel := tt.ctx(context.Background())
752
			go func() {
753
				err = m.Do(ctx, func(ctx context.Context) error {
754
					return m.Do(ctx, func(ctx context.Context) error {
755
						tt.do(t, ctx)
756

757
						return nil
758
					})
759
				})
760

761
				wg.Done()
762
			}()
763

764
			cancel()
765

766
			wg.Wait()
767

768
			tt.wantErr(t, err)
769
		})
770
	}
771
}
772

773
func TestManager_WithOpts(t *testing.T) {
774
	t.Parallel()
775

776
	t.Run("set", func(t *testing.T) {
777
		t.Parallel()
778

779
		l := mock2.NewZeroLog()
780
		m := Must(nil, WithLog(l), WithSettings(s{}))
781

782
		assert.Equal(t, l, m.log)
783
		assert.Equal(t, s{}, m.settings)
784
	})
785

786
	t.Run("default", func(t *testing.T) {
787
		t.Parallel()
788

789
		m := Must(nil)
790

791
		assert.Equal(t, defaultLog, m.log)
792
		assert.Equal(t, settings.Must(), m.settings)
793
	})
794
}
795

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.