github.com/lingyao2333/mo-zero@v1.4.1/core/breaker/breaker_test.go (about)

     1  package breaker
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/lingyao2333/mo-zero/core/stat"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func init() {
    15  	stat.SetReporter(nil)
    16  }
    17  
    18  func TestCircuitBreaker_Allow(t *testing.T) {
    19  	b := NewBreaker()
    20  	assert.True(t, len(b.Name()) > 0)
    21  	_, err := b.Allow()
    22  	assert.Nil(t, err)
    23  }
    24  
    25  func TestLogReason(t *testing.T) {
    26  	b := NewBreaker()
    27  	assert.True(t, len(b.Name()) > 0)
    28  
    29  	for i := 0; i < 1000; i++ {
    30  		_ = b.Do(func() error {
    31  			return errors.New(strconv.Itoa(i))
    32  		})
    33  	}
    34  	errs := b.(*circuitBreaker).throttle.(loggedThrottle).errWin
    35  	assert.Equal(t, numHistoryReasons, errs.count)
    36  }
    37  
    38  func TestErrorWindow(t *testing.T) {
    39  	tests := []struct {
    40  		name    string
    41  		reasons []string
    42  	}{
    43  		{
    44  			name: "no error",
    45  		},
    46  		{
    47  			name:    "one error",
    48  			reasons: []string{"foo"},
    49  		},
    50  		{
    51  			name:    "two errors",
    52  			reasons: []string{"foo", "bar"},
    53  		},
    54  		{
    55  			name:    "five errors",
    56  			reasons: []string{"first", "second", "third", "fourth", "fifth"},
    57  		},
    58  		{
    59  			name:    "six errors",
    60  			reasons: []string{"first", "second", "third", "fourth", "fifth", "sixth"},
    61  		},
    62  	}
    63  
    64  	for _, test := range tests {
    65  		t.Run(test.name, func(t *testing.T) {
    66  			var ew errorWindow
    67  			for _, reason := range test.reasons {
    68  				ew.add(reason)
    69  			}
    70  			var reasons []string
    71  			if len(test.reasons) > numHistoryReasons {
    72  				reasons = test.reasons[len(test.reasons)-numHistoryReasons:]
    73  			} else {
    74  				reasons = test.reasons
    75  			}
    76  			for _, reason := range reasons {
    77  				assert.True(t, strings.Contains(ew.String(), reason), fmt.Sprintf("actual: %s", ew.String()))
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  func TestPromiseWithReason(t *testing.T) {
    84  	tests := []struct {
    85  		name   string
    86  		reason string
    87  		expect string
    88  	}{
    89  		{
    90  			name: "success",
    91  		},
    92  		{
    93  			name:   "success",
    94  			reason: "fail",
    95  			expect: "fail",
    96  		},
    97  	}
    98  
    99  	for _, test := range tests {
   100  		t.Run(test.name, func(t *testing.T) {
   101  			promise := promiseWithReason{
   102  				promise: new(mockedPromise),
   103  				errWin:  new(errorWindow),
   104  			}
   105  			if len(test.reason) == 0 {
   106  				promise.Accept()
   107  			} else {
   108  				promise.Reject(test.reason)
   109  			}
   110  
   111  			assert.True(t, strings.Contains(promise.errWin.String(), test.expect))
   112  		})
   113  	}
   114  }
   115  
   116  func BenchmarkGoogleBreaker(b *testing.B) {
   117  	br := NewBreaker()
   118  	for i := 0; i < b.N; i++ {
   119  		_ = br.Do(func() error {
   120  			return nil
   121  		})
   122  	}
   123  }
   124  
   125  type mockedPromise struct{}
   126  
   127  func (m *mockedPromise) Accept() {
   128  }
   129  
   130  func (m *mockedPromise) Reject() {
   131  }